xref: /6.0.3/moxi/src/check_util.c (revision d0366df5)
1#include <stdio.h>
2#include <stdlib.h>
3#include <math.h>
4#include <string.h>
5#include <sys/time.h>
6#include <check.h>
7
8#include "memcached.h"
9
10START_TEST (test_safe_strtoul)
11{
12    uint32_t val;
13    fail_unless(safe_strtoul("123", &val), "Failed parsing 123");
14    fail_unless(val == 123, "Didn't parse 123 to 123");
15    fail_unless(safe_strtoul("+123", &val), "Failed parsing +123");
16    fail_unless(val == 123, "Didn't parse +123 to 123");
17    fail_if(safe_strtoul("", &val), "Unexpectedly parsed an empty string.");
18    fail_if(safe_strtoul("123BOGUS", &val), "Parsed 123BOGUS");
19    /* Not sure what it does, but this works with ICC :/
20       cb_assert(!safe_strtoul("92837498237498237498029383", &val)); /* out of range */
21    */
22
23    /* extremes: */
24    /* 2**32 -1 */
25    fail_unless(safe_strtoul("4294967295", &val), "Failed parsing 4294967295");
26    fail_unless(val == 4294967295L, "4294967295 != 4294967295L somehow");
27    /* This actually works on 64-bit ubuntu
28       cb_assert(!safe_strtoul("4294967296", &val)); /* 2**32 */
29    */
30    fail_if(safe_strtoul("-1", &val), "Parsed a negative number as unsigned.");
31}
32END_TEST
33
34START_TEST (test_safe_strtoull)
35{
36    uint64_t val;
37
38    fail_unless(safe_strtoull("123", &val), "Failed parsing 123");
39    fail_unless(val == 123, "Didn't parse 123 to 123");
40    fail_unless(safe_strtoull("+123", &val), "Failed parsing +123");
41    fail_unless(val == 123, "Didn't parse +123 to 123");
42    fail_if(safe_strtoull("", &val), "Unexpectedly parsed an empty string.");
43    fail_if(safe_strtoull("123BOGUS", &val), "Parsed 123BOGUS");
44
45    fail_if(safe_strtoull("92837498237498237498029383", &val),
46            "Parsed out of range value.");
47
48    /* extremes: */
49    fail_unless(safe_strtoull("18446744073709551615", &val),
50                "Failed parsing 18446744073709551615"); /* 2**64 - 1 */
51    fail_unless(val == 18446744073709551615ULL,
52                "18446744073709551615 != 18446744073709551615ULL");
53    fail_if(safe_strtoull("18446744073709551616", &val),
54            "Parsed 18446744073709551616"); /* 2**64 */
55    fail_if(safe_strtoull("-1", &val), "Parsed a negative number as unsigned.");
56}
57END_TEST
58
59START_TEST (test_safe_strtoll)
60{
61    int64_t val;
62    fail_unless(safe_strtoll("123", &val), "Failed parsing 123");
63    fail_unless(val == 123, "123 != 123");
64    fail_unless(safe_strtoll("+123", &val), "Failed parsing +123");
65    fail_unless(val == 123, "123 != 123");
66    fail_unless(safe_strtoll("-123", &val), "Failed parsing -123");
67    fail_unless(val == -123, "-123 != -123");
68    fail_if(safe_strtoll("", &val), "Parsed an empty string"); /* empty */
69    fail_if(safe_strtoll("123BOGUS", &val), "Parsed 123BOGUS"); /* non-numeric */
70    fail_if(safe_strtoll("92837498237498237498029383", &val),
71            "Parsed out of range value"); /* out of range */
72
73    /* extremes: */
74    fail_if(safe_strtoll("18446744073709551615", &val),
75            "Parsed out of range value"); /* 2**64 - 1 */
76    fail_unless(safe_strtoll("9223372036854775807", &val),
77                "Failed parsing 9223372036854775807"); /* 2**63 - 1 */
78    fail_unless(val == 9223372036854775807LL,
79                "9223372036854775807 != 9223372036854775807LL");
80    /*
81      cb_assert(safe_strtoll("-9223372036854775808", &val)); /* -2**63 */
82      cb_assert(val == -9223372036854775808LL);
83    */
84    fail_if(safe_strtoll("-9223372036854775809", &val),
85            "Parsed out of range value"); /* -2**63 - 1 */
86
87    /* We'll allow space to terminate the string.  And leading space. */
88    fail_unless(safe_strtoll(" 123 foo", &val), "Failed parsing \" 123 foo\"");
89    fail_unless(val == 123, "\" 123 foo\" != 123");
90}
91END_TEST
92
93START_TEST (test_safe_strtol)
94{
95    int32_t val;
96    fail_unless(safe_strtol("123", &val), "Failed parsing 123");
97    fail_unless(val == 123, "123 != 123");
98    fail_unless(safe_strtol("+123", &val), "Failed parsing +123");
99    fail_unless(val == 123, "+123 != 123");
100    fail_unless(safe_strtol("-123", &val), "Failed parsing -123");
101    fail_unless(val == -123, "-123 != -123");
102    fail_if(safe_strtol("", &val), "Parsing empty string");
103    fail_if(safe_strtol("123BOGUS", &val), "Parsed 123BOGUS");
104    fail_if(safe_strtol("92837498237498237498029383", &val),
105            "Parsed out of range value.");
106
107    /* extremes: */
108    /* This actually works on 64-bit ubuntu
109       cb_assert(!safe_strtol("2147483648", &val)); /* (expt 2.0 31.0) */
110    */
111    fail_unless(safe_strtol("2147483647", &val),
112                "Failed parsing upper limit."); /* (- (expt 2.0 31) 1) */
113    fail_unless(val == 2147483647L, "2147483647 != 2147483647L");
114    /* This actually works on 64-bit ubuntu
115       cb_assert(!safe_strtol("-2147483649", &val)); /* (- (expt -2.0 31) 1) */
116    */
117
118    /* We'll allow space to terminate the string.  And leading space. */
119    fail_unless(safe_strtol(" 123 foo", &val), "Failed parsing \" 123 foo\"");
120    fail_unless(val == 123, "\" 123 foo\" != 123");
121}
122END_TEST
123
124START_TEST (test_timeval_subtract_secs)
125{
126    struct timeval tv1 = { 11, 0 };
127    struct timeval tv2 = { 13, 0 };
128    struct timeval res = { 0, 0 };
129
130    fail_if(timeval_subtract(&res, &tv2, &tv1) == 1,
131            "Expected positive result.");
132
133    fail_unless(res.tv_sec == 2, "Expected two second diff.");
134    fail_unless(res.tv_usec == 0, "Expected no millisecond diff.");
135}
136END_TEST
137
138START_TEST (test_timeval_subtract_usecs)
139{
140    struct timeval tv1 = { 0, 11 };
141    struct timeval tv2 = { 0, 13 };
142    struct timeval res = { 0, 0 };
143
144    fail_if(timeval_subtract(&res, &tv2, &tv1) == 1,
145            "Expected positive result.");
146
147    fail_unless(res.tv_sec == 0, "Expected no second diff.");
148    fail_unless(res.tv_usec == 2, "Expected two millisecond diff.");
149}
150END_TEST
151
152START_TEST (test_timeval_subtract_secs_and_usecs)
153{
154    struct timeval tv1 = { 3, 11 };
155    struct timeval tv2 = { 4, 13 };
156    struct timeval res = { 0, 0 };
157
158    fail_if(timeval_subtract(&res, &tv2, &tv1) == 1,
159            "Expected positive result.");
160
161    fail_unless(res.tv_sec == 1, "Expected one second diff.");
162    fail_unless(res.tv_usec == 2, "Expected two millisecond diff.");
163}
164END_TEST
165
166static bool almost_equal(double a, double b)
167{
168    return fabs(a - b) < 0.00001;
169}
170
171START_TEST (test_timeval_to_double_secs)
172{
173    struct timeval tv = { 3, 69825 };
174    double d = timeval_to_double(tv);
175
176    fail_unless(almost_equal(d, 3.069825), "Double conversion failed.");
177}
178END_TEST
179
180START_TEST (test_compute_stats)
181{
182    double vals[] = { 2, 4, 4, 4, 5, 5, 7, 9 };
183    struct moxi_stats stats;
184
185    compute_stats(&stats, vals, sizeof(vals) / sizeof(double));
186
187    fail_unless(almost_equal(stats.min, 2.0), "Min should be 2");
188    fail_unless(almost_equal(stats.max, 9.0), "Max should be 9");
189    fail_unless(almost_equal(stats.avg, 5.0), "Avg should be 5");
190    fail_unless(almost_equal(stats.stddev, 2.0),
191                "Standard devition should be 2.");
192    fail_unless(almost_equal(stats.ninetyfifth, 9.0),
193                "95th %%ile should be 9.");
194}
195END_TEST
196
197static Suite* util_suite (void)
198{
199    Suite *s = suite_create ("util");
200
201    /* Core test case */
202    TCase *tc_core = tcase_create ("Core");
203    tcase_add_test(tc_core, test_safe_strtoul);
204    tcase_add_test(tc_core, test_safe_strtoull);
205    tcase_add_test(tc_core, test_safe_strtoll);
206    tcase_add_test(tc_core, test_safe_strtol);
207    tcase_add_test(tc_core, test_timeval_subtract_secs);
208    tcase_add_test(tc_core, test_timeval_subtract_usecs);
209    tcase_add_test(tc_core, test_timeval_subtract_secs_and_usecs);
210    tcase_add_test(tc_core, test_timeval_to_double_secs);
211    tcase_add_test(tc_core, test_compute_stats);
212    suite_add_tcase(s, tc_core);
213
214    return s;
215}
216
217int
218main (void)
219{
220    int number_failed;
221    Suite *s = util_suite ();
222    SRunner *sr = srunner_create (s);
223    srunner_run_all (sr, CK_ENV);
224    number_failed = srunner_ntests_failed (sr);
225    srunner_free (sr);
226    return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
227}
228