root/tests/lib/vfs/vfs_parse_ls_lga.c

/* [previous][next][first][last][top][bottom][index][help]  */

DEFINITIONS

This source file includes following definitions.
  1. message
  2. teardown
  3. message
  4. fill_stat_struct
  5. START_PARAMETRIZED_TEST
  6. START_TEST
  7. START_TEST
  8. main

   1 /*
   2    lib/vfs - test vfs_parse_ls_lga() functionality
   3 
   4    Copyright (C) 2011-2025
   5    Free Software Foundation, Inc.
   6 
   7    Written by:
   8    Slava Zanko <slavazanko@gmail.com>, 2011, 2013
   9 
  10    This file is part of the Midnight Commander.
  11 
  12    The Midnight Commander is free software: you can redistribute it
  13    and/or modify it under the terms of the GNU General Public License as
  14    published by the Free Software Foundation, either version 3 of the License,
  15    or (at your option) any later version.
  16 
  17    The Midnight Commander is distributed in the hope that it will be useful,
  18    but WITHOUT ANY WARRANTY; without even the implied warranty of
  19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20    GNU General Public License for more details.
  21 
  22    You should have received a copy of the GNU General Public License
  23    along with this program.  If not, see <https://www.gnu.org/licenses/>.
  24  */
  25 
  26 #define TEST_SUITE_NAME "/lib/vfs"
  27 
  28 #include "tests/mctest.h"
  29 
  30 #include <stdio.h>
  31 
  32 #include "lib/vfs/utilvfs.h"
  33 #include "lib/vfs/xdirentry.h"
  34 #include "lib/strutil.h"
  35 
  36 #include "src/vfs/local/local.c"
  37 
  38 static struct vfs_s_subclass test_subclass1;
  39 static struct vfs_class *vfs_test_ops1 = VFS_CLASS (&test_subclass1);
  40 
  41 static struct vfs_s_entry *vfs_root_entry;
  42 static struct vfs_s_inode *vfs_root_inode;
  43 static struct vfs_s_super *vfs_test_super;
  44 
  45 void message (int flags, const char *title, const char *text, ...) G_GNUC_PRINTF (3, 4);
     /* [previous][next][first][last][top][bottom][index][help]  */
  46 
  47 /* --------------------------------------------------------------------------------------------- */
  48 
  49 /* @Before */
  50 static void
  51 setup (void)
  52 {
  53     static struct stat initstat;
  54 
  55     str_init_strings (NULL);
  56 
  57     vfs_init ();
  58     vfs_init_localfs ();
  59     vfs_setup_work_dir ();
  60 
  61     vfs_init_subclass (&test_subclass1, "testfs1", VFSF_NOLINKS | VFSF_REMOTE, "test1");
  62     vfs_register_class (vfs_test_ops1);
  63 
  64     vfs_test_super = g_new0 (struct vfs_s_super, 1);
  65     vfs_test_super->me = vfs_test_ops1;
  66 
  67     vfs_root_inode = vfs_s_new_inode (vfs_test_ops1, vfs_test_super, &initstat);
  68     vfs_root_entry = vfs_s_new_entry (vfs_test_ops1, "/", vfs_root_inode);
  69 }
  70 
  71 /* --------------------------------------------------------------------------------------------- */
  72 
  73 /* @After */
  74 static void
  75 teardown (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
  76 {
  77     vfs_s_free_entry (vfs_test_ops1, vfs_root_entry);
  78     vfs_shut ();
  79     str_uninit_strings ();
  80 }
  81 
  82 /* --------------------------------------------------------------------------------------------- */
  83 
  84 /* @Mock */
  85 void
  86 message (int flags, const char *title, const char *text, ...)
     /* [previous][next][first][last][top][bottom][index][help]  */
  87 {
  88     char *p;
  89     va_list ap;
  90 
  91     (void) flags;
  92     (void) title;
  93 
  94     va_start (ap, text);
  95     p = g_strdup_vprintf (text, ap);
  96     va_end (ap);
  97     printf ("message(): %s\n", p);
  98     g_free (p);
  99 }
 100 
 101 /* --------------------------------------------------------------------------------------------- */
 102 
 103 static void
 104 fill_stat_struct (struct stat *etalon_stat, int iterator)
     /* [previous][next][first][last][top][bottom][index][help]  */
 105 {
 106     vfs_zero_stat_times (etalon_stat);
 107 
 108     switch (iterator)
 109     {
 110     case 0:
 111         etalon_stat->st_dev = 0;
 112         etalon_stat->st_ino = 0;
 113         etalon_stat->st_mode = 0x41fd;
 114         etalon_stat->st_nlink = 10;
 115         etalon_stat->st_uid = 500;
 116         etalon_stat->st_gid = 500;
 117 #ifdef HAVE_STRUCT_STAT_ST_RDEV
 118         etalon_stat->st_rdev = 0;
 119 #endif
 120         etalon_stat->st_size = 4096;
 121 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
 122         etalon_stat->st_blksize = 512;
 123 #endif
 124 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
 125         etalon_stat->st_blocks = 8;
 126 #endif
 127         etalon_stat->st_atime = 1308838140;
 128         etalon_stat->st_mtime = 1308838140;
 129         etalon_stat->st_ctime = 1308838140;
 130         break;
 131     case 1:
 132         etalon_stat->st_dev = 0;
 133         etalon_stat->st_ino = 0;
 134         etalon_stat->st_mode = 0xa1ff;
 135         etalon_stat->st_nlink = 10;
 136         etalon_stat->st_uid = 500;
 137         etalon_stat->st_gid = 500;
 138 #ifdef HAVE_STRUCT_STAT_ST_RDEV
 139         etalon_stat->st_rdev = 0;
 140 #endif
 141         etalon_stat->st_size = 11;
 142 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
 143         etalon_stat->st_blksize = 512;
 144 #endif
 145 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
 146         etalon_stat->st_blocks = 1;
 147 #endif
 148         etalon_stat->st_atime = 1268431200;
 149         etalon_stat->st_mtime = 1268431200;
 150         etalon_stat->st_ctime = 1268431200;
 151         break;
 152     case 2:
 153         etalon_stat->st_dev = 0;
 154         etalon_stat->st_ino = 0;
 155         etalon_stat->st_mode = 0x41fd;
 156         etalon_stat->st_nlink = 10;
 157         etalon_stat->st_uid = 500;
 158         etalon_stat->st_gid = 500;
 159 #ifdef HAVE_STRUCT_STAT_ST_RDEV
 160         etalon_stat->st_rdev = 0;
 161 #endif
 162         etalon_stat->st_size = 4096;
 163 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
 164         etalon_stat->st_blksize = 512;
 165 #endif
 166 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
 167         etalon_stat->st_blocks = 8;
 168 #endif
 169         etalon_stat->st_atime = 1308838140;
 170         etalon_stat->st_mtime = 1308838140;
 171         etalon_stat->st_ctime = 1308838140;
 172         break;
 173     case 3:
 174         etalon_stat->st_dev = 0;
 175         etalon_stat->st_ino = 0;
 176         etalon_stat->st_mode = 0x41fd;
 177         etalon_stat->st_nlink = 10;
 178         etalon_stat->st_uid = 500;
 179         etalon_stat->st_gid = 500;
 180 #ifdef HAVE_STRUCT_STAT_ST_RDEV
 181         etalon_stat->st_rdev = 0;
 182 #endif
 183         etalon_stat->st_size = 4096;
 184 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
 185         etalon_stat->st_blksize = 512;
 186 #endif
 187 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
 188         etalon_stat->st_blocks = 8;
 189 #endif
 190         etalon_stat->st_atime = 1308838140;
 191         etalon_stat->st_mtime = 1308838140;
 192         etalon_stat->st_ctime = 1308838140;
 193         break;
 194     default:
 195         break;
 196     }
 197 }
 198 
 199 /* --------------------------------------------------------------------------------------------- */
 200 
 201 /* @DataSource("test_vfs_parse_ls_lga_ds") */
 202 static const struct test_vfs_parse_ls_lga_ds
 203 {
 204     const char *input_string;
 205     int expected_result;
 206     const char *expected_filename;
 207     const char *expected_linkname;
 208     const size_t expected_filepos;
 209 } test_vfs_parse_ls_lga_ds[] = {
 210     {
 211         // 0.
 212         "drwxrwxr-x   10 500      500          4096 Jun 23 17:09 build_root",
 213         1,
 214         "build_root",
 215         NULL,
 216         0,
 217     },
 218     {
 219         // 1.
 220         "lrwxrwxrwx    1 500      500            11 Mar 13  2010 COPYING -> doc/COPYING",
 221         1,
 222         "COPYING",
 223         "doc/COPYING",
 224         0,
 225     },
 226     {
 227         // 2.
 228         "drwxrwxr-x   10 500      500          4096 Jun 23 17:09 ..",
 229         1,
 230         "..",
 231         NULL,
 232         0,
 233     },
 234     {
 235         // 3.
 236         "drwxrwxr-x   10 500      500          4096 Jun 23 17:09   build_root",
 237         1,
 238         "build_root",
 239         NULL,
 240         0,
 241     },
 242 };
 243 
 244 /* @Test(dataSource = "test_vfs_parse_ls_lga_ds") */
 245 START_PARAMETRIZED_TEST (test_vfs_parse_ls_lga, test_vfs_parse_ls_lga_ds)
     /* [previous][next][first][last][top][bottom][index][help]  */
 246 
 247 {
 248     // given
 249     size_t filepos = 0;
 250     struct stat etalon_stat;
 251     static struct stat test_stat;
 252     char *filename = NULL;
 253     char *linkname = NULL;
 254     gboolean actual_result;
 255 
 256     vfs_parse_ls_lga_init ();
 257 
 258 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
 259     etalon_stat.st_blocks = 0;
 260 #endif
 261     etalon_stat.st_size = 0;
 262     etalon_stat.st_mode = 0;
 263     fill_stat_struct (&etalon_stat, _i);
 264 
 265     // when
 266     actual_result =
 267         vfs_parse_ls_lga (data->input_string, &test_stat, &filename, &linkname, &filepos);
 268 
 269     // then
 270     ck_assert_int_eq (actual_result, data->expected_result);
 271 
 272     mctest_assert_str_eq (filename, data->expected_filename);
 273     mctest_assert_str_eq (linkname, data->expected_linkname);
 274 
 275     ck_assert_int_eq (etalon_stat.st_dev, test_stat.st_dev);
 276     ck_assert_int_eq (etalon_stat.st_ino, test_stat.st_ino);
 277     ck_assert_int_eq (etalon_stat.st_mode, test_stat.st_mode);
 278     ck_assert_int_eq (etalon_stat.st_uid, test_stat.st_uid);
 279     ck_assert_int_eq (etalon_stat.st_gid, test_stat.st_gid);
 280 #ifdef HAVE_STRUCT_STAT_ST_RDEV
 281     ck_assert_int_eq (etalon_stat.st_rdev, test_stat.st_rdev);
 282 #endif
 283     ck_assert_int_eq (etalon_stat.st_size, test_stat.st_size);
 284 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
 285     ck_assert_int_eq (etalon_stat.st_blksize, test_stat.st_blksize);
 286 #endif
 287 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
 288     ck_assert_int_eq (etalon_stat.st_blocks, test_stat.st_blocks);
 289 #endif
 290 
 291     /* FIXME: these commented checks are related to time zone!
 292        ck_assert_int_eq (etalon_stat.st_atime, test_stat.st_atime);
 293        ck_assert_int_eq (etalon_stat.st_mtime, test_stat.st_mtime);
 294        ck_assert_int_eq (etalon_stat.st_ctime, test_stat.st_ctime);
 295      */
 296 
 297 #ifdef HAVE_STRUCT_STAT_ST_MTIM
 298     ck_assert_int_eq (0, test_stat.st_atim.tv_nsec);
 299     ck_assert_int_eq (0, test_stat.st_mtim.tv_nsec);
 300     ck_assert_int_eq (0, test_stat.st_ctim.tv_nsec);
 301 #endif
 302 }
 303 END_PARAMETRIZED_TEST
 304 
 305 /* --------------------------------------------------------------------------------------------- */
 306 
 307 /* @Test */
 308 START_TEST (test_vfs_parse_ls_lga_reorder)
     /* [previous][next][first][last][top][bottom][index][help]  */
 309 {
 310     // given
 311     size_t filepos = 0;
 312     struct vfs_s_entry *ent1, *ent2, *ent3;
 313 
 314     vfs_parse_ls_lga_init ();
 315 
 316     // init ent1
 317     ent1 = vfs_s_generate_entry (vfs_test_ops1, NULL, vfs_root_inode, 0);
 318     vfs_parse_ls_lga ("drwxrwxr-x   10 500      500          4096 Jun 23 17:09      build_root1",
 319                       &ent1->ino->st, &ent1->name, &ent1->ino->linkname, &filepos);
 320     vfs_s_store_filename_leading_spaces (ent1, filepos);
 321     vfs_s_insert_entry (vfs_test_ops1, vfs_root_inode, ent1);
 322 
 323     // init ent2
 324     ent2 = vfs_s_generate_entry (vfs_test_ops1, NULL, vfs_root_inode, 0);
 325     vfs_parse_ls_lga ("drwxrwxr-x   10 500      500          4096 Jun 23 17:09    build_root2",
 326                       &ent2->ino->st, &ent2->name, &ent2->ino->linkname, &filepos);
 327     vfs_s_store_filename_leading_spaces (ent2, filepos);
 328     vfs_s_insert_entry (vfs_test_ops1, vfs_root_inode, ent2);
 329 
 330     // init ent3
 331     ent3 = vfs_s_generate_entry (vfs_test_ops1, NULL, vfs_root_inode, 0);
 332     vfs_parse_ls_lga ("drwxrwxr-x   10 500      500          4096 Jun 23 17:09 ..", &ent3->ino->st,
 333                       &ent3->name, &ent3->ino->linkname, &filepos);
 334     vfs_s_store_filename_leading_spaces (ent3, filepos);
 335     vfs_s_insert_entry (vfs_test_ops1, vfs_root_inode, ent3);
 336 
 337     // when
 338     vfs_s_normalize_filename_leading_spaces (vfs_root_inode, vfs_parse_ls_lga_get_final_spaces ());
 339 
 340     // then
 341     mctest_assert_str_eq (ent1->name, "     build_root1");
 342     mctest_assert_str_eq (ent2->name, "   build_root2");
 343 }
 344 END_TEST
 345 
 346 /* --------------------------------------------------------------------------------------------- */
 347 #define parse_one_line(ent_index, ls_output)                                                       \
 348     {                                                                                              \
 349         ent[ent_index] = vfs_s_generate_entry (vfs_test_ops1, NULL, vfs_root_inode, 0);            \
 350         if (!vfs_parse_ls_lga (ls_output, &ent[ent_index]->ino->st, &ent[ent_index]->name,         \
 351                                &ent[ent_index]->ino->linkname, &filepos))                          \
 352         {                                                                                          \
 353             ck_abort_msg ("An error occurred while parse ls output");                              \
 354             return;                                                                                \
 355         }                                                                                          \
 356         vfs_s_store_filename_leading_spaces (ent[ent_index], filepos);                             \
 357         vfs_s_insert_entry (vfs_test_ops1, vfs_root_inode, ent[ent_index]);                        \
 358     }
 359 
 360 /* @Test */
 361 START_TEST (test_vfs_parse_ls_lga_unaligned)
     /* [previous][next][first][last][top][bottom][index][help]  */
 362 {
 363     // given
 364     size_t filepos = 0;
 365     struct vfs_s_entry *ent[4];
 366 
 367     vfs_parse_ls_lga_init ();
 368 
 369     parse_one_line (0, "drwxrwxr-x   10 500      500          4096 Jun 23 17:09  build_root1");
 370     parse_one_line (1, "drwxrwxr-x   10 500     500         4096 Jun 23 17:09     build_root2");
 371     parse_one_line (2, "drwxrwxr-x 10 500 500 4096 Jun 23 17:09  ..");
 372     parse_one_line (
 373         3,
 374         "drwxrwxr-x      10   500        500             4096   Jun   23   17:09   build_root 0");
 375 
 376     // when
 377     vfs_s_normalize_filename_leading_spaces (vfs_root_inode, vfs_parse_ls_lga_get_final_spaces ());
 378 
 379     // then
 380     mctest_assert_str_eq (ent[0]->name, "build_root1");
 381     mctest_assert_str_eq (ent[0]->name, "build_root1");
 382     mctest_assert_str_eq (ent[1]->name, "   build_root2");
 383     mctest_assert_str_eq (ent[3]->name, " build_root 0");
 384 }
 385 END_TEST
 386 
 387 /* --------------------------------------------------------------------------------------------- */
 388 
 389 int
 390 main (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
 391 {
 392     TCase *tc_core;
 393 
 394     tc_core = tcase_create ("Core");
 395 
 396     tcase_add_checked_fixture (tc_core, setup, teardown);
 397 
 398     // Add new tests here: ***************
 399     mctest_add_parameterized_test (tc_core, test_vfs_parse_ls_lga, test_vfs_parse_ls_lga_ds);
 400     tcase_add_test (tc_core, test_vfs_parse_ls_lga_reorder);
 401     tcase_add_test (tc_core, test_vfs_parse_ls_lga_unaligned);
 402     // ***********************************
 403 
 404     return mctest_run_all (tc_core);
 405 }
 406 
 407 /* --------------------------------------------------------------------------------------------- */

/* [previous][next][first][last][top][bottom][index][help]  */