LCOV - code coverage report
Current view: top level - tests/src - test0029.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 100.0 % 174 174
Test Date: 2026-07-12 01:01:34 Functions: 100.0 % 7 7
Branches: 100.0 % 2 2

             Branch data     Line data    Source code
       1                 :             : #include "sute.h"
       2                 :             : 
       3                 :             : /**
       4                 :             :  * @brief Verify reporting and preservation of inaccessible paths
       5                 :             :  *
       6                 :             :  * Makes one file and one directory inaccessible, runs an update without
       7                 :             :  * `--db-drop-inaccessible`, and verifies that the expected inaccessible-path
       8                 :             :  * messages are produced while their database records are retained
       9                 :             :  */
      10                 :           2 : static Return test0029_1(void)
      11                 :             : {
      12                 :           2 :         INITTEST;
      13                 :             : 
      14                 :             :         // Create memory for the result
      15                 :           2 :         m_create(char,result,MEMORY_STRING);
      16                 :           2 :         m_create(char,pattern,MEMORY_STRING);
      17                 :             : 
      18                 :             :         // Preparation for tests
      19                 :           2 :         ASSERT(SUCCESS == prepare_mutable_fixture("tests/fixtures/diffs/diff1"));
      20                 :             : 
      21                 :           2 :         ASSERT(SUCCESS == set_environment_variable("TESTING","false"));
      22                 :             : 
      23                 :           2 :         const char *arguments = "--silent --database=database1.db tests/fixtures/diffs/diff1";
      24                 :             : 
      25                 :           2 :         ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
      26                 :             : 
      27                 :           2 :         ASSERT(result->length == 0);
      28                 :             : 
      29                 :           2 :         ASSERT(SUCCESS == change_mode("tests/fixtures/diffs/diff1/1/AAA/ZAW/D/e/f/b_file.txt",0000));
      30                 :           2 :         ASSERT(SUCCESS == change_mode("tests/fixtures/diffs/diff1/2/AAA/BBB/CZC",0000));
      31                 :             : 
      32                 :           2 :         ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
      33                 :             : 
      34                 :           2 :         arguments = "--update --database=database1.db tests/fixtures/diffs/diff1";
      35                 :             : 
      36                 :           2 :         ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
      37                 :             : 
      38                 :           2 :         const char *filename = "templates/0029_001.txt";
      39                 :             : 
      40                 :           2 :         ASSERT(SUCCESS == get_file_content(filename,pattern));
      41                 :           2 :         ASSERT(SUCCESS == match_pattern(result,pattern,filename));
      42                 :             : 
      43                 :           2 :         m_del(pattern);
      44                 :           2 :         m_del(result);
      45                 :             : 
      46                 :             :         // Clean up test results
      47                 :           2 :         ASSERT(SUCCESS == delete_path("database1.db"));
      48                 :           2 :         ASSERT(SUCCESS == change_mode("tests/fixtures/diffs/diff1/1/AAA/ZAW/D/e/f/b_file.txt",0666));
      49                 :           2 :         ASSERT(SUCCESS == change_mode("tests/fixtures/diffs/diff1/2/AAA/BBB/CZC",0777));
      50                 :           2 :         ASSERT(SUCCESS == restore_mutable_fixture("tests/fixtures/diffs/diff1"));
      51                 :             : 
      52                 :           2 :         RETURN_STATUS;
      53                 :             : }
      54                 :             : 
      55                 :             : /**
      56                 :             :  * @brief Verify removal of inaccessible records with --db-drop-inaccessible
      57                 :             :  *
      58                 :             :  * Makes one file and one directory inaccessible, enables
      59                 :             :  * `--db-drop-inaccessible`, and verifies that their database records are
      60                 :             :  * removed during the update
      61                 :             :  */
      62                 :           2 : static Return test0029_2(void)
      63                 :             : {
      64                 :           2 :         INITTEST;
      65                 :             : 
      66                 :             :         // Create memory for the result
      67                 :           2 :         m_create(char,result,MEMORY_STRING);
      68                 :           2 :         m_create(char,pattern,MEMORY_STRING);
      69                 :             : 
      70                 :             :         // Preparation for tests
      71                 :           2 :         ASSERT(SUCCESS == prepare_mutable_fixture("tests/fixtures/diffs/diff1"));
      72                 :             : 
      73                 :           2 :         ASSERT(SUCCESS == set_environment_variable("TESTING","false"));
      74                 :             : 
      75                 :           2 :         const char *arguments = "--silent --database=database2.db tests/fixtures/diffs/diff1";
      76                 :             : 
      77                 :           2 :         ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
      78                 :             : 
      79                 :           2 :         ASSERT(result->length == 0);
      80                 :             : 
      81                 :           2 :         ASSERT(SUCCESS == change_mode("tests/fixtures/diffs/diff1/1/AAA/ZAW/D/e/f/b_file.txt",0000));
      82                 :           2 :         ASSERT(SUCCESS == change_mode("tests/fixtures/diffs/diff1/2/AAA/BBB/CZC",0000));
      83                 :             : 
      84                 :           2 :         ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
      85                 :             : 
      86                 :           2 :         arguments = "--update --db-drop-inaccessible --database=database2.db "
      87                 :             :                 "tests/fixtures/diffs/diff1";
      88                 :             : 
      89                 :           2 :         ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
      90                 :             : 
      91                 :           2 :         const char *filename = "templates/0029_002.txt";
      92                 :             : 
      93                 :           2 :         ASSERT(SUCCESS == get_file_content(filename,pattern));
      94                 :           2 :         ASSERT(SUCCESS == match_pattern(result,pattern,filename));
      95                 :             : 
      96                 :           2 :         m_del(pattern);
      97                 :           2 :         m_del(result);
      98                 :             : 
      99                 :             :         // Clean up test results
     100                 :           2 :         ASSERT(SUCCESS == delete_path("database2.db"));
     101                 :           2 :         ASSERT(SUCCESS == change_mode("tests/fixtures/diffs/diff1/1/AAA/ZAW/D/e/f/b_file.txt",0666));
     102                 :           2 :         ASSERT(SUCCESS == change_mode("tests/fixtures/diffs/diff1/2/AAA/BBB/CZC",0777));
     103                 :           2 :         ASSERT(SUCCESS == restore_mutable_fixture("tests/fixtures/diffs/diff1"));
     104                 :             : 
     105                 :           2 :         RETURN_STATUS;
     106                 :             : }
     107                 :             : 
     108                 :             : /**
     109                 :             :  * @brief Verify that an access-check failure for one regular file does not stop traversal
     110                 :             :  *
     111                 :             :  * Forces one early file to report FILE_ACCESS_ERROR during an update run, then
     112                 :             :  * changes a later file. The update for the later file proves that traversal
     113                 :             :  * continued after the access-check failure
     114                 :             :  */
     115                 :           2 : static Return test0029_3(void)
     116                 :             : {
     117                 :           2 :         INITTEST;
     118                 :             : 
     119                 :           2 :         m_create(char,result,MEMORY_STRING);
     120                 :           2 :         m_create(char,pattern,MEMORY_STRING);
     121                 :             : 
     122                 :           2 :         const char *db_filename = "database3.db";
     123                 :           2 :         const char *access_error_root_path = "tests/fixtures/diffs/diff1";
     124                 :           2 :         const char *access_error_relative_path = "1/AAA/ZAW/D/e/f/b_file.txt";
     125                 :           2 :         const char *changed_later_file_path = "tests/fixtures/diffs/diff1/4/AAA/BBB/CCC/a.txt";
     126                 :             : 
     127                 :           2 :         ASSERT(SUCCESS == prepare_mutable_fixture("tests/fixtures/diffs/diff1"));
     128                 :             : 
     129                 :           2 :         ASSERT(SUCCESS == set_environment_variable("TESTING","false"));
     130                 :             : 
     131                 :           2 :         const char *arguments = "--silent --database=database3.db tests/fixtures/diffs/diff1";
     132                 :             : 
     133                 :           2 :         ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
     134                 :             : 
     135                 :           2 :         ASSERT(result->length == 0);
     136                 :             : 
     137                 :           2 :         ASSERT(SUCCESS == replase_to_string("access check failure must not stop traversal",changed_later_file_path));
     138                 :             : 
     139                 :           2 :         ASSERT(SUCCESS == expect_file_access_from_root(
     140                 :             :                 access_error_root_path,
     141                 :             :                 access_error_relative_path,
     142                 :             :                 R_OK,
     143                 :             :                 FILE_ACCESS_ALLOWED));
     144                 :             : 
     145                 :           2 :         ASSERT(SUCCESS == set_environment_variable("TESTITALL_TEST_ENV_FILE_ACCESS_SUFFIX",access_error_relative_path));
     146                 :           2 :         ASSERT(SUCCESS == set_environment_variable("TESTITALL_TEST_ENV_FILE_ACCESS_STATUS","FILE_ACCESS_ERROR"));
     147                 :           2 :         ASSERT(SUCCESS == expect_file_access_from_root(
     148                 :             :                 access_error_root_path,
     149                 :             :                 access_error_relative_path,
     150                 :             :                 R_OK,
     151                 :             :                 FILE_ACCESS_ERROR));
     152                 :             : 
     153                 :           2 :         ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
     154                 :             : 
     155                 :           2 :         arguments = "--update --database=database3.db tests/fixtures/diffs/diff1";
     156                 :             : 
     157                 :           2 :         ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
     158                 :             : 
     159                 :           2 :         ASSERT(SUCCESS == set_environment_variable("TESTITALL_TEST_ENV_FILE_ACCESS_SUFFIX",""));
     160                 :           2 :         ASSERT(SUCCESS == set_environment_variable("TESTITALL_TEST_ENV_FILE_ACCESS_STATUS",""));
     161                 :             : 
     162                 :           2 :         const char *filename = "templates/0029_003.txt";
     163                 :             : 
     164                 :           2 :         ASSERT(SUCCESS == get_file_content(filename,pattern));
     165                 :           2 :         ASSERT(SUCCESS == match_pattern(result,pattern,filename));
     166                 :             : 
     167                 :           2 :         m_del(pattern);
     168                 :           2 :         m_del(result);
     169                 :             : 
     170                 :           2 :         ASSERT(SUCCESS == delete_path(db_filename));
     171                 :           2 :         ASSERT(SUCCESS == restore_mutable_fixture("tests/fixtures/diffs/diff1"));
     172                 :             : 
     173                 :           2 :         RETURN_STATUS;
     174                 :             : }
     175                 :             : 
     176                 :             : /**
     177                 :             :  * @brief Verify that every root opening failure safely skips metadata cleanup
     178                 :             :  *
     179                 :             :  * Creates a baseline database, skips file traversal, and forces root opening
     180                 :             :  * to report access denied, not found, and an unexpected access error. Every
     181                 :             :  * update uses `--db-drop-inaccessible` and must still finish successfully
     182                 :             :  * without deleting file records. The complete output from every update is
     183                 :             :  * matched against the same PCRE2 template
     184                 :             :  */
     185                 :           2 : static Return test0029_4(void)
     186                 :             : {
     187                 :           2 :         INITTEST;
     188                 :             : 
     189                 :           2 :         m_create(char,result,MEMORY_STRING);
     190                 :           2 :         m_create(char,pattern,MEMORY_STRING);
     191                 :             : 
     192                 :           2 :         const char *db_filename = "database4.db";
     193                 :           2 :         const char *filename = "templates/0029_004.txt";
     194                 :           2 :         const char *root_access_statuses[] = {
     195                 :             :                 "FILE_ACCESS_DENIED",
     196                 :             :                 "FILE_NOT_FOUND",
     197                 :             :                 "FILE_ACCESS_ERROR"
     198                 :             :         };
     199                 :           2 :         const size_t root_access_status_count =
     200                 :             :                 sizeof(root_access_statuses) / sizeof(root_access_statuses[0]);
     201                 :           2 :         int files_count_before = 0;
     202                 :             : 
     203                 :           2 :         ASSERT(SUCCESS == prepare_mutable_fixture("tests/fixtures/diffs/diff1"));
     204                 :           2 :         ASSERT(SUCCESS == set_environment_variable("TESTING","false"));
     205                 :             : 
     206                 :           2 :         const char *arguments = "--silent --database=database4.db tests/fixtures/diffs/diff1";
     207                 :             : 
     208                 :           2 :         ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
     209                 :           2 :         ASSERT(result->length == 0);
     210                 :           2 :         ASSERT(SUCCESS == db_read_files_count(db_filename,&files_count_before));
     211                 :           2 :         ASSERT(files_count_before > 0);
     212                 :             : 
     213                 :           2 :         ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
     214                 :           2 :         ASSERT(SUCCESS == set_environment_variable("TESTITALL_TEST_ENV_SKIP_FILE_LIST","1"));
     215                 :           2 :         ASSERT(SUCCESS == set_environment_variable("TESTITALL_TEST_ENV_FILE_ACCESS_SUFFIX","diff1"));
     216                 :           2 :         ASSERT(SUCCESS == get_file_content(filename,pattern));
     217                 :             : 
     218                 :           2 :         arguments = "--update --db-drop-inaccessible --database=database4.db "
     219                 :             :                 "tests/fixtures/diffs/diff1";
     220                 :             : 
     221         [ +  + ]:           8 :         for(size_t index = 0; index < root_access_status_count; index++)
     222                 :             :         {
     223                 :           6 :                 int files_count_after = 0;
     224                 :             : 
     225                 :           6 :                 ASSERT(SUCCESS == set_environment_variable(
     226                 :             :                         "TESTITALL_TEST_ENV_FILE_ACCESS_STATUS",
     227                 :             :                         root_access_statuses[index]));
     228                 :             : 
     229                 :           6 :                 ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
     230                 :           6 :                 ASSERT(SUCCESS == match_pattern(result,pattern,filename));
     231                 :             : 
     232                 :           6 :                 ASSERT(SUCCESS == db_read_files_count(db_filename,&files_count_after));
     233                 :           6 :                 ASSERT(files_count_after == files_count_before);
     234                 :             :         }
     235                 :             : 
     236                 :           2 :         ASSERT(SUCCESS == set_environment_variable("TESTITALL_TEST_ENV_SKIP_FILE_LIST",""));
     237                 :           2 :         ASSERT(SUCCESS == set_environment_variable("TESTITALL_TEST_ENV_FILE_ACCESS_SUFFIX",""));
     238                 :           2 :         ASSERT(SUCCESS == set_environment_variable("TESTITALL_TEST_ENV_FILE_ACCESS_STATUS",""));
     239                 :             : 
     240                 :           2 :         m_del(pattern);
     241                 :           2 :         m_del(result);
     242                 :             : 
     243                 :           2 :         ASSERT(SUCCESS == delete_path(db_filename));
     244                 :           2 :         ASSERT(SUCCESS == restore_mutable_fixture("tests/fixtures/diffs/diff1"));
     245                 :             : 
     246                 :           2 :         RETURN_STATUS;
     247                 :             : }
     248                 :             : 
     249                 :             : /**
     250                 :             :  * @brief Verify that an unavailable PATH root does not stop later roots
     251                 :             :  *
     252                 :             :  * Forces the first of two traversal roots to fail during root opening. The
     253                 :             :  * unavailable root must be reported immediately and shown again in the final
     254                 :             :  * warning summary, while a file from the second root must still be written to
     255                 :             :  * the database
     256                 :             :  */
     257                 :           2 : static Return test0029_5(void)
     258                 :             : {
     259                 :           2 :         INITTEST;
     260                 :             : 
     261                 :           2 :         m_create(char,result,MEMORY_STRING);
     262                 :           2 :         m_create(char,pattern,MEMORY_STRING);
     263                 :             : 
     264                 :           2 :         const char *db_filename = "database5.db";
     265                 :           2 :         const char *filename = "templates/0029_005.txt";
     266                 :           2 :         const char *available_relative_path = "AAA/BBB/CCC/a.txt";
     267                 :           2 :         bool available_path_exists = false;
     268                 :             : 
     269                 :           2 :         ASSERT(SUCCESS == set_environment_variable("TESTING","false"));
     270                 :           2 :         ASSERT(SUCCESS == set_environment_variable("TESTITALL_TEST_ENV_FILE_ACCESS_SUFFIX","diff1/1"));
     271                 :           2 :         ASSERT(SUCCESS == set_environment_variable("TESTITALL_TEST_ENV_FILE_ACCESS_STATUS","FILE_ACCESS_DENIED"));
     272                 :             : 
     273                 :           2 :         const char *arguments = "--database=database5.db "
     274                 :             :                 "tests/fixtures/diffs/diff1/1 tests/fixtures/diffs/diff1/4";
     275                 :             : 
     276                 :           2 :         ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
     277                 :             : 
     278                 :           2 :         ASSERT(SUCCESS == get_file_content(filename,pattern));
     279                 :           2 :         ASSERT(SUCCESS == match_pattern(result,pattern,filename));
     280                 :           2 :         ASSERT(SUCCESS == db_relative_path_exists(db_filename,available_relative_path,&available_path_exists));
     281                 :           2 :         ASSERT(available_path_exists == true);
     282                 :             : 
     283                 :           2 :         ASSERT(SUCCESS == set_environment_variable("TESTITALL_TEST_ENV_FILE_ACCESS_SUFFIX",""));
     284                 :           2 :         ASSERT(SUCCESS == set_environment_variable("TESTITALL_TEST_ENV_FILE_ACCESS_STATUS",""));
     285                 :             : 
     286                 :           2 :         m_del(pattern);
     287                 :           2 :         m_del(result);
     288                 :             : 
     289                 :           2 :         ASSERT(SUCCESS == delete_path(db_filename));
     290                 :             : 
     291                 :           2 :         RETURN_STATUS;
     292                 :             : }
     293                 :             : 
     294                 :             : /**
     295                 :             :  * @brief Verify --db-drop-inaccessible does not override ignore scope
     296                 :             :  *
     297                 :             :  * Makes one file inaccessible and ignores the same relative path during update.
     298                 :             :  * Even with --db-drop-inaccessible, the ignored non-locked row must stay in the
     299                 :             :  * DB and must not be reported through inaccessible cleanup
     300                 :             :  */
     301                 :           2 : static Return test0029_6(void)
     302                 :             : {
     303                 :           2 :         INITTEST;
     304                 :             : 
     305                 :           2 :         m_create(char,result,MEMORY_STRING);
     306                 :           2 :         m_create(char,pattern,MEMORY_STRING);
     307                 :             : 
     308                 :           2 :         const char *db_filename = "database6.db";
     309                 :           2 :         const char *ignored_relative_path = "1/AAA/ZAW/D/e/f/b_file.txt";
     310                 :           2 :         bool ignored_path_exists = false;
     311                 :             : 
     312                 :           2 :         ASSERT(SUCCESS == prepare_mutable_fixture("tests/fixtures/diffs/diff1"));
     313                 :           2 :         ASSERT(SUCCESS == set_environment_variable("TESTING","false"));
     314                 :             : 
     315                 :           2 :         const char *arguments = "--silent --database=database6.db tests/fixtures/diffs/diff1";
     316                 :             : 
     317                 :           2 :         ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
     318                 :           2 :         ASSERT(result->length == 0);
     319                 :             : 
     320                 :           2 :         ASSERT(SUCCESS == change_mode("tests/fixtures/diffs/diff1/1/AAA/ZAW/D/e/f/b_file.txt",0000));
     321                 :           2 :         ASSERT(SUCCESS == set_environment_variable("TESTING","true"));
     322                 :             : 
     323                 :           2 :         arguments = "--update --db-drop-inaccessible "
     324                 :             :                 "--ignore=\"^1/AAA/ZAW/D/e/f/b_file\\.txt$\" "
     325                 :             :                 "--database=database6.db tests/fixtures/diffs/diff1";
     326                 :             : 
     327                 :           2 :         ASSERT(SUCCESS == runit(arguments,result,NULL,COMPLETED,ALLOW_BOTH));
     328                 :             : 
     329                 :           2 :         const char *filename = "templates/0029_006.txt";
     330                 :           2 :         ASSERT(SUCCESS == get_file_content(filename,pattern));
     331                 :           2 :         ASSERT(SUCCESS == match_pattern(result,pattern,filename));
     332                 :             : 
     333                 :           2 :         ASSERT(SUCCESS == db_relative_path_exists(db_filename,ignored_relative_path,&ignored_path_exists));
     334                 :           2 :         ASSERT(ignored_path_exists == true);
     335                 :             : 
     336                 :           2 :         m_del(pattern);
     337                 :           2 :         m_del(result);
     338                 :             : 
     339                 :           2 :         ASSERT(SUCCESS == change_mode("tests/fixtures/diffs/diff1/1/AAA/ZAW/D/e/f/b_file.txt",0666));
     340                 :           2 :         ASSERT(SUCCESS == delete_path(db_filename));
     341                 :           2 :         ASSERT(SUCCESS == restore_mutable_fixture("tests/fixtures/diffs/diff1"));
     342                 :             : 
     343                 :           2 :         RETURN_STATUS;
     344                 :             : }
     345                 :             : 
     346                 :             : /**
     347                 :             :  * @brief Run inaccessible-path behavior tests
     348                 :             :  *
     349                 :             :  * Covers preservation, explicit removal, unexpected file access-check failure,
     350                 :             :  * safe cleanup skipping, and continued traversal after a PATH root cannot be
     351                 :             :  * opened
     352                 :             :  */
     353                 :           2 : Return test0029(void)
     354                 :             : {
     355                 :           2 :         INITTEST;
     356                 :             : 
     357                 :           2 :         TEST(test0029_1,"Inaccessible paths are reported and kept by default");
     358                 :           2 :         TEST(test0029_2,"--db-drop-inaccessible drops inaccessible DB records");
     359                 :           2 :         TEST(test0029_3,"Access-check failure for a regular file does not stop traversal");
     360                 :           2 :         TEST(test0029_4,"Root opening failures skip metadata cleanup without deleting records");
     361                 :           2 :         TEST(test0029_5,"Unavailable PATH root is remembered while later roots continue");
     362                 :           2 :         TEST(test0029_6,"--db-drop-inaccessible does not override ignore scope");
     363                 :             : 
     364                 :           2 :         RETURN_STATUS;
     365                 :             : }
        

Generated by: LCOV version 2.0-1