check: allow '-e testid' to exclude a single test
[xfstests-dev.git] / dmapi / src / suite2 / src / test_eventlist.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2000-2001 Silicon Graphics, Inc.
4  * All Rights Reserved.
5  */
6
7 #include <lib/hsm.h>
8 #include <lib/errtest.h>
9
10 #include <getopt.h>
11 #include <string.h>
12
13
14 /*---------------------------------------------------------------------------
15
16 Test program used to test the DMAPI function dm_set_eventlist().  The
17 command line is:
18
19         test_eventlist [-v] [-s sid] [-t token] directory
20
21 where:
22 ls_path
23         is the path to a specific copy of ls, important only for its size
24 directory
25         is the pathname to a DMAPI filesystem.
26 sid
27         is the dm_sessid_t value to use.
28 token
29         is the dm_token_t value to use (DM_NO_TOKEN is the default).
30 ----------------------------------------------------------------------------*/
31
32 #ifndef linux
33 extern  char    *sys_errlist[];
34 #endif
35 extern  int     optind;
36 extern  char    *optarg;
37
38
39 char    *Progname;
40
41 int check_one_event (dm_sessid_t, void*, size_t, dm_token_t, 
42                      dm_eventtype_t, int);
43
44 static void
45 usage(void)
46 {
47         fprintf(stderr, "usage:\t%s [-v] [-s sid] [-t token]"
48                 "ls_path directory \n", Progname);
49         /* fprintf(stderr, "possible events are:\n");
50            for (i = 0; i < ev_namecnt; i++) {
51                 fprintf(stderr, "%s (%d)\n", ev_names[i].name,
52                         ev_names[i].value);
53         }
54         */
55         exit(1);
56 }
57
58
59 int
60 main(
61         int     argc, 
62         char    **argv)
63 {
64         dm_sessid_t     sid = DM_NO_SESSION;
65         dm_token_t      token = DM_NO_TOKEN;
66         char            object[128];
67         void            *hanp;
68         size_t          hlen;
69         int             Vflag = 0;
70         char            *name;
71         int             opt;
72         int             error;
73         void           *fshanp;
74         size_t          fshlen;
75         int             i;
76         char            command[128];
77         char           *ls_path;
78         char           *dir_name;
79         dm_token_t      test_token = DM_NO_TOKEN;
80         dm_eventset_t   eventset;
81         void           *test_vp;
82         u_int           nelemp;
83
84         Progname = strrchr(argv[0], '/');
85         if (Progname) {
86                 Progname++;
87         } else {
88                 Progname = argv[0];
89         }
90
91         /* Crack and validate the command line options. */
92
93         while ((opt = getopt(argc, argv, "s:t:uv")) != EOF) {
94                 switch (opt) {
95                 case 's':
96                         sid = atol(optarg);
97                         break;
98                 case 't':
99                         token = atol(optarg);
100                         break;
101                 case 'u':
102                         Vflag=2;
103                         break;
104                 case 'v':
105                         if (Vflag==0) Vflag=1;
106                         break;
107                 case '?':
108                         usage();
109                 }
110         }
111
112         if (optind + 2 != argc)
113                 usage();
114         ls_path = argv[optind];
115         dir_name = argv[optind+1];
116
117         if (dm_init_service(&name) == -1)  {
118                 fprintf(stderr, "Can't initialize the DMAPI\n");
119                 exit(1);
120         }
121
122         if (sid == DM_NO_SESSION)
123                 find_test_session(&sid);
124         
125         /* Get the directory handle */
126         if (dm_path_to_handle(dir_name, &hanp, &hlen)) {
127                 fprintf(stderr, "can't get handle for %s\n", dir_name);
128                 exit(1);
129         }
130
131         /***********************************************\
132         |* Test to run on a FILE...                    *|
133         \***********************************************/
134         
135         printf("File test beginning...\n");
136         sprintf(object, "%s/VeryLongUnlikelyFilename.DMAPIFOO", dir_name);
137         sprintf(command, "cp %s %s \n", ls_path, object); 
138         system(command);
139
140         if (dm_path_to_handle(object, &hanp, &hlen)) {
141                 fprintf(stderr, "can't get handle for %s\n; aborting test",
142                         object);
143         }
144         else {
145           for (i = 0; i < ev_namecnt; i++) {
146             error = check_one_event(sid, hanp, hlen, token,
147                                     ev_names[i].value, Vflag);  
148             switch (ev_names[i].value){
149             case DM_EVENT_ATTRIBUTE: case DM_EVENT_DESTROY:
150               if (error) {
151                 fprintf(stderr, "ERROR: %s failed on a file!\n",
152                         ev_names[i].name);  
153               }
154               break;
155             default: 
156               if (!error) {
157                 fprintf(stderr, "ERROR: %s succeeded on a file!\n",
158                         ev_names[i].name);  
159               }
160             }
161           }
162           /*------------------------*\
163           |*  ## Errno subtests ##  *|
164           \*------------------------*/
165           printf("\t(errno subtests beginning...)\n");
166           DMEV_ZERO(eventset);
167           DMEV_SET(DM_EVENT_ATTRIBUTE, eventset);
168           /*---------------------------------------------------------*/
169           EXCLTEST("set", hanp, hlen, test_token, 
170                    dm_set_eventlist(sid, hanp, hlen, test_token, 
171                                     &eventset, DM_EVENT_MAX))
172           /*---------------------------------------------------------*/
173           if ((test_vp = handle_clone(hanp, hlen)) == NULL) {
174             fprintf(stderr, 
175                     "Cannot create a test handle (%s); skipping EBADF test\n",
176                     ERR_NAME);
177           }
178           else {
179             /* Alter the handle copy to make it (presumably) invalid */
180             ((char *) test_vp)[hlen/2]++;
181             ERRTEST(EBADF,
182                     "set",
183                     dm_set_eventlist(sid, test_vp, hlen, token,
184                                      &eventset, DM_EVENT_MAX))
185             dm_handle_free(test_vp, hlen);
186           }
187           /*---------------------------------------------------------*/
188 #ifdef  VERITAS_21
189         /* Veritas gets a segmentation fault if hanp is NULL or if the
190            &eventset is out of range.
191         */
192         fprintf(stderr, "\tERROR testing for EFAULT in set (bad hanp): "
193                 "Veritas gets a segmentation fault.\n");
194         fprintf(stderr, "\tERROR testing for EFAULT in set (bad eventset): "
195                 "Veritas gets a segmentation fault.\n");
196 #else
197           ERRTEST(EFAULT, 
198                   "set",
199                   dm_set_eventlist(sid, NULL, hlen, token, 
200                                 &eventset, DM_EVENT_MAX))
201           ERRTEST(EFAULT, 
202                   "set",
203                   dm_set_eventlist(sid, hanp, hlen, token, 
204                                 (dm_eventset_t*)(-1000), DM_EVENT_MAX))
205 #endif
206           /*---------------------------------------------------------*/
207           ERRTEST(EINVAL,
208                   "set (bad session)",
209                   dm_set_eventlist(-100, hanp, hlen, token,
210                                    &eventset, DM_EVENT_MAX))
211           /*---------------------------------------------------------*/
212           ERRTEST(EINVAL, 
213                   "set (bad token)",
214                   dm_set_eventlist(sid, hanp, hlen, 0, 
215                                 &eventset, DM_EVENT_MAX))
216           /*---------------------------------------------------------*/
217 #if 0
218           PROBLEM: too-small buffer does not produce E2BIG 
219           { 
220             dm_eventset_t  *small_evsp = malloc(0);
221             if (dm_handle_to_fshandle(hanp, hlen, &fshanp, &fshlen)) {
222               fprintf(stderr, 
223                       "can't get filesystem handle from %s; aborting test\n",
224                       dir_name);
225             } 
226             else {
227               check_one_event(sid, fshanp, fshlen, token, 
228                               DM_EVENT_CREATE, Vflag);
229               ERRTEST(E2BIG,
230                       "(broken) get",
231                       dm_get_eventlist(sid, fshanp, fshlen, token, 
232                                        DM_EVENT_MAX, small_evsp, &nelemp))
233               check_one_event(sid, fshanp, fshlen, token, 
234                               DM_EVENT_INVALID, Vflag);
235             }
236           }
237 #endif
238           /*---------------------------------------------------------*/
239           SHAREDTEST("get", hanp, hlen, test_token, 
240                      dm_get_eventlist(sid, hanp, hlen, test_token,
241                                       DM_EVENT_MAX, &eventset, &nelemp))
242           /*---------------------------------------------------------*/
243           ERRTEST(EBADF,
244                   "get",
245                   dm_get_eventlist(sid, test_vp, hlen, token, DM_EVENT_MAX,
246                                    &eventset, &nelemp))
247           /*---------------------------------------------------------*/
248 #ifdef  VERITAS_21
249         /* Veritas gets a segmentation fault if hanp is NULL. */
250
251         fprintf(stderr, "\tERROR testing for EFAULT in get (bad hanp): "
252                 "Veritas gets a segmentation fault.\n");
253 #else
254           ERRTEST(EFAULT, 
255                   "get",
256                   dm_get_eventlist(sid, NULL, hlen, token, DM_EVENT_MAX,
257                                    &eventset, &nelemp ))
258 #endif
259           /*---------------------------------------------------------*/
260           ERRTEST(EINVAL,
261                   "get (bad session)",
262                   dm_get_eventlist(-100, hanp, hlen, token, DM_EVENT_MAX,
263                                    &eventset, &nelemp))
264           /*---------------------------------------------------------*/
265           ERRTEST(EINVAL, 
266                   "get (bad token)",
267                   dm_get_eventlist(sid, hanp, hlen, 0, DM_EVENT_MAX,
268                                 &eventset, &nelemp))
269           /*---------------------------------------------------------*/
270           printf("\t(errno subtests complete)\n");
271           /*---------------------*\
272           |* End of errno tests  *|
273           \*---------------------*/
274
275         /* Finally, use DM_EVENT_INVALID to delete events... */
276         check_one_event(sid, hanp, hlen, token, DM_EVENT_INVALID, Vflag);
277         }
278         sprintf(command, "rm %s \n", object); 
279         system(command);
280         printf("\tFile test complete.\n");
281         if (Vflag) printf("\n");
282         
283         /***********************************************\
284         |* Test to run on a DIRECTORY...               *|
285         \***********************************************/
286         
287         printf("Directory test beginning...\n");
288         sprintf(object, "%s/VeryLongUnlikelyDirectoryName.DMAPIFOO",
289                 dir_name);
290         sprintf(command, "mkdir %s \n", object); 
291         system(command);        
292         
293         if (opaque_to_handle(object, &hanp, &hlen)) {
294                 fprintf(stderr, "can't get handle for %s\n; aborting test",
295                         object);
296         }
297         else {
298           for (i = 0; i < ev_namecnt; i++) {
299             error = check_one_event(sid, hanp, hlen, token,
300                                     ev_names[i].value, Vflag);
301             switch (ev_names[i].value){
302             case DM_EVENT_CREATE:    case DM_EVENT_POSTCREATE:
303             case DM_EVENT_REMOVE:    case DM_EVENT_POSTREMOVE:
304             case DM_EVENT_RENAME:    case DM_EVENT_POSTRENAME:
305             case DM_EVENT_LINK:      case DM_EVENT_POSTLINK:
306             case DM_EVENT_SYMLINK:   case DM_EVENT_POSTSYMLINK:
307             case DM_EVENT_ATTRIBUTE: case DM_EVENT_DESTROY:
308               if (error) {
309                 fprintf(stderr, "ERROR: %s failed on a directory!\n",
310                         ev_names[i].name);  
311               }
312               break;
313             default: 
314               if (!error) {
315                 fprintf(stderr, "ERROR: %s succeeded on a directory!\n",
316                         ev_names[i].name);  
317               }
318             }
319           }
320         /* Use DM_EVENT_INVALID to delete events... */
321         check_one_event(sid, hanp, hlen, token, DM_EVENT_INVALID, Vflag);
322         }
323         sprintf(object, "%s/VeryLongUnlikelyDirectoryName.DMAPIFOO", dir_name);
324         sprintf(command, "rmdir %s\n", object); 
325         system(command);
326         printf("\tDirectory test complete.\n");
327         if (Vflag) printf("\n");
328
329         /***********************************************\
330         |* Test to run on a FILESYSTEM...              *|
331         \***********************************************/
332         
333         printf("Filesystem test beginning...\n");
334         
335         if (dm_handle_to_fshandle(hanp, hlen, &fshanp, &fshlen)) {
336           fprintf(stderr, 
337                   "can't get filesystem handle from %s; aborting test\n",
338                   dir_name);
339         }
340         else {
341           for (i = 0; i < ev_namecnt; i++) {
342             error = check_one_event(sid, fshanp, fshlen, token, 
343                                     ev_names[i].value, Vflag);
344             switch (ev_names[i].value){
345             case DM_EVENT_PREUNMOUNT: case DM_EVENT_UNMOUNT:
346             case DM_EVENT_NOSPACE:    case DM_EVENT_DEBUT:
347             case DM_EVENT_CREATE:     case DM_EVENT_POSTCREATE:
348             case DM_EVENT_REMOVE:     case DM_EVENT_POSTREMOVE:
349             case DM_EVENT_RENAME:     case DM_EVENT_POSTRENAME:
350             case DM_EVENT_LINK:       case DM_EVENT_POSTLINK:
351             case DM_EVENT_SYMLINK:    case DM_EVENT_POSTSYMLINK:
352             case DM_EVENT_ATTRIBUTE:  case DM_EVENT_DESTROY:
353               if (error) {
354                 fprintf(stderr, "ERROR: %s failed on a filesystem!\n",
355                         ev_names[i].name);  
356               }
357               break;
358             default: 
359               if (!error) {
360                 fprintf(stderr, "ERROR: %s succeeded on a filesystem!\n",
361                         ev_names[i].name);  
362               }
363             }
364           }
365         /* Use DM_EVENT_INVALID to delete events... */
366         check_one_event(sid, fshanp, fshlen, token, DM_EVENT_INVALID, Vflag);
367         }
368         printf("\tFilesystem test complete.\n");
369
370         /***********************************************\
371         |* End of tests!                               *|
372         \***********************************************/
373
374         dm_handle_free(fshanp, fshlen);
375         dm_handle_free(hanp, hlen);
376         exit(0);
377 }
378
379 /*-------------------------------------------------------------------
380   check_one_event: 
381    
382   Using dm_set_eventlist, set a single event on the object
383   indicated by the handle.
384
385   Using dm_get_eventlist, check to see that the single event
386   was set correctly.
387   -------------------------------------------------------------------*/
388
389 int 
390 check_one_event (
391                  dm_sessid_t       sid,
392                  void              *hanp,
393                  size_t            hlen,
394                  dm_token_t        token,
395                  dm_eventtype_t    event,
396                  int               Vflag )
397 {
398         dm_eventset_t   eventset;
399         dm_eventset_t   check_eventset;
400         u_int           nelemp;
401         int             set_count = 0;
402         int             i;
403
404         DMEV_ZERO(eventset);
405         DMEV_ZERO(check_eventset);
406                 
407         if (event != DM_EVENT_INVALID) {
408           DMEV_SET(event, eventset);
409         }
410
411         if (dm_set_eventlist(sid, hanp, hlen, token, 
412                                       &eventset, DM_EVENT_MAX)) {
413                 if (Vflag){
414                   fprintf(stdout, " note: %s could not be set (%s)\n",
415                           ev_value_to_name(event), errno_names[errno]);
416                 }
417                 return (-1);
418         }
419
420         if (dm_get_eventlist(sid, hanp, hlen, token,
421                              DM_EVENT_MAX, &check_eventset, &nelemp)) {
422                 if (Vflag){
423                 fprintf(stdout, "dm_get_eventlist failed, %s\n",
424                         errno_names[errno]);
425                 }
426                 return (-2);
427         }
428         
429         /*  For each element, see that get_eventlist agrees 
430          *  with set_eventlist; if not, make noise.
431          */  
432         for (i = 0; i < ev_namecnt; i++) {
433           int set = DMEV_ISSET(ev_names[i].value, eventset);
434           int found = DMEV_ISSET(ev_names[i].value, check_eventset);
435           if (set && !found) {
436             fprintf(stderr, "ERROR: event %s was set but not found.\n",
437                     ev_names[i].name);
438             return (-3);
439           } 
440           else if (!set && found) {
441             fprintf(stderr, "ERROR: Found unexpected event %s \n",
442                     ev_names[i].name);
443             return (-4);
444           }
445           else if ((Vflag == 2) && !set && !found) {
446             fprintf(stderr, "clear: %s\n",
447                    ev_names[i].name);
448           }
449           else if (Vflag && set && found) {
450             fprintf(stderr, "  SET: %s\n", ev_names[i].name);
451             set_count++;
452           }
453         }
454         if (Vflag && set_count == 0) {
455           fprintf(stderr, "\t(All events cleared)\n");
456         }
457         return 0;
458 }