Branch data Line data Source code
1 : : #include "sute.h"
2 : : #include "db_upgrade.h"
3 : :
4 : : #define LEGACY_V3_UTF8_DB "0015_database_v3 это база данных с пробелами и символами UTF-8.db"
5 : : #define LEGACY_V4_UTF8_DB "0015_database_v4 это база данных с пробелами и символами UTF-8.db"
6 : :
7 : 38 : static Return open_db_from_tmpdir(
8 : : const char *db_filename,
9 : : const int open_flags,
10 : : sqlite3 **db_out)
11 : : {
12 : : /* Status returned by this function through provide()
13 : : Default value assumes successful completion */
14 : 38 : Return status = SUCCESS;
15 : :
16 : 38 : create(char,db_path);
17 : :
18 [ + - - + ]: 38 : if(db_filename == NULL || db_out == NULL)
19 : : {
20 : 0 : status = FAILURE;
21 : : }
22 : :
23 [ + - ]: 38 : if(SUCCESS == status)
24 : : {
25 : 38 : status = construct_path(db_filename,db_path);
26 : : }
27 : :
28 [ + - ]: 38 : if(SUCCESS == status)
29 : : {
30 : 38 : *db_out = NULL;
31 : :
32 [ - + ]: 38 : if(SQLITE_OK != sqlite3_open_v2(getcstring(db_path),db_out,open_flags,NULL))
33 : : {
34 : 0 : status = FAILURE;
35 : :
36 [ # # ]: 0 : if(*db_out != NULL)
37 : : {
38 : 0 : (void)sqlite3_close(*db_out);
39 : 0 : *db_out = NULL;
40 : : }
41 : : }
42 : : }
43 : :
44 : 38 : del(db_path);
45 : :
46 : 38 : return(status);
47 : : }
48 : :
49 : 6 : static Return read_first_row_id(
50 : : const char *db_filename,
51 : : sqlite3_int64 *row_id_out)
52 : : {
53 : : /* Status returned by this function through provide()
54 : : Default value assumes successful completion */
55 : 6 : Return status = SUCCESS;
56 : 6 : sqlite3 *db = NULL;
57 : 6 : sqlite3_stmt *stmt = NULL;
58 : 6 : const char *sql = "SELECT ID FROM files ORDER BY ID ASC LIMIT 1;";
59 : :
60 [ + - - + ]: 6 : if(db_filename == NULL || row_id_out == NULL)
61 : : {
62 : 0 : status = FAILURE;
63 : : }
64 : :
65 [ + - ]: 6 : if(SUCCESS == status)
66 : : {
67 : 6 : status = open_db_from_tmpdir(db_filename,SQLITE_OPEN_READONLY,&db);
68 : : }
69 : :
70 [ + - - + ]: 6 : if(SUCCESS == status && SQLITE_OK != sqlite3_prepare_v2(db,sql,-1,&stmt,NULL))
71 : : {
72 : 0 : status = FAILURE;
73 : : }
74 : :
75 [ + - ]: 6 : if(SUCCESS == status)
76 : : {
77 : 6 : int rc = sqlite3_step(stmt);
78 : :
79 [ + - ]: 6 : if(SQLITE_ROW == rc)
80 : : {
81 : 6 : *row_id_out = sqlite3_column_int64(stmt,0);
82 : 6 : rc = sqlite3_step(stmt);
83 : :
84 [ - + ]: 6 : if(SQLITE_DONE != rc)
85 : : {
86 : 0 : status = FAILURE;
87 : : }
88 : : } else {
89 : 0 : status = FAILURE;
90 : : }
91 : : }
92 : :
93 [ + - ]: 6 : if(stmt != NULL)
94 : : {
95 : 6 : (void)sqlite3_finalize(stmt);
96 : : }
97 : :
98 [ + - ]: 6 : if(db != NULL)
99 : : {
100 : 6 : (void)sqlite3_close(db);
101 : : }
102 : :
103 : 6 : return(status);
104 : : }
105 : :
106 : 4 : static Return overwrite_stat_blob_by_row_id(
107 : : const char *db_filename,
108 : : const sqlite3_int64 row_id,
109 : : const void *blob,
110 : : const int blob_size)
111 : : {
112 : : /* Status returned by this function through provide()
113 : : Default value assumes successful completion */
114 : 4 : Return status = SUCCESS;
115 : 4 : sqlite3 *db = NULL;
116 : 4 : sqlite3_stmt *stmt = NULL;
117 : 4 : const char *sql = "UPDATE files SET stat = ?1 WHERE ID = ?2;";
118 : :
119 [ + - + - : 4 : if(db_filename == NULL || blob == NULL || blob_size < 0)
- + ]
120 : : {
121 : 0 : status = FAILURE;
122 : : }
123 : :
124 [ + - ]: 4 : if(SUCCESS == status)
125 : : {
126 : 4 : status = open_db_from_tmpdir(db_filename,SQLITE_OPEN_READWRITE,&db);
127 : : }
128 : :
129 [ + - - + ]: 4 : if(SUCCESS == status && SQLITE_OK != sqlite3_prepare_v2(db,sql,-1,&stmt,NULL))
130 : : {
131 : 0 : status = FAILURE;
132 : : }
133 : :
134 [ + - - + ]: 4 : if(SUCCESS == status && SQLITE_OK != sqlite3_bind_blob(stmt,1,blob,blob_size,SQLITE_TRANSIENT))
135 : : {
136 : 0 : status = FAILURE;
137 : : }
138 : :
139 [ + - - + ]: 4 : if(SUCCESS == status && SQLITE_OK != sqlite3_bind_int64(stmt,2,row_id))
140 : : {
141 : 0 : status = FAILURE;
142 : : }
143 : :
144 [ + - - + ]: 4 : if(SUCCESS == status && SQLITE_DONE != sqlite3_step(stmt))
145 : : {
146 : 0 : status = FAILURE;
147 : : }
148 : :
149 [ + - - + ]: 4 : if(SUCCESS == status && sqlite3_changes(db) < 1)
150 : : {
151 : 0 : status = FAILURE;
152 : : }
153 : :
154 [ + - ]: 4 : if(stmt != NULL)
155 : : {
156 : 4 : (void)sqlite3_finalize(stmt);
157 : : }
158 : :
159 [ + - ]: 4 : if(db != NULL)
160 : : {
161 : 4 : (void)sqlite3_close(db);
162 : : }
163 : :
164 : 4 : return(status);
165 : : }
166 : :
167 : 2 : static Return read_files_count(
168 : : const char *db_filename,
169 : : int *count_out)
170 : : {
171 : : /* Status returned by this function through provide()
172 : : Default value assumes successful completion */
173 : 2 : Return status = SUCCESS;
174 : 2 : sqlite3 *db = NULL;
175 : 2 : sqlite3_stmt *stmt = NULL;
176 : 2 : const char *sql = "SELECT COUNT(*) FROM files;";
177 : :
178 [ + - - + ]: 2 : if(db_filename == NULL || count_out == NULL)
179 : : {
180 : 0 : status = FAILURE;
181 : : }
182 : :
183 [ + - ]: 2 : if(SUCCESS == status)
184 : : {
185 : 2 : status = open_db_from_tmpdir(db_filename,SQLITE_OPEN_READONLY,&db);
186 : : }
187 : :
188 [ + - - + ]: 2 : if(SUCCESS == status && SQLITE_OK != sqlite3_prepare_v2(db,sql,-1,&stmt,NULL))
189 : : {
190 : 0 : status = FAILURE;
191 : : }
192 : :
193 [ + - ]: 2 : if(SUCCESS == status)
194 : : {
195 : 2 : int rc = sqlite3_step(stmt);
196 : :
197 [ + - ]: 2 : if(SQLITE_ROW == rc)
198 : : {
199 : 2 : *count_out = sqlite3_column_int(stmt,0);
200 : 2 : rc = sqlite3_step(stmt);
201 : :
202 [ - + ]: 2 : if(SQLITE_DONE != rc)
203 : : {
204 : 0 : status = FAILURE;
205 : : }
206 : : } else {
207 : 0 : status = FAILURE;
208 : : }
209 : : }
210 : :
211 [ + - ]: 2 : if(stmt != NULL)
212 : : {
213 : 2 : (void)sqlite3_finalize(stmt);
214 : : }
215 : :
216 [ + - ]: 2 : if(db != NULL)
217 : : {
218 : 2 : (void)sqlite3_close(db);
219 : : }
220 : :
221 : 2 : return(status);
222 : : }
223 : :
224 : 4 : static Return read_files_count_with_blob_size(
225 : : const char *db_filename,
226 : : const int blob_size,
227 : : int *count_out)
228 : : {
229 : : /* Status returned by this function through provide()
230 : : Default value assumes successful completion */
231 : 4 : Return status = SUCCESS;
232 : 4 : sqlite3 *db = NULL;
233 : 4 : sqlite3_stmt *stmt = NULL;
234 : 4 : const char *sql = "SELECT COUNT(*) FROM files WHERE length(stat) = ?1;";
235 : :
236 [ + - + - : 4 : if(db_filename == NULL || blob_size < 0 || count_out == NULL)
- + ]
237 : : {
238 : 0 : status = FAILURE;
239 : : }
240 : :
241 [ + - ]: 4 : if(SUCCESS == status)
242 : : {
243 : 4 : status = open_db_from_tmpdir(db_filename,SQLITE_OPEN_READONLY,&db);
244 : : }
245 : :
246 [ + - - + ]: 4 : if(SUCCESS == status && SQLITE_OK != sqlite3_prepare_v2(db,sql,-1,&stmt,NULL))
247 : : {
248 : 0 : status = FAILURE;
249 : : }
250 : :
251 [ + - - + ]: 4 : if(SUCCESS == status && SQLITE_OK != sqlite3_bind_int(stmt,1,blob_size))
252 : : {
253 : 0 : status = FAILURE;
254 : : }
255 : :
256 [ + - ]: 4 : if(SUCCESS == status)
257 : : {
258 : 4 : int rc = sqlite3_step(stmt);
259 : :
260 [ + - ]: 4 : if(SQLITE_ROW == rc)
261 : : {
262 : 4 : *count_out = sqlite3_column_int(stmt,0);
263 : 4 : rc = sqlite3_step(stmt);
264 : :
265 [ - + ]: 4 : if(SQLITE_DONE != rc)
266 : : {
267 : 0 : status = FAILURE;
268 : : }
269 : : } else {
270 : 0 : status = FAILURE;
271 : : }
272 : : }
273 : :
274 [ + - ]: 4 : if(stmt != NULL)
275 : : {
276 : 4 : (void)sqlite3_finalize(stmt);
277 : : }
278 : :
279 [ + - ]: 4 : if(db != NULL)
280 : : {
281 : 4 : (void)sqlite3_close(db);
282 : : }
283 : :
284 : 4 : return(status);
285 : : }
286 : :
287 : 10 : static Return read_db_version_from_metadata(
288 : : const char *db_filename,
289 : : int *db_version_out)
290 : : {
291 : : /* Status returned by this function through provide()
292 : : Default value assumes successful completion */
293 : 10 : Return status = SUCCESS;
294 : 10 : sqlite3 *db = NULL;
295 : 10 : sqlite3_stmt *stmt = NULL;
296 : 10 : const char *sql = "SELECT db_version FROM metadata LIMIT 1;";
297 : :
298 [ + - - + ]: 10 : if(db_filename == NULL || db_version_out == NULL)
299 : : {
300 : 0 : status = FAILURE;
301 : : }
302 : :
303 [ + - ]: 10 : if(SUCCESS == status)
304 : : {
305 : 10 : status = open_db_from_tmpdir(db_filename,SQLITE_OPEN_READONLY,&db);
306 : : }
307 : :
308 [ + - - + ]: 10 : if(SUCCESS == status && SQLITE_OK != sqlite3_prepare_v2(db,sql,-1,&stmt,NULL))
309 : : {
310 : 0 : status = FAILURE;
311 : : }
312 : :
313 [ + - ]: 10 : if(SUCCESS == status)
314 : : {
315 : 10 : int rc = sqlite3_step(stmt);
316 : :
317 [ + - ]: 10 : if(SQLITE_ROW == rc)
318 : : {
319 : 10 : *db_version_out = sqlite3_column_int(stmt,0);
320 : 10 : rc = sqlite3_step(stmt);
321 : :
322 [ - + ]: 10 : if(SQLITE_DONE != rc)
323 : : {
324 : 0 : status = FAILURE;
325 : : }
326 : : } else {
327 : 0 : status = FAILURE;
328 : : }
329 : : }
330 : :
331 [ + - ]: 10 : if(stmt != NULL)
332 : : {
333 : 10 : (void)sqlite3_finalize(stmt);
334 : : }
335 : :
336 [ + - ]: 10 : if(db != NULL)
337 : : {
338 : 10 : (void)sqlite3_close(db);
339 : : }
340 : :
341 : 10 : return(status);
342 : : }
343 : :
344 : 2 : static Return set_db_version_in_metadata(
345 : : const char *db_filename,
346 : : const int db_version)
347 : : {
348 : : /* Status returned by this function through provide()
349 : : Default value assumes successful completion */
350 : 2 : Return status = SUCCESS;
351 : 2 : sqlite3 *db = NULL;
352 : 2 : sqlite3_stmt *stmt = NULL;
353 : 2 : const char *sql = "UPDATE metadata SET db_version = ?1;";
354 : :
355 [ + - - + ]: 2 : if(db_filename == NULL || db_version < 0)
356 : : {
357 : 0 : status = FAILURE;
358 : : }
359 : :
360 [ + - ]: 2 : if(SUCCESS == status)
361 : : {
362 : 2 : status = open_db_from_tmpdir(db_filename,SQLITE_OPEN_READWRITE,&db);
363 : : }
364 : :
365 [ + - - + ]: 2 : if(SUCCESS == status && SQLITE_OK != sqlite3_prepare_v2(db,sql,-1,&stmt,NULL))
366 : : {
367 : 0 : status = FAILURE;
368 : : }
369 : :
370 [ + - - + ]: 2 : if(SUCCESS == status && SQLITE_OK != sqlite3_bind_int(stmt,1,db_version))
371 : : {
372 : 0 : status = FAILURE;
373 : : }
374 : :
375 [ + - - + ]: 2 : if(SUCCESS == status && SQLITE_DONE != sqlite3_step(stmt))
376 : : {
377 : 0 : status = FAILURE;
378 : : }
379 : :
380 [ + - - + ]: 2 : if(SUCCESS == status && sqlite3_changes(db) < 1)
381 : : {
382 : 0 : status = FAILURE;
383 : : }
384 : :
385 [ + - ]: 2 : if(stmt != NULL)
386 : : {
387 : 2 : (void)sqlite3_finalize(stmt);
388 : : }
389 : :
390 [ + - ]: 2 : if(db != NULL)
391 : : {
392 : 2 : (void)sqlite3_close(db);
393 : : }
394 : :
395 : 2 : return(status);
396 : : }
397 : :
398 : 8 : static Return read_stat_blob_by_row_id(
399 : : const char *db_filename,
400 : : const sqlite3_int64 row_id,
401 : : unsigned char *blob_out,
402 : : const size_t blob_out_size,
403 : : int *blob_size_out)
404 : : {
405 : : /* Status returned by this function through provide()
406 : : Default value assumes successful completion */
407 : 8 : Return status = SUCCESS;
408 : 8 : sqlite3 *db = NULL;
409 : 8 : sqlite3_stmt *stmt = NULL;
410 : 8 : const char *sql = "SELECT stat FROM files WHERE ID = ?1;";
411 : :
412 [ + - - + ]: 8 : if(db_filename == NULL || blob_size_out == NULL)
413 : : {
414 : 0 : status = FAILURE;
415 : : }
416 : :
417 [ + - ]: 8 : if(SUCCESS == status)
418 : : {
419 : 8 : status = open_db_from_tmpdir(db_filename,SQLITE_OPEN_READONLY,&db);
420 : : }
421 : :
422 [ + - - + ]: 8 : if(SUCCESS == status && SQLITE_OK != sqlite3_prepare_v2(db,sql,-1,&stmt,NULL))
423 : : {
424 : 0 : status = FAILURE;
425 : : }
426 : :
427 [ + - - + ]: 8 : if(SUCCESS == status && SQLITE_OK != sqlite3_bind_int64(stmt,1,row_id))
428 : : {
429 : 0 : status = FAILURE;
430 : : }
431 : :
432 [ + - ]: 8 : if(SUCCESS == status)
433 : : {
434 : 8 : int rc = sqlite3_step(stmt);
435 : :
436 [ + - ]: 8 : if(SQLITE_ROW == rc)
437 : : {
438 : 8 : const void *blob = sqlite3_column_blob(stmt,0);
439 : 8 : const int blob_size = sqlite3_column_bytes(stmt,0);
440 : :
441 [ - + ]: 8 : if(blob_size < 0)
442 : : {
443 : 0 : status = FAILURE;
444 : : }
445 : :
446 [ + - + - : 8 : if(SUCCESS == status && blob_size > 0 && blob == NULL)
- + ]
447 : : {
448 : 0 : status = FAILURE;
449 : : }
450 : :
451 [ + - + - ]: 8 : if(SUCCESS == status && blob_out != NULL)
452 : : {
453 [ - + ]: 8 : if((size_t)blob_size > blob_out_size)
454 : : {
455 : 0 : status = FAILURE;
456 [ + - ]: 8 : } else if(blob_size > 0){
457 : 8 : memcpy(blob_out,blob,(size_t)blob_size);
458 : : }
459 : : }
460 : :
461 [ + - ]: 8 : if(SUCCESS == status)
462 : : {
463 : 8 : *blob_size_out = blob_size;
464 : : }
465 : :
466 : 8 : rc = sqlite3_step(stmt);
467 : :
468 [ + - - + ]: 8 : if(SUCCESS == status && SQLITE_DONE != rc)
469 : : {
470 : 0 : status = FAILURE;
471 : : }
472 : : } else {
473 : 0 : status = FAILURE;
474 : : }
475 : : }
476 : :
477 [ + - ]: 8 : if(stmt != NULL)
478 : : {
479 : 8 : (void)sqlite3_finalize(stmt);
480 : : }
481 : :
482 [ + - ]: 8 : if(db != NULL)
483 : : {
484 : 8 : (void)sqlite3_close(db);
485 : : }
486 : :
487 : 8 : return(status);
488 : : }
489 : :
490 : 4 : static Return read_cmpctstat_by_row_id(
491 : : const char *db_filename,
492 : : const sqlite3_int64 row_id,
493 : : CmpctStat *stat_out)
494 : : {
495 : : /* Status returned by this function through provide()
496 : : Default value assumes successful completion */
497 : 4 : Return status = SUCCESS;
498 : : unsigned char raw[sizeof(CmpctStat)];
499 : 4 : int blob_size = 0;
500 : :
501 [ - + ]: 4 : if(stat_out == NULL)
502 : : {
503 : 0 : status = FAILURE;
504 : : }
505 : :
506 [ + - ]: 4 : if(SUCCESS == status)
507 : : {
508 : 4 : status = read_stat_blob_by_row_id(db_filename,row_id,raw,sizeof(raw),&blob_size);
509 : : }
510 : :
511 [ + - - + ]: 4 : if(SUCCESS == status && blob_size != (int)sizeof(CmpctStat))
512 : : {
513 : 0 : status = FAILURE;
514 : : }
515 : :
516 [ + - ]: 4 : if(SUCCESS == status)
517 : : {
518 : 4 : memcpy(stat_out,raw,sizeof(CmpctStat));
519 : : }
520 : :
521 : 4 : return(status);
522 : : }
523 : :
524 : 4 : static Return verify_zero_converted_cmpctstat(
525 : : const CmpctStat *stat)
526 : : {
527 [ - + ]: 4 : if(stat == NULL)
528 : : {
529 : 0 : return FAILURE;
530 : : }
531 : :
532 [ - + ]: 4 : if(stat->st_size != 0)
533 : : {
534 : 0 : return FAILURE;
535 : : }
536 : :
537 [ - + ]: 4 : if(stat->st_blocks != BLKCNT_UNKNOWN)
538 : : {
539 : 0 : return FAILURE;
540 : : }
541 : :
542 [ + - - + ]: 4 : if(stat->st_dev != 0 || stat->st_ino != 0)
543 : : {
544 : 0 : return FAILURE;
545 : : }
546 : :
547 [ + - - + ]: 4 : if(stat->mtim_tv_sec != 0 || stat->mtim_tv_nsec != 0)
548 : : {
549 : 0 : return FAILURE;
550 : : }
551 : :
552 [ + - - + ]: 4 : if(stat->ctim_tv_sec != 0 || stat->ctim_tv_nsec != 0)
553 : : {
554 : 0 : return FAILURE;
555 : : }
556 : :
557 : 4 : return SUCCESS;
558 : : }
559 : :
560 : 4 : static Return corrupt_first_row_stat_blob(
561 : : const char *db_filename,
562 : : sqlite3_int64 *row_id_out)
563 : : {
564 : : /* Status returned by this function through provide()
565 : : Default value assumes successful completion */
566 : 4 : Return status = SUCCESS;
567 : 4 : sqlite3_int64 row_id = 0;
568 : 4 : const unsigned char corrupt_blob[] = {0xA5};
569 : :
570 [ + - ]: 4 : if(SUCCESS == status)
571 : : {
572 : 4 : status = read_first_row_id(db_filename,&row_id);
573 : : }
574 : :
575 [ + - ]: 4 : if(SUCCESS == status)
576 : : {
577 : 4 : status = overwrite_stat_blob_by_row_id(db_filename,row_id,corrupt_blob,(int)sizeof(corrupt_blob));
578 : : }
579 : :
580 [ + - + - ]: 4 : if(SUCCESS == status && row_id_out != NULL)
581 : : {
582 : 4 : *row_id_out = row_id;
583 : : }
584 : :
585 : 4 : return(status);
586 : : }
587 : :
588 : 2 : static Return create_abort_on_second_stat_update_trigger(
589 : : const char *db_filename)
590 : : {
591 : : /* Status returned by this function through provide()
592 : : Default value assumes successful completion */
593 : 2 : Return status = SUCCESS;
594 : 2 : sqlite3 *db = NULL;
595 : 2 : const char *sql =
596 : : "DROP TRIGGER IF EXISTS __test_abort_on_second_update;"
597 : : "DROP TABLE IF EXISTS __test_fail_counter;"
598 : : "CREATE TABLE __test_fail_counter(n INTEGER NOT NULL);"
599 : : "INSERT INTO __test_fail_counter(n) VALUES(0);"
600 : : "CREATE TRIGGER __test_abort_on_second_update "
601 : : "BEFORE UPDATE OF stat ON files "
602 : : "BEGIN "
603 : : "UPDATE __test_fail_counter SET n = n + 1;"
604 : : "SELECT CASE WHEN (SELECT n FROM __test_fail_counter LIMIT 1) >= 2 "
605 : : "THEN RAISE(ABORT,'forced rollback test failure') END;"
606 : : "END;";
607 : :
608 [ - + ]: 2 : if(db_filename == NULL)
609 : : {
610 : 0 : status = FAILURE;
611 : : }
612 : :
613 [ + - ]: 2 : if(SUCCESS == status)
614 : : {
615 : 2 : status = open_db_from_tmpdir(db_filename,SQLITE_OPEN_READWRITE,&db);
616 : : }
617 : :
618 [ + - - + ]: 2 : if(SUCCESS == status && SQLITE_OK != sqlite3_exec(db,sql,NULL,NULL,NULL))
619 : : {
620 : 0 : status = FAILURE;
621 : : }
622 : :
623 [ + - ]: 2 : if(db != NULL)
624 : : {
625 : 2 : (void)sqlite3_close(db);
626 : : }
627 : :
628 : 2 : return(status);
629 : : }
630 : :
631 : : /**
632 : : *
633 : : * Upgrade a DB from version 0 to the current version as the primary database.
634 : : * Verify the run fails without the --update parameter and prints the proper error.
635 : : *
636 : : */
637 : 2 : Return test0015_1(void)
638 : : {
639 : 2 : INITTEST;
640 : :
641 [ + - + - ]: 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
642 : :
643 : 2 : const char *command = "cp -a ${ORIGIN_DIR}/tests/templates/0015_database_v0.db ${TMPDIR}/";
644 : :
645 [ + - + - ]: 2 : ASSERT(SUCCESS == external_call(command,NULL,NULL,COMPLETED,ALLOW_BOTH));
646 : :
647 : 2 : const char *arguments = "--database=./0015_database_v0.db tests/fixtures/diffs/diff1";
648 : :
649 : 2 : create(char,result);
650 : 2 : create(char,pattern);
651 : :
652 : 2 : const char *filename = "templates/0015_001.txt";
653 : :
654 [ + - + - ]: 2 : ASSERT(SUCCESS == runit(arguments,result,NULL,WARNING,ALLOW_BOTH));
655 : :
656 [ + - + - ]: 2 : ASSERT(SUCCESS == get_file_content(filename,pattern));
657 : :
658 : : // Match the result against the pattern
659 [ + - + - ]: 2 : ASSERT(SUCCESS == match_pattern(result,pattern,filename));
660 : :
661 : : // Clean to use it iteratively
662 : 2 : del(pattern);
663 : 2 : del(result);
664 : :
665 : : // Clean up test results
666 : 2 : command = "rm \"${TMPDIR}/0015_database_v0.db\"";
667 : :
668 [ + - + - ]: 2 : ASSERT(SUCCESS == external_call(command,NULL,NULL,COMPLETED,ALLOW_BOTH));
669 : :
670 [ + - - + : 2 : RETURN_STATUS;
- - - + +
- ]
671 : : }
672 : :
673 : : /**
674 : : *
675 : : * Upgrade a DB from version 0 to the current version as the primary database.
676 : : * Running the test with the --update parameter to ensure the update
677 : : * completes successfully
678 : : *
679 : : */
680 : 2 : Return test0015_2(void)
681 : : {
682 : 2 : INITTEST;
683 : :
684 : 2 : const char *command = "cp -a ${ORIGIN_DIR}/tests/templates/0015_database_v0.db ${TMPDIR}/";
685 : :
686 [ + - + - ]: 2 : ASSERT(SUCCESS == external_call(command,NULL,NULL,COMPLETED,ALLOW_BOTH));
687 : :
688 [ + - + - ]: 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
689 : :
690 : 2 : const char *arguments = "--update --database=0015_database_v0.db "
691 : : "tests/fixtures/diffs/diff1";
692 : :
693 : 2 : create(char,result);
694 : 2 : create(char,pattern);
695 : :
696 : 2 : const char *filename = "templates/0015_002_1.txt";
697 : :
698 [ + - + - ]: 2 : ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
699 : :
700 [ + - + - ]: 2 : ASSERT(SUCCESS == get_file_content(filename,pattern));
701 : :
702 : : // Match the result against the pattern
703 [ + - + - ]: 2 : ASSERT(SUCCESS == match_pattern(result,pattern,filename));
704 : :
705 : : // Clean up test results
706 : 2 : command = "rm \"${TMPDIR}/0015_database_v0.db\"";
707 : :
708 [ + - + - ]: 2 : ASSERT(SUCCESS == external_call(command,NULL,NULL,COMPLETED,ALLOW_BOTH));
709 : :
710 : : // Clean to use it iteratively
711 : 2 : del(pattern);
712 : 2 : del(result);
713 : :
714 [ + - - + : 2 : RETURN_STATUS;
- - - + +
- ]
715 : : }
716 : :
717 : : /**
718 : : *
719 : : * Upgrade a DB from version 0 to the current version as the primary database.
720 : : * Running the test with the --update and --watch-timestamps parameters to ensure
721 : : * the update completes successfully with according details in output
722 : : *
723 : : */
724 : 2 : Return test0015_3(void)
725 : : {
726 : 2 : INITTEST;
727 : :
728 : 2 : const char *command = "cp -a ${ORIGIN_DIR}/tests/templates/0015_database_v0.db ${TMPDIR}/";
729 : :
730 [ + - + - ]: 2 : ASSERT(SUCCESS == external_call(command,NULL,NULL,COMPLETED,ALLOW_BOTH));
731 : :
732 [ + - + - ]: 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
733 : :
734 : 2 : const char *arguments = "--watch-timestamps --update --database=0015_database_v0.db "
735 : : "tests/fixtures/diffs/diff1";
736 : :
737 : 2 : create(char,result);
738 : 2 : create(char,pattern);
739 : :
740 : 2 : const char *filename = "templates/0015_002_2.txt";
741 : :
742 [ + - + - ]: 2 : ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
743 : :
744 [ + - + - ]: 2 : ASSERT(SUCCESS == get_file_content(filename,pattern));
745 : :
746 : : // Match the result against the pattern
747 [ + - + - ]: 2 : ASSERT(SUCCESS == match_pattern(result,pattern,filename));
748 : :
749 : : // Clean to use it iteratively
750 : 2 : del(pattern);
751 : 2 : del(result);
752 : :
753 [ + - - + : 2 : RETURN_STATUS;
- - - + +
- ]
754 : : }
755 : :
756 : : /**
757 : : *
758 : : * Run the program again to verify that the database
759 : : * is actually at the current version
760 : : *
761 : : */
762 : 2 : Return test0015_4(void)
763 : : {
764 : 2 : INITTEST;
765 : :
766 : 2 : create(char,result);
767 : 2 : create(char,pattern);
768 : :
769 : 2 : const char *filename = "templates/0015_003.txt";
770 : :
771 [ + - + - ]: 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
772 : :
773 : 2 : const char *arguments = "--update --database=./0015_database_v0.db "
774 : : "tests/fixtures/diffs/diff1";
775 : :
776 [ + - + - ]: 2 : ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
777 : :
778 [ + - + - ]: 2 : ASSERT(SUCCESS == get_file_content(filename,pattern));
779 : :
780 : : // Match the result against the pattern
781 [ + - + - ]: 2 : ASSERT(SUCCESS == match_pattern(result,pattern,filename));
782 : :
783 : : // Clean to use it iteratively
784 : 2 : del(pattern);
785 : 2 : del(result);
786 : :
787 : : // Clean up test results
788 : 2 : const char *command = "rm \"${TMPDIR}/0015_database_v0.db\"";
789 : :
790 [ + - + - ]: 2 : ASSERT(SUCCESS == external_call(command,NULL,NULL,COMPLETED,ALLOW_BOTH));
791 : :
792 [ + - - + : 2 : RETURN_STATUS;
- - - + +
- ]
793 : : }
794 : :
795 : : /**
796 : : *
797 : : * Run the program again to verify that the database is actually at the current version
798 : : * Create a database with the default name
799 : : *
800 : : */
801 : 2 : Return test0015_5(void)
802 : : {
803 : 2 : INITTEST;
804 : :
805 [ + - + - ]: 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
806 : :
807 : : // Get the output of an external program
808 : 2 : const char *arguments = "tests/fixtures/diffs/diff1";
809 : :
810 : 2 : const char *filename = "templates/0015_004.txt"; // File name
811 : 2 : const char *template = "%DB_NAME%";
812 : :
813 : 2 : const char *replacement = getenv("DBNAME"); // Database name
814 : :
815 [ + - + - ]: 2 : ASSERT(replacement != NULL);
816 : :
817 [ + - + - ]: 2 : ASSERT(SUCCESS == match_app_output(arguments,filename,template,replacement,COMPLETED));
818 : :
819 [ + - - + : 2 : RETURN_STATUS;
- - - + +
- ]
820 : : }
821 : :
822 : : /**
823 : : *
824 : : * Run the program with the --compare parameter to compare databases
825 : : * when one of them has an older version — this should generate an
826 : : * appropriate error message
827 : : *
828 : : */
829 : 2 : Return test0015_6(void)
830 : : {
831 : 2 : INITTEST;
832 : :
833 [ + - + - ]: 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
834 : :
835 : : // Get the output of an external program
836 : 2 : const char *command = "cp -a ${ORIGIN_DIR}/tests/templates/0015_database_v0.db ${TMPDIR}/";
837 : :
838 [ + - + - ]: 2 : ASSERT(SUCCESS == external_call(command,NULL,NULL,COMPLETED,ALLOW_BOTH));
839 : :
840 : 2 : const char *arguments = "--compare $DBNAME 0015_database_v0.db";
841 : :
842 : 2 : const char *filename = "templates/0015_005.txt"; // File name
843 : 2 : const char *template = "%DB_NAME%";
844 : :
845 : 2 : const char *replacement = getenv("DBNAME"); // Database name
846 : :
847 [ + - + - ]: 2 : ASSERT(replacement != NULL);
848 : :
849 [ + - + - ]: 2 : ASSERT(SUCCESS == match_app_output(arguments,filename,template,replacement,WARNING));
850 : :
851 [ + - - + : 2 : RETURN_STATUS;
- - - + +
- ]
852 : : }
853 : :
854 : : /**
855 : : *
856 : : * Run the database comparison again using the --compare parameter, but this time with
857 : : * the --update option. The database should be upgraded accordingly.
858 : : * Upgrading from 0 to the last version
859 : : *
860 : : */
861 : 2 : Return test0015_7(void)
862 : : {
863 : 2 : INITTEST;
864 : :
865 [ + - + - ]: 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
866 : :
867 : : // Get the output of an external program
868 : 2 : const char *arguments = "--compare --update $DBNAME 0015_database_v0.db";
869 : :
870 : 2 : const char *filename = "templates/0015_006.txt"; // File name
871 : 2 : const char *template = "%DB_NAME%";
872 : :
873 : 2 : const char *replacement = getenv("DBNAME"); // Database name
874 : :
875 [ + - + - ]: 2 : ASSERT(replacement != NULL);
876 : :
877 [ + - + - ]: 2 : ASSERT(SUCCESS == match_app_output(arguments,filename,template,replacement,COMPLETED));
878 : :
879 : : // Clean up test results
880 : 2 : const char *command = "rm \"${TMPDIR}/0015_database_v0.db\"";
881 : :
882 [ + - + - ]: 2 : ASSERT(SUCCESS == external_call(command,NULL,NULL,COMPLETED,ALLOW_BOTH));
883 : :
884 [ + - - + : 2 : RETURN_STATUS;
- - - + +
- ]
885 : : }
886 : :
887 : : /**
888 : : *
889 : : * Upgrade a DB from version 1 to the current version as the primary database.
890 : : * Running the test with the --update parameter to ensure the update
891 : : * completes successfully
892 : : *
893 : : */
894 : 2 : Return test0015_8(void)
895 : : {
896 : 2 : INITTEST;
897 : :
898 [ + - + - ]: 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
899 : :
900 : 2 : const char *command = "cp -a ${ORIGIN_DIR}/tests/templates/0015_database_v1.db ${TMPDIR}/";
901 : :
902 [ + - + - ]: 2 : ASSERT(SUCCESS == external_call(command,NULL,NULL,COMPLETED,ALLOW_BOTH));
903 : :
904 : 2 : const char *arguments = "--update --database=0015_database_v1.db "
905 : : "tests/fixtures/diffs/diff1";
906 : :
907 : 2 : create(char,result);
908 : 2 : create(char,pattern);
909 : :
910 : 2 : const char *filename = "templates/0015_007.txt";
911 : :
912 [ + - + - ]: 2 : ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
913 : :
914 [ + - + - ]: 2 : ASSERT(SUCCESS == get_file_content(filename,pattern));
915 : :
916 : : // Match the result against the pattern
917 [ + - + - ]: 2 : ASSERT(SUCCESS == match_pattern(result,pattern,filename));
918 : :
919 : : // Clean to use it iteratively
920 : 2 : del(pattern);
921 : 2 : del(result);
922 : :
923 [ + - - + : 2 : RETURN_STATUS;
- - - + +
- ]
924 : : }
925 : :
926 : : /**
927 : : *
928 : : * Run the program again to verify that the database
929 : : * is actually at the current version
930 : : *
931 : : */
932 : 2 : Return test0015_9(void)
933 : : {
934 : 2 : INITTEST;
935 : :
936 : 2 : create(char,result);
937 : 2 : create(char,pattern);
938 : :
939 : 2 : const char *filename = "templates/0015_008.txt";
940 : :
941 [ + - + - ]: 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
942 : :
943 : 2 : const char *arguments = "--update --database=./0015_database_v1.db "
944 : : "tests/fixtures/diffs/diff1";
945 : :
946 [ + - + - ]: 2 : ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
947 : :
948 [ + - + - ]: 2 : ASSERT(SUCCESS == get_file_content(filename,pattern));
949 : :
950 : : // Match the result against the pattern
951 [ + - + - ]: 2 : ASSERT(SUCCESS == match_pattern(result,pattern,filename));
952 : :
953 : : // Clean to use it iteratively
954 : 2 : del(pattern);
955 : 2 : del(result);
956 : :
957 : : // Clean up test results
958 : 2 : const char *command = "rm \"${TMPDIR}/0015_database_v1.db\"";
959 : :
960 [ + - + - ]: 2 : ASSERT(SUCCESS == external_call(command,NULL,NULL,COMPLETED,ALLOW_BOTH));
961 : :
962 [ + - - + : 2 : RETURN_STATUS;
- - - + +
- ]
963 : : }
964 : :
965 : : /**
966 : : *
967 : : * Run the database comparison again using the --compare and --update parameters.
968 : : * Upgrading from 1 to the last version
969 : : *
970 : : */
971 : 2 : Return test0015_10(void)
972 : : {
973 : 2 : INITTEST;
974 : :
975 [ + - + - ]: 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
976 : :
977 : : // Get the output of an external program
978 : 2 : const char *command = "cp -a ${ORIGIN_DIR}/tests/templates/0015_database_v1.db ${TMPDIR}/";
979 : :
980 [ + - + - ]: 2 : ASSERT(SUCCESS == external_call(command,NULL,NULL,COMPLETED,ALLOW_BOTH));
981 : :
982 : 2 : const char *arguments = "--compare --update $DBNAME 0015_database_v1.db";
983 : :
984 : 2 : const char *filename = "templates/0015_009.txt"; // File name
985 : 2 : const char *template = "%DB_NAME%";
986 : :
987 : 2 : const char *replacement = getenv("DBNAME"); // Database name
988 : :
989 [ + - + - ]: 2 : ASSERT(replacement != NULL);
990 : :
991 [ + - + - ]: 2 : ASSERT(SUCCESS == match_app_output(arguments,filename,template,replacement,COMPLETED));
992 : :
993 : : // Clean up test results
994 : 2 : command = "rm \"${TMPDIR}/0015_database_v1.db\"";
995 : :
996 [ + - + - ]: 2 : ASSERT(SUCCESS == external_call(command,NULL,NULL,COMPLETED,ALLOW_BOTH));
997 : :
998 [ + - - + : 2 : RETURN_STATUS;
- - - + +
- ]
999 : : }
1000 : :
1001 : : /**
1002 : : *
1003 : : * Upgrade a DB from version 2 to the current version as the primary database.
1004 : : * Running the test with the --update parameter to ensure the update
1005 : : * completes successfully
1006 : : *
1007 : : */
1008 : 2 : Return test0015_11(void)
1009 : : {
1010 : 2 : INITTEST;
1011 : :
1012 [ + - + - ]: 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","false"));
1013 : :
1014 : 2 : const char *command = "cp -a ${ORIGIN_DIR}/tests/templates/0015_database_v2.db ${TMPDIR}/";
1015 : :
1016 [ + - + - ]: 2 : ASSERT(SUCCESS == external_call(command,NULL,NULL,COMPLETED,ALLOW_BOTH));
1017 : :
1018 : 2 : const char *arguments = "--update --database=0015_database_v2.db --verbose "
1019 : : "tests/fixtures/diffs/diff1";
1020 : :
1021 : 2 : create(char,result);
1022 : 2 : create(char,pattern);
1023 : :
1024 [ + - + - ]: 2 : ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
1025 : :
1026 : 2 : const char *filename = "templates/0015_010.txt";
1027 : :
1028 [ + - + - ]: 2 : ASSERT(SUCCESS == get_file_content(filename,pattern));
1029 : :
1030 : : // Match the result against the pattern
1031 [ + - + - ]: 2 : ASSERT(SUCCESS == match_pattern(result,pattern,filename));
1032 : :
1033 : : // Clean up test results
1034 : 2 : command = "rm \"${TMPDIR}/0015_database_v2.db\"";
1035 : :
1036 [ + - + - ]: 2 : ASSERT(SUCCESS == external_call(command,NULL,NULL,COMPLETED,ALLOW_BOTH));
1037 : :
1038 : : // Clean to use it iteratively
1039 : 2 : del(pattern);
1040 : 2 : del(result);
1041 : :
1042 [ + - - + : 2 : RETURN_STATUS;
- - - + +
- ]
1043 : : }
1044 : :
1045 : : /**
1046 : : *
1047 : : * Run the database comparison again using the --compare and --update parameters.
1048 : : * Upgrading from 2 to the last version
1049 : : *
1050 : : */
1051 : 2 : Return test0015_12(void)
1052 : : {
1053 : 2 : INITTEST;
1054 : :
1055 [ + - + - ]: 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
1056 : :
1057 : : // Get the output of an external program
1058 : 2 : const char *command = "cp -a ${ORIGIN_DIR}/tests/templates/0015_database_v2.db ${TMPDIR}/";
1059 : :
1060 [ + - + - ]: 2 : ASSERT(SUCCESS == external_call(command,NULL,NULL,COMPLETED,ALLOW_BOTH));
1061 : :
1062 : 2 : const char *arguments = "--compare --update $DBNAME 0015_database_v2.db";
1063 : :
1064 : 2 : const char *filename = "templates/0015_011.txt"; // File name
1065 : 2 : const char *template = "%DB_NAME%";
1066 : :
1067 : 2 : const char *replacement = getenv("DBNAME"); // Database name
1068 : :
1069 [ + - + - ]: 2 : ASSERT(replacement != NULL);
1070 : :
1071 [ + - + - ]: 2 : ASSERT(SUCCESS == match_app_output(arguments,filename,template,replacement,COMPLETED));
1072 : :
1073 : : // Clean up test results
1074 : 2 : command = "rm \"${TMPDIR}/${DBNAME}\" && "
1075 : : "rm \"${TMPDIR}/0015_database_v2.db\"";
1076 : :
1077 [ + - + - ]: 2 : ASSERT(SUCCESS == external_call(command,NULL,NULL,COMPLETED,ALLOW_BOTH));
1078 : :
1079 [ + - - + : 2 : RETURN_STATUS;
- - - + +
- ]
1080 : : }
1081 : :
1082 : : /**
1083 : : *
1084 : : * Upgrade a DB with UTF-8 name from version 3 to the current version
1085 : : * as the primary database using --update.
1086 : : *
1087 : : */
1088 : 2 : Return test0015_13(void)
1089 : : {
1090 : 2 : INITTEST;
1091 : :
1092 [ + - + - ]: 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
1093 : :
1094 : 2 : const char *command = "cp -a \"${ORIGIN_DIR}/tests/templates/0015_database_v3 это база данных с пробелами и символами UTF-8.db\" ${TMPDIR}/";
1095 : :
1096 [ + - + - ]: 2 : ASSERT(SUCCESS == external_call(command,NULL,NULL,COMPLETED,ALLOW_BOTH));
1097 : :
1098 : 2 : const char *arguments = "--update --database=\"0015_database_v3 это база данных с пробелами и символами UTF-8.db\" "
1099 : : "tests/fixtures/diffs/diff1";
1100 : :
1101 : 2 : create(char,result);
1102 : :
1103 [ + - + - ]: 2 : ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
1104 : :
1105 : 2 : const char *filename = "templates/0015_012.txt";
1106 : :
1107 : 2 : create(char,pattern);
1108 : :
1109 [ + - + - ]: 2 : ASSERT(SUCCESS == get_file_content(filename,pattern));
1110 : :
1111 : : // Match the result against the pattern
1112 [ + - + - ]: 2 : ASSERT(SUCCESS == match_pattern(result,pattern,filename));
1113 : :
1114 : : // Clean up test results
1115 : 2 : command = "rm \"${TMPDIR}/0015_database_v3 это база данных с пробелами и символами UTF-8.db\"";
1116 : :
1117 [ + - + - ]: 2 : ASSERT(SUCCESS == external_call(command,NULL,NULL,COMPLETED,ALLOW_BOTH));
1118 : :
1119 : : // Clean to use it iteratively
1120 : 2 : del(pattern);
1121 : 2 : del(result);
1122 : :
1123 [ + - - + : 2 : RETURN_STATUS;
- - - + +
- ]
1124 : : }
1125 : :
1126 : : /**
1127 : : * Upgrade from version 3 during database comparison using
1128 : : * --compare and --update parameters.
1129 : : */
1130 : 2 : Return test0015_14(void)
1131 : : {
1132 : 2 : INITTEST;
1133 : :
1134 [ + - + - ]: 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
1135 : :
1136 : 2 : const char *command = "cp -a \"${ORIGIN_DIR}/tests/templates/0015_database_v3 это база данных с пробелами и символами UTF-8.db\" ${TMPDIR}/ && "
1137 : : "cp -a \"${ORIGIN_DIR}/tests/templates/0015_database_v4 это база данных с пробелами и символами UTF-8.db\" ${TMPDIR}/";
1138 : :
1139 [ + - + - ]: 2 : ASSERT(SUCCESS == external_call(command,NULL,NULL,COMPLETED,ALLOW_BOTH));
1140 : :
1141 : 2 : const char *arguments = "--compare --update "
1142 : : "\"0015_database_v3 это база данных с пробелами и символами UTF-8.db\" "
1143 : : "\"0015_database_v4 это база данных с пробелами и символами UTF-8.db\"";
1144 : :
1145 : 2 : create(char,result);
1146 : 2 : create(char,pattern);
1147 : :
1148 [ + - + - ]: 2 : ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
1149 : :
1150 : 2 : const char *filename = "templates/0015_013.txt";
1151 : :
1152 [ + - + - ]: 2 : ASSERT(SUCCESS == get_file_content(filename,pattern));
1153 : :
1154 : : // Match the result against the pattern
1155 [ + - + - ]: 2 : ASSERT(SUCCESS == match_pattern(result,pattern,filename));
1156 : :
1157 : 2 : del(result);
1158 : 2 : del(pattern);
1159 : :
1160 : 2 : command = "rm \"${TMPDIR}/0015_database_v3 это база данных с пробелами и символами UTF-8.db\" "
1161 : : "\"${TMPDIR}/0015_database_v4 это база данных с пробелами и символами UTF-8.db\"";
1162 : :
1163 [ + - + - ]: 2 : ASSERT(SUCCESS == external_call(command,NULL,NULL,COMPLETED,ALLOW_BOTH));
1164 : :
1165 [ + - - + : 2 : RETURN_STATUS;
- - - + +
- ]
1166 : : }
1167 : :
1168 : : /**
1169 : : * Create a fresh database inside tests/fixtures/diffs/ with the UTF-8 name
1170 : : * "Это новая база данных.db" and ensure the app can read/write it despite
1171 : : * spaces and non-ASCII characters.
1172 : : * Then compare it against the legacy database
1173 : : * "0015_database_v4 это база данных с пробелами и символами UTF-8.db" that was
1174 : : * produced by a well-tested older release when upgraded to the version 4.
1175 : : * If the files and checksums match, the current checksum calculation is
1176 : : * considered compatible with the legacy well-tested algorithm.
1177 : : */
1178 : 2 : Return test0015_15(void)
1179 : : {
1180 : 2 : INITTEST;
1181 : :
1182 [ + - + - ]: 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
1183 : :
1184 : 2 : const char *command = "cp -a \"${ORIGIN_DIR}/tests/templates/0015_database_v4 это база данных с пробелами и символами UTF-8.db\" ${TMPDIR}/";
1185 : :
1186 [ + - + - ]: 2 : ASSERT(SUCCESS == external_call(command,NULL,NULL,COMPLETED,ALLOW_BOTH));
1187 : :
1188 : 2 : create(char,pattern);
1189 : 2 : create(char,result);
1190 : 2 : create(char,chunk);
1191 : :
1192 : 2 : const char *arguments = "--database=\"Это новая база данных.db\" "
1193 : : "tests/fixtures/diffs/diff1";
1194 : :
1195 [ + - + - ]: 2 : ASSERT(SUCCESS == runit(arguments,chunk,NULL,COMPLETED,ALLOW_BOTH));
1196 [ + - + - ]: 2 : ASSERT(SUCCESS == copy(result,chunk));
1197 : :
1198 : 2 : arguments = "--compare \"Это новая база данных.db\" "
1199 : : "\"0015_database_v4 это база данных с пробелами и символами UTF-8.db\"";
1200 : :
1201 [ + - + - ]: 2 : ASSERT(SUCCESS == runit(arguments,chunk,NULL,COMPLETED,ALLOW_BOTH));
1202 [ + - + - ]: 2 : ASSERT(SUCCESS == concat_strings(result,chunk));
1203 : :
1204 : 2 : const char *filename = "templates/0015_014.txt";
1205 : :
1206 [ + - + - ]: 2 : ASSERT(SUCCESS == get_file_content(filename,pattern));
1207 : :
1208 : : // Match the result against the pattern
1209 [ + - + - ]: 2 : ASSERT(SUCCESS == match_pattern(result,pattern,filename));
1210 : :
1211 : : // Clean to use it iteratively
1212 : 2 : del(pattern);
1213 : 2 : del(result);
1214 : 2 : del(chunk);
1215 : :
1216 : : // Clean up test results
1217 : 2 : command = "rm \"${TMPDIR}/Это новая база данных.db\" \"${TMPDIR}/0015_database_v4 это база данных с пробелами и символами UTF-8.db\"";
1218 : :
1219 [ + - + - ]: 2 : ASSERT(SUCCESS == external_call(command,NULL,NULL,COMPLETED,ALLOW_BOTH));
1220 : :
1221 [ + - - + : 2 : RETURN_STATUS;
- - - + +
- ]
1222 : : }
1223 : :
1224 : : /**
1225 : : * Corrupt one v0 row stat blob and verify that upgrade still completes.
1226 : : * The corrupted row must end up as converted "zero source" v4 compact stat.
1227 : : */
1228 : 2 : Return test0015_16(void)
1229 : : {
1230 : 2 : INITTEST;
1231 : :
1232 [ + - + - ]: 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
1233 : :
1234 : 2 : const char *command =
1235 : : "cp -a \"${ORIGIN_DIR}/tests/templates/0015_database_v0.db\" "
1236 : : "\"${TMPDIR}/0015_database_v0_corrupt.db\" && "
1237 : : "cp -a \"${ORIGIN_DIR}/tests/templates/" LEGACY_V4_UTF8_DB "\" "
1238 : : "\"${TMPDIR}/0015_database_v4_reference.db\"";
1239 : :
1240 [ + - + - ]: 2 : ASSERT(SUCCESS == external_call(command,NULL,NULL,COMPLETED,ALLOW_BOTH));
1241 : :
1242 : 2 : sqlite3_int64 row_id = 0;
1243 [ + - + - ]: 2 : ASSERT(SUCCESS == corrupt_first_row_stat_blob("0015_database_v0_corrupt.db",&row_id));
1244 : :
1245 : 2 : create(char,result);
1246 : 2 : create(char,pattern);
1247 : :
1248 : 2 : const char *arguments = "--compare --update "
1249 : : "0015_database_v4_reference.db 0015_database_v0_corrupt.db";
1250 : :
1251 [ + - + - ]: 2 : ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
1252 : 2 : const char *filename = "templates/0015_015.txt";
1253 [ + - + - ]: 2 : ASSERT(SUCCESS == get_file_content(filename,pattern));
1254 [ + - + - ]: 2 : ASSERT(SUCCESS == match_pattern(result,pattern,filename));
1255 : :
1256 : 2 : int db_version = 0;
1257 [ + - + - ]: 2 : ASSERT(SUCCESS == read_db_version_from_metadata("0015_database_v0_corrupt.db",&db_version));
1258 [ + - + - ]: 2 : ASSERT(db_version == 4);
1259 : :
1260 : 2 : CmpctStat stat = {0};
1261 [ + - + - ]: 2 : ASSERT(SUCCESS == read_cmpctstat_by_row_id("0015_database_v0_corrupt.db",row_id,&stat));
1262 [ + - + - ]: 2 : ASSERT(SUCCESS == verify_zero_converted_cmpctstat(&stat));
1263 : :
1264 : 2 : command = "rm -f \"${TMPDIR}/0015_database_v0_corrupt.db\" "
1265 : : "\"${TMPDIR}/0015_database_v4_reference.db\"";
1266 : :
1267 [ + - + - ]: 2 : ASSERT(SUCCESS == external_call(command,NULL,NULL,COMPLETED,ALLOW_BOTH));
1268 : :
1269 : 2 : del(result);
1270 : 2 : del(pattern);
1271 : :
1272 [ + - - + : 2 : RETURN_STATUS;
- - - + +
- ]
1273 : : }
1274 : :
1275 : : /**
1276 : : * Corrupt one v3 row stat blob and verify that upgrade still completes.
1277 : : * The corrupted row must be stored using zero-source conversion logic.
1278 : : */
1279 : 2 : Return test0015_17(void)
1280 : : {
1281 : 2 : INITTEST;
1282 : :
1283 [ + - + - ]: 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
1284 : :
1285 : 2 : const char *command =
1286 : : "cp -a \"${ORIGIN_DIR}/tests/templates/" LEGACY_V3_UTF8_DB "\" "
1287 : : "\"${TMPDIR}/0015_database_v3_corrupt.db\" && "
1288 : : "cp -a \"${ORIGIN_DIR}/tests/templates/" LEGACY_V4_UTF8_DB "\" "
1289 : : "\"${TMPDIR}/0015_database_v4_reference.db\"";
1290 : :
1291 [ + - + - ]: 2 : ASSERT(SUCCESS == external_call(command,NULL,NULL,COMPLETED,ALLOW_BOTH));
1292 : :
1293 : 2 : sqlite3_int64 row_id = 0;
1294 [ + - + - ]: 2 : ASSERT(SUCCESS == corrupt_first_row_stat_blob("0015_database_v3_corrupt.db",&row_id));
1295 : :
1296 : 2 : create(char,result);
1297 : 2 : create(char,pattern);
1298 : :
1299 : 2 : const char *arguments = "--compare --update "
1300 : : "0015_database_v4_reference.db 0015_database_v3_corrupt.db";
1301 : :
1302 [ + - + - ]: 2 : ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
1303 : 2 : const char *filename = "templates/0015_016.txt";
1304 [ + - + - ]: 2 : ASSERT(SUCCESS == get_file_content(filename,pattern));
1305 [ + - + - ]: 2 : ASSERT(SUCCESS == match_pattern(result,pattern,filename));
1306 : :
1307 : 2 : int db_version = 0;
1308 [ + - + - ]: 2 : ASSERT(SUCCESS == read_db_version_from_metadata("0015_database_v3_corrupt.db",&db_version));
1309 [ + - + - ]: 2 : ASSERT(db_version == 4);
1310 : :
1311 : 2 : CmpctStat stat = {0};
1312 [ + - + - ]: 2 : ASSERT(SUCCESS == read_cmpctstat_by_row_id("0015_database_v3_corrupt.db",row_id,&stat));
1313 [ + - + - ]: 2 : ASSERT(SUCCESS == verify_zero_converted_cmpctstat(&stat));
1314 : :
1315 : 2 : command = "rm -f \"${TMPDIR}/0015_database_v3_corrupt.db\" "
1316 : : "\"${TMPDIR}/0015_database_v4_reference.db\"";
1317 : :
1318 [ + - + - ]: 2 : ASSERT(SUCCESS == external_call(command,NULL,NULL,COMPLETED,ALLOW_BOTH));
1319 : :
1320 : 2 : del(result);
1321 : 2 : del(pattern);
1322 : :
1323 [ + - - + : 2 : RETURN_STATUS;
- - - + +
- ]
1324 : : }
1325 : :
1326 : : /**
1327 : : * Regression test: when a SQLite error occurs during 3->4 migration,
1328 : : * the opened transaction must be rolled back.
1329 : : */
1330 : 2 : Return test0015_18(void)
1331 : : {
1332 : 2 : INITTEST;
1333 : :
1334 [ + - + - ]: 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
1335 : :
1336 : 2 : const char *command =
1337 : : "cp -a \"${ORIGIN_DIR}/tests/templates/" LEGACY_V3_UTF8_DB "\" "
1338 : : "\"${TMPDIR}/0015_database_v3_rollback.db\" && "
1339 : : "cp -a \"${ORIGIN_DIR}/tests/templates/" LEGACY_V4_UTF8_DB "\" "
1340 : : "\"${TMPDIR}/0015_database_v4_reference.db\"";
1341 : :
1342 [ + - + - ]: 2 : ASSERT(SUCCESS == external_call(command,NULL,NULL,COMPLETED,ALLOW_BOTH));
1343 : :
1344 : 2 : int files_count = 0;
1345 [ + - + - ]: 2 : ASSERT(SUCCESS == read_files_count("0015_database_v3_rollback.db",&files_count));
1346 [ + - + - ]: 2 : ASSERT(files_count >= 2);
1347 : :
1348 : 2 : sqlite3_int64 row_id = 0;
1349 [ + - + - ]: 2 : ASSERT(SUCCESS == read_first_row_id("0015_database_v3_rollback.db",&row_id));
1350 : :
1351 : : unsigned char before_blob[512];
1352 : 2 : int before_blob_size = 0;
1353 [ + - + - ]: 2 : ASSERT(SUCCESS == read_stat_blob_by_row_id("0015_database_v3_rollback.db",
1354 : : row_id,
1355 : : before_blob,
1356 : : sizeof(before_blob),
1357 : : &before_blob_size));
1358 : :
1359 : 2 : int v1_rows_before = 0;
1360 [ + - + - ]: 2 : ASSERT(SUCCESS == read_files_count_with_blob_size("0015_database_v3_rollback.db",
1361 : : (int)sizeof(CmpctStat_v1),
1362 : : &v1_rows_before));
1363 : :
1364 [ + - + - ]: 2 : ASSERT(SUCCESS == create_abort_on_second_stat_update_trigger("0015_database_v3_rollback.db"));
1365 : :
1366 : 2 : create(char,result);
1367 : 2 : create(char,pattern);
1368 : :
1369 : 2 : const char *arguments = "--compare --update "
1370 : : "0015_database_v4_reference.db 0015_database_v3_rollback.db";
1371 : :
1372 [ + - + - ]: 2 : ASSERT(SUCCESS == runit(arguments,result,NULL,FAILURE,ALLOW_BOTH));
1373 : 2 : const char *filename = "templates/0015_017.txt";
1374 [ + - + - ]: 2 : ASSERT(SUCCESS == get_file_content(filename,pattern));
1375 [ + - + - ]: 2 : ASSERT(SUCCESS == match_pattern(result,pattern,filename));
1376 : :
1377 : 2 : int db_version = 0;
1378 [ + - + - ]: 2 : ASSERT(SUCCESS == read_db_version_from_metadata("0015_database_v3_rollback.db",&db_version));
1379 [ + - + - ]: 2 : ASSERT(db_version == 3);
1380 : :
1381 : : unsigned char after_blob[512];
1382 : 2 : int after_blob_size = 0;
1383 [ + - + - ]: 2 : ASSERT(SUCCESS == read_stat_blob_by_row_id("0015_database_v3_rollback.db",
1384 : : row_id,
1385 : : after_blob,
1386 : : sizeof(after_blob),
1387 : : &after_blob_size));
1388 : :
1389 [ + - + - ]: 2 : ASSERT(before_blob_size == after_blob_size);
1390 : :
1391 [ + - ]: 2 : if(before_blob_size > 0)
1392 : : {
1393 [ + - + - ]: 2 : ASSERT(0 == memcmp(before_blob,after_blob,(size_t)before_blob_size));
1394 : : }
1395 : :
1396 : 2 : int v1_rows_after = 0;
1397 [ + - + - ]: 2 : ASSERT(SUCCESS == read_files_count_with_blob_size("0015_database_v3_rollback.db",
1398 : : (int)sizeof(CmpctStat_v1),
1399 : : &v1_rows_after));
1400 [ + - + - ]: 2 : ASSERT(v1_rows_before == v1_rows_after);
1401 : :
1402 : 2 : command = "rm -f \"${TMPDIR}/0015_database_v3_rollback.db\" "
1403 : : "\"${TMPDIR}/0015_database_v4_reference.db\"";
1404 : :
1405 [ + - + - ]: 2 : ASSERT(SUCCESS == external_call(command,NULL,NULL,COMPLETED,ALLOW_BOTH));
1406 : :
1407 : 2 : del(result);
1408 : 2 : del(pattern);
1409 : :
1410 [ + - - + : 2 : RETURN_STATUS;
- - - + +
- ]
1411 : : }
1412 : :
1413 : : /**
1414 : : * Generate a fresh database, force future metadata version and verify warning path
1415 : : */
1416 : 2 : Return test0015_19(void)
1417 : : {
1418 : 2 : INITTEST;
1419 : :
1420 [ + - + - ]: 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
1421 : :
1422 : 2 : const char *db_filename = "0015_database_future_version.db";
1423 : 2 : const char *command = "rm -f \"${TMPDIR}/0015_database_future_version.db\"";
1424 : :
1425 [ + - + - ]: 2 : ASSERT(SUCCESS == external_call(command,NULL,NULL,COMPLETED,ALLOW_BOTH));
1426 : :
1427 : 2 : const char *arguments = "--database=0015_database_future_version.db "
1428 : : "tests/fixtures/diffs/diff1";
1429 : :
1430 : 2 : create(char,result);
1431 : 2 : create(char,pattern);
1432 : :
1433 [ + - + - ]: 2 : ASSERT(SUCCESS == runit(arguments,NULL,NULL,COMPLETED,ALLOW_BOTH));
1434 [ + - + - ]: 2 : ASSERT(SUCCESS == set_db_version_in_metadata(db_filename,CURRENT_DB_VERSION + 1));
1435 : :
1436 : 2 : int db_version = 0;
1437 [ + - + - ]: 2 : ASSERT(SUCCESS == read_db_version_from_metadata(db_filename,&db_version));
1438 [ + - + - ]: 2 : ASSERT(db_version == CURRENT_DB_VERSION + 1);
1439 : :
1440 [ + - + - ]: 2 : ASSERT(SUCCESS == runit(arguments,result,NULL,WARNING,ALLOW_BOTH));
1441 : :
1442 : 2 : const char *filename = "templates/0015_018_1.txt";
1443 : :
1444 [ + - + - ]: 2 : ASSERT(SUCCESS == get_file_content(filename,pattern));
1445 [ + - + - ]: 2 : ASSERT(SUCCESS == match_pattern(result,pattern,filename));
1446 : :
1447 [ + - + - ]: 2 : ASSERT(SUCCESS == read_db_version_from_metadata(db_filename,&db_version));
1448 [ + - + - ]: 2 : ASSERT(db_version == CURRENT_DB_VERSION + 1);
1449 : :
1450 [ + - + - ]: 2 : ASSERT(SUCCESS == set_environment_variable("TESTING","false"));
1451 [ + - + - ]: 2 : ASSERT(SUCCESS == runit(arguments,result,NULL,WARNING,ALLOW_BOTH));
1452 : :
1453 : 2 : filename = "templates/0015_018_2.txt";
1454 : :
1455 [ + - + - ]: 2 : ASSERT(SUCCESS == get_file_content(filename,pattern));
1456 [ + - + - ]: 2 : ASSERT(SUCCESS == match_pattern(result,pattern,filename));
1457 : :
1458 [ + - + - ]: 2 : ASSERT(SUCCESS == external_call(command,NULL,NULL,COMPLETED,ALLOW_BOTH));
1459 : :
1460 : 2 : del(result);
1461 : 2 : del(pattern);
1462 : :
1463 [ + - - + : 2 : RETURN_STATUS;
- - - + +
- ]
1464 : : }
1465 : :
1466 : : /**
1467 : : * Testing scenario 15
1468 : : *
1469 : : * Database upgrade testing:
1470 : : * - Upgrade DBs from versions 0, 1, 2, and 3 to the current version as the primary database using --update
1471 : : * - Upgrade DBs from versions 0, 1, 2, and 3 during comparison using --compare --update
1472 : : * - Launch the program without specifying a database to ensure that a new database is created with the correct version
1473 : : * - Compare a current database with an outdated version (v0) without --update and check for the expected error
1474 : : * - Validate UTF-8 database names and checksum compatibility against a legacy v4 database
1475 : : * - Verify upgrade resilience for corrupted stat blobs in legacy DB v0 and v3
1476 : : * - Regression-check rollback behavior on forced SQLite failure during migration
1477 : : * - Generate a fresh DB and verify warning behavior for future DB version
1478 : : */
1479 : 2 : Return test0015(void)
1480 : : {
1481 : 2 : INITTEST;
1482 : :
1483 [ + - ]: 2 : TEST(test0015_1,"Upgrade a DB from v0 to the current version. Error handling…");
1484 [ + - ]: 2 : TEST(test0015_2,"Upgrade a DB from v0 to the current version as the primary database…");
1485 [ + - ]: 2 : TEST(test0015_3,"Upgrade a DB from v0 to the current version with --watch-timestamps…");
1486 [ + - ]: 2 : TEST(test0015_4,"Verify that the DB is actually at the current version…");
1487 [ + - ]: 2 : TEST(test0015_5,"Create default name database…");
1488 [ + - ]: 2 : TEST(test0015_6,"Attempting an upgrade with a single --compare parameter…");
1489 [ + - ]: 2 : TEST(test0015_7,"Upgrading from 0 to the last version using the --compare and --update…");
1490 [ + - ]: 2 : TEST(test0015_8,"Upgrade a DB from v1 to the current version as the primary database…");
1491 [ + - ]: 2 : TEST(test0015_9,"Verify that the DB is actually at the current version…");
1492 [ + - ]: 2 : TEST(test0015_10,"Upgrading from 1 to the last version using the --compare and --update…");
1493 [ + - ]: 2 : TEST(test0015_11,"Upgrade a DB from v2 to the current version as the primary database…");
1494 [ + - ]: 2 : TEST(test0015_12,"Upgrading from 2 to the last version using the --compare and --update…");
1495 [ + - ]: 2 : TEST(test0015_13,"Upgrading from 3 with UTF-8 name to the last version using the --update…");
1496 [ + - ]: 2 : TEST(test0015_14,"Upgrading from 3 to the last version using the --compare and --update…");
1497 [ + - ]: 2 : TEST(test0015_15,"Create and compare DBs with UTF-8 names and checksums from legacy DB…");
1498 [ + - ]: 2 : TEST(test0015_16,"Corrupted v0 stat blob does not break the full upgrade…");
1499 [ + - ]: 2 : TEST(test0015_17,"Corrupted v3 stat blob does not break the full upgrade…");
1500 [ + - ]: 2 : TEST(test0015_18,"Forced SQLite failure triggers rollback during 3->4 migration…");
1501 [ + - ]: 2 : TEST(test0015_19,"Fresh DB with forced future version returns warning and stays unchanged…");
1502 : :
1503 [ + - - + : 2 : RETURN_STATUS;
- - - + +
- ]
1504 : : }
|