LCOV - code coverage report
Current view: top level - tests/src - test0015.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 98.0 % 399 391
Test Date: 2026-10-20 14:27:43 Functions: 100.0 % 22 22
Branches: 50.0 % 28 14

             Branch data     Line data    Source code
       1                 :             : #include "sute.h"
       2                 :             : #include "db_upgrade.h"
       3                 :             : 
       4                 :             : /**
       5                 :             :  * @brief Validate zero-converted CmpctStat values after migration fixups
       6                 :             :  *
       7                 :             :  * @param[in] stat Compact stat structure to verify
       8                 :             :  *
       9                 :             :  * @return Return status code:
      10                 :             :  *         - SUCCESS: Structure matches expected zero-converted values
      11                 :             :  *         - FAILURE: One or more fields differ from expected values
      12                 :             :  */
      13                 :           4 : static Return db_verify_zero_converted_cmpctstat(const CmpctStat *stat)
      14                 :             : {
      15         [ -  + ]:           4 :         if(stat == NULL)
      16                 :             :         {
      17                 :           0 :                 return FAILURE;
      18                 :             :         }
      19                 :             : 
      20         [ -  + ]:           4 :         if(stat->st_size != 0)
      21                 :             :         {
      22                 :           0 :                 return FAILURE;
      23                 :             :         }
      24                 :             : 
      25         [ -  + ]:           4 :         if(stat->st_blocks != BLKCNT_UNKNOWN)
      26                 :             :         {
      27                 :           0 :                 return FAILURE;
      28                 :             :         }
      29                 :             : 
      30   [ +  -  -  + ]:           4 :         if(stat->st_dev != 0 || stat->st_ino != 0)
      31                 :             :         {
      32                 :           0 :                 return FAILURE;
      33                 :             :         }
      34                 :             : 
      35   [ +  -  -  + ]:           4 :         if(stat->mtim_tv_sec != 0 || stat->mtim_tv_nsec != 0)
      36                 :             :         {
      37                 :           0 :                 return FAILURE;
      38                 :             :         }
      39                 :             : 
      40   [ +  -  -  + ]:           4 :         if(stat->ctim_tv_sec != 0 || stat->ctim_tv_nsec != 0)
      41                 :             :         {
      42                 :           0 :                 return FAILURE;
      43                 :             :         }
      44                 :             : 
      45                 :           4 :         return SUCCESS;
      46                 :             : }
      47                 :             : 
      48                 :             : /**
      49                 :             :  * @brief Create trigger that aborts on second stat update in files table
      50                 :             :  *
      51                 :             :  * @param[in] db_filename Database filename relative to TMPDIR
      52                 :             :  *
      53                 :             :  * @return Return status code:
      54                 :             :  *         - SUCCESS: Trigger and helper table were created
      55                 :             :  *         - FAILURE: Validation, DB open, or SQL execution failed
      56                 :             :  */
      57                 :           2 : static Return db_create_abort_on_second_stat_update_trigger(const char *db_filename)
      58                 :             : {
      59                 :             :         /* Status returned by this function through provide()
      60                 :             :            Default value assumes successful completion */
      61                 :           2 :         Return status = SUCCESS;
      62                 :           2 :         sqlite3 *db = NULL;
      63                 :           2 :         const char *sql =
      64                 :             :                 "DROP TRIGGER IF EXISTS __test_abort_on_second_update;"
      65                 :             :                 "DROP TABLE IF EXISTS __test_fail_counter;"
      66                 :             :                 "CREATE TABLE __test_fail_counter(n INTEGER NOT NULL);"
      67                 :             :                 "INSERT INTO __test_fail_counter(n) VALUES(0);"
      68                 :             :                 "CREATE TRIGGER __test_abort_on_second_update "
      69                 :             :                 "BEFORE UPDATE OF stat ON files "
      70                 :             :                 "BEGIN "
      71                 :             :                 "UPDATE __test_fail_counter SET n = n + 1;"
      72                 :             :                 "SELECT CASE WHEN (SELECT n FROM __test_fail_counter LIMIT 1) >= 2 "
      73                 :             :                 "THEN RAISE(ABORT,'forced rollback test failure') END;"
      74                 :             :                 "END;";
      75                 :             : 
      76         [ -  + ]:           2 :         if(db_filename == NULL)
      77                 :             :         {
      78                 :           0 :                 status = FAILURE;
      79                 :             :         }
      80                 :             : 
      81         [ +  - ]:           2 :         if(SUCCESS == status)
      82                 :             :         {
      83                 :           2 :                 status = open_db_from_tmpdir(db_filename,SQLITE_OPEN_READWRITE,&db);
      84                 :             :         }
      85                 :             : 
      86   [ +  -  -  + ]:           2 :         if(SUCCESS == status && SQLITE_OK != sqlite3_exec(db,sql,NULL,NULL,NULL))
      87                 :             :         {
      88                 :           0 :                 status = FAILURE;
      89                 :             :         }
      90                 :             : 
      91                 :           2 :         (void)sqlite3_close(db);
      92                 :             : 
      93                 :           2 :         return(status);
      94                 :             : }
      95                 :             : 
      96                 :             : /**
      97                 :             :  * @brief Reject using a legacy v0 DB as the primary database without --update
      98                 :             :  *
      99                 :             :  * Verify CLI and configuration runs select QUICK verification and print the
     100                 :             :  * same upgrade warning. The rejected upgrade leaves the fixture unchanged
     101                 :             :  */
     102                 :           2 : Return test0015_1(void)
     103                 :             : {
     104                 :           2 :         INITTEST;
     105                 :             : 
     106                 :           2 :         ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
     107                 :           2 :         ASSERT(SUCCESS == copy_path("tests/templates/0015_database_v0.db","0015_database_v0.db"));
     108                 :             : 
     109                 :           2 :         const char *arguments = "--check-level=QUICK --database=./0015_database_v0.db tests/fixtures/diffs/diff1";
     110                 :           2 :         const char *filename = "templates/0015_001.txt";
     111                 :           2 :         const struct argument_test_case cases[] = {
     112                 :             :                 {arguments,WARNING,filename,STDERR_MUST_BE_EMPTY},
     113                 :             :                 {0}
     114                 :             :         };
     115                 :             : 
     116                 :             :         // Match the result against the pattern
     117                 :           2 :         ASSERT(SUCCESS == run_and_match_templates(cases,NULL,NULL));
     118                 :             : 
     119                 :             :         /* The rejected upgrade leaves the same database ready for the configuration run */
     120                 :           2 :         ASSERT(SUCCESS == copy_path("tests/templates/0015_001.conf","0015_001.conf"));
     121                 :           2 :         const struct argument_test_case file_cases[] = {
     122                 :             :                 {"--config=0015_001.conf",WARNING,filename,STDERR_MUST_BE_EMPTY},
     123                 :             :                 {0}
     124                 :             :         };
     125                 :           2 :         ASSERT(SUCCESS == run_and_match_templates(file_cases,NULL,NULL));
     126                 :           2 :         call(delete_path_if_present("0015_001.conf"));
     127                 :             : 
     128                 :             :         // Clean up test results
     129                 :           2 :         ASSERT(SUCCESS == delete_path("0015_database_v0.db"));
     130                 :             : 
     131                 :           2 :         RETURN_STATUS;
     132                 :             : }
     133                 :             : 
     134                 :             : /**
     135                 :             :  * @brief Upgrade a legacy v0 DB as the primary database with --update
     136                 :             :  *
     137                 :             :  * Verify the upgrade succeeds and produces the expected output
     138                 :             :  */
     139                 :           2 : Return test0015_2(void)
     140                 :             : {
     141                 :           2 :         INITTEST;
     142                 :           2 :         ASSERT(SUCCESS == copy_path("tests/templates/0015_database_v0.db","0015_database_v0.db"));
     143                 :             : 
     144                 :           2 :         ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
     145                 :             : 
     146                 :           2 :         const char *arguments = "--check-level=QUICK --update --database=0015_database_v0.db "
     147                 :             :                 "tests/fixtures/diffs/diff1";
     148                 :             : 
     149                 :           2 :         m_create(char,result,MEMORY_STRING);
     150                 :           2 :         m_create(char,pattern,MEMORY_STRING);
     151                 :             : 
     152                 :           2 :         const char *filename = "templates/0015_002_1.txt";
     153                 :             : 
     154                 :           2 :         ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
     155                 :             : 
     156                 :           2 :         ASSERT(SUCCESS == get_file_content(filename,pattern));
     157                 :             : 
     158                 :             :         // Match the result against the pattern
     159                 :           2 :         ASSERT(SUCCESS == match_pattern(result,pattern,filename));
     160                 :             : 
     161                 :             :         // Clean up test results
     162                 :           2 :         ASSERT(SUCCESS == delete_path("0015_database_v0.db"));
     163                 :             : 
     164                 :             :         // Clean to use it iteratively
     165                 :           2 :         m_del(pattern);
     166                 :           2 :         m_del(result);
     167                 :             : 
     168                 :           2 :         RETURN_STATUS;
     169                 :             : }
     170                 :             : 
     171                 :             : /**
     172                 :             :  * @brief Upgrade a legacy v0 DB with --watch-timestamps enabled
     173                 :             :  *
     174                 :             :  * Verify the upgrade succeeds and reports timestamp details in the output
     175                 :             :  */
     176                 :           2 : Return test0015_3(void)
     177                 :             : {
     178                 :           2 :         INITTEST;
     179                 :           2 :         ASSERT(SUCCESS == copy_path("tests/templates/0015_database_v0.db","0015_database_v0.db"));
     180                 :             : 
     181                 :           2 :         ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
     182                 :             : 
     183                 :           2 :         const char *arguments = "--check-level=QUICK --watch-timestamps --update --database=0015_database_v0.db "
     184                 :             :                 "tests/fixtures/diffs/diff1";
     185                 :             : 
     186                 :           2 :         m_create(char,result,MEMORY_STRING);
     187                 :           2 :         m_create(char,pattern,MEMORY_STRING);
     188                 :             : 
     189                 :           2 :         const char *filename = "templates/0015_002_2.txt";
     190                 :             : 
     191                 :           2 :         ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
     192                 :             : 
     193                 :           2 :         ASSERT(SUCCESS == get_file_content(filename,pattern));
     194                 :             : 
     195                 :             :         // Match the result against the pattern
     196                 :           2 :         ASSERT(SUCCESS == match_pattern(result,pattern,filename));
     197                 :             : 
     198                 :             :         // Clean to use it iteratively
     199                 :           2 :         m_del(pattern);
     200                 :           2 :         m_del(result);
     201                 :             : 
     202                 :           2 :         RETURN_STATUS;
     203                 :             : }
     204                 :             : 
     205                 :             : /**
     206                 :             :  * @brief Re-run upgrade for the already upgraded v0 DB
     207                 :             :  *
     208                 :             :  * Verify the database passes the default full integrity check, is treated
     209                 :             :  * as current, and the run stays successful
     210                 :             :  */
     211                 :           2 : Return test0015_4(void)
     212                 :             : {
     213                 :           2 :         INITTEST;
     214                 :             : 
     215                 :           2 :         m_create(char,result,MEMORY_STRING);
     216                 :           2 :         m_create(char,pattern,MEMORY_STRING);
     217                 :             : 
     218                 :           2 :         const char *filename = "templates/0015_003.txt";
     219                 :             : 
     220                 :           2 :         ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
     221                 :             : 
     222                 :           2 :         const char *arguments = "--update --database=./0015_database_v0.db "
     223                 :             :                 "tests/fixtures/diffs/diff1";
     224                 :             : 
     225                 :           2 :         ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
     226                 :             : 
     227                 :           2 :         ASSERT(SUCCESS == get_file_content(filename,pattern));
     228                 :             : 
     229                 :             :         // Match the result against the pattern
     230                 :           2 :         ASSERT(SUCCESS == match_pattern(result,pattern,filename));
     231                 :             : 
     232                 :             :         // Clean to use it iteratively
     233                 :           2 :         m_del(pattern);
     234                 :           2 :         m_del(result);
     235                 :             : 
     236                 :             :         // Clean up test results
     237                 :           2 :         ASSERT(SUCCESS == delete_path("0015_database_v0.db"));
     238                 :             : 
     239                 :           2 :         RETURN_STATUS;
     240                 :             : }
     241                 :             : 
     242                 :             : /**
     243                 :             :  * @brief Create a fresh DB with the default generated filename
     244                 :             :  *
     245                 :             :  * Verify CLI and file-supplied roots produce the same generated DB name and
     246                 :             :  * match the same complete output template. The template allows the additional
     247                 :             :  * configuration-path diagnostic for the file run
     248                 :             :  */
     249                 :           2 : Return test0015_5(void)
     250                 :             : {
     251                 :           2 :         INITTEST;
     252                 :             : 
     253                 :           2 :         ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
     254                 :             : 
     255                 :             :         // Run the application without an explicit DB name
     256                 :           2 :         const char *arguments = "tests/fixtures/diffs/diff1";
     257                 :             : 
     258                 :           2 :         const char *filename = "templates/0015_004.txt"; // File name
     259                 :           2 :         const char *template = "%DB_NAME%";
     260                 :             : 
     261                 :           2 :         const char *replacement = getenv("DBNAME"); // Database name
     262                 :             : 
     263                 :           2 :         ASSERT(replacement != NULL);
     264                 :             : 
     265                 :           2 :         const struct argument_test_case cases[] = {
     266                 :             :                 {arguments,COMPLETED,filename,STDERR_MUST_BE_EMPTY},
     267                 :             :                 {0}
     268                 :             :         };
     269                 :             : 
     270                 :           2 :         ASSERT(SUCCESS == run_and_match_templates(cases,template,replacement));
     271                 :             : 
     272                 :             :         /* Repeat the target creation from the same initial state. The resulting
     273                 :             :            database remains available to the following comparison tests */
     274                 :           2 :         ASSERT(SUCCESS == delete_path(replacement));
     275                 :           2 :         ASSERT(SUCCESS == copy_from_origin("tests/templates/0015_004.conf",
     276                 :             :                 "tests/templates/0015_004.conf",REQUIRE_SOURCE_EXISTS));
     277                 :           2 :         const struct argument_test_case file_cases[] = {
     278                 :             :                 {"--config=tests/templates/0015_004.conf",COMPLETED,filename,STDERR_MUST_BE_EMPTY},
     279                 :             :                 {0}
     280                 :             :         };
     281                 :           2 :         ASSERT(SUCCESS == run_and_match_templates(file_cases,template,replacement));
     282                 :           2 :         call(delete_path_if_present("tests/templates/0015_004.conf"));
     283                 :             : 
     284                 :           2 :         RETURN_STATUS;
     285                 :             : }
     286                 :             : 
     287                 :             : /**
     288                 :             :  * @brief Compare a current DB against a legacy v0 DB without --update
     289                 :             :  *
     290                 :             :  * Verify the application warns that the legacy DB must be upgraded first
     291                 :             :  */
     292                 :           2 : Return test0015_6(void)
     293                 :             : {
     294                 :           2 :         INITTEST;
     295                 :             : 
     296                 :           2 :         ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
     297                 :             : 
     298                 :           2 :         ASSERT(SUCCESS == copy_path("tests/templates/0015_database_v0.db","0015_database_v0.db"));
     299                 :             : 
     300                 :           2 :         const char *arguments = "--check-level=QUICK --compare $DBNAME 0015_database_v0.db";
     301                 :             : 
     302                 :           2 :         const char *filename = "templates/0015_005.txt"; // File name
     303                 :           2 :         const char *template = "%DB_NAME%";
     304                 :             : 
     305                 :           2 :         const char *replacement = getenv("DBNAME"); // Database name
     306                 :             : 
     307                 :           2 :         ASSERT(replacement != NULL);
     308                 :             : 
     309                 :           2 :         const struct argument_test_case cases[] = {
     310                 :             :                 {arguments,WARNING,filename,STDERR_MUST_BE_EMPTY},
     311                 :             :                 {0}
     312                 :             :         };
     313                 :             : 
     314                 :           2 :         ASSERT(SUCCESS == run_and_match_templates(cases,template,replacement));
     315                 :             : 
     316                 :           2 :         RETURN_STATUS;
     317                 :             : }
     318                 :             : 
     319                 :             : /**
     320                 :             :  * @brief Compare and upgrade a legacy v0 DB with --compare --update
     321                 :             :  *
     322                 :             :  * Verify the legacy DB is upgraded during comparison and the run completes
     323                 :             :  */
     324                 :           2 : Return test0015_7(void)
     325                 :             : {
     326                 :           2 :         INITTEST;
     327                 :             : 
     328                 :           2 :         ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
     329                 :           2 :         ASSERT(SUCCESS == copy_path("0015_database_v0.db","0015_006.db"));
     330                 :             : 
     331                 :             :         // Run the comparison and upgrade flow
     332                 :           2 :         const char *arguments = "--check-level=QUICK --compare --update $DBNAME 0015_database_v0.db";
     333                 :             : 
     334                 :           2 :         const char *filename = "templates/0015_006.txt"; // File name
     335                 :           2 :         const char *template = "%DB_NAME%";
     336                 :             : 
     337                 :           2 :         const char *replacement = getenv("DBNAME"); // Database name
     338                 :             : 
     339                 :           2 :         ASSERT(replacement != NULL);
     340                 :             : 
     341                 :           2 :         const struct argument_test_case cases[] = {
     342                 :             :                 {arguments,COMPLETED,filename,STDERR_MUST_BE_EMPTY},
     343                 :             :                 {0}
     344                 :             :         };
     345                 :             : 
     346                 :           2 :         ASSERT(SUCCESS == run_and_match_templates(cases,template,replacement));
     347                 :             : 
     348                 :             :         /* Restore the legacy database so the file run performs the same upgrade */
     349                 :           2 :         ASSERT(SUCCESS == copy_path("0015_006.db","0015_database_v0.db"));
     350                 :           2 :         ASSERT(SUCCESS == copy_path("tests/templates/0015_006.conf","0015_006.conf"));
     351                 :           2 :         ASSERT(SUCCESS == replace_placeholder_in_file("$TMPDIR/0015_006.conf","%DB_NAME%","$DBNAME"));
     352                 :           2 :         const struct argument_test_case file_cases[] = {
     353                 :             :                 {"--config=0015_006.conf",COMPLETED,filename,STDERR_MUST_BE_EMPTY},
     354                 :             :                 {0}
     355                 :             :         };
     356                 :           2 :         ASSERT(SUCCESS == run_and_match_templates(file_cases,template,replacement));
     357                 :           2 :         call(delete_path_if_present("0015_006.conf"));
     358                 :           2 :         call(delete_path_if_present("0015_006.db"));
     359                 :             : 
     360                 :             :         // Clean up test results
     361                 :           2 :         ASSERT(SUCCESS == delete_path("0015_database_v0.db"));
     362                 :             : 
     363                 :           2 :         RETURN_STATUS;
     364                 :             : }
     365                 :             : 
     366                 :             : /**
     367                 :             :  * @brief Upgrade a legacy v1 DB as the primary database with --update
     368                 :             :  *
     369                 :             :  * Verify the upgrade succeeds and produces the expected output
     370                 :             :  */
     371                 :           2 : Return test0015_8(void)
     372                 :             : {
     373                 :           2 :         INITTEST;
     374                 :             : 
     375                 :           2 :         ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
     376                 :           2 :         ASSERT(SUCCESS == copy_path("tests/templates/0015_database_v1.db","0015_database_v1.db"));
     377                 :             : 
     378                 :           2 :         const char *arguments = "--check-level=QUICK --update --database=0015_database_v1.db "
     379                 :             :                 "tests/fixtures/diffs/diff1";
     380                 :             : 
     381                 :           2 :         m_create(char,result,MEMORY_STRING);
     382                 :           2 :         m_create(char,pattern,MEMORY_STRING);
     383                 :             : 
     384                 :           2 :         const char *filename = "templates/0015_007.txt";
     385                 :             : 
     386                 :           2 :         ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
     387                 :             : 
     388                 :           2 :         ASSERT(SUCCESS == get_file_content(filename,pattern));
     389                 :             : 
     390                 :             :         // Match the result against the pattern
     391                 :           2 :         ASSERT(SUCCESS == match_pattern(result,pattern,filename));
     392                 :             : 
     393                 :             :         // Clean to use it iteratively
     394                 :           2 :         m_del(pattern);
     395                 :           2 :         m_del(result);
     396                 :             : 
     397                 :           2 :         RETURN_STATUS;
     398                 :             : }
     399                 :             : 
     400                 :             : /**
     401                 :             :  * @brief Re-run upgrade for the already upgraded v1 DB
     402                 :             :  *
     403                 :             :  * Verify the database passes the default full integrity check, is treated
     404                 :             :  * as current, and the run stays successful
     405                 :             :  */
     406                 :           2 : Return test0015_9(void)
     407                 :             : {
     408                 :           2 :         INITTEST;
     409                 :             : 
     410                 :           2 :         m_create(char,result,MEMORY_STRING);
     411                 :           2 :         m_create(char,pattern,MEMORY_STRING);
     412                 :             : 
     413                 :           2 :         const char *filename = "templates/0015_008.txt";
     414                 :             : 
     415                 :           2 :         ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
     416                 :             : 
     417                 :           2 :         const char *arguments = "--update --database=./0015_database_v1.db "
     418                 :             :                 "tests/fixtures/diffs/diff1";
     419                 :             : 
     420                 :           2 :         ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
     421                 :             : 
     422                 :           2 :         ASSERT(SUCCESS == get_file_content(filename,pattern));
     423                 :             : 
     424                 :             :         // Match the result against the pattern
     425                 :           2 :         ASSERT(SUCCESS == match_pattern(result,pattern,filename));
     426                 :             : 
     427                 :             :         // Clean to use it iteratively
     428                 :           2 :         m_del(pattern);
     429                 :           2 :         m_del(result);
     430                 :             : 
     431                 :             :         // Clean up test results
     432                 :           2 :         ASSERT(SUCCESS == delete_path("0015_database_v1.db"));
     433                 :             : 
     434                 :           2 :         RETURN_STATUS;
     435                 :             : }
     436                 :             : 
     437                 :             : /**
     438                 :             :  * @brief Compare and upgrade a legacy v1 DB with --compare --update
     439                 :             :  *
     440                 :             :  * Verify the legacy DB is upgraded during comparison and the run completes
     441                 :             :  */
     442                 :           2 : Return test0015_10(void)
     443                 :             : {
     444                 :           2 :         INITTEST;
     445                 :             : 
     446                 :           2 :         ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
     447                 :             : 
     448                 :             :         // Run the comparison and upgrade flow
     449                 :           2 :         ASSERT(SUCCESS == copy_path("tests/templates/0015_database_v1.db","0015_database_v1.db"));
     450                 :             : 
     451                 :           2 :         const char *arguments = "--check-level=QUICK --compare --update $DBNAME 0015_database_v1.db";
     452                 :             : 
     453                 :           2 :         const char *filename = "templates/0015_009.txt"; // File name
     454                 :           2 :         const char *template = "%DB_NAME%";
     455                 :             : 
     456                 :           2 :         const char *replacement = getenv("DBNAME"); // Database name
     457                 :             : 
     458                 :           2 :         ASSERT(replacement != NULL);
     459                 :             : 
     460                 :           2 :         const struct argument_test_case cases[] = {
     461                 :             :                 {arguments,COMPLETED,filename,STDERR_MUST_BE_EMPTY},
     462                 :             :                 {0}
     463                 :             :         };
     464                 :             : 
     465                 :           2 :         ASSERT(SUCCESS == run_and_match_templates(cases,template,replacement));
     466                 :             : 
     467                 :             :         // Clean up test results
     468                 :           2 :         ASSERT(SUCCESS == delete_path("0015_database_v1.db"));
     469                 :             : 
     470                 :           2 :         RETURN_STATUS;
     471                 :             : }
     472                 :             : 
     473                 :             : /**
     474                 :             :  * @brief Upgrade a legacy v2 DB as the primary database with --update
     475                 :             :  *
     476                 :             :  * Verify the upgrade succeeds and prints the verbose migration details
     477                 :             :  */
     478                 :           2 : Return test0015_11(void)
     479                 :             : {
     480                 :           2 :         INITTEST;
     481                 :             : 
     482                 :           2 :         ASSERT(SUCCESS == set_environment_variable("TESTING","false"));
     483                 :           2 :         ASSERT(SUCCESS == copy_path("tests/templates/0015_database_v2.db","0015_database_v2.db"));
     484                 :             : 
     485                 :           2 :         const char *arguments = "--check-level=QUICK --update --database=0015_database_v2.db --verbose "
     486                 :             :                 "tests/fixtures/diffs/diff1";
     487                 :             : 
     488                 :           2 :         m_create(char,result,MEMORY_STRING);
     489                 :           2 :         m_create(char,pattern,MEMORY_STRING);
     490                 :             : 
     491                 :           2 :         ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
     492                 :             : 
     493                 :           2 :         const char *filename = "templates/0015_010.txt";
     494                 :             : 
     495                 :           2 :         ASSERT(SUCCESS == get_file_content(filename,pattern));
     496                 :             : 
     497                 :             :         // Match the result against the pattern
     498                 :           2 :         ASSERT(SUCCESS == match_pattern(result,pattern,filename));
     499                 :             : 
     500                 :             :         // Clean up test results
     501                 :           2 :         ASSERT(SUCCESS == delete_path("0015_database_v2.db"));
     502                 :             : 
     503                 :             :         // Clean to use it iteratively
     504                 :           2 :         m_del(pattern);
     505                 :           2 :         m_del(result);
     506                 :             : 
     507                 :           2 :         RETURN_STATUS;
     508                 :             : }
     509                 :             : 
     510                 :             : /**
     511                 :             :  * @brief Compare and upgrade a legacy v2 DB with --compare --update
     512                 :             :  *
     513                 :             :  * Verify the legacy DB is upgraded during comparison and the run completes
     514                 :             :  */
     515                 :           2 : Return test0015_12(void)
     516                 :             : {
     517                 :           2 :         INITTEST;
     518                 :             : 
     519                 :           2 :         ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
     520                 :             : 
     521                 :             :         // Run the comparison and upgrade flow
     522                 :           2 :         ASSERT(SUCCESS == copy_path("tests/templates/0015_database_v2.db","0015_database_v2.db"));
     523                 :             : 
     524                 :           2 :         const char *arguments = "--check-level=QUICK --compare --update $DBNAME 0015_database_v2.db";
     525                 :             : 
     526                 :           2 :         const char *filename = "templates/0015_011.txt"; // File name
     527                 :           2 :         const char *template = "%DB_NAME%";
     528                 :             : 
     529                 :           2 :         const char *replacement = getenv("DBNAME"); // Database name
     530                 :             : 
     531                 :           2 :         ASSERT(replacement != NULL);
     532                 :             : 
     533                 :           2 :         const struct argument_test_case cases[] = {
     534                 :             :                 {arguments,COMPLETED,filename,STDERR_MUST_BE_EMPTY},
     535                 :             :                 {0}
     536                 :             :         };
     537                 :             : 
     538                 :           2 :         ASSERT(SUCCESS == run_and_match_templates(cases,template,replacement));
     539                 :             : 
     540                 :             :         // Clean up test results
     541                 :           2 :         ASSERT(SUCCESS == delete_path(replacement));
     542                 :           2 :         ASSERT(SUCCESS == delete_path("0015_database_v2.db"));
     543                 :             : 
     544                 :           2 :         RETURN_STATUS;
     545                 :             : }
     546                 :             : 
     547                 :             : /**
     548                 :             :  * @brief Upgrade a legacy v3 DB whose filename contains UTF-8 characters
     549                 :             :  *
     550                 :             :  * Verify the primary DB upgrade works with spaces and non-ASCII characters
     551                 :             :  * through CLI and configuration. Both runs start from the same v3 fixture
     552                 :             :  * and use the same full output template
     553                 :             :  *
     554                 :             :  * @return Return status for the CLI and configuration upgrade checks
     555                 :             :  */
     556                 :           2 : Return test0015_13(void)
     557                 :             : {
     558                 :           2 :         INITTEST;
     559                 :             : 
     560                 :           2 :         ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
     561                 :             : 
     562                 :           2 :         ASSERT(SUCCESS == copy_path("tests/templates/0015_database_v3 это база данных с пробелами и символами UTF-8.db","0015_database_v3 это база данных с пробелами и символами UTF-8.db"));
     563                 :             : 
     564                 :           2 :         const char *arguments = "--check-level=QUICK --update --database=\"0015_database_v3 это база данных с пробелами и символами UTF-8.db\" "
     565                 :             :                 "tests/fixtures/diffs/diff1";
     566                 :           2 :         const char *filename = "templates/0015_012.txt";
     567                 :           2 :         const struct argument_test_case cases[] = {
     568                 :             :                 {arguments,COMPLETED,filename,STDERR_MUST_BE_EMPTY},
     569                 :             :                 {0}
     570                 :             :         };
     571                 :             : 
     572                 :             :         // Match the result against the pattern
     573                 :           2 :         ASSERT(SUCCESS == run_and_match_templates(cases,NULL,NULL));
     574                 :             : 
     575                 :             :         /* Restore the original v3 database before repeating the upgrade through configuration */
     576                 :           2 :         ASSERT(SUCCESS == copy_path("tests/templates/0015_database_v3 это база данных с пробелами и символами UTF-8.db","0015_database_v3 это база данных с пробелами и символами UTF-8.db"));
     577                 :           2 :         ASSERT(SUCCESS == copy_path("tests/templates/0015_013.conf","0015_013.conf"));
     578                 :           2 :         const struct argument_test_case file_cases[] = {
     579                 :             :                 {"--config=0015_013.conf",COMPLETED,filename,STDERR_MUST_BE_EMPTY},
     580                 :             :                 {0}
     581                 :             :         };
     582                 :           2 :         ASSERT(SUCCESS == run_and_match_templates(file_cases,NULL,NULL));
     583                 :             : 
     584                 :             :         // Clean up test results
     585                 :           2 :         call(delete_path_if_present("0015_013.conf"));
     586                 :           2 :         ASSERT(SUCCESS == delete_path("0015_database_v3 это база данных с пробелами и символами UTF-8.db"));
     587                 :             : 
     588                 :           2 :         RETURN_STATUS;
     589                 :             : }
     590                 :             : 
     591                 :             : /**
     592                 :             :  * @brief Compare and upgrade a legacy v3 UTF-8 DB with --compare --update
     593                 :             :  *
     594                 :             :  * Verify the upgrade path works when both compared DB filenames contain UTF-8
     595                 :             :  */
     596                 :           2 : Return test0015_14(void)
     597                 :             : {
     598                 :           2 :         INITTEST;
     599                 :             : 
     600                 :           2 :         ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
     601                 :             : 
     602                 :           2 :         ASSERT(SUCCESS == copy_path("tests/templates/0015_database_v3 это база данных с пробелами и символами UTF-8.db","0015_database_v3 это база данных с пробелами и символами UTF-8.db"));
     603                 :             : 
     604                 :           2 :         ASSERT(SUCCESS == copy_path("tests/templates/0015_database_v4 это база данных с пробелами и символами UTF-8.db","0015_database_v4 это база данных с пробелами и символами UTF-8.db"));
     605                 :             : 
     606                 :           2 :         const char *arguments = "--check-level=QUICK --compare --update "
     607                 :             :                 "\"0015_database_v3 это база данных с пробелами и символами UTF-8.db\" "
     608                 :             :                 "\"0015_database_v4 это база данных с пробелами и символами UTF-8.db\"";
     609                 :             : 
     610                 :           2 :         m_create(char,result,MEMORY_STRING);
     611                 :           2 :         m_create(char,pattern,MEMORY_STRING);
     612                 :             : 
     613                 :           2 :         ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
     614                 :             : 
     615                 :           2 :         const char *filename = "templates/0015_013.txt";
     616                 :             : 
     617                 :           2 :         ASSERT(SUCCESS == get_file_content(filename,pattern));
     618                 :             : 
     619                 :             :         // Match the result against the pattern
     620                 :           2 :         ASSERT(SUCCESS == match_pattern(result,pattern,filename));
     621                 :             : 
     622                 :           2 :         m_del(result);
     623                 :           2 :         m_del(pattern);
     624                 :             : 
     625                 :           2 :         ASSERT(SUCCESS == delete_path("0015_database_v3 это база данных с пробелами и символами UTF-8.db"));
     626                 :           2 :         ASSERT(SUCCESS == delete_path("0015_database_v4 это база данных с пробелами и символами UTF-8.db"));
     627                 :             : 
     628                 :           2 :         RETURN_STATUS;
     629                 :             : }
     630                 :             : 
     631                 :             : /**
     632                 :             :  * @brief Compare a fresh UTF-8 DB against a legacy UTF-8 v4 reference DB
     633                 :             :  *
     634                 :             :  * Verify the application can create, read, and compare DB filenames with
     635                 :             :  * spaces and non-ASCII characters while keeping checksum compatibility
     636                 :             :  */
     637                 :           2 : Return test0015_15(void)
     638                 :             : {
     639                 :           2 :         INITTEST;
     640                 :             : 
     641                 :           2 :         ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
     642                 :             : 
     643                 :           2 :         ASSERT(SUCCESS == copy_path("tests/templates/0015_database_v4 это база данных с пробелами и символами UTF-8.db","0015_database_v4 это база данных с пробелами и символами UTF-8.db"));
     644                 :             : 
     645                 :           2 :         m_create(char,pattern,MEMORY_STRING);
     646                 :           2 :         m_create(char,result,MEMORY_STRING);
     647                 :           2 :         m_create(char,chunk,MEMORY_STRING);
     648                 :             : 
     649                 :           2 :         const char *arguments = "--database=\"Это новая база данных.db\" "
     650                 :             :                 "tests/fixtures/diffs/diff1";
     651                 :             : 
     652                 :           2 :         ASSERT(SUCCESS == runit(arguments,chunk,NULL,COMPLETED,ALLOW_BOTH));
     653                 :           2 :         ASSERT(SUCCESS == m_copy(result,chunk));
     654                 :             : 
     655                 :           2 :         arguments = "--check-level=QUICK --compare \"Это новая база данных.db\" "
     656                 :             :                 "\"0015_database_v4 это база данных с пробелами и символами UTF-8.db\"";
     657                 :             : 
     658                 :           2 :         ASSERT(SUCCESS == runit(arguments,chunk,NULL,COMPLETED,ALLOW_BOTH));
     659                 :           2 :         ASSERT(SUCCESS == m_concat_strings(result,chunk));
     660                 :             : 
     661                 :           2 :         const char *filename = "templates/0015_014.txt";
     662                 :             : 
     663                 :           2 :         ASSERT(SUCCESS == get_file_content(filename,pattern));
     664                 :             : 
     665                 :             :         // Match the result against the pattern
     666                 :           2 :         ASSERT(SUCCESS == match_pattern(result,pattern,filename));
     667                 :             : 
     668                 :             :         // Clean to use it iteratively
     669                 :           2 :         m_del(pattern);
     670                 :           2 :         m_del(result);
     671                 :           2 :         m_del(chunk);
     672                 :             : 
     673                 :             :         // Clean up test results
     674                 :           2 :         ASSERT(SUCCESS == delete_path("Это новая база данных.db"));
     675                 :           2 :         ASSERT(SUCCESS == delete_path("0015_database_v4 это база данных с пробелами и символами UTF-8.db"));
     676                 :             : 
     677                 :           2 :         RETURN_STATUS;
     678                 :             : }
     679                 :             : 
     680                 :             : /**
     681                 :             :  * @brief Upgrade a v0 DB with one corrupted legacy stat blob
     682                 :             :  *
     683                 :             :  * Verify the full upgrade still completes and the corrupted row is converted
     684                 :             :  * into the expected zero-source compact stat representation
     685                 :             :  */
     686                 :           2 : Return test0015_16(void)
     687                 :             : {
     688                 :           2 :         INITTEST;
     689                 :           2 :         const char *corrupted_db_filename = "0015_database_v0_corrupt.db";
     690                 :           2 :         const char *reference_db_filename = "0015_database_v4_reference.db";
     691                 :             : 
     692                 :           2 :         ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
     693                 :           2 :         ASSERT(SUCCESS == copy_path("tests/templates/0015_database_v0.db",corrupted_db_filename));
     694                 :           2 :         ASSERT(SUCCESS == copy_path("tests/templates/0015_database_v4 это база данных с пробелами и символами UTF-8.db",reference_db_filename));
     695                 :             : 
     696                 :           2 :         sqlite3_int64 row_id = 0;
     697                 :             : 
     698                 :           2 :         ASSERT(SUCCESS == db_corrupt_first_row_stat_blob(corrupted_db_filename,&row_id));
     699                 :             : 
     700                 :           2 :         m_create(char,result,MEMORY_STRING);
     701                 :           2 :         m_create(char,pattern,MEMORY_STRING);
     702                 :             : 
     703                 :           2 :         const char *arguments = "--check-level=QUICK --compare --update 0015_database_v4_reference.db 0015_database_v0_corrupt.db";
     704                 :             : 
     705                 :           2 :         ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
     706                 :           2 :         const char *filename = "templates/0015_015.txt";
     707                 :           2 :         ASSERT(SUCCESS == get_file_content(filename,pattern));
     708                 :           2 :         ASSERT(SUCCESS == match_pattern(result,pattern,filename));
     709                 :             : 
     710                 :           2 :         int db_version = 0;
     711                 :           2 :         ASSERT(SUCCESS == read_db_version_from_metadata(corrupted_db_filename,&db_version));
     712                 :           2 :         ASSERT(db_version == 4);
     713                 :             : 
     714                 :           2 :         CmpctStat stat = {0};
     715                 :           2 :         ASSERT(SUCCESS == db_read_cmpctstat_by_row_id(corrupted_db_filename,row_id,&stat));
     716                 :           2 :         ASSERT(SUCCESS == db_verify_zero_converted_cmpctstat(&stat));
     717                 :             : 
     718                 :           2 :         ASSERT(SUCCESS == delete_path(corrupted_db_filename));
     719                 :           2 :         ASSERT(SUCCESS == delete_path(reference_db_filename));
     720                 :             : 
     721                 :           2 :         m_del(result);
     722                 :           2 :         m_del(pattern);
     723                 :             : 
     724                 :           2 :         RETURN_STATUS;
     725                 :             : }
     726                 :             : 
     727                 :             : /**
     728                 :             :  * @brief Upgrade a v3 DB with one corrupted legacy stat blob
     729                 :             :  *
     730                 :             :  * Verify the full upgrade still completes and the corrupted row is stored
     731                 :             :  * using the zero-source conversion logic
     732                 :             :  */
     733                 :           2 : Return test0015_17(void)
     734                 :             : {
     735                 :           2 :         INITTEST;
     736                 :           2 :         const char *corrupted_db_filename = "0015_database_v3_corrupt.db";
     737                 :           2 :         const char *reference_db_filename = "0015_database_v4_reference.db";
     738                 :             : 
     739                 :           2 :         ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
     740                 :           2 :         ASSERT(SUCCESS == copy_path("tests/templates/0015_database_v3 это база данных с пробелами и символами UTF-8.db",corrupted_db_filename));
     741                 :           2 :         ASSERT(SUCCESS == copy_path("tests/templates/0015_database_v4 это база данных с пробелами и символами UTF-8.db",reference_db_filename));
     742                 :             : 
     743                 :           2 :         sqlite3_int64 row_id = 0;
     744                 :           2 :         ASSERT(SUCCESS == db_corrupt_first_row_stat_blob(corrupted_db_filename,&row_id));
     745                 :             : 
     746                 :           2 :         const char *arguments = "--check-level=QUICK --compare --update 0015_database_v4_reference.db 0015_database_v3_corrupt.db";
     747                 :             : 
     748                 :           2 :         m_create(char,result,MEMORY_STRING);
     749                 :           2 :         m_create(char,pattern,MEMORY_STRING);
     750                 :             : 
     751                 :           2 :         ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
     752                 :           2 :         const char *filename = "templates/0015_016.txt";
     753                 :           2 :         ASSERT(SUCCESS == get_file_content(filename,pattern));
     754                 :           2 :         ASSERT(SUCCESS == match_pattern(result,pattern,filename));
     755                 :             : 
     756                 :           2 :         int db_version = 0;
     757                 :           2 :         ASSERT(SUCCESS == read_db_version_from_metadata(corrupted_db_filename,&db_version));
     758                 :           2 :         ASSERT(db_version == 4);
     759                 :             : 
     760                 :           2 :         CmpctStat stat = {0};
     761                 :           2 :         ASSERT(SUCCESS == db_read_cmpctstat_by_row_id(corrupted_db_filename,row_id,&stat));
     762                 :           2 :         ASSERT(SUCCESS == db_verify_zero_converted_cmpctstat(&stat));
     763                 :             : 
     764                 :           2 :         ASSERT(SUCCESS == delete_path(corrupted_db_filename));
     765                 :           2 :         ASSERT(SUCCESS == delete_path(reference_db_filename));
     766                 :             : 
     767                 :           2 :         m_del(result);
     768                 :           2 :         m_del(pattern);
     769                 :             : 
     770                 :           2 :         RETURN_STATUS;
     771                 :             : }
     772                 :             : 
     773                 :             : /**
     774                 :             :  * @brief Roll back 3->4 migration when SQLite fails during stat conversion
     775                 :             :  *
     776                 :             :  * Verify the transaction is rolled back and the DB content stays unchanged
     777                 :             :  */
     778                 :           2 : Return test0015_18(void)
     779                 :             : {
     780                 :           2 :         INITTEST;
     781                 :           2 :         const char *rollback_db_filename = "0015_database_v3_rollback.db";
     782                 :           2 :         const char *reference_db_filename = "0015_database_v4_reference.db";
     783                 :             : 
     784                 :           2 :         ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
     785                 :           2 :         ASSERT(SUCCESS == copy_path("tests/templates/0015_database_v3 это база данных с пробелами и символами UTF-8.db",rollback_db_filename));
     786                 :           2 :         ASSERT(SUCCESS == copy_path("tests/templates/0015_database_v4 это база данных с пробелами и символами UTF-8.db",reference_db_filename));
     787                 :             : 
     788                 :           2 :         int files_count = 0;
     789                 :           2 :         ASSERT(SUCCESS == db_read_files_count(rollback_db_filename,&files_count));
     790                 :           2 :         ASSERT(files_count >= 2);
     791                 :             : 
     792                 :           2 :         sqlite3_int64 row_id = 0;
     793                 :           2 :         ASSERT(SUCCESS == db_read_first_row_id(rollback_db_filename,&row_id));
     794                 :             : 
     795                 :             :         unsigned char before_blob[512];
     796                 :           2 :         int before_blob_size = 0;
     797                 :           2 :         ASSERT(SUCCESS == db_read_stat_blob_by_row_id(rollback_db_filename,
     798                 :             :                 row_id,
     799                 :             :                 before_blob,
     800                 :             :                 sizeof(before_blob),
     801                 :             :                 &before_blob_size));
     802                 :             : 
     803                 :           2 :         int v1_rows_before = 0;
     804                 :           2 :         ASSERT(SUCCESS == db_read_files_count_with_blob_size(rollback_db_filename,
     805                 :             :                 (int)sizeof(CmpctStat_v1),
     806                 :             :                 &v1_rows_before));
     807                 :             : 
     808                 :           2 :         ASSERT(SUCCESS == db_create_abort_on_second_stat_update_trigger(rollback_db_filename));
     809                 :             : 
     810                 :           2 :         const char *arguments = "--check-level=QUICK --compare --update 0015_database_v4_reference.db 0015_database_v3_rollback.db";
     811                 :             : 
     812                 :           2 :         m_create(char,result,MEMORY_STRING);
     813                 :           2 :         m_create(char,pattern,MEMORY_STRING);
     814                 :             : 
     815                 :           2 :         ASSERT(SUCCESS == runit(arguments,result,NULL,FAILURE,ALLOW_BOTH));
     816                 :           2 :         const char *filename = "templates/0015_017.txt";
     817                 :           2 :         ASSERT(SUCCESS == get_file_content(filename,pattern));
     818                 :           2 :         ASSERT(SUCCESS == match_pattern(result,pattern,filename));
     819                 :             : 
     820                 :           2 :         int db_version = 0;
     821                 :           2 :         ASSERT(SUCCESS == read_db_version_from_metadata(rollback_db_filename,&db_version));
     822                 :           2 :         ASSERT(db_version == 3);
     823                 :             : 
     824                 :             :         unsigned char after_blob[512];
     825                 :           2 :         int after_blob_size = 0;
     826                 :           2 :         ASSERT(SUCCESS == db_read_stat_blob_by_row_id(rollback_db_filename,
     827                 :             :                 row_id,
     828                 :             :                 after_blob,
     829                 :             :                 sizeof(after_blob),
     830                 :             :                 &after_blob_size));
     831                 :             : 
     832                 :           2 :         ASSERT(before_blob_size == after_blob_size);
     833                 :             : 
     834         [ +  - ]:           2 :         if(before_blob_size > 0)
     835                 :             :         {
     836                 :           2 :                 ASSERT(0 == memcmp(before_blob,after_blob,(size_t)before_blob_size));
     837                 :             :         }
     838                 :             : 
     839                 :           2 :         int v1_rows_after = 0;
     840                 :           2 :         ASSERT(SUCCESS == db_read_files_count_with_blob_size(rollback_db_filename,
     841                 :             :                 (int)sizeof(CmpctStat_v1),
     842                 :             :                 &v1_rows_after));
     843                 :           2 :         ASSERT(v1_rows_before == v1_rows_after);
     844                 :             : 
     845                 :           2 :         ASSERT(SUCCESS == delete_path(rollback_db_filename));
     846                 :           2 :         ASSERT(SUCCESS == delete_path(reference_db_filename));
     847                 :             : 
     848                 :           2 :         m_del(result);
     849                 :           2 :         m_del(pattern);
     850                 :             : 
     851                 :           2 :         RETURN_STATUS;
     852                 :             : }
     853                 :             : 
     854                 :             : /**
     855                 :             :  * @brief Warn when metadata declares a DB version newer than supported
     856                 :             :  *
     857                 :             :  * Verify both testing and non-testing modes keep the future DB unchanged
     858                 :             :  */
     859                 :           2 : Return test0015_19(void)
     860                 :             : {
     861                 :           2 :         INITTEST;
     862                 :             : 
     863                 :           2 :         ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
     864                 :             : 
     865                 :           2 :         const char *db_filename = "0015_database_future_version.db";
     866                 :           2 :         const char *arguments = "--database=0015_database_future_version.db "
     867                 :             :                 "tests/fixtures/diffs/diff1";
     868                 :             : 
     869                 :           2 :         m_create(char,result,MEMORY_STRING);
     870                 :           2 :         m_create(char,pattern,MEMORY_STRING);
     871                 :             : 
     872                 :           2 :         ASSERT(SUCCESS == runit(arguments,NULL,NULL,COMPLETED,ALLOW_BOTH));
     873                 :           2 :         ASSERT(SUCCESS == set_db_version_in_metadata(db_filename,CURRENT_DB_VERSION + 1));
     874                 :             : 
     875                 :           2 :         int db_version = 0;
     876                 :           2 :         ASSERT(SUCCESS == read_db_version_from_metadata(db_filename,&db_version));
     877                 :           2 :         ASSERT(db_version == CURRENT_DB_VERSION + 1);
     878                 :             : 
     879                 :           2 :         arguments = "--check-level=QUICK --database=0015_database_future_version.db "
     880                 :             :                 "tests/fixtures/diffs/diff1";
     881                 :             : 
     882                 :           2 :         ASSERT(SUCCESS == runit(arguments,result,NULL,WARNING,ALLOW_BOTH));
     883                 :             : 
     884                 :           2 :         const char *filename = "templates/0015_018_1.txt";
     885                 :             : 
     886                 :           2 :         ASSERT(SUCCESS == get_file_content(filename,pattern));
     887                 :           2 :         ASSERT(SUCCESS == match_pattern(result,pattern,filename));
     888                 :             : 
     889                 :           2 :         ASSERT(SUCCESS == read_db_version_from_metadata(db_filename,&db_version));
     890                 :           2 :         ASSERT(db_version == CURRENT_DB_VERSION + 1);
     891                 :             : 
     892                 :           2 :         ASSERT(SUCCESS == set_environment_variable("TESTING","false"));
     893                 :           2 :         ASSERT(SUCCESS == runit(arguments,result,NULL,WARNING,ALLOW_BOTH));
     894                 :             : 
     895                 :           2 :         filename = "templates/0015_018_2.txt";
     896                 :             : 
     897                 :           2 :         ASSERT(SUCCESS == get_file_content(filename,pattern));
     898                 :           2 :         ASSERT(SUCCESS == match_pattern(result,pattern,filename));
     899                 :             : 
     900                 :           2 :         ASSERT(SUCCESS == delete_path(db_filename));
     901                 :             : 
     902                 :           2 :         m_del(result);
     903                 :           2 :         m_del(pattern);
     904                 :             : 
     905                 :           2 :         RETURN_STATUS;
     906                 :             : }
     907                 :             : 
     908                 :             : /**
     909                 :             :  * @brief Exercise DB upgrade and migration regressions across legacy formats
     910                 :             :  *
     911                 :             :  * This scenario covers primary DB upgrades from legacy versions 0 through 3,
     912                 :             :  * comparison-driven upgrades, default DB creation, UTF-8 filename handling,
     913                 :             :  * checksum compatibility against a legacy v4 reference DB, resilient handling
     914                 :             :  * of corrupted legacy stat blobs, rollback on forced SQLite migration failure,
     915                 :             :  * and warning behavior for a DB that reports a future metadata version
     916                 :             :  */
     917                 :           2 : Return test0015(void)
     918                 :             : {
     919                 :           2 :         INITTEST;
     920                 :             : 
     921                 :           2 :         TEST(test0015_1,"Upgrade a DB from v0 to the current version. Error handling");
     922                 :           2 :         TEST(test0015_2,"Upgrade a DB from v0 to the current version as the primary database");
     923                 :           2 :         TEST(test0015_3,"Upgrade a DB from v0 to the current version with --watch-timestamps");
     924                 :           2 :         TEST(test0015_4,"Verify that the upgraded v0 DB is actually at the current version");
     925                 :           2 :         TEST(test0015_5,"Create default name database");
     926                 :           2 :         TEST(test0015_6,"Attempting an upgrade with a single --compare parameter");
     927                 :           2 :         TEST(test0015_7,"Upgrading from 0 to the last version using the --compare and --update");
     928                 :           2 :         TEST(test0015_8,"Upgrade a DB from v1 to the current version as the primary database");
     929                 :           2 :         TEST(test0015_9,"Verify that the upgraded v1 DB is actually at the current version");
     930                 :           2 :         TEST(test0015_10,"Upgrading from 1 to the last version using the --compare and --update");
     931                 :           2 :         TEST(test0015_11,"Upgrade a DB from v2 to the current version as the primary database");
     932                 :           2 :         TEST(test0015_12,"Upgrading from 2 to the last version using the --compare and --update");
     933                 :           2 :         TEST(test0015_13,"Upgrading from 3 with UTF-8 name to the last version using the --update");
     934                 :           2 :         TEST(test0015_14,"Upgrading from 3 to the last version using the --compare and --update");
     935                 :           2 :         TEST(test0015_15,"Create and compare DBs with UTF-8 names and checksums from legacy DB");
     936                 :           2 :         TEST(test0015_16,"Corrupted v0 stat blob does not break the full upgrade");
     937                 :           2 :         TEST(test0015_17,"Corrupted v3 stat blob does not break the full upgrade");
     938                 :           2 :         TEST(test0015_18,"Forced SQLite failure triggers rollback during 3->4 migration");
     939                 :           2 :         TEST(test0015_19,"Fresh DB with forced future version returns warning and stays unchanged");
     940                 :             : 
     941                 :           2 :         RETURN_STATUS;
     942                 :             : }
        

Generated by: LCOV version 2.0-1