"Fossies" - the Fresh Open Source Software Archive

Member "inotify-tools-3.20.11.0/libinotifytools/src/test.c" (13 Nov 2020, 12930 Bytes) of package /linux/privat/inotify-tools-3.20.11.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes report for "test.c": 3.20.2.2_vs_3.20.11.0.

    1 #include "inotifytools/inotify.h"
    2 #include "inotifytools/inotifytools.h"
    3 
    4 #include "../../config.h"
    5 
    6 #include <unistd.h>
    7 
    8 #include <errno.h>
    9 #include <fcntl.h>
   10 #include <stdint.h>
   11 #include <stdio.h>
   12 #include <stdlib.h>
   13 #include <string.h>
   14 #include <sys/stat.h>
   15 #include <sys/types.h>
   16 #include <time.h>
   17 
   18 #ifdef HAVE_MCHECK_H
   19 #include <mcheck.h>
   20 #endif
   21 
   22 #define verify(A)                                                              \
   23     if (!_verify((int)(A), #A, __FILE__, __LINE__, __PRETTY_FUNCTION__))       \
   24         return;
   25 #define verify2(A, B)                                                          \
   26     if (!_verify((int)(A), B, __FILE__, __LINE__, __PRETTY_FUNCTION__))        \
   27         return;
   28 #define compare(A, B)                                                          \
   29     if (!_compare((uintptr_t)(A), (int)(B), #A, #B, __FILE__, __LINE__,        \
   30                   __PRETTY_FUNCTION__))                                        \
   31         return;
   32 
   33 #define succeed()                                                              \
   34     do {                                                                       \
   35         ++tests_succeeded;                                                     \
   36         /*fprintf(stderr, "%s:%d Test '%s' passed", file, line, func);*/       \
   37         /*fprintf(stderr, "\n");*/                                             \
   38     } while (0)
   39 
   40 #define fail(...)                                                              \
   41     do {                                                                       \
   42         ++tests_failed;                                                        \
   43         fprintf(stderr, "%s:%d Test '%s' failed: ", file, line, func);         \
   44         fprintf(stderr, __VA_ARGS__);                                          \
   45         fprintf(stderr, "\n");                                                 \
   46         if (inotifytools_error() != 0) {                                       \
   47             fprintf(stderr, "inotifytools_error() returns %d (%s)\n",          \
   48                     inotifytools_error(), strerror(inotifytools_error()));     \
   49         }                                                                      \
   50     } while (0)
   51 
   52 #define TEST_DIR "/tmp/inotifytools_test"
   53 
   54 #define INFO(...)                                                              \
   55     do {                                                                       \
   56         printf("%s: ", __PRETTY_FUNCTION__);                                   \
   57         printf(__VA_ARGS__);                                                   \
   58     } while (0)
   59 
   60 #define ENTER INFO("test begin\n");
   61 #define EXIT INFO("test end\n");
   62 
   63 static int tests_failed;
   64 static int tests_succeeded;
   65 
   66 int _verify(int cond, char const *teststr, char const *file, int line,
   67             char const *func) {
   68     if (cond) {
   69         succeed();
   70         return cond;
   71     }
   72 
   73     fail("Verification failed (%s)", teststr);
   74     return cond;
   75 }
   76 
   77 int _compare(int value, int expval, char const *act_str, char const *exp_str,
   78              char const *file, int line, char const *func) {
   79     if (value == expval) {
   80         succeed();
   81         return 1;
   82     }
   83 
   84     fail("Actual (%s): %d, Expected (%s): %d", act_str, value, exp_str, expval);
   85     return 0;
   86 }
   87 
   88 void event_to_str() {
   89     ENTER
   90     verify2(
   91         !strcmp(inotifytools_event_to_str(IN_OPEN | IN_MODIFY | IN_ACCESS),
   92                 "OPEN,MODIFY,ACCESS") ||
   93             !strcmp(inotifytools_event_to_str(IN_OPEN | IN_MODIFY | IN_ACCESS),
   94                     "OPEN,ACCESS,MODIFY") ||
   95             !strcmp(inotifytools_event_to_str(IN_OPEN | IN_MODIFY | IN_ACCESS),
   96                     "ACCESS,OPEN,MODIFY") ||
   97             !strcmp(inotifytools_event_to_str(IN_OPEN | IN_MODIFY | IN_ACCESS),
   98                     "MODIFY,OPEN,ACCESS") ||
   99             !strcmp(inotifytools_event_to_str(IN_OPEN | IN_MODIFY | IN_ACCESS),
  100                     "ACCESS,MODIFY,OPEN") ||
  101             !strcmp(inotifytools_event_to_str(IN_OPEN | IN_MODIFY | IN_ACCESS),
  102                     "MODIFY,ACCESS,OPEN"),
  103         inotifytools_event_to_str(IN_OPEN | IN_MODIFY | IN_ACCESS));
  104     EXIT
  105 }
  106 
  107 void event_to_str_sep() {
  108     ENTER
  109     verify2(
  110         !strcmp(
  111             inotifytools_event_to_str_sep(IN_OPEN | IN_MODIFY | IN_ACCESS, ':'),
  112             "OPEN:MODIFY:ACCESS") ||
  113             !strcmp(inotifytools_event_to_str_sep(
  114                         IN_OPEN | IN_MODIFY | IN_ACCESS, ':'),
  115                     "OPEN:ACCESS:MODIFY") ||
  116             !strcmp(inotifytools_event_to_str_sep(
  117                         IN_OPEN | IN_MODIFY | IN_ACCESS, ':'),
  118                     "ACCESS:OPEN:MODIFY") ||
  119             !strcmp(inotifytools_event_to_str_sep(
  120                         IN_OPEN | IN_MODIFY | IN_ACCESS, ':'),
  121                     "MODIFY:OPEN:ACCESS") ||
  122             !strcmp(inotifytools_event_to_str_sep(
  123                         IN_OPEN | IN_MODIFY | IN_ACCESS, ':'),
  124                     "ACCESS:MODIFY:OPEN") ||
  125             !strcmp(inotifytools_event_to_str_sep(
  126                         IN_OPEN | IN_MODIFY | IN_ACCESS, ':'),
  127                     "MODIFY:ACCESS:OPEN"),
  128         inotifytools_event_to_str_sep(IN_OPEN | IN_MODIFY | IN_ACCESS, ':'));
  129     EXIT
  130 }
  131 
  132 void str_to_event() {
  133     ENTER
  134     compare(inotifytools_str_to_event("open,modify,access"),
  135             IN_OPEN | IN_MODIFY | IN_ACCESS);
  136     compare(inotifytools_str_to_event(",open,modify,access"), 0);
  137     compare(inotifytools_str_to_event("open,modify,access,"), 0);
  138     compare(inotifytools_str_to_event("open,modify,,access,close"), 0);
  139     compare(inotifytools_str_to_event("open,mod,access,close"), -1);
  140     compare(inotifytools_str_to_event("mod"), -1);
  141     compare(inotifytools_str_to_event(","), 0);
  142     compare(inotifytools_str_to_event(",,"), 0);
  143     compare(inotifytools_str_to_event("open"), IN_OPEN);
  144     compare(inotifytools_str_to_event("close"), IN_CLOSE);
  145     compare(inotifytools_str_to_event(",close"), 0);
  146     compare(inotifytools_str_to_event(",,close"), 0);
  147     compare(inotifytools_str_to_event("close,"), 0);
  148     compare(inotifytools_str_to_event("close,,"), 0);
  149     EXIT
  150 }
  151 
  152 void str_to_event_sep() {
  153     ENTER
  154     compare(inotifytools_str_to_event_sep("open:modify:access", ':'),
  155             IN_OPEN | IN_MODIFY | IN_ACCESS);
  156     compare(inotifytools_str_to_event_sep("open,modify,access", ','),
  157             IN_OPEN | IN_MODIFY | IN_ACCESS);
  158     compare(inotifytools_str_to_event_sep(":open:modify:access", ':'), 0);
  159     compare(inotifytools_str_to_event_sep("open:modify:access:", ':'), 0);
  160     compare(inotifytools_str_to_event_sep("open:modify::access:close", ':'), 0);
  161     compare(inotifytools_str_to_event_sep("open:mod:access:close", ':'), -1);
  162     compare(inotifytools_str_to_event_sep("mod", ':'), -1);
  163     compare(inotifytools_str_to_event_sep(":", ':'), 0);
  164     compare(inotifytools_str_to_event_sep("::", ':'), 0);
  165     compare(inotifytools_str_to_event_sep("open", ':'), IN_OPEN);
  166     compare(inotifytools_str_to_event_sep("close", ':'), IN_CLOSE);
  167     compare(inotifytools_str_to_event_sep(":close", ':'), 0);
  168     compare(inotifytools_str_to_event_sep("::close", ':'), 0);
  169     compare(inotifytools_str_to_event_sep("close:", ':'), 0);
  170     compare(inotifytools_str_to_event_sep("close::", ':'), 0);
  171     compare(inotifytools_str_to_event_sep("open:modify:access", ','), -1);
  172     compare(inotifytools_str_to_event_sep("open:modify:access", 'o'), -1);
  173     EXIT
  174 }
  175 
  176 void basic_watch_info() {
  177     ENTER
  178     verify(inotifytools_initialize());
  179     verify(inotifytools_watch_file("/", IN_CLOSE));
  180     compare(inotifytools_wd_from_filename("/"), 1);
  181     compare(inotifytools_wd_from_filename("foobar"), -1);
  182     verify(!strcmp(inotifytools_filename_from_wd(1), "/"));
  183     verify(inotifytools_remove_watch_by_filename("/"));
  184     compare(inotifytools_wd_from_filename("/"), -1);
  185     compare(inotifytools_filename_from_wd(1), 0);
  186     verify(inotifytools_watch_file("/", IN_CLOSE));
  187     compare(inotifytools_wd_from_filename("/"), 2);
  188     compare(inotifytools_wd_from_filename("foobar"), -1);
  189     verify(!strcmp(inotifytools_filename_from_wd(2), "/"));
  190     verify(inotifytools_remove_watch_by_wd(2));
  191     compare(inotifytools_wd_from_filename("/"), -1);
  192     compare(inotifytools_filename_from_wd(2), 0);
  193     EXIT
  194 }
  195 
  196 void tst_inotifytools_snprintf() {
  197     ENTER
  198     verify((0 == mkdir(TEST_DIR, 0700)) || (EEXIST == errno));
  199     verify(inotifytools_initialize());
  200     verify(inotifytools_watch_file(TEST_DIR, IN_CLOSE));
  201 
  202 #define RESET                                                                  \
  203     do {                                                                       \
  204         memset(out.buf, 0, MAX_STRLEN);                                            \
  205         memset(test_event, 0, sizeof(struct inotify_event));                   \
  206         test_event->wd = inotifytools_wd_from_filename(TEST_DIR "/");          \
  207         verify(test_event->wd >= 0);                                           \
  208         inotifytools_set_printf_timefmt(0);                                    \
  209     } while (0)
  210 
  211     struct nstring out;
  212     char event_buf[4096];
  213     struct inotify_event *test_event = (struct inotify_event *)event_buf;
  214 
  215     RESET;
  216     test_event->mask = IN_ACCESS;
  217     inotifytools_snprintf(&out, MAX_STRLEN, test_event, "Event %e %.e on %w %f %T");
  218     verify2(!strcmp(out.buf, "Event ACCESS ACCESS on " TEST_DIR "/  "), out.buf);
  219 
  220     RESET;
  221     test_event->mask = IN_ACCESS | IN_DELETE;
  222     inotifytools_snprintf(&out, MAX_STRLEN, test_event, "Event %e %.e on %w %f %T");
  223     verify2(
  224         !strcmp(out.buf, "Event ACCESS,DELETE ACCESS.DELETE on " TEST_DIR "/  ") ||
  225             !strcmp(out.buf,
  226                     "Event DELETE,ACCESS DELETE.ACCESS on " TEST_DIR "/  "),
  227         out.buf);
  228 
  229     RESET;
  230     test_event->mask = IN_MODIFY;
  231     inotifytools_snprintf(&out, 10, test_event, "Event %e %.e on %w %f %T");
  232     verify2(!strcmp(out.buf, "Event MODI"), out.buf);
  233 
  234     RESET;
  235     test_event->mask = IN_ACCESS;
  236     strcpy(test_event->name, "my_great_file");
  237     test_event->len = strlen(test_event->name) + 1;
  238     inotifytools_snprintf(&out, MAX_STRLEN, test_event, "Event %e %.e on %w %f %T");
  239     verify2(!strcmp(out.buf, "Event ACCESS ACCESS on " TEST_DIR "/ my_great_file "),
  240             out.buf);
  241 
  242     RESET;
  243     test_event->mask = IN_ACCESS;
  244     inotifytools_set_printf_timefmt("%D%% %H:%M");
  245     {
  246         char expected[MAX_STRLEN];
  247         char timestr[512];
  248         time_t now = time(0);
  249         strftime(timestr, 512, "%D%% %H:%M", localtime(&now));
  250         snprintf(expected, MAX_STRLEN, "Event ACCESS ACCESS on %s/  %s", TEST_DIR,
  251                  timestr);
  252         inotifytools_snprintf(&out, MAX_STRLEN, test_event,
  253                               "Event %e %.e on %w %f %T");
  254         verify2(!strcmp(out.buf, expected), out.buf);
  255     }
  256 
  257     EXIT
  258 }
  259 
  260 void watch_limit() {
  261     ENTER
  262     verify((0 == mkdir(TEST_DIR, 0700)) || (EEXIST == errno));
  263 
  264     INFO("Warning, this test may take a while\n");
  265 #define INNER_LIMIT 16000
  266 #define OUTER_LIMIT 5
  267 
  268     verify(inotifytools_initialize());
  269     inotifytools_initialize_stats();
  270 
  271     for (int j = 0; j < OUTER_LIMIT; ++j) {
  272         char fn[1024];
  273         int max = 0;
  274         for (int i = 0; i < INNER_LIMIT; ++i) {
  275             snprintf(fn, 1023, "%s/%d", TEST_DIR, i);
  276             int fd = creat(fn, 0700);
  277             verify(-1 != fd);
  278             verify(0 == close(fd));
  279             int ret = inotifytools_watch_file(fn, IN_ALL_EVENTS);
  280             verify(ret || inotifytools_error() == ENOSPC);
  281             if (ret) {
  282                 max = i + 1;
  283                 int wd = inotifytools_wd_from_filename(fn);
  284                 verify(wd > 0);
  285                 verify(!strcmp(fn, inotifytools_filename_from_wd(wd)));
  286             }
  287         }
  288 
  289         compare(inotifytools_get_num_watches(), max);
  290 
  291         for (int i = 0; i < max; ++i) {
  292             snprintf(fn, 1023, "%s/%d", TEST_DIR, i);
  293             verify(inotifytools_remove_watch_by_filename(fn));
  294         }
  295     }
  296     EXIT
  297 }
  298 
  299 void cleanup() {
  300     compare(system("rm -rf " TEST_DIR), 0);
  301     inotifytools_cleanup();
  302 }
  303 
  304 int main() {
  305     tests_failed = 0;
  306     tests_succeeded = 0;
  307 
  308 #ifdef HAVE_MCHECK_H
  309     char *mtrace_name = getenv("MALLOC_TRACE");
  310     if (mtrace_name) {
  311         printf("malloc trace might be written to %s\n", mtrace_name);
  312     } else {
  313         printf("If you want to do a malloc trace, set MALLOC_TRACE to "
  314                "a path for logging.\n");
  315     }
  316     mtrace();
  317 #endif
  318 
  319     cleanup();
  320 
  321     event_to_str();
  322     cleanup();
  323     event_to_str_sep();
  324     cleanup();
  325 
  326     str_to_event();
  327     cleanup();
  328     str_to_event_sep();
  329     cleanup();
  330 
  331     basic_watch_info();
  332     cleanup();
  333 
  334     watch_limit();
  335     cleanup();
  336 
  337     tst_inotifytools_snprintf();
  338     cleanup();
  339 
  340     printf("Out of %d tests, %d succeeded and %d failed.\n",
  341            tests_failed + tests_succeeded, tests_succeeded, tests_failed);
  342 
  343     if (tests_failed)
  344         return -tests_failed;
  345 }