Branch data Line data Source code
1 : : #include "sute.h"
2 : :
3 : : /**
4 : : * Runs precizer with the given arguments and validates output with optional
5 : : * stdout/stderr regex templates.
6 : : */
7 : 90 : static Return assert_compare_output(
8 : : const char *arguments,
9 : : const int expected_return_code,
10 : : const char *stdout_pattern_file,
11 : : const char *stderr_pattern_file)
12 : : {
13 : : /* The status that will be returned before exiting */
14 : : /* By default, assumes the function ran without errors */
15 : 90 : Return status = SUCCESS;
16 : :
17 : 90 : create(char,stdout_result);
18 : 90 : create(char,stderr_result);
19 : 90 : create(char,stdout_pattern);
20 : 90 : create(char,stderr_pattern);
21 : :
22 [ + - - + ]: 90 : if((SUCCESS & status) && arguments == NULL)
23 : : {
24 : 0 : status = FAILURE;
25 : : }
26 : :
27 : 90 : unsigned int capture_policy = ALLOW_BOTH;
28 : :
29 [ + + - + ]: 90 : if(expected_return_code != COMPLETED || stderr_pattern_file != NULL)
30 : : {
31 : 20 : capture_policy = STDERR_ALLOW;
32 : : }
33 : :
34 [ + - - + ]: 90 : run(runit(arguments,stdout_result,stderr_result,expected_return_code,capture_policy));
35 : :
36 [ + + ]: 90 : if(stdout_pattern_file != NULL)
37 : : {
38 [ + - - + ]: 84 : run(get_file_content(stdout_pattern_file,stdout_pattern));
39 [ + - - + ]: 84 : run(match_pattern(stdout_result,stdout_pattern,stdout_pattern_file));
40 : : }
41 : :
42 [ + + ]: 90 : if(stderr_pattern_file != NULL)
43 : : {
44 [ + - - + ]: 20 : run(get_file_content(stderr_pattern_file,stderr_pattern));
45 [ + - - + ]: 20 : run(match_pattern(stderr_result,stderr_pattern,stderr_pattern_file));
46 : : }
47 : :
48 : 90 : del(stderr_pattern);
49 : 90 : del(stdout_pattern);
50 : 90 : del(stderr_result);
51 : 90 : del(stdout_result);
52 : :
53 [ - + - - : 90 : deliver(status);
- + + - ]
54 : : }
55 : :
56 : : /**
57 : : * Prepares two databases with known differences for compare-filter tests.
58 : : */
59 : 6 : static Return prepare_compare_filter_differences_fixture(void)
60 : : {
61 : : /* The status that will be returned before exiting */
62 : : /* By default, assumes the function ran without errors */
63 : 6 : Return status = SUCCESS;
64 : :
65 : 6 : create(char,result);
66 : :
67 [ + - - + ]: 6 : run(move_path("tests/fixtures/diffs/diff1","tests/fixtures/diff1_backup"));
68 [ + - - + ]: 6 : run(copy_path("tests/fixtures/diff1_backup","tests/fixtures/diffs/diff1"));
69 : :
70 [ + - - + ]: 6 : run(set_environment_variable("TESTING","false"));
71 : :
72 : 6 : const char *arguments = "--silent --database=database1.db tests/fixtures/diffs/diff1";
73 [ + - - + ]: 6 : run(runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
74 : :
75 [ + - - + ]: 6 : if((SUCCESS & status) && result->length != 0)
76 : : {
77 : 0 : status = FAILURE;
78 : : }
79 : :
80 [ + - - + ]: 6 : run(delete_path("tests/fixtures/diffs/diff1/2/AAA/BBB/CZC/a.txt"));
81 [ + - - + ]: 6 : run(add_string_to("AFAKDSJ","tests/fixtures/diffs/diff1/1/AAA/ZAW/D/e/f/b_file.txt"));
82 [ + - - + ]: 6 : run(replase_to_string("WNEURHGO","tests/fixtures/diffs/diff1/2/AAA/BBB/CZC/b.txt"));
83 : :
84 : 6 : arguments = "--silent --database=database2.db tests/fixtures/diffs/diff1";
85 [ + - - + ]: 6 : run(runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
86 : :
87 [ + - - + ]: 6 : if((SUCCESS & status) && result->length != 0)
88 : : {
89 : 0 : status = FAILURE;
90 : : }
91 : :
92 : 6 : del(result);
93 : :
94 [ - + - - : 6 : deliver(status);
- + + - ]
95 : : }
96 : :
97 : : /**
98 : : * Prepares two databases where only one existence side differs:
99 : : * database2 contains one extra path compared to database1.
100 : : */
101 : 2 : static Return prepare_compare_filter_one_sided_fixture(void)
102 : : {
103 : : /* The status that will be returned before exiting */
104 : : /* By default, assumes the function ran without errors */
105 : 2 : Return status = SUCCESS;
106 : :
107 : 2 : create(char,result);
108 : :
109 [ + - - + ]: 2 : run(move_path("tests/fixtures/diffs/diff1","tests/fixtures/diff1_backup"));
110 [ + - - + ]: 2 : run(copy_path("tests/fixtures/diff1_backup","tests/fixtures/diffs/diff1"));
111 : :
112 [ + - - + ]: 2 : run(set_environment_variable("TESTING","false"));
113 : :
114 : 2 : const char *arguments = "--silent --database=database1.db tests/fixtures/diffs/diff1";
115 [ + - - + ]: 2 : run(runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
116 : :
117 [ + - - + ]: 2 : if((SUCCESS & status) && result->length != 0)
118 : : {
119 : 0 : status = FAILURE;
120 : : }
121 : :
122 [ + - - + ]: 2 : run(replase_to_string("ONLY_DB2_FILE","tests/fixtures/diffs/diff1/2/AAA/BBB/CZC/only_db2.txt"));
123 : :
124 : 2 : arguments = "--silent --database=database2.db tests/fixtures/diffs/diff1";
125 [ + - - + ]: 2 : run(runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
126 : :
127 [ + - - + ]: 2 : if((SUCCESS & status) && result->length != 0)
128 : : {
129 : 0 : status = FAILURE;
130 : : }
131 : :
132 : 2 : del(result);
133 : :
134 [ - + - - : 2 : deliver(status);
- + + - ]
135 : : }
136 : :
137 : : /**
138 : : * Cleans temporary files created by the "differences" fixture.
139 : : */
140 : 8 : static Return cleanup_compare_filter_differences_fixture(void)
141 : : {
142 : : /* The status that will be returned before exiting */
143 : : /* By default, assumes the function ran without errors */
144 : 8 : Return status = SUCCESS;
145 : :
146 [ + - - + ]: 8 : run(delete_path("database1.db"));
147 [ + - - + ]: 8 : run(delete_path("database2.db"));
148 [ + - - + ]: 8 : run(delete_path("tests/fixtures/diffs/diff1"));
149 : :
150 [ + - - + ]: 8 : run(move_path("tests/fixtures/diff1_backup","tests/fixtures/diffs/diff1"));
151 : :
152 [ - + - - : 8 : deliver(status);
- + + - ]
153 : : }
154 : :
155 : : /**
156 : : * Prepares two equal databases for compare-filter tests.
157 : : */
158 : 8 : static Return prepare_compare_filter_equal_fixture(void)
159 : : {
160 : : /* The status that will be returned before exiting */
161 : : /* By default, assumes the function ran without errors */
162 : 8 : Return status = SUCCESS;
163 : :
164 : 8 : create(char,result);
165 : :
166 [ + - - + ]: 8 : run(set_environment_variable("TESTING","false"));
167 : :
168 : 8 : const char *arguments = "--silent --database=database1.db tests/fixtures/diffs/diff1";
169 [ + - - + ]: 8 : run(runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
170 : :
171 [ + - - + ]: 8 : if((SUCCESS & status) && result->length != 0)
172 : : {
173 : 0 : status = FAILURE;
174 : : }
175 : :
176 : 8 : arguments = "--silent --database=database2.db tests/fixtures/diffs/diff1";
177 [ + - - + ]: 8 : run(runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
178 : :
179 [ + - - + ]: 8 : if((SUCCESS & status) && result->length != 0)
180 : : {
181 : 0 : status = FAILURE;
182 : : }
183 : :
184 : 8 : del(result);
185 : :
186 [ - + - - : 8 : deliver(status);
- + + - ]
187 : : }
188 : :
189 : : /**
190 : : * Cleans temporary files created by the "equal" fixture.
191 : : */
192 : 6 : static Return cleanup_compare_filter_equal_fixture(void)
193 : : {
194 : : /* The status that will be returned before exiting */
195 : : /* By default, assumes the function ran without errors */
196 : 6 : Return status = SUCCESS;
197 : :
198 [ + - - + ]: 6 : run(delete_path("database1.db"));
199 [ + - - + ]: 6 : run(delete_path("database2.db"));
200 : :
201 [ - + - - : 6 : deliver(status);
- + + - ]
202 : : }
203 : :
204 : : /**
205 : : * One file is removed, updated, and added at a time
206 : : */
207 : 2 : static Return test0028_1(void)
208 : : {
209 : 2 : INITTEST;
210 : :
211 : : // Create memory for the result
212 : 2 : create(char,result);
213 : 2 : create(char,pattern);
214 : :
215 : : // Preparation for tests
216 : 2 : ASSERT(SUCCESS == move_path("tests/fixtures/diffs/diff1","tests/fixtures/diff1_backup"));
217 : 2 : ASSERT(SUCCESS == copy_path("tests/fixtures/diff1_backup","tests/fixtures/diffs/diff1"));
218 : :
219 : 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","false"));
220 : :
221 : 2 : const char *arguments = "--silent --database=database1.db tests/fixtures/diffs/diff1";
222 : :
223 : 2 : ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
224 : :
225 : 2 : ASSERT(result->length == 0);
226 : :
227 : 2 : ASSERT(SUCCESS == delete_path("tests/fixtures/diffs/diff1/2/AAA/BBB/CZC/a.txt")); // Remove
228 : 2 : ASSERT(SUCCESS == add_string_to("AFAKDSJ","tests/fixtures/diffs/diff1/1/AAA/ZAW/D/e/f/b_file.txt")); // Modify
229 : 2 : ASSERT(SUCCESS == replase_to_string("WNEURHGO","tests/fixtures/diffs/diff1/2/AAA/BBB/CZC/b.txt")); // New file
230 : :
231 : 2 : arguments = "--silent --database=database2.db tests/fixtures/diffs/diff1";
232 : :
233 : 2 : ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
234 : :
235 : 2 : ASSERT(result->length == 0);
236 : :
237 : 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
238 : :
239 : 2 : arguments = "--compare database1.db database2.db";
240 : :
241 : 2 : ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
242 : :
243 : 2 : const char *filename = "templates/0028_001.txt";
244 : :
245 : 2 : ASSERT(SUCCESS == get_file_content(filename,pattern));
246 : 2 : ASSERT(SUCCESS == match_pattern(result,pattern,filename));
247 : :
248 : 2 : del(pattern);
249 : 2 : del(result);
250 : :
251 : : // Clean up test results
252 : 2 : ASSERT(SUCCESS == delete_path("database1.db"));
253 : 2 : ASSERT(SUCCESS == delete_path("database2.db"));
254 : 2 : ASSERT(SUCCESS == delete_path("tests/fixtures/diffs/diff1"));
255 : :
256 : 2 : ASSERT(SUCCESS == move_path("tests/fixtures/diff1_backup","tests/fixtures/diffs/diff1"));
257 : :
258 : 2 : RETURN_STATUS;
259 : : }
260 : :
261 : : /**
262 : : * One file is removed. It should be reflected as a change in one of the databases.
263 : : */
264 : 2 : static Return test0028_2(void)
265 : : {
266 : 2 : INITTEST;
267 : :
268 : : // Create memory for the result
269 : 2 : create(char,result);
270 : 2 : create(char,pattern);
271 : :
272 : : // Preparation for tests
273 : 2 : ASSERT(SUCCESS == move_path("tests/fixtures/diffs/diff1","tests/fixtures/diff1_backup"));
274 : 2 : ASSERT(SUCCESS == copy_path("tests/fixtures/diff1_backup","tests/fixtures/diffs/diff1"));
275 : :
276 : 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","false"));
277 : :
278 : 2 : const char *arguments = "--silent --database=database1.db tests/fixtures/diffs/diff1";
279 : :
280 : 2 : ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
281 : :
282 : 2 : ASSERT(result->length == 0);
283 : :
284 : 2 : ASSERT(SUCCESS == delete_path("tests/fixtures/diffs/diff1/2/AAA/BBB/CZC/a.txt")); // Remove
285 : :
286 : 2 : arguments = "--silent --database=database2.db tests/fixtures/diffs/diff1";
287 : :
288 : 2 : ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
289 : :
290 : 2 : ASSERT(result->length == 0);
291 : :
292 : 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
293 : :
294 : 2 : arguments = "--compare database1.db database2.db";
295 : :
296 : 2 : ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
297 : :
298 : 2 : const char *filename = "templates/0028_002_1.txt";
299 : :
300 : 2 : ASSERT(SUCCESS == get_file_content(filename,pattern));
301 : 2 : ASSERT(SUCCESS == match_pattern(result,pattern,filename));
302 : :
303 : 2 : del(pattern);
304 : 2 : del(result);
305 : :
306 : : // Clean up test results
307 : 2 : ASSERT(SUCCESS == delete_path("database1.db"));
308 : 2 : ASSERT(SUCCESS == delete_path("database2.db"));
309 : 2 : ASSERT(SUCCESS == delete_path("tests/fixtures/diffs/diff1"));
310 : :
311 : 2 : ASSERT(SUCCESS == move_path("tests/fixtures/diff1_backup","tests/fixtures/diffs/diff1"));
312 : :
313 : 2 : RETURN_STATUS;
314 : : }
315 : :
316 : : /**
317 : : * One file is added. It should be reflected as a change in one of the databases.
318 : : */
319 : 2 : static Return test0028_3(void)
320 : : {
321 : 2 : INITTEST;
322 : :
323 : : // Create memory for the result
324 : 2 : create(char,result);
325 : 2 : create(char,pattern);
326 : :
327 : : // Preparation for tests
328 : 2 : ASSERT(SUCCESS == move_path("tests/fixtures/diffs/diff1","tests/fixtures/diff1_backup"));
329 : 2 : ASSERT(SUCCESS == copy_path("tests/fixtures/diff1_backup","tests/fixtures/diffs/diff1"));
330 : :
331 : 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","false"));
332 : :
333 : 2 : const char *arguments = "--silent --database=database1.db tests/fixtures/diffs/diff1";
334 : :
335 : 2 : ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
336 : :
337 : 2 : ASSERT(result->length == 0);
338 : :
339 : 2 : ASSERT(SUCCESS == replase_to_string("WNEURHGO","tests/fixtures/diffs/diff1/2/AAA/BBB/CZC/b.txt")); // New file
340 : :
341 : 2 : arguments = "--silent --database=database2.db tests/fixtures/diffs/diff1";
342 : :
343 : 2 : ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
344 : :
345 : 2 : ASSERT(result->length == 0);
346 : :
347 : 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
348 : :
349 : 2 : arguments = "--compare database1.db database2.db";
350 : :
351 : 2 : ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
352 : :
353 : 2 : const char *filename = "templates/0028_003_1.txt";
354 : :
355 : 2 : ASSERT(SUCCESS == get_file_content(filename,pattern));
356 : 2 : ASSERT(SUCCESS == match_pattern(result,pattern,filename));
357 : :
358 : 2 : del(pattern);
359 : 2 : del(result);
360 : :
361 : : // Clean up test results
362 : 2 : ASSERT(SUCCESS == delete_path("database1.db"));
363 : 2 : ASSERT(SUCCESS == delete_path("database2.db"));
364 : 2 : ASSERT(SUCCESS == delete_path("tests/fixtures/diffs/diff1"));
365 : :
366 : 2 : ASSERT(SUCCESS == move_path("tests/fixtures/diff1_backup","tests/fixtures/diffs/diff1"));
367 : :
368 : 2 : RETURN_STATUS;
369 : : }
370 : :
371 : : /**
372 : : * One file is updated and its checksum should change
373 : : */
374 : 2 : static Return test0028_4(void)
375 : : {
376 : 2 : INITTEST;
377 : :
378 : : // Create memory for the result
379 : 2 : create(char,result);
380 : 2 : create(char,pattern);
381 : :
382 : : // Preparation for tests
383 : 2 : ASSERT(SUCCESS == move_path("tests/fixtures/diffs/diff1","tests/fixtures/diff1_backup"));
384 : 2 : ASSERT(SUCCESS == copy_path("tests/fixtures/diff1_backup","tests/fixtures/diffs/diff1"));
385 : :
386 : 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","false"));
387 : :
388 : 2 : const char *arguments = "--silent --database=database1.db tests/fixtures/diffs/diff1";
389 : :
390 : 2 : ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
391 : :
392 : 2 : ASSERT(result->length == 0);
393 : :
394 : 2 : ASSERT(SUCCESS == add_string_to("AFAKDSJ","tests/fixtures/diffs/diff1/1/AAA/ZAW/D/e/f/b_file.txt")); // Modify
395 : :
396 : 2 : arguments = "--silent --database=database2.db tests/fixtures/diffs/diff1";
397 : :
398 : 2 : ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
399 : :
400 : 2 : ASSERT(result->length == 0);
401 : :
402 : 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
403 : :
404 : 2 : arguments = "--compare database1.db database2.db";
405 : :
406 : 2 : ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
407 : :
408 : 2 : const char *filename = "templates/0028_004.txt";
409 : :
410 : 2 : ASSERT(SUCCESS == get_file_content(filename,pattern));
411 : 2 : ASSERT(SUCCESS == match_pattern(result,pattern,filename));
412 : :
413 : 2 : del(pattern);
414 : 2 : del(result);
415 : :
416 : : // Clean up test results
417 : 2 : ASSERT(SUCCESS == delete_path("database1.db"));
418 : 2 : ASSERT(SUCCESS == delete_path("database2.db"));
419 : 2 : ASSERT(SUCCESS == delete_path("tests/fixtures/diffs/diff1"));
420 : :
421 : 2 : ASSERT(SUCCESS == move_path("tests/fixtures/diff1_backup","tests/fixtures/diffs/diff1"));
422 : :
423 : 2 : RETURN_STATUS;
424 : : }
425 : :
426 : : /**
427 : : * Nothing changes. The databases should be equivalent
428 : : */
429 : 2 : static Return test0028_5(void)
430 : : {
431 : 2 : INITTEST;
432 : :
433 : : // Create memory for the result
434 : 2 : create(char,result);
435 : 2 : create(char,pattern);
436 : :
437 : 2 : const char *arguments = "--database=database1.db tests/fixtures/diffs/diff1";
438 : :
439 : 2 : ASSERT(SUCCESS == runit(arguments,NULL,NULL,COMPLETED,ALLOW_BOTH));
440 : :
441 : 2 : arguments = "--database=database2.db tests/fixtures/diffs/diff1";
442 : :
443 : 2 : ASSERT(SUCCESS == runit(arguments,NULL,NULL,COMPLETED,ALLOW_BOTH));
444 : :
445 : 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
446 : :
447 : 2 : arguments = "--compare database1.db database2.db";
448 : :
449 : 2 : ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
450 : :
451 : 2 : const char *filename = "templates/0028_005.txt";
452 : :
453 : 2 : ASSERT(SUCCESS == get_file_content(filename,pattern));
454 : 2 : ASSERT(SUCCESS == match_pattern(result,pattern,filename));
455 : :
456 : 2 : del(pattern);
457 : 2 : del(result);
458 : :
459 : : // Clean up test results
460 : 2 : ASSERT(SUCCESS == delete_path("database1.db"));
461 : 2 : ASSERT(SUCCESS == delete_path("database2.db"));
462 : :
463 : 2 : RETURN_STATUS;
464 : : }
465 : :
466 : : /**
467 : : * Compare-filter combinations in compare mode and argument validation.
468 : : */
469 : 2 : static Return test0028_6(void)
470 : : {
471 : 2 : INITTEST;
472 : :
473 : : struct compare_filter_case {
474 : : const char *arguments;
475 : : int expected_return_code;
476 : : const char *stdout_pattern_file;
477 : : const char *stderr_pattern_file;
478 : : };
479 : :
480 : 2 : const struct compare_filter_case equal_cases[] = {
481 : : // Valid combinations with --compare for equal databases
482 : : {"--compare database1.db database2.db",COMPLETED,"templates/0028_005.txt",NULL},
483 : : {"--compare --compare-filter=checksum-mismatch database1.db database2.db",COMPLETED,"templates/0028_006_1.txt",NULL},
484 : : {"--compare database1.db database2.db --compare-filter=checksum-mismatch",COMPLETED,"templates/0028_006_1.txt",NULL},
485 : : {"--compare --compare-filter=first-source database1.db database2.db",COMPLETED,"templates/0028_006_2.txt",NULL},
486 : : {"--compare --compare-filter=second-source database1.db database2.db",COMPLETED,"templates/0028_006_3.txt",NULL},
487 : : {"--compare --compare-filter=first-source --compare-filter=second-source database1.db database2.db",COMPLETED,"templates/0028_006_4.txt",NULL},
488 : : {"--compare --compare-filter=checksum-mismatch --compare-filter=first-source database1.db database2.db",COMPLETED,"templates/0028_006_5.txt",NULL},
489 : : {"--compare --compare-filter=checksum-mismatch --compare-filter=second-source database1.db database2.db",COMPLETED,"templates/0028_006_6.txt",NULL},
490 : : {"--compare --compare-filter=checksum-mismatch --compare-filter=first-source --compare-filter=second-source database1.db database2.db",COMPLETED,"templates/0028_006_19.txt",NULL}
491 : : };
492 : :
493 : 2 : const struct compare_filter_case one_sided_cases[] = {
494 : : // Regression: one-sided filter must not claim full identity if opposite side has differences
495 : : {"--compare --compare-filter=first-source database1.db database2.db",COMPLETED,"templates/0028_006_7.txt",NULL},
496 : : {"--compare --compare-filter=second-source database1.db database2.db",COMPLETED,"templates/0028_006_8.txt",NULL},
497 : : {"--compare database2.db database1.db --compare-filter=first-source",COMPLETED,"templates/0028_006_17.txt",NULL},
498 : : {"--compare database2.db database1.db --compare-filter=second-source",COMPLETED,"templates/0028_006_18.txt",NULL}
499 : : };
500 : :
501 : 2 : const struct compare_filter_case differences_cases[] = {
502 : : // Valid combinations with --compare for databases with all difference categories
503 : : {"--compare database1.db database2.db",COMPLETED,"templates/0028_001.txt",NULL},
504 : : {"--compare --compare-filter=checksum-mismatch database1.db database2.db",COMPLETED,"templates/0028_006_21.txt",NULL},
505 : : {"--compare --compare-filter=first-source database1.db database2.db",COMPLETED,"templates/0028_006_9.txt",NULL},
506 : : {"--compare --compare-filter=second-source database1.db database2.db",COMPLETED,"templates/0028_006_10.txt",NULL},
507 : : {"--compare --compare-filter=checksum-mismatch --compare-filter=first-source database1.db database2.db",COMPLETED,"templates/0028_006_11.txt",NULL},
508 : : {"--compare --compare-filter=checksum-mismatch --compare-filter=second-source database1.db database2.db",COMPLETED,"templates/0028_006_12.txt",NULL},
509 : : {"--compare --compare-filter=first-source --compare-filter=second-source database1.db database2.db",COMPLETED,"templates/0028_006_13.txt",NULL},
510 : : {"--compare --compare-filter=checksum-mismatch --compare-filter=first-source --compare-filter=second-source database1.db database2.db",COMPLETED,"templates/0028_006_20.txt",NULL}
511 : : };
512 : :
513 : 2 : const struct compare_filter_case invalid_cases[] = {
514 : : // Invalid combinations: --compare-filter=value without --compare
515 : : {"--compare-filter=checksum-mismatch database1.db database2.db",FAILURE,"templates/0028_006_14.txt","templates/0028_006_15.txt"},
516 : : {"--compare-filter=first-source database1.db database2.db",FAILURE,"templates/0028_006_14.txt","templates/0028_006_15.txt"},
517 : : {"--compare-filter=second-source database1.db database2.db",FAILURE,"templates/0028_006_14.txt","templates/0028_006_15.txt"},
518 : : {"--compare-filter=checksum-mismatch --compare-filter=first-source database1.db database2.db",FAILURE,"templates/0028_006_14.txt","templates/0028_006_15.txt"},
519 : : {"--compare-filter=checksum-mismatch --compare-filter=second-source database1.db database2.db",FAILURE,"templates/0028_006_14.txt","templates/0028_006_15.txt"},
520 : : {"--compare-filter=first-source --compare-filter=second-source database1.db database2.db",FAILURE,"templates/0028_006_14.txt","templates/0028_006_15.txt"},
521 : : {"--compare-filter=checksum-mismatch --compare-filter=first-source --compare-filter=second-source database1.db database2.db",FAILURE,"templates/0028_006_14.txt","templates/0028_006_15.txt"},
522 : :
523 : : // Invalid combinations: --compare-filter without argument
524 : : {"--compare database1.db database2.db --compare-filter",FAILURE,NULL,"templates/0028_006_16.txt"},
525 : : {"--compare-filter",FAILURE,NULL,"templates/0028_006_16.txt"}
526 : : };
527 : :
528 : 2 : ASSERT(SUCCESS & prepare_compare_filter_equal_fixture());
529 : 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
530 : :
531 [ + + + - ]: 20 : for(size_t i = 0; (i < sizeof(equal_cases) / sizeof(equal_cases[0])) && (SUCCESS == status); i++)
532 : : {
533 : 18 : ASSERT(SUCCESS & assert_compare_output(
534 : : equal_cases[i].arguments,
535 : : equal_cases[i].expected_return_code,
536 : : equal_cases[i].stdout_pattern_file,
537 : : equal_cases[i].stderr_pattern_file));
538 : : }
539 : :
540 : 2 : ASSERT(SUCCESS & cleanup_compare_filter_equal_fixture());
541 : :
542 : 2 : ASSERT(SUCCESS & prepare_compare_filter_one_sided_fixture());
543 : 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
544 : :
545 [ + + + - ]: 10 : for(size_t i = 0; (i < sizeof(one_sided_cases) / sizeof(one_sided_cases[0])) && (SUCCESS == status); i++)
546 : : {
547 : 8 : ASSERT(SUCCESS & assert_compare_output(
548 : : one_sided_cases[i].arguments,
549 : : one_sided_cases[i].expected_return_code,
550 : : one_sided_cases[i].stdout_pattern_file,
551 : : one_sided_cases[i].stderr_pattern_file));
552 : : }
553 : :
554 : 2 : ASSERT(SUCCESS & cleanup_compare_filter_differences_fixture());
555 : :
556 : 2 : ASSERT(SUCCESS & prepare_compare_filter_differences_fixture());
557 : 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
558 : :
559 [ + + + - ]: 18 : for(size_t i = 0; (i < sizeof(differences_cases) / sizeof(differences_cases[0])) && (SUCCESS == status); i++)
560 : : {
561 : 16 : ASSERT(SUCCESS & assert_compare_output(
562 : : differences_cases[i].arguments,
563 : : differences_cases[i].expected_return_code,
564 : : differences_cases[i].stdout_pattern_file,
565 : : differences_cases[i].stderr_pattern_file));
566 : : }
567 : :
568 : 2 : ASSERT(SUCCESS & cleanup_compare_filter_differences_fixture());
569 : :
570 : 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
571 : :
572 [ + + + - ]: 20 : for(size_t i = 0; (i < sizeof(invalid_cases) / sizeof(invalid_cases[0])) && (SUCCESS == status); i++)
573 : : {
574 : 18 : ASSERT(SUCCESS & assert_compare_output(
575 : : invalid_cases[i].arguments,
576 : : invalid_cases[i].expected_return_code,
577 : : invalid_cases[i].stdout_pattern_file,
578 : : invalid_cases[i].stderr_pattern_file));
579 : : }
580 : :
581 : 2 : RETURN_STATUS;
582 : : }
583 : :
584 : : /**
585 : : * Invalid --compare-filter value should fail argument parsing
586 : : */
587 : 2 : static Return test0028_7(void)
588 : : {
589 : 2 : INITTEST;
590 : :
591 : 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
592 : :
593 : 2 : const char *arguments = "--compare --compare-filter=invalid-value database1.db database2.db";
594 : :
595 : 2 : ASSERT(SUCCESS & assert_compare_output(arguments,FAILURE,NULL,"templates/0028_007_1.txt"));
596 : :
597 : 2 : RETURN_STATUS;
598 : : }
599 : :
600 : : /**
601 : : * NULL vs non-NULL SHA512 rows must be reported as checksum mismatches
602 : : */
603 : 2 : static Return test0028_8(void)
604 : : {
605 : 2 : INITTEST;
606 : :
607 : 2 : ASSERT(SUCCESS & prepare_compare_filter_equal_fixture());
608 : 2 : ASSERT(SUCCESS == db_set_sha512_to_null("database2.db","1/AAA/ZAW/D/e/f/b_file.txt"));
609 : 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
610 : :
611 : 2 : ASSERT(SUCCESS & assert_compare_output("--compare database1.db database2.db",COMPLETED,"templates/0028_000.txt",NULL));
612 : :
613 : 2 : ASSERT(SUCCESS & cleanup_compare_filter_equal_fixture());
614 : :
615 : 2 : RETURN_STATUS;
616 : : }
617 : :
618 : : /**
619 : : * NULL SHA512 produced by fixture changes must be reported as a mismatch
620 : : */
621 : 2 : static Return test0028_9(void)
622 : : {
623 : 2 : INITTEST;
624 : :
625 : 2 : create(char,result);
626 : :
627 : 2 : ASSERT(SUCCESS == move_path("tests/fixtures/diffs/diff1","tests/fixtures/diff1_backup"));
628 : 2 : ASSERT(SUCCESS == copy_path("tests/fixtures/diff1_backup","tests/fixtures/diffs/diff1"));
629 : :
630 : 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","false"));
631 : :
632 : 2 : const char *arguments = "--silent --database=database1.db tests/fixtures/diffs/diff1";
633 : 2 : ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
634 : :
635 : 2 : ASSERT(result->length == 0);
636 : :
637 : 2 : ASSERT(SUCCESS == truncate_file_to_zero_size("tests/fixtures/diffs/diff1/1/AAA/ZAW/D/e/f/b_file.txt"));
638 : :
639 : 2 : arguments = "--silent --database=database2.db tests/fixtures/diffs/diff1";
640 : 2 : ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
641 : :
642 : 2 : ASSERT(result->length == 0);
643 : 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
644 : :
645 : 2 : ASSERT(SUCCESS & assert_compare_output(
646 : : "--compare database1.db database2.db",
647 : : COMPLETED,
648 : : "templates/0028_000.txt",
649 : : NULL));
650 : :
651 : 2 : ASSERT(SUCCESS == delete_path("database1.db"));
652 : 2 : ASSERT(SUCCESS == delete_path("database2.db"));
653 : 2 : ASSERT(SUCCESS == delete_path("tests/fixtures/diffs/diff1"));
654 : :
655 : 2 : ASSERT(SUCCESS == move_path("tests/fixtures/diff1_backup","tests/fixtures/diffs/diff1"));
656 : :
657 : 2 : del(result);
658 : :
659 : 2 : RETURN_STATUS;
660 : : }
661 : :
662 : : /**
663 : : * Compare mode must support attached database paths containing apostrophes
664 : : */
665 : 2 : static Return test0028_10(void)
666 : : {
667 : 2 : INITTEST;
668 : :
669 : 2 : ASSERT(SUCCESS & prepare_compare_filter_equal_fixture());
670 : 2 : ASSERT(SUCCESS == move_path("database1.db","database'1.db"));
671 : 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
672 : :
673 : 2 : ASSERT(SUCCESS & assert_compare_output(
674 : : "--compare database\\'1.db database2.db",
675 : : COMPLETED,
676 : : "templates/0028_010_1.txt",
677 : : NULL));
678 : :
679 : 2 : ASSERT(SUCCESS == delete_path("database'1.db"));
680 : 2 : ASSERT(SUCCESS == delete_path("database2.db"));
681 : :
682 : 2 : RETURN_STATUS;
683 : : }
684 : :
685 : : /**
686 : : * Silent compare mode should print only compare results
687 : : */
688 : 2 : static Return test0028_11(void)
689 : : {
690 : : /* This function was reviewed line by line by a human and is not AI-generated
691 : : Any change to this function requires separate explicit approval */
692 : :
693 : 2 : INITTEST;
694 : :
695 : 2 : create(char,result);
696 : :
697 : 2 : ASSERT(SUCCESS & prepare_compare_filter_differences_fixture());
698 : 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","false"));
699 : :
700 : 2 : ASSERT(SUCCESS & assert_compare_output("--silent --compare database1.db database2.db",COMPLETED,"templates/0028_011_1.txt",NULL));
701 : 2 : ASSERT(SUCCESS & assert_compare_output("--silent --compare --compare-filter=first-source database1.db database2.db",COMPLETED,"templates/0028_011_2.txt",NULL));
702 : 2 : ASSERT(SUCCESS & assert_compare_output("--silent --compare --compare-filter=second-source database1.db database2.db",COMPLETED,"templates/0028_011_5.txt",NULL));
703 : 2 : ASSERT(SUCCESS & assert_compare_output("--silent --compare --compare-filter=checksum-mismatch database1.db database2.db",COMPLETED,"templates/0028_011_3.txt",NULL));
704 : 2 : ASSERT(SUCCESS & assert_compare_output("--silent --compare --compare-filter=first-source --compare-filter=second-source database1.db database2.db",COMPLETED,"templates/0028_011_4.txt",NULL));
705 : :
706 : 2 : ASSERT(SUCCESS & cleanup_compare_filter_differences_fixture());
707 : :
708 : 2 : ASSERT(SUCCESS & prepare_compare_filter_equal_fixture());
709 : 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","false"));
710 : :
711 : 2 : ASSERT(SUCCESS == runit("--silent --compare database1.db database2.db",result,NULL,COMPLETED,ALLOW_BOTH));
712 : 2 : ASSERT(result->length == 0);
713 : :
714 : 2 : ASSERT(SUCCESS & cleanup_compare_filter_equal_fixture());
715 : :
716 : 2 : del(result);
717 : :
718 : 2 : RETURN_STATUS;
719 : : }
720 : :
721 : : /**
722 : : * Compare mode must apply --ignore and --include to the reported compare scope
723 : : *
724 : : * Hidden paths are treated as out of scope for category listings, category
725 : : * summaries, and final equality messages. Paths restored with --include become
726 : : * visible again even when they also match an --ignore pattern
727 : : */
728 : 2 : static Return test0028_12(void)
729 : : {
730 : 2 : INITTEST;
731 : :
732 : 2 : ASSERT(SUCCESS & prepare_compare_filter_differences_fixture());
733 : 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
734 : :
735 : : // All three raw differences are filtered out, so the filtered compare scope is fully identical
736 : 2 : ASSERT(SUCCESS & assert_compare_output("--compare --ignore=\"^1/AAA/ZAW/D/e/f/b_file\\.txt$\" --ignore=\"^2/AAA/BBB/CZC/.*$\" database1.db database2.db",COMPLETED,"templates/0028_012_1.txt",NULL));
737 : :
738 : : // Restore only the first-source path a.txt; the hidden checksum mismatch stays outside the reported scope
739 : 2 : ASSERT(SUCCESS & assert_compare_output("--compare --ignore=\"^1/AAA/ZAW/D/e/f/b_file\\.txt$\" --ignore=\"^2/AAA/BBB/CZC/.*$\" --include=\"^2/AAA/BBB/CZC/a\\.txt$\" database1.db database2.db",COMPLETED,"templates/0028_012_2.txt",NULL));
740 : :
741 : : // Keep only the first-source path a.txt visible by filtering out the checksum mismatch and the opposite-side path
742 : 2 : ASSERT(SUCCESS & assert_compare_output("--compare --ignore=\"^1/AAA/ZAW/D/e/f/b_file\\.txt$\" --ignore=\"^2/AAA/BBB/CZC/b\\.txt$\" database1.db database2.db",COMPLETED,"templates/0028_012_3.txt",NULL));
743 : :
744 : : // Hide only a.txt so the remaining reported scope still contains the opposite-side path and the checksum mismatch
745 : 2 : ASSERT(SUCCESS & assert_compare_output("--compare --ignore=\"^2/AAA/BBB/CZC/a\\.txt$\" database1.db database2.db",COMPLETED,"templates/0028_012_4.txt",NULL));
746 : :
747 : : // Ignore everything, then restore only b.txt; the checksum mismatch remains intentionally out of scope
748 : 2 : ASSERT(SUCCESS & assert_compare_output("--compare --ignore=\"^.*$\" --include=\"^2/AAA/BBB/CZC/b\\.txt$\" database1.db database2.db",COMPLETED,"templates/0028_012_5.txt",NULL));
749 : :
750 : : // Ignore the whole 2/ subtree, then restore both existence-side differences while the 1/ checksum mismatch remains visible
751 : 2 : ASSERT(SUCCESS & assert_compare_output("--compare --ignore=\"^2/.*$\" --include=\"^2/AAA/BBB/CZC/a\\.txt$\" --include=\"^2/AAA/BBB/CZC/b\\.txt$\" database1.db database2.db",COMPLETED,"templates/0028_012_6.txt",NULL));
752 : :
753 : 2 : ASSERT(SUCCESS & cleanup_compare_filter_differences_fixture());
754 : :
755 : 2 : RETURN_STATUS;
756 : : }
757 : :
758 : : /**
759 : : *
760 : : * Testing the --compare mode across different types of responses
761 : : *
762 : : */
763 : 2 : Return test0028(void)
764 : : {
765 : 2 : INITTEST;
766 : :
767 : 2 : TEST(test0028_1,"One file is removed, updated, and added at a time…");
768 : 2 : TEST(test0028_2,"One file is removed. It should be reflected as a change in one of the databases…");
769 : 2 : TEST(test0028_3,"One file is added. It should be reflected as a change in one of the databases…");
770 : 2 : TEST(test0028_4,"One file is updated and its checksum should change…");
771 : 2 : TEST(test0028_5,"Nothing changes. The databases should be equivalent…");
772 : 2 : TEST(test0028_6,"All supported --compare-filter combinations should behave as expected…");
773 : 2 : TEST(test0028_7,"Invalid --compare-filter value should fail with an argument parsing error…");
774 : 2 : TEST(test0028_8,"NULL and non-NULL SHA512 values should be reported as mismatches…");
775 : 2 : TEST(test0028_9,"NULL SHA512 created from fixture changes should be reported as a mismatch…");
776 : 2 : TEST(test0028_10,"Compare mode should work with database names containing apostrophes…");
777 : 2 : TEST(test0028_11,"Silent compare mode should print only compare results…");
778 : 2 : TEST(test0028_12,"Compare mode should apply --ignore and --include to the reported comparison scope, including summaries and equality messages…");
779 : :
780 : 2 : RETURN_STATUS;
781 : : }
|