]>
Commit | Line | Data |
---|---|---|
6c7cee42 RD |
1 | #include "clar_libgit2.h" |
2 | #include "transports/smart.h" | |
3 | ||
4 | enum expected_status { | |
5 | PARSE_SUCCESS, | |
6 | PARSE_FAILURE | |
7 | }; | |
8 | ||
9 | static void assert_flush_parses(const char *line) | |
10 | { | |
11 | size_t linelen = strlen(line) + 1; | |
12 | const char *endptr; | |
13 | git_pkt *pkt; | |
14 | ||
15 | cl_git_pass(git_pkt_parse_line((git_pkt **) &pkt, &endptr, line, linelen)); | |
16 | cl_assert_equal_i(pkt->type, GIT_PKT_FLUSH); | |
17 | cl_assert_equal_strn(endptr, line + 4, linelen - 4); | |
18 | ||
19 | git_pkt_free((git_pkt *) pkt); | |
20 | } | |
21 | ||
22 | static void assert_data_pkt_parses(const char *line, const char *expected_data, size_t expected_len) | |
23 | { | |
24 | size_t linelen = strlen(line) + 1; | |
25 | const char *endptr; | |
26 | git_pkt_data *pkt; | |
27 | ||
28 | cl_git_pass(git_pkt_parse_line((git_pkt **) &pkt, &endptr, line, linelen)); | |
29 | cl_assert_equal_i(pkt->type, GIT_PKT_DATA); | |
30 | cl_assert_equal_i(pkt->len, expected_len); | |
31 | cl_assert_equal_strn(pkt->data, expected_data, expected_len); | |
32 | ||
33 | git_pkt_free((git_pkt *) pkt); | |
34 | } | |
35 | ||
36 | static void assert_sideband_progress_parses(const char *line, const char *expected_data, size_t expected_len) | |
37 | { | |
38 | size_t linelen = strlen(line) + 1; | |
39 | const char *endptr; | |
40 | git_pkt_progress *pkt; | |
41 | ||
42 | cl_git_pass(git_pkt_parse_line((git_pkt **) &pkt, &endptr, line, linelen)); | |
43 | cl_assert_equal_i(pkt->type, GIT_PKT_PROGRESS); | |
44 | cl_assert_equal_i(pkt->len, expected_len); | |
45 | cl_assert_equal_strn(pkt->data, expected_data, expected_len); | |
46 | ||
47 | git_pkt_free((git_pkt *) pkt); | |
48 | } | |
49 | ||
50 | static void assert_error_parses(const char *line, const char *expected_error, size_t expected_len) | |
51 | { | |
52 | size_t linelen = strlen(line) + 1; | |
53 | const char *endptr; | |
54 | git_pkt_err *pkt; | |
55 | ||
56 | cl_git_pass(git_pkt_parse_line((git_pkt **) &pkt, &endptr, line, linelen)); | |
57 | cl_assert_equal_i(pkt->type, GIT_PKT_ERR); | |
58 | cl_assert_equal_i(pkt->len, expected_len); | |
59 | cl_assert_equal_strn(pkt->error, expected_error, expected_len); | |
60 | ||
61 | git_pkt_free((git_pkt *) pkt); | |
62 | } | |
63 | ||
64 | static void assert_ack_parses(const char *line, const char *expected_oid, enum git_ack_status expected_status) | |
65 | { | |
66 | size_t linelen = strlen(line) + 1; | |
67 | const char *endptr; | |
68 | git_pkt_ack *pkt; | |
69 | git_oid oid; | |
70 | ||
71 | cl_git_pass(git_oid_fromstr(&oid, expected_oid)); | |
72 | ||
73 | cl_git_pass(git_pkt_parse_line((git_pkt **) &pkt, &endptr, line, linelen)); | |
74 | cl_assert_equal_i(pkt->type, GIT_PKT_ACK); | |
75 | cl_assert_equal_oid(&pkt->oid, &oid); | |
76 | cl_assert_equal_i(pkt->status, expected_status); | |
77 | ||
78 | git_pkt_free((git_pkt *) pkt); | |
79 | } | |
80 | ||
81 | static void assert_nak_parses(const char *line) | |
82 | { | |
83 | size_t linelen = strlen(line) + 1; | |
84 | const char *endptr; | |
85 | git_pkt *pkt; | |
86 | ||
87 | cl_git_pass(git_pkt_parse_line((git_pkt **) &pkt, &endptr, line, linelen)); | |
88 | cl_assert_equal_i(pkt->type, GIT_PKT_NAK); | |
89 | cl_assert_equal_strn(endptr, line + 7, linelen - 7); | |
90 | ||
91 | git_pkt_free((git_pkt *) pkt); | |
92 | } | |
93 | ||
94 | static void assert_comment_parses(const char *line, const char *expected_comment) | |
95 | { | |
96 | size_t linelen = strlen(line) + 1; | |
97 | const char *endptr; | |
98 | git_pkt_comment *pkt; | |
99 | ||
100 | cl_git_pass(git_pkt_parse_line((git_pkt **) &pkt, &endptr, line, linelen)); | |
101 | cl_assert_equal_i(pkt->type, GIT_PKT_COMMENT); | |
102 | cl_assert_equal_strn(pkt->comment, expected_comment, strlen(expected_comment)); | |
103 | ||
104 | git_pkt_free((git_pkt *) pkt); | |
105 | } | |
106 | ||
107 | static void assert_ok_parses(const char *line, const char *expected_ref) | |
108 | { | |
109 | size_t linelen = strlen(line) + 1; | |
110 | const char *endptr; | |
111 | git_pkt_ok *pkt; | |
112 | ||
113 | cl_git_pass(git_pkt_parse_line((git_pkt **) &pkt, &endptr, line, linelen)); | |
114 | cl_assert_equal_i(pkt->type, GIT_PKT_OK); | |
115 | cl_assert_equal_strn(pkt->ref, expected_ref, strlen(expected_ref)); | |
116 | ||
117 | git_pkt_free((git_pkt *) pkt); | |
118 | } | |
119 | ||
120 | static void assert_unpack_parses(const char *line, bool ok) | |
121 | { | |
122 | size_t linelen = strlen(line) + 1; | |
123 | const char *endptr; | |
124 | git_pkt_unpack *pkt; | |
125 | ||
126 | cl_git_pass(git_pkt_parse_line((git_pkt **) &pkt, &endptr, line, linelen)); | |
127 | cl_assert_equal_i(pkt->type, GIT_PKT_UNPACK); | |
128 | cl_assert_equal_i(pkt->unpack_ok, ok); | |
129 | ||
130 | git_pkt_free((git_pkt *) pkt); | |
131 | } | |
132 | ||
133 | static void assert_ng_parses(const char *line, const char *expected_ref, const char *expected_msg) | |
134 | { | |
135 | size_t linelen = strlen(line) + 1; | |
136 | const char *endptr; | |
137 | git_pkt_ng *pkt; | |
138 | ||
139 | cl_git_pass(git_pkt_parse_line((git_pkt **) &pkt, &endptr, line, linelen)); | |
140 | cl_assert_equal_i(pkt->type, GIT_PKT_NG); | |
141 | cl_assert_equal_strn(pkt->ref, expected_ref, strlen(expected_ref)); | |
142 | cl_assert_equal_strn(pkt->msg, expected_msg, strlen(expected_msg)); | |
143 | ||
144 | git_pkt_free((git_pkt *) pkt); | |
145 | } | |
146 | ||
147 | #define assert_ref_parses(line, expected_oid, expected_ref, expected_capabilities) \ | |
148 | assert_ref_parses_(line, sizeof(line), expected_oid, expected_ref, expected_capabilities) | |
149 | ||
150 | static void assert_ref_parses_(const char *line, size_t linelen, const char *expected_oid, | |
151 | const char *expected_ref, const char *expected_capabilities) | |
152 | { | |
153 | const char *endptr; | |
154 | git_pkt_ref *pkt; | |
155 | git_oid oid; | |
156 | ||
157 | cl_git_pass(git_oid_fromstr(&oid, expected_oid)); | |
158 | ||
159 | cl_git_pass(git_pkt_parse_line((git_pkt **) &pkt, &endptr, line, linelen)); | |
160 | cl_assert_equal_i(pkt->type, GIT_PKT_REF); | |
161 | cl_assert_equal_oid(&pkt->head.oid, &oid); | |
162 | cl_assert_equal_strn(pkt->head.name, expected_ref, strlen(expected_ref)); | |
163 | if (expected_capabilities) | |
164 | cl_assert_equal_strn(pkt->capabilities, expected_capabilities, strlen(expected_capabilities)); | |
165 | else | |
166 | cl_assert_equal_p(NULL, pkt->capabilities); | |
167 | ||
168 | git_pkt_free((git_pkt *) pkt); | |
169 | } | |
170 | ||
171 | static void assert_pkt_fails(const char *line) | |
172 | { | |
173 | const char *endptr; | |
174 | git_pkt *pkt; | |
175 | cl_git_fail(git_pkt_parse_line(&pkt, &endptr, line, strlen(line) + 1)); | |
176 | } | |
177 | ||
178 | void test_transports_smart_packet__parsing_garbage_fails(void) | |
179 | { | |
180 | assert_pkt_fails("0foobar"); | |
181 | assert_pkt_fails("00foobar"); | |
182 | assert_pkt_fails("000foobar"); | |
183 | assert_pkt_fails("0001"); | |
184 | assert_pkt_fails(""); | |
185 | assert_pkt_fails("0"); | |
186 | assert_pkt_fails("0i00"); | |
187 | assert_pkt_fails("f"); | |
188 | } | |
189 | ||
190 | void test_transports_smart_packet__flush_parses(void) | |
191 | { | |
192 | assert_flush_parses("0000"); | |
193 | assert_flush_parses("0000foobar"); | |
194 | } | |
195 | ||
196 | void test_transports_smart_packet__data_pkt(void) | |
197 | { | |
198 | assert_pkt_fails("000foobar"); | |
199 | assert_pkt_fails("0001o"); | |
200 | assert_pkt_fails("0001\1"); | |
201 | assert_data_pkt_parses("0005\1", "", 0); | |
202 | assert_pkt_fails("0009\1o"); | |
203 | assert_data_pkt_parses("0009\1data", "data", 4); | |
204 | assert_data_pkt_parses("000a\1data", "data", 5); | |
205 | } | |
206 | ||
207 | void test_transports_smart_packet__sideband_progress_pkt(void) | |
208 | { | |
209 | assert_pkt_fails("0001\2"); | |
210 | assert_sideband_progress_parses("0005\2", "", 0); | |
211 | assert_pkt_fails("0009\2o"); | |
212 | assert_sideband_progress_parses("0009\2data", "data", 4); | |
213 | assert_sideband_progress_parses("000a\2data", "data", 5); | |
214 | } | |
215 | ||
216 | void test_transports_smart_packet__sideband_err_pkt(void) | |
217 | { | |
218 | assert_pkt_fails("0001\3"); | |
219 | assert_error_parses("0005\3", "", 0); | |
220 | assert_pkt_fails("0009\3o"); | |
221 | assert_error_parses("0009\3data", "data", 4); | |
222 | assert_error_parses("000a\3data", "data", 5); | |
223 | } | |
224 | ||
225 | void test_transports_smart_packet__ack_pkt(void) | |
226 | { | |
227 | assert_ack_parses("0030ACK 0000000000000000000000000000000000000000", | |
228 | "0000000000000000000000000000000000000000", 0); | |
229 | assert_ack_parses("0039ACK 0000000000000000000000000000000000000000 continue", | |
230 | "0000000000000000000000000000000000000000", | |
231 | GIT_ACK_CONTINUE); | |
232 | assert_ack_parses("0037ACK 0000000000000000000000000000000000000000 common", | |
233 | "0000000000000000000000000000000000000000", | |
234 | GIT_ACK_COMMON); | |
235 | assert_ack_parses("0037ACK 0000000000000000000000000000000000000000 ready", | |
236 | "0000000000000000000000000000000000000000", | |
237 | GIT_ACK_READY); | |
238 | ||
239 | /* these should fail as they don't have OIDs */ | |
240 | assert_pkt_fails("0007ACK"); | |
241 | assert_pkt_fails("0008ACK "); | |
242 | ||
243 | /* this one is missing a space and should thus fail */ | |
244 | assert_pkt_fails("0036ACK00000000000000000x0000000000000000000000 ready"); | |
245 | ||
246 | /* the following ones have invalid OIDs and should thus fail */ | |
247 | assert_pkt_fails("0037ACK 00000000000000000x0000000000000000000000 ready"); | |
248 | assert_pkt_fails("0036ACK 000000000000000000000000000000000000000 ready"); | |
249 | assert_pkt_fails("0036ACK 00000000000000000x0000000000000000000000ready"); | |
250 | ||
251 | /* this one has an invalid status and should thus fail */ | |
252 | assert_pkt_fails("0036ACK 0000000000000000000000000000000000000000 read"); | |
253 | } | |
254 | ||
255 | void test_transports_smart_packet__nak_pkt(void) | |
256 | { | |
257 | assert_nak_parses("0007NAK"); | |
258 | assert_pkt_fails("0007NaK"); | |
259 | assert_pkt_fails("0007nak"); | |
260 | assert_nak_parses("0007NAKfoobar"); | |
261 | assert_pkt_fails("0007nakfoobar"); | |
262 | assert_pkt_fails("0007 NAK"); | |
263 | } | |
264 | ||
265 | void test_transports_smart_packet__error_pkt(void) | |
266 | { | |
267 | assert_pkt_fails("0007ERR"); | |
268 | assert_pkt_fails("0008ERRx"); | |
269 | assert_error_parses("0008ERR ", "", 0); | |
270 | assert_error_parses("000EERR ERRMSG", "ERRMSG", 6); | |
271 | } | |
272 | ||
273 | void test_transports_smart_packet__comment_pkt(void) | |
274 | { | |
275 | assert_comment_parses("0005#", ""); | |
276 | assert_comment_parses("000B#foobar", "#fooba"); | |
277 | assert_comment_parses("000C#foobar", "#foobar"); | |
278 | assert_comment_parses("001A#this is a comment\nfoo", "#this is a comment\nfoo"); | |
279 | } | |
280 | ||
281 | void test_transports_smart_packet__ok_pkt(void) | |
282 | { | |
283 | assert_pkt_fails("0007ok\n"); | |
284 | assert_ok_parses("0007ok ", ""); | |
285 | assert_ok_parses("0008ok \n", ""); | |
286 | assert_ok_parses("0008ok x", "x"); | |
287 | assert_ok_parses("0009ok x\n", "x"); | |
288 | assert_pkt_fails("001OK ref/foo/bar"); | |
289 | assert_ok_parses("0012ok ref/foo/bar", "ref/foo/bar"); | |
290 | assert_pkt_fails("0013OK ref/foo/bar\n"); | |
291 | assert_ok_parses("0013ok ref/foo/bar\n", "ref/foo/bar"); | |
292 | } | |
293 | ||
294 | void test_transports_smart_packet__ng_pkt(void) | |
295 | { | |
296 | /* TODO: same as for ok pkt */ | |
297 | assert_pkt_fails("0007ng\n"); | |
298 | assert_pkt_fails("0008ng \n"); | |
299 | assert_pkt_fails("000Bng ref\n"); | |
300 | assert_pkt_fails("000Bng ref\n"); | |
301 | /* TODO: is this a valid packet line? Probably not. */ | |
302 | assert_ng_parses("000Ang x\n", "", "x"); | |
303 | assert_ng_parses("000Fng ref msg\n", "ref", "msg"); | |
304 | assert_ng_parses("000Fng ref msg\n", "ref", "msg"); | |
305 | } | |
306 | ||
307 | void test_transports_smart_packet__unpack_pkt(void) | |
308 | { | |
309 | assert_unpack_parses("000Dunpack ok", 1); | |
310 | assert_unpack_parses("000Dunpack ng error-msg", 0); | |
311 | /* TODO: the following tests should fail */ | |
312 | assert_unpack_parses("000Aunpack", 0); | |
313 | assert_unpack_parses("0011unpack foobar", 0); | |
314 | assert_unpack_parses("0010unpack ng ok", 0); | |
315 | assert_unpack_parses("0010unpack okfoo", 1); | |
316 | } | |
317 | ||
318 | void test_transports_smart_packet__ref_pkt(void) | |
319 | { | |
320 | assert_pkt_fails("002C0000000000000000000000000000000000000000"); | |
321 | assert_pkt_fails("002D0000000000000000000000000000000000000000\n"); | |
322 | assert_pkt_fails("00300000000000000000000000000000000000000000HEAD"); | |
323 | assert_pkt_fails("004800000000x0000000000000000000000000000000 refs/heads/master\0multi_ack"); | |
324 | assert_ref_parses( | |
325 | "003F0000000000000000000000000000000000000000 refs/heads/master\0", | |
326 | "0000000000000000000000000000000000000000", "refs/heads/master", ""); | |
327 | assert_ref_parses( | |
328 | "00480000000000000000000000000000000000000000 refs/heads/master\0multi_ack", | |
329 | "0000000000000000000000000000000000000000", "refs/heads/master", "multi_ack"); | |
330 | assert_ref_parses( | |
331 | "00460000000000000000000000000000000000000000 refs/heads/master\0one two", | |
332 | "0000000000000000000000000000000000000000", "refs/heads/master", "one two"); | |
333 | assert_ref_parses( | |
334 | "00310000000000000000000000000000000000000000 HEAD", | |
335 | "0000000000000000000000000000000000000000", "HEAD", NULL); | |
336 | assert_pkt_fails("0031000000000000000000000000000000000000000 HEAD"); | |
337 | assert_ref_parses( | |
338 | "00360000000000000000000000000000000000000000 HEAD HEAD", | |
339 | "0000000000000000000000000000000000000000", "HEAD HEAD", NULL); | |
340 | } |