]> begriffs open source - libpw/blob - test.c
More information about dummy hash choice vs NULL
[libpw] / test.c
1 #include "pw.h"
2 #include "vendor/tap.h"
3
4 // posix for clock/timer functions
5 #define _POSIX_C_SOURCE 200112L
6
7 #include <math.h>
8 #include <stdbool.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <time.h>
12
13 bool get_monotonic_timestamp(double *ts);
14
15 int main(int argc, char **argv){
16         sqlite3 *db = NULL;
17         int rc;
18
19         if (argc != 2)
20         {
21                 fprintf(stderr, "Usage: %s DATABASE\n", argv[0]);
22                 goto fail;
23         }
24         rc = sqlite3_open(argv[1], &db);
25         if( rc ){
26                 fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
27                 goto fail;
28         }
29
30         pw_context *ctx;
31         pw_init_context(db, &ctx);
32
33         char *u1  = "foo@example.com", *p1 = "password123",
34                  *u1c = "FOO@EXAMPLE.COM";
35
36         plan(6);
37
38         ok(PW_OK == pw_set(ctx, u1, p1), "pw_set");
39
40         ok(PW_OK == pw_check(ctx, u1, p1),
41                 "pw_check accepts the same credentials");
42
43         ok(PW_OK == pw_check(ctx, u1c, p1),
44                 "pw_check also accepts mixed case user");
45         ok(PW_BAD_PASS == pw_check(ctx, u1, "wrong"),
46                 "pw_check fails for wrong pass");
47         ok(PW_NO_USER == pw_check(ctx, "fake", "wrong"),
48                 "pw_check fails for missing user");
49
50         int i;
51         double start, end,
52                t_found, t_notfound,
53                    pct_diff;
54
55         diag("check password 100 times");
56         get_monotonic_timestamp(&start);
57         for (i = 0; i < 100; i++)
58                 pw_check(ctx, u1, p1);
59         get_monotonic_timestamp(&end);
60         t_found = end - start;
61
62         diag("check 100 times for missing user");
63         get_monotonic_timestamp(&start);
64         for (i = 0; i < 100; i++)
65                 pw_check(ctx, "fake", "wrong");
66         get_monotonic_timestamp(&end);
67         t_notfound = end - start;
68
69         pct_diff = 100.0 *
70                 fabs( (t_found - t_notfound) / ((t_found + t_notfound)/2) );
71
72         cmp_ok(pct_diff, "<", 1.0, "less than 1%% time difference");
73
74         free(ctx);
75         sqlite3_close(db);
76         return 0;
77
78 fail:
79         sqlite3_close(db);
80         return EXIT_FAILURE;
81 }
82
83 // idea for using double representation taken from
84 // https://github.com/solemnwarning/timespec
85 #define NSEC_PER_SEC 1000000000
86 bool get_monotonic_timestamp(double *ts)
87 {
88         struct timespec now;
89         int rc = clock_gettime(CLOCK_MONOTONIC, &now);
90         if (rc != 0)
91                 return false;
92         *ts = (
93                  ((double)now.tv_sec) +
94                 (((double)now.tv_nsec) / NSEC_PER_SEC)
95         );
96         return true;
97 }