1 /* check-sources:disable-copyright-check */
2 /* unit test the code in droplet.c */
3 #include <sys/types.h>
4 #include <limits.h>
5 #include <stdio.h>
6 #include <unistd.h>
7 #include <stdlib.h>
8 #include <errno.h>
9 #include <check.h>
10 #include <droplet.h>
11
12 #include "utest_main.h"
13
START_TEST(status_str_test)14 START_TEST(status_str_test)
15 {
16 dpl_assert_str_eq("DPL_SUCCESS", dpl_status_str(0));
17 dpl_assert_str_eq("DPL_SUCCESS", dpl_status_str(DPL_SUCCESS));
18 dpl_assert_str_eq("DPL_FAILURE", dpl_status_str(DPL_FAILURE));
19 /* lots of others, just try one */
20 dpl_assert_str_eq("DPL_ECONNECT", dpl_status_str(DPL_ECONNECT));
21 /* we get a non-null string when passing completely bogus error codes */
22 dpl_assert_ptr_not_null(dpl_status_str(3000));
23 dpl_assert_ptr_not_null(dpl_status_str(-3000));
24 }
25 END_TEST
26
START_TEST(init_test)27 START_TEST(init_test)
28 {
29 dpl_init();
30 dpl_free();
31 }
32 END_TEST
33
START_TEST(option_test)34 START_TEST(option_test)
35 {
36 dpl_status_t r;
37 dpl_option_t opt;
38 dpl_option_t* o2;
39
40 /* the API has no initialiser macro or dpl_option_new() */
41 memset(&opt, 0xff, sizeof(opt));
42
43 /* testcases where parsing fails */
44 #define TESTCASE(str, err) \
45 { \
46 r = dpl_parse_option(str, &opt); \
47 dpl_assert_int_eq(err, r); \
48 }
49
50 /* colons are necessary (which is dumb, but there it is) */
51 TESTCASE("lazy", DPL_EINVAL);
52 /* a bogus option name fails cleanly */
53 TESTCASE("i_am_so_bogus:", DPL_EINVAL);
54
55 #undef TESTCASE
56 /* testcases where parsing succeeds */
57 #define TESTCASE(str, maskval, expvers, forvers) \
58 r = dpl_parse_option(str, &opt); \
59 dpl_assert_int_eq(DPL_SUCCESS, r); \
60 dpl_assert_int_eq(maskval, opt.mask); \
61 dpl_assert_str_eq(expvers, opt.expect_version); \
62 dpl_assert_str_eq(forvers, opt.force_version); \
63 o2 = dpl_option_dup(&opt); \
64 dpl_assert_int_eq(maskval, o2->mask); \
65 dpl_assert_str_eq(expvers, o2->expect_version); \
66 dpl_assert_str_eq(forvers, o2->force_version); \
67 dpl_option_free(o2)
68
69 /* an empty string is a valid set of options */
70 TESTCASE("", 0, "", "");
71 /* run through all the options to make sure they are parsed correctly */
72 TESTCASE("lazy:", DPL_OPTION_LAZY, "", "");
73 TESTCASE("http_compat:", DPL_OPTION_HTTP_COMPAT, "", "");
74 TESTCASE("raw:", DPL_OPTION_RAW, "", "");
75 TESTCASE("append_metadata:", DPL_OPTION_APPEND_METADATA, "", "");
76 TESTCASE("consistent:", DPL_OPTION_CONSISTENT, "", "");
77 TESTCASE("expect_version:123", DPL_OPTION_EXPECT_VERSION, "123", "");
78 TESTCASE("force_version:123", DPL_OPTION_FORCE_VERSION, "", "123");
79 /* two options separated by various separators */
80 TESTCASE("lazy: http_compat:", DPL_OPTION_LAZY | DPL_OPTION_HTTP_COMPAT, "",
81 "");
82 TESTCASE("lazy:,http_compat:", DPL_OPTION_LAZY | DPL_OPTION_HTTP_COMPAT, "",
83 "");
84 TESTCASE("lazy:;http_compat:", DPL_OPTION_LAZY | DPL_OPTION_HTTP_COMPAT, "",
85 "");
86 /* many options */
87 TESTCASE("lazy: http_compat: raw: append_metadata: consistent:",
88 DPL_OPTION_LAZY | DPL_OPTION_HTTP_COMPAT | DPL_OPTION_RAW
89 | DPL_OPTION_APPEND_METADATA | DPL_OPTION_CONSISTENT,
90 "", "");
91 /* order doesn't matter */
92 TESTCASE("http_compat: lazy:", DPL_OPTION_LAZY | DPL_OPTION_HTTP_COMPAT, "",
93 "");
94 TESTCASE("append_metadata: http_compat: raw: consistent: lazy:",
95 DPL_OPTION_LAZY | DPL_OPTION_HTTP_COMPAT | DPL_OPTION_RAW
96 | DPL_OPTION_APPEND_METADATA | DPL_OPTION_CONSISTENT,
97 "", "");
98
99 #undef TESTCASE
100 }
101 END_TEST
102
START_TEST(condition_test)103 START_TEST(condition_test)
104 {
105 dpl_status_t r;
106 int i;
107 dpl_condition_t cond;
108 dpl_condition_t* c2;
109
110 /* the API has no initialiser macro or dpl_condition_new() */
111 memset(&cond, 0xff, sizeof(cond));
112
113 /* testcases where parsing fails */
114 #define TESTCASE(str, err) \
115 { \
116 r = dpl_parse_condition(str, &cond); \
117 dpl_assert_int_eq(err, r); \
118 }
119
120 /* colons are necessary (which is dumb, but there it is) */
121 TESTCASE("if-match", DPL_EINVAL);
122 /* a bogus option name fails cleanly */
123 TESTCASE("i_am_so_bogus:", DPL_EINVAL);
124 /* an etag which is too long */
125 TESTCASE(
126 "if-none-match:"
127 "ecf3245105b18821eda700c279ba9ae39af72c169574ea47e3c37037744fb444710f4f31"
128 "d655894305f380b0a8c1aa83",
129 DPL_EINVAL);
130 /* an invalid time string */
131 TESTCASE("if-modified-since:356-Flubuary-20789", DPL_EINVAL);
132 /* too many conditions */
133 TESTCASE(
134 "if-match:a if-match:b if-match:c if-match:d if-match:e "
135 "if-match:f if-match:g if-match:h if-match:i if-match:j "
136 "if-match:k",
137 DPL_ENAMETOOLONG);
138
139 #undef TESTCASE
140 /* testcases where parsing succeeds */
141 #define TESTCASE(str, ...) \
142 { \
143 const dpl_condition_one_t _e[] = {__VA_ARGS__}; \
144 int _n = sizeof(_e) / sizeof(_e[0]); \
145 r = dpl_parse_condition(str, &cond); \
146 dpl_assert_int_eq(DPL_SUCCESS, r); \
147 dpl_assert_int_eq(_n, cond.n_conds); \
148 for (i = 0; i < _n; i++) { \
149 dpl_assert_int_eq(_e[i].type, cond.conds[i].type); \
150 dpl_assert_int_eq(_e[i].time, cond.conds[i].time); \
151 dpl_assert_str_eq(_e[i].etag, cond.conds[i].etag); \
152 } \
153 c2 = dpl_condition_dup(&cond); \
154 dpl_assert_ptr_not_null(c2); \
155 dpl_assert_int_eq(0, memcmp(c2, &cond, sizeof(cond))); \
156 dpl_condition_free(c2); \
157 }
158
159 /* an empty string is a valid set of conditions */
160 TESTCASE("");
161 /* run through all the conditions to make sure they are parsed correctly */
162 TESTCASE("if-match:5eaebe6fcda83fa5c9904836314df05d",
163 {.type = DPL_CONDITION_IF_MATCH,
164 .etag = "5eaebe6fcda83fa5c9904836314df05d"});
165 TESTCASE("if-none-match:3381508f73d74f53a76a8d748f4b2a6d",
166 {.type = DPL_CONDITION_IF_NONE_MATCH,
167 .etag = "3381508f73d74f53a76a8d748f4b2a6d"});
168 TESTCASE("if-modified-since:15-Oct-2010()03:19:52()+1100",
169 {.type = DPL_CONDITION_IF_MODIFIED_SINCE, .time = 1287073192L});
170 TESTCASE("if-unmodified-since:5-Oct-2010()03:19:52()+1100",
171 {.type = DPL_CONDITION_IF_UNMODIFIED_SINCE, .time = 1286209192L});
172 /* multiple conditions */
173 TESTCASE("if-match:a if-match:b",
174 {.type = DPL_CONDITION_IF_MATCH, .etag = "a"},
175 {.type = DPL_CONDITION_IF_MATCH, .etag = "b"});
176 TESTCASE("if-match:a if-none-match:b if-match:c",
177 {.type = DPL_CONDITION_IF_MATCH, .etag = "a"},
178 {.type = DPL_CONDITION_IF_NONE_MATCH, .etag = "b"},
179 {.type = DPL_CONDITION_IF_MATCH, .etag = "c"});
180
181 #undef TESTCASE
182 }
183 END_TEST
184
droplet_suite()185 Suite* droplet_suite()
186 {
187 Suite* s = suite_create("droplet");
188 TCase* t = tcase_create("base");
189 tcase_add_test(t, status_str_test);
190 tcase_add_test(t, init_test);
191 tcase_add_test(t, option_test);
192 tcase_add_test(t, condition_test);
193 suite_add_tcase(s, t);
194 return s;
195 }
196