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 
START_TESTnull10 START_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 }
32 END_TEST
33 
START_TESTnull34 START_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 }
57 END_TEST
58 
START_TESTnull59 START_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 }
91 END_TEST
92 
START_TESTnull93 START_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 }
122 END_TEST
123 
START_TESTnull124 START_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 }
136 END_TEST
137 
START_TESTnull138 START_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 }
150 END_TEST
151 
START_TESTnull152 START_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 }
164 END_TEST
165 
almost_equal(double a, double b)166 static bool almost_equal(double a, double b)
167 {
168     return fabs(a - b) < 0.00001;
169 }
170 
START_TESTnull171 START_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 }
178 END_TEST
179 
START_TESTnull180 START_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 }
195 END_TEST
196 
util_suite(void)197 static 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 
217 int
main(void)218 main (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