LCOV - code coverage report
Current view: top level - cmdline - mktest.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 222 238 93.3 %
Date: 2017-11-06 22:14:04 Functions: 18 18 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (C) 2011 Andrea Mazzoleni
       3             :  *
       4             :  * This program is free software: you can redistribute it and/or modify
       5             :  * it under the terms of the GNU General Public License as published by
       6             :  * the Free Software Foundation, either version 3 of the License, or
       7             :  * (at your option) any later version.
       8             :  *
       9             :  * This program is distributed in the hope that it will be useful,
      10             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12             :  * GNU General Public License for more details.
      13             :  *
      14             :  * You should have received a copy of the GNU General Public License
      15             :  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
      16             :  */
      17             : 
      18             : #include "portable.h"
      19             : 
      20             : #include "support.h"
      21             : 
      22             : /****************************************************************************/
      23             : /* random */
      24             : 
      25             : /**
      26             :  * Pseudo random number generator.
      27             :  */
      28             : unsigned long long seed = 0;
      29             : 
      30    55864576 : unsigned rnd(unsigned max)
      31             : {
      32    55864576 :         seed = seed * 6364136223846793005LL + 1442695040888963407LL;
      33             : 
      34    55864576 :         return (seed >> 32) % max;
      35             : }
      36             : 
      37    55453401 : unsigned rndnz(unsigned max)
      38             : {
      39    55453401 :         if (max <= 1)
      40        2831 :                 return 1;
      41             :         else
      42    55450570 :                 return rnd(max - 1) + 1;
      43             : }
      44             : 
      45       32695 : void rndnz_range(unsigned char* data, int size)
      46             : {
      47             :         int i;
      48             : 
      49    55479340 :         for (i = 0; i < size; ++i)
      50    55446645 :                 data[i] = rndnz(256);
      51       32695 : }
      52             : 
      53        1821 : void rndnz_damage(unsigned char* data, int size)
      54             : {
      55             :         int i;
      56             : 
      57             :         /* corrupt ensuring always different data */
      58        3642 :         for (i = 0; i < size; ++i) {
      59             :                 unsigned char c;
      60             : 
      61             :                 do {
      62        1825 :                         c = rndnz(256);
      63        1825 :                 } while (c == data[i]);
      64             : 
      65        1821 :                 data[i] = c;
      66             :         }
      67        1821 : }
      68             : 
      69             : char CHARSET[] = "qwertyuiopasdfghjklzxcvbnm1234567890 .-+";
      70             : #define CHARSET_LEN (sizeof(CHARSET) - 1)
      71             : 
      72       26833 : void rnd_name(char* file)
      73             : {
      74       26833 :         int l = 1 + rnd(20);
      75             : 
      76      335293 :         while (l) {
      77      281627 :                 *file++ = CHARSET[rnd(CHARSET_LEN)];
      78      281627 :                 --l;
      79             :         }
      80       26833 :         *file = 0;
      81       26833 : }
      82             : 
      83             : /****************************************************************************/
      84             : /* file */
      85             : 
      86      146777 : int file_cmp(const void* a, const void* b)
      87             : {
      88      146777 :         return strcmp(a, b);
      89             : }
      90             : 
      91        1821 : int fallback(int f, struct stat* st)
      92             : {
      93             : #if HAVE_FUTIMENS
      94             :         struct timespec tv[2];
      95             : #else
      96             :         struct timeval tv[2];
      97             : #endif
      98             :         int ret;
      99             : 
     100             : #if HAVE_FUTIMENS /* futimens() is preferred because it gives nanosecond precision */
     101        1821 :         tv[0].tv_sec = st->st_mtime;
     102        1821 :         if (STAT_NSEC(st) != STAT_NSEC_INVALID)
     103        1821 :                 tv[0].tv_nsec = STAT_NSEC(st);
     104             :         else
     105           0 :                 tv[0].tv_nsec = 0;
     106        1821 :         tv[1].tv_sec = tv[0].tv_sec;
     107        1821 :         tv[1].tv_nsec = tv[0].tv_nsec;
     108             : 
     109        1821 :         ret = futimens(f, tv);
     110             : #elif HAVE_FUTIMES /* fallback to futimes() if nanosecond precision is not available */
     111             :         tv[0].tv_sec = st->st_mtime;
     112             :         if (STAT_NSEC(st) != STAT_NSEC_INVALID)
     113             :                 tv[0].tv_usec = STAT_NSEC(st) / 1000;
     114             :         else
     115             :                 tv[0].tv_usec = 0;
     116             :         tv[1].tv_sec = tv[0].tv_sec;
     117             :         tv[1].tv_usec = tv[0].tv_usec;
     118             : 
     119             :         ret = futimes(f, tv);
     120             : #elif HAVE_FUTIMESAT /* fallback to futimesat() for Solaris, it only has futimesat() */
     121             :         tv[0].tv_sec = st->st_mtime;
     122             :         if (STAT_NSEC(st) != STAT_NSEC_INVALID)
     123             :                 tv[0].tv_usec = STAT_NSEC(st) / 1000;
     124             :         else
     125             :                 tv[0].tv_usec = 0;
     126             :         tv[1].tv_sec = tv[0].tv_sec;
     127             :         tv[1].tv_usec = tv[0].tv_usec;
     128             : 
     129             :         ret = futimesat(f, 0, tv);
     130             : #else
     131             : #error No function available to set file timestamps
     132             : #endif
     133        1821 :         return ret;
     134             : }
     135             : 
     136             : /****************************************************************************/
     137             : /* cmd */
     138             : 
     139             : /**
     140             :  * Create a file with random content.
     141             :  * - If the file exists it's rewritten, but avoiding to truncating it to 0.
     142             :  */
     143       23267 : void cmd_generate_file(const char* path, int size)
     144             : {
     145             :         unsigned char* data;
     146             :         int f;
     147             : 
     148             :         /* remove the existing file/symlink if any */
     149       23267 :         if (remove(path) != 0) {
     150       22446 :                 if (errno != ENOENT) {
     151             :                         /* LCOV_EXCL_START */
     152             :                         log_fatal("Error removing file %s\n", path);
     153             :                         exit(EXIT_FAILURE);
     154             :                         /* LCOV_EXCL_STOP */
     155             :                 }
     156             :         } else {
     157             :                 /* don't truncate files to 0 size to avoid ZERO file size protection */
     158         821 :                 ++size;
     159             :         }
     160             : 
     161       23267 :         data = malloc(size);
     162             : 
     163             :         /* We don't write zero bytes because we want to test */
     164             :         /* the recovering of new files, after an aborted sync */
     165             :         /* If the files contains full blocks at zero */
     166             :         /* this is an impossible condition to recover */
     167             :         /* because we cannot differentiate between an unused block */
     168             :         /* and a file filled with 0 */
     169       23267 :         rndnz_range(data, size);
     170             : 
     171       23267 :         f = open(path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_NOFOLLOW, 0600);
     172       23267 :         if (f < 0) {
     173             :                 /* LCOV_EXCL_START */
     174             :                 log_fatal("Error creating file %s\n", path);
     175             :                 exit(EXIT_FAILURE);
     176             :                 /* LCOV_EXCL_STOP */
     177             :         }
     178             : 
     179       23267 :         if (write(f, data, size) != size) {
     180             :                 /* LCOV_EXCL_START */
     181             :                 log_fatal("Error writing file %s\n", path);
     182             :                 exit(EXIT_FAILURE);
     183             :                 /* LCOV_EXCL_STOP */
     184             :         }
     185             : 
     186       23267 :         if (close(f) != 0) {
     187             :                 /* LCOV_EXCL_START */
     188             :                 log_fatal("Error closing file %s\n", path);
     189             :                 exit(EXIT_FAILURE);
     190             :                 /* LCOV_EXCL_STOP */
     191             :         }
     192             : 
     193       23267 :         free(data);
     194       23267 : }
     195             : 
     196             : /**
     197             :  * Create a symlink.
     198             :  * - If the file already exists, it's removed.
     199             :  */
     200         924 : void cmd_generate_symlink(const char* path, const char* linkto)
     201             : {
     202             :         /* remove the existing file/symlink if any */
     203         924 :         if (remove(path) != 0) {
     204         903 :                 if (errno != ENOENT) {
     205             :                         /* LCOV_EXCL_START */
     206             :                         log_fatal("Error removing file %s\n", path);
     207             :                         exit(EXIT_FAILURE);
     208             :                         /* LCOV_EXCL_STOP */
     209             :                 }
     210             :         }
     211             : 
     212         924 :         if (symlink(linkto, path) != 0) {
     213             :                 /* LCOV_EXCL_START */
     214             :                 log_fatal("Error writing symlink %s\n", path);
     215             :                 exit(EXIT_FAILURE);
     216             :                 /* LCOV_EXCL_STOP */
     217             :         }
     218         924 : }
     219             : 
     220             : /**
     221             :  * Create a file or a symlink with a random name.
     222             :  */
     223       24000 : void cmd_generate(int disk, int size)
     224             : {
     225             :         char path[PATH_MAX];
     226             :         char* file;
     227             : 
     228       24000 :         snprintf(path, sizeof(path), "bench/disk%d/", disk);
     229       24000 :         file = path + strlen(path);
     230             : 
     231             :         /* add a directory */
     232       24000 :         *file++ = 'a' + rnd(2);
     233       24000 :         *file = 0;
     234             : 
     235             :         /* create it */
     236       24000 :         if (mkdir(path, 0777) != 0) {
     237       23988 :                 if (errno != EEXIST) {
     238             :                         /* LCOV_EXCL_START */
     239             :                         log_fatal("Error creating directory %s\n", path);
     240             :                         exit(EXIT_FAILURE);
     241             :                         /* LCOV_EXCL_STOP */
     242             :                 }
     243             :         }
     244             : 
     245       24000 :         *file++ = '/';
     246             : 
     247             :         while (1) {
     248             :                 /* add a random file */
     249       25909 :                 rnd_name(file);
     250             : 
     251             :                 /* skip some invalid file name, see http://en.wikipedia.org/wiki/Filename */
     252       25909 :                 if (strcmp(file, ".") == 0
     253       25874 :                         || strcmp(file, "..") == 0
     254       25874 :                         || strcmp(file, "prn") == 0
     255       25874 :                         || strcmp(file, "con") == 0
     256       25873 :                         || strcmp(file, "nul") == 0
     257       25873 :                         || strcmp(file, "aux") == 0
     258       25873 :                         || file[0] == ' '
     259       25199 :                         || file[strlen(file) - 1] == ' '
     260       24608 :                         || file[strlen(file) - 1] == '.'
     261             :                 ) {
     262        1909 :                         continue;
     263             :                 }
     264             : 
     265       24000 :                 break;
     266        1909 :         }
     267             : 
     268             : #ifndef WIN32 /* Windows XP doesn't support symlinks */
     269       24000 :         if (rnd(32) == 0) {
     270             :                 /* symlink */
     271             :                 char linkto[PATH_MAX];
     272             : 
     273         733 :                 rnd_name(linkto);
     274             : 
     275         733 :                 cmd_generate_symlink(path, linkto);
     276             :         } else
     277             : #endif
     278             :         {
     279             :                 /* file */
     280       23267 :                 cmd_generate_file(path, size);
     281             :         }
     282       24000 : }
     283             : 
     284             : /**
     285             :  * Write a partially a file.
     286             :  * - The file must exist.
     287             :  * - The file size is not changed.
     288             :  * - The written data may be equal or not at the already existing one.
     289             :  * - If it's a symlink nothing is done.
     290             :  */
     291        6265 : void cmd_write(const char* path, int size)
     292             : {
     293             :         struct stat st;
     294             : 
     295        6265 :         if (lstat(path, &st) != 0) {
     296             :                 /* LCOV_EXCL_START */
     297             :                 log_fatal("Error accessing %s\n", path);
     298             :                 exit(EXIT_FAILURE);
     299             :                 /* LCOV_EXCL_STOP */
     300             :         }
     301             : 
     302        6265 :         if (S_ISREG(st.st_mode)) {
     303             :                 unsigned char* data;
     304             :                 off_t off;
     305             :                 int f;
     306             : 
     307             :                 /* not over the end */
     308        6238 :                 if (size > st.st_size)
     309         687 :                         size = st.st_size;
     310             : 
     311             :                 /* start at random position inside the file */
     312        6238 :                 if (size < st.st_size)
     313        5551 :                         off = rnd(st.st_size - size);
     314             :                 else
     315         687 :                         off = 0;
     316             : 
     317        6238 :                 data = malloc(size);
     318             : 
     319        6238 :                 rndnz_range(data, size);
     320             : 
     321        6238 :                 f = open(path, O_WRONLY | O_BINARY | O_NOFOLLOW);
     322        6238 :                 if (f < 0) {
     323             :                         /* LCOV_EXCL_START */
     324             :                         log_fatal("Error creating file %s\n", path);
     325             :                         exit(EXIT_FAILURE);
     326             :                         /* LCOV_EXCL_STOP */
     327             :                 }
     328             : 
     329        6238 :                 if (lseek(f, off, SEEK_SET) != off) {
     330             :                         /* LCOV_EXCL_START */
     331             :                         log_fatal("Error seeking file %s\n", path);
     332             :                         exit(EXIT_FAILURE);
     333             :                         /* LCOV_EXCL_STOP */
     334             :                 }
     335             : 
     336        6238 :                 if (write(f, data, size) != size) {
     337             :                         /* LCOV_EXCL_START */
     338             :                         log_fatal("Error writing file %s\n", path);
     339             :                         exit(EXIT_FAILURE);
     340             :                         /* LCOV_EXCL_STOP */
     341             :                 }
     342             : 
     343        6238 :                 if (close(f) != 0) {
     344             :                         /* LCOV_EXCL_START */
     345             :                         log_fatal("Error closing file %s\n", path);
     346             :                         exit(EXIT_FAILURE);
     347             :                         /* LCOV_EXCL_STOP */
     348             :                 }
     349             : 
     350        6238 :                 free(data);
     351             :         }
     352        6265 : }
     353             : 
     354             : /**
     355             :  * Damage a file.
     356             :  * - The file must exist.
     357             :  * - The file size is not changed.
     358             :  * - The written data is SURELY different than the already existing one.
     359             :  * - The file timestamp is NOT modified.
     360             :  * - If it's a symlink nothing is done.
     361             :  */
     362        1882 : void cmd_damage(const char* path, int size)
     363             : {
     364             :         struct stat st;
     365             : 
     366             :         /* here a 0 size means to change nothing */
     367             :         /* as also the timestamp should not be changed */
     368        1882 :         if (!size)
     369           3 :                 return;
     370             : 
     371        1882 :         if (lstat(path, &st) != 0) {
     372             :                 /* LCOV_EXCL_START */
     373             :                 log_fatal("Error accessing %s\n", path);
     374             :                 exit(EXIT_FAILURE);
     375             :                 /* LCOV_EXCL_STOP */
     376             :         }
     377             : 
     378        1882 :         if (st.st_size == 0)
     379           3 :                 return;
     380             : 
     381        1879 :         if (S_ISREG(st.st_mode)) {
     382             :                 off_t off;
     383             :                 unsigned char* data;
     384             :                 int f;
     385             : 
     386             :                 /* not over the end */
     387        1821 :                 if (size > st.st_size)
     388           0 :                         size = st.st_size;
     389             : 
     390             :                 /* start at random position inside the file */
     391        1821 :                 if (size < st.st_size)
     392        1820 :                         off = rnd(st.st_size - size);
     393             :                 else
     394           1 :                         off = 0;
     395             : 
     396        1821 :                 data = malloc(size);
     397             : 
     398        1821 :                 f = open(path, O_RDWR | O_BINARY | O_NOFOLLOW);
     399        1821 :                 if (f < 0) {
     400             :                         /* LCOV_EXCL_START */
     401             :                         log_fatal("Error creating file %s\n", path);
     402             :                         exit(EXIT_FAILURE);
     403             :                         /* LCOV_EXCL_STOP */
     404             :                 }
     405             : 
     406        1821 :                 if (lseek(f, off, SEEK_SET) != off) {
     407             :                         /* LCOV_EXCL_START */
     408             :                         log_fatal("Error seeking file %s\n", path);
     409             :                         exit(EXIT_FAILURE);
     410             :                         /* LCOV_EXCL_STOP */
     411             :                 }
     412             : 
     413        1821 :                 if (read(f, data, size) != size) {
     414             :                         /* LCOV_EXCL_START */
     415             :                         log_fatal("Error writing file %s\n", path);
     416             :                         exit(EXIT_FAILURE);
     417             :                         /* LCOV_EXCL_STOP */
     418             :                 }
     419             : 
     420        1821 :                 rndnz_damage(data, size);
     421             : 
     422        1821 :                 if (lseek(f, off, SEEK_SET) != off) {
     423             :                         /* LCOV_EXCL_START */
     424             :                         log_fatal("Error seeking file %s\n", path);
     425             :                         exit(EXIT_FAILURE);
     426             :                         /* LCOV_EXCL_STOP */
     427             :                 }
     428             : 
     429        1821 :                 if (write(f, data, size) != size) {
     430             :                         /* LCOV_EXCL_START */
     431             :                         log_fatal("Error writing file %s\n", path);
     432             :                         exit(EXIT_FAILURE);
     433             :                         /* LCOV_EXCL_STOP */
     434             :                 }
     435             : 
     436        1821 :                 if (fallback(f, &st) != 0) {
     437             :                         /* LCOV_EXCL_START */
     438             :                         log_fatal("Error setting time for file %s\n", path);
     439             :                         exit(EXIT_FAILURE);
     440             :                         /* LCOV_EXCL_STOP */
     441             :                 }
     442             : 
     443        1821 :                 if (close(f) != 0) {
     444             :                         /* LCOV_EXCL_START */
     445             :                         log_fatal("Error closing file %s\n", path);
     446             :                         exit(EXIT_FAILURE);
     447             :                         /* LCOV_EXCL_STOP */
     448             :                 }
     449             : 
     450        1821 :                 free(data);
     451             :         }
     452             : }
     453             : 
     454             : /**
     455             :  * Append to a file.
     456             :  * - The file must exist.
     457             :  * - If it's a symlink nothing is done.
     458             :  */
     459        3190 : void cmd_append(const char* path, int size)
     460             : {
     461             :         struct stat st;
     462             : 
     463        3190 :         if (lstat(path, &st) != 0) {
     464             :                 /* LCOV_EXCL_START */
     465             :                 log_fatal("Error accessing %s\n", path);
     466             :                 exit(EXIT_FAILURE);
     467             :                 /* LCOV_EXCL_STOP */
     468             :         }
     469             : 
     470        3190 :         if (S_ISREG(st.st_mode)) {
     471             :                 unsigned char* data;
     472             :                 int f;
     473             : 
     474        3190 :                 data = malloc(size);
     475             : 
     476        3190 :                 rndnz_range(data, size);
     477             : 
     478        3190 :                 f = open(path, O_WRONLY | O_APPEND | O_BINARY | O_NOFOLLOW);
     479        3190 :                 if (f < 0) {
     480             :                         /* LCOV_EXCL_START */
     481             :                         log_fatal("Error opening file %s\n", path);
     482             :                         exit(EXIT_FAILURE);
     483             :                         /* LCOV_EXCL_STOP */
     484             :                 }
     485             : 
     486        3190 :                 if (write(f, data, size) != size) {
     487             :                         /* LCOV_EXCL_START */
     488             :                         log_fatal("Error writing file %s\n", path);
     489             :                         exit(EXIT_FAILURE);
     490             :                         /* LCOV_EXCL_STOP */
     491             :                 }
     492             : 
     493        3190 :                 if (close(f) != 0) {
     494             :                         /* LCOV_EXCL_START */
     495             :                         log_fatal("Error closing file %s\n", path);
     496             :                         exit(EXIT_FAILURE);
     497             :                         /* LCOV_EXCL_STOP */
     498             :                 }
     499             : 
     500        3190 :                 free(data);
     501             :         }
     502        3190 : }
     503             : 
     504             : /**
     505             :  * Truncate a file.
     506             :  * - The file must exist.
     507             :  * - The file is NEVER truncated to 0.
     508             :  * - If it's a symlink nothing is done.
     509             :  */
     510        3042 : void cmd_truncate(const char* path, int size)
     511             : {
     512             :         struct stat st;
     513             : 
     514        3042 :         if (lstat(path, &st) != 0) {
     515             :                 /* LCOV_EXCL_START */
     516             :                 log_fatal("Error accessing %s\n", path);
     517             :                 exit(EXIT_FAILURE);
     518             :                 /* LCOV_EXCL_STOP */
     519             :         }
     520             : 
     521        3042 :         if (S_ISREG(st.st_mode)) {
     522             :                 off_t off;
     523             :                 int f;
     524             : 
     525             :                 /* if file is empty, just rewrite it */
     526        3042 :                 if (st.st_size == 0) {
     527           3 :                         size = 0;
     528             :                 } else {
     529             :                         /* don't truncate files to 0 size to avoid ZERO file size protection */
     530        3039 :                         if (size >= st.st_size)
     531         162 :                                 size = st.st_size - 1;
     532             :                 }
     533             : 
     534        3042 :                 off = st.st_size - size;
     535             : 
     536        3042 :                 f = open(path, O_WRONLY | O_BINARY | O_NOFOLLOW);
     537        3042 :                 if (f < 0) {
     538             :                         /* LCOV_EXCL_START */
     539             :                         log_fatal("Error opening file %s\n", path);
     540             :                         exit(EXIT_FAILURE);
     541             :                         /* LCOV_EXCL_STOP */
     542             :                 }
     543             : 
     544        3042 :                 if (ftruncate(f, off) != 0) {
     545             :                         /* LCOV_EXCL_START */
     546             :                         log_fatal("Error truncating file %s\n", path);
     547             :                         exit(EXIT_FAILURE);
     548             :                         /* LCOV_EXCL_STOP */
     549             :                 }
     550             : 
     551        3042 :                 if (close(f) != 0) {
     552             :                         /* LCOV_EXCL_START */
     553             :                         log_fatal("Error closing file %s\n", path);
     554             :                         exit(EXIT_FAILURE);
     555             :                         /* LCOV_EXCL_STOP */
     556             :                 }
     557             :         }
     558        3042 : }
     559             : 
     560             : /**
     561             :  * Delete a file.
     562             :  * - The file must exist.
     563             :  */
     564        3254 : void cmd_delete(const char* path)
     565             : {
     566        3254 :         if (remove(path) != 0) {
     567             :                 /* LCOV_EXCL_START */
     568             :                 log_fatal("Error removing %s\n", path);
     569             :                 exit(EXIT_FAILURE);
     570             :                 /* LCOV_EXCL_STOP */
     571             :         }
     572        3254 : }
     573             : 
     574             : /**
     575             :  * Change a file. Or deleted/truncated/append/created.
     576             :  * - The file must exist.
     577             :  */
     578       13128 : void cmd_change(const char* path, int size)
     579             : {
     580             :         struct stat st;
     581             : 
     582       13128 :         if (!size)
     583          33 :                 return;
     584             : 
     585       13095 :         if (lstat(path, &st) != 0) {
     586             :                 /* LCOV_EXCL_START */
     587             :                 log_fatal("Error accessing %s\n", path);
     588             :                 exit(EXIT_FAILURE);
     589             :                 /* LCOV_EXCL_STOP */
     590             :         }
     591             : 
     592       13095 :         if (S_ISLNK(st.st_mode)) {
     593             :                 /* symlink */
     594         393 :                 if (rnd(2) == 0) {
     595             :                         /* delete */
     596         202 :                         if (remove(path) != 0) {
     597             :                                 /* LCOV_EXCL_START */
     598             :                                 log_fatal("Error removing %s\n", path);
     599             :                                 exit(EXIT_FAILURE);
     600             :                                 /* LCOV_EXCL_STOP */
     601             :                         }
     602             :                 } else {
     603             :                         /* recreate */
     604             :                         char linkto[PATH_MAX];
     605             : 
     606         191 :                         if (remove(path) != 0) {
     607             :                                 /* LCOV_EXCL_START */
     608             :                                 log_fatal("Error removing %s\n", path);
     609             :                                 exit(EXIT_FAILURE);
     610             :                                 /* LCOV_EXCL_STOP */
     611             :                         }
     612             : 
     613         191 :                         rnd_name(linkto);
     614             : 
     615         191 :                         cmd_generate_symlink(path, linkto);
     616             :                 }
     617       12702 :         } else if (S_ISREG(st.st_mode)) {
     618             :                 int r;
     619             : 
     620       12702 :                 r = rnd(4);
     621             : 
     622       12702 :                 if (r == 0) {
     623        3216 :                         cmd_write(path, size);
     624        9486 :                 } else if (r == 1) {
     625        3190 :                         cmd_append(path, size);
     626        6296 :                 } else if (r == 2) {
     627        3042 :                         cmd_truncate(path, size);
     628             :                 } else {
     629        3254 :                         cmd_delete(path);
     630             :                 }
     631             :         }
     632             : }
     633             : 
     634           1 : void help(void)
     635             : {
     636           1 :         printf("Test for " PACKAGE " v" VERSION " by Andrea Mazzoleni, " PACKAGE_URL "\n");
     637           1 :         printf("Usage:\n");
     638           1 :         printf("\tmktest generate SEED DISK_NUM FILE_NUM FILE_SIZE\n");
     639           1 :         printf("\tmktest damage SEED NUM SIZE FILE\n");
     640           1 :         printf("\tmktest write SEED NUM SIZE FILE\n");
     641           1 :         printf("\tmktest change SEED SIZE FILE\n");
     642           1 :         printf("\tmktest append SEED SIZE FILE\n");
     643           1 :         printf("\tmktest truncate SEED SIZE FILE\n");
     644           1 : }
     645             : 
     646          22 : int main(int argc, char* argv[])
     647             : {
     648             :         int i, j, b;
     649             : 
     650          22 :         lock_init();
     651             : 
     652          22 :         if (argc < 2) {
     653           1 :                 help();
     654           1 :                 exit(EXIT_SUCCESS);
     655             :         }
     656             : 
     657          21 :         if (strcmp(argv[1], "generate") == 0) {
     658             :                 int disk, file, size;
     659             : 
     660           4 :                 if (argc != 6) {
     661             :                         /* LCOV_EXCL_START */
     662             :                         help();
     663             :                         exit(EXIT_FAILURE);
     664             :                         /* LCOV_EXCL_STOP */
     665             :                 }
     666             : 
     667           4 :                 seed = atoi(argv[2]);
     668           4 :                 disk = atoi(argv[3]);
     669           4 :                 file = atoi(argv[4]);
     670           4 :                 size = atoi(argv[5]);
     671             : 
     672          28 :                 for (i = 0; i < disk; ++i) {
     673       24024 :                         for (j = 0; j < file; ++j) {
     674       24000 :                                 if (j == 0)
     675             :                                         /* create at least a big one */
     676          24 :                                         cmd_generate(i + 1, size);
     677       23976 :                                 else if (j == 1)
     678             :                                         /* create at least an empty one */
     679          24 :                                         cmd_generate(i + 1, 0);
     680             :                                 else
     681       23952 :                                         cmd_generate(i + 1, rnd(size));
     682             :                         }
     683             :                 }
     684          17 :         } else if (strcmp(argv[1], "write") == 0) {
     685             :                 int fail, size;
     686             : 
     687           7 :                 if (argc < 6) {
     688             :                         /* LCOV_EXCL_START */
     689             :                         help();
     690             :                         exit(EXIT_FAILURE);
     691             :                         /* LCOV_EXCL_STOP */
     692             :                 }
     693             : 
     694           7 :                 seed = atoi(argv[2]);
     695           7 :                 fail = atoi(argv[3]);
     696           7 :                 size = atoi(argv[4]);
     697           7 :                 b = 5;
     698             : 
     699             :                 /* sort the file names */
     700           7 :                 qsort(&argv[b], argc - b, sizeof(argv[b]), file_cmp);
     701             : 
     702         977 :                 for (i = b; i < argc; ++i)
     703        4019 :                         for (j = 0; j < fail; ++j)
     704        3049 :                                 cmd_write(argv[i], rndnz(size));
     705          10 :         } else if (strcmp(argv[1], "damage") == 0) {
     706             :                 int fail, size;
     707             : 
     708           3 :                 if (argc < 6) {
     709             :                         /* LCOV_EXCL_START */
     710             :                         help();
     711             :                         exit(EXIT_FAILURE);
     712             :                         /* LCOV_EXCL_STOP */
     713             :                 }
     714             : 
     715           3 :                 seed = atoi(argv[2]);
     716           3 :                 fail = atoi(argv[3]);
     717           3 :                 size = atoi(argv[4]);
     718           3 :                 b = 5;
     719             : 
     720             :                 /* sort the file names */
     721           3 :                 qsort(&argv[b], argc - b, sizeof(argv[b]), file_cmp);
     722             : 
     723        1885 :                 for (i = b; i < argc; ++i)
     724        3764 :                         for (j = 0; j < fail; ++j)
     725        1882 :                                 cmd_damage(argv[i], rndnz(size)); /* at least one byte */
     726           7 :         } else if (strcmp(argv[1], "append") == 0) {
     727             :                 int size;
     728             : 
     729           0 :                 if (argc < 5) {
     730             :                         /* LCOV_EXCL_START */
     731             :                         help();
     732             :                         exit(EXIT_FAILURE);
     733             :                         /* LCOV_EXCL_STOP */
     734             :                 }
     735             : 
     736           0 :                 seed = atoi(argv[2]);
     737           0 :                 size = atoi(argv[3]);
     738           0 :                 b = 4;
     739             : 
     740             :                 /* sort the file names */
     741           0 :                 qsort(&argv[b], argc - b, sizeof(argv[b]), file_cmp);
     742             : 
     743           0 :                 for (i = b; i < argc; ++i)
     744           0 :                         cmd_append(argv[i], rndnz(size)); /* at least one byte */
     745           7 :         } else if (strcmp(argv[1], "truncate") == 0) {
     746             :                 int size;
     747             : 
     748           0 :                 if (argc < 5) {
     749             :                         /* LCOV_EXCL_START */
     750             :                         help();
     751             :                         exit(EXIT_FAILURE);
     752             :                         /* LCOV_EXCL_STOP */
     753             :                 }
     754             : 
     755           0 :                 seed = atoi(argv[2]);
     756           0 :                 size = atoi(argv[3]);
     757           0 :                 b = 4;
     758             : 
     759             :                 /* sort the file names */
     760           0 :                 qsort(&argv[b], argc - b, sizeof(argv[b]), file_cmp);
     761             : 
     762           0 :                 for (i = b; i < argc; ++i)
     763           0 :                         cmd_truncate(argv[i], rnd(size));
     764           7 :         } else if (strcmp(argv[1], "change") == 0) {
     765             :                 int size;
     766             : 
     767           7 :                 if (argc < 5) {
     768             :                         /* LCOV_EXCL_START */
     769             :                         help();
     770             :                         exit(EXIT_FAILURE);
     771             :                         /* LCOV_EXCL_STOP */
     772             :                 }
     773             : 
     774           7 :                 seed = atoi(argv[2]);
     775           7 :                 size = atoi(argv[3]);
     776           7 :                 b = 4;
     777             : 
     778             :                 /* sort the file names */
     779           7 :                 qsort(&argv[b], argc - b, sizeof(argv[b]), file_cmp);
     780             : 
     781       13135 :                 for (i = b; i < argc; ++i)
     782       13128 :                         cmd_change(argv[i], rnd(size));
     783             :         } else {
     784             :                 /* LCOV_EXCL_START */
     785             :                 help();
     786             :                 exit(EXIT_FAILURE);
     787             :                 /* LCOV_EXCL_STOP */
     788             :         }
     789             : 
     790          21 :         lock_done();
     791             : 
     792          21 :         return 0;
     793             : }
     794             : 

Generated by: LCOV version 1.13