Update copyright annotations and license boilerplates to correspond with SGI Legals...
[xfstests-dev.git] / dmapi / src / suite2 / src / test_dmattr.c
1 /*
2  * Copyright (c) 2000-2001 Silicon Graphics, Inc.
3  * All Rights Reserved.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it would 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, write the Free Software Foundation,
16  * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17  */
18
19 #include <sys/types.h>
20 #include <sys/stat.h>
21
22 #include <limits.h>
23
24 #include <lib/hsm.h>
25 #include <lib/errtest.h>
26
27 #include <getopt.h>
28 #include <string.h>
29
30
31 /*---------------------------------------------------------------------------
32 Automated test of the DMAPI functions: 
33      dm_set_dmattr()
34      dm_get_dmattr()
35      dm_remove_dmattr()
36
37 The command line is:
38
39         test_dmattr [-v] [-n num] [-l length] [-s sid] directory 
40
41 where 
42    ls_path 
43      is the path to a specific copy of ls, important only for its size
44    directory 
45      is the pathname to a DMAPI filesystem
46    num
47      is the number of files to create for the test.
48    length
49      is the length of the attribute value for the test.
50    sid 
51      is the session ID whose attributes you are interested in.
52
53 ----------------------------------------------------------------------------*/
54
55 #define VALUE_LENGTH 22
56 #define NUM_ITERATIONS 50
57 #ifndef linux
58 extern  char    *sys_errlist[];
59 #endif
60 extern  int     optind;
61 extern  char    *optarg;
62
63
64 char    *Progname;
65
66 static void
67 usage(void)
68 {
69         fprintf(stderr, "usage:\t%s [-v] [-n number] [-l length] "
70                 "[-s sid] ls_path pathname\n", Progname);
71         exit(1);
72 }
73
74
75 int
76 main(
77         int     argc, 
78         char    **argv)
79 {
80         dm_sessid_t     sid = DM_NO_SESSION;
81         char            *dir_name;
82         char            *ls_path;
83         dm_attrname_t   *attrnamep;
84         size_t          buflen=VALUE_LENGTH;
85         char            *bufp;
86         int             setdtime = 0;
87         size_t          rlenp;
88         void            *hanp;
89         size_t          hlen;
90         char            *name;
91         int             opt;
92         int             i=0;
93         int             j=0;
94         int             Vflag=0;
95         int             num_iter = NUM_ITERATIONS;
96         char            test_file[128];
97         char            command[128];
98         char            **test_array;
99         dm_size_t       config_retval;
100         dm_token_t      test_token;
101         struct stat    *statbuf;
102         struct stat    *checkbuf;
103
104         if (Progname = strrchr(argv[0], '/')) {
105                 Progname++;
106         } else {
107                 Progname = argv[0];
108         }
109
110         /* Crack and validate the command line options. */
111
112         while ((opt = getopt(argc, argv, "vn:l:s:")) != EOF) {
113                 switch (opt) {
114                 case 'v':
115                         Vflag++;
116                         break;
117                 case 'n':
118                         num_iter = atoi(optarg);
119                         break;
120                 case 'l':
121                         buflen = atoi(optarg);
122                         break;
123                 case 's':
124                         sid = atol(optarg);
125                         break;
126                 case '?':
127                         usage();
128                 }
129         }
130         if (optind + 2 != argc)
131                 usage();
132         ls_path = argv[optind];
133         dir_name = argv[optind+1];
134
135         bufp =
136           (char *)(malloc (buflen * sizeof(char)));  
137         statbuf = 
138           (struct stat *)(malloc (num_iter * sizeof(struct stat)));
139         checkbuf = 
140           (struct stat *)(malloc (num_iter * sizeof(struct stat)));
141         test_array = 
142           (char **)(malloc (num_iter * sizeof(char *)));
143         if (bufp==NULL || test_array==NULL || 
144             statbuf==NULL || checkbuf==NULL) {
145           printf("Malloc failed\n");
146           exit(1);
147         }
148         for (i=0; i<num_iter; i++) {
149           test_array[i] =
150             (char*)(malloc (buflen * sizeof(char)));
151           if (test_array[i] == NULL) {
152             printf("Malloc failed\n");
153             exit(1);
154           }
155         }
156
157         if (dm_init_service(&name) == -1)  {
158                 fprintf(stderr, "Can't initialize the DMAPI\n");
159                 exit(1);
160         }
161         if (sid == DM_NO_SESSION)
162                 find_test_session(&sid);
163         
164         printf("Attribute tests beginning...\n");
165         
166         attrnamep = (dm_attrname_t *)("DMATTR");
167
168         /* File creation loop*/
169         for (i=0; i < num_iter; i++) {
170           sprintf(test_file, "%s/DMAPI_attribute_test_file.%d", 
171                   dir_name, i);
172           sprintf(command, "cp %s %s \n", ls_path, test_file); 
173           system(command);
174         }
175
176         /* SET loop */
177         for (i=0; i < num_iter; i++) {
178           sprintf(test_file, "%s/DMAPI_attribute_test_file.%d", 
179                   dir_name, i);
180
181           if (stat(test_file, &(statbuf[i]))){
182             fprintf(stdout, 
183                     "Error: unable to stat the test file; %s (before set)\n", 
184                     test_file);
185           }
186           if (dm_path_to_handle(test_file, &hanp, &hlen)) {
187             fprintf(stderr, "can't get handle for %s; bypassing test\n",
188                     test_file);
189           }
190           else {
191             for (j=0; j < VALUE_LENGTH; j++) {
192               test_array[i][j]=(char)(rand()/128);;
193             } 
194             /* buflen is already set (to VALUE_LENGTH) */
195             if (dm_set_dmattr(sid, hanp, hlen, DM_NO_TOKEN, attrnamep, 
196                               (i<num_iter/2)?0:1, buflen, test_array[i])) {
197               fprintf(stderr, "dm_set_dmattr failed on test %d, %s\n",
198                       i, ERR_NAME);
199             }
200             else { 
201               if (Vflag){
202                 printf("Report: success with set #%d.\n", i);
203               }
204             }
205           }
206         }
207                 
208         /* GET loop */
209         for (i=0; i < num_iter; i++) {
210           sprintf(test_file, "%s/DMAPI_attribute_test_file.%d", 
211                   dir_name, i);
212
213           if (stat(test_file, &(checkbuf[i]))){
214             fprintf(stdout, 
215                     "Error: unable to stat the test file; %s (before get)\n", 
216                     test_file);
217           }
218           if (dm_path_to_handle(test_file, &hanp, &hlen)) {
219             fprintf(stderr, "can't get handle for %s; bypassing test\n",
220                     test_file);
221           }
222           else {
223             if (dm_get_dmattr(sid, hanp, hlen, DM_NO_TOKEN, attrnamep, buflen,
224                               bufp, &rlenp)) {
225               if (errno == E2BIG) {
226                 fprintf(stderr, "dm_get_dmattr buffer too small, "
227                         "should be %d bytes\n", rlenp);
228               } else {
229                 fprintf(stderr, "dm_get_dmattr failed (%s) for test file %d\n",
230                         ERR_NAME, i);
231               }
232             }
233             else {
234               /* Compare bufp with test_array[i]: */
235               if (strncmp(test_array[i], bufp, buflen)){
236                 printf("ERROR: failure on get test #%d.\n", i);
237               }
238               else if (Vflag) {
239                 printf("Report: success with get #%d. "
240                        "(output matches expectation)\n",i);
241               }
242             }
243           }
244         }
245         
246         /* It's time for timestamp checking! */
247         for (i=0; i < num_iter; i++) {
248 #ifdef linux
249           if ((statbuf[i].st_atime == checkbuf[i].st_atime) &&
250               (statbuf[i].st_mtime == checkbuf[i].st_mtime) &&
251               (statbuf[i].st_ctime == checkbuf[i].st_ctime))
252 #else
253           if ((statbuf[i].st_atim.tv_sec == checkbuf[i].st_atim.tv_sec) &&
254               (statbuf[i].st_atim.tv_nsec == checkbuf[i].st_atim.tv_nsec) &&
255               (statbuf[i].st_mtim.tv_sec == checkbuf[i].st_mtim.tv_sec) &&
256               (statbuf[i].st_mtim.tv_nsec == checkbuf[i].st_mtim.tv_nsec) &&
257               (statbuf[i].st_ctim.tv_sec == checkbuf[i].st_ctim.tv_sec) &&
258               (statbuf[i].st_ctim.tv_nsec == checkbuf[i].st_ctim.tv_nsec))
259 #endif
260           {
261             if (i < num_iter/2) {
262               /* Time stamp did not change, correctly */
263                 if (Vflag) {
264                 fprintf(stdout, "Report: Time stamp was correctly "
265                         "unchanged by test %d.\n", i);
266                 }
267             }
268             else {
269               /* Time stamp did not change, but should have */
270               fprintf(stdout, "Error: the time stamp should have "
271                       "changed in test file %d\n", i);
272             }
273           }
274           else {
275             /* Time stamp changed, but should not have. */
276             if (i < num_iter/2) {
277               fprintf(stdout, "Error: the time stamp should not"
278                       "change in test file %d\n", i);
279             }
280             else {
281             /* Time stamp changed, and should  have. */
282               if (Vflag) {
283                 fprintf(stdout, "Report: Time stamp was correctly "
284                         "changed by test %d.\n", i);
285               }
286             }
287           }
288         }
289
290         
291         /* REMOVE loop */
292         for (i=0; i < num_iter; i++) {
293           sprintf(test_file, "%s/DMAPI_attribute_test_file.%d", 
294                   dir_name, i);
295
296           if (dm_path_to_handle(test_file, &hanp, &hlen)) {
297             fprintf(stderr, "can't get handle for %s; bypassing test\n",
298                     test_file);
299           }
300           else {
301             if (dm_remove_dmattr(sid, hanp, hlen, DM_NO_TOKEN, setdtime,
302                                  attrnamep)) {
303               fprintf(stderr, "dm_remove_dmattr failed (%s) on test #%d\n",
304                       ERR_NAME, i);
305             }
306             else {
307               if (Vflag) {
308                 printf("Report: success with remove test #%d.\n",i);
309               }
310             }
311           }
312         }
313
314         for (i=0; i < num_iter; i++) {
315           sprintf(test_file, "%s/DMAPI_attribute_test_file.%d", 
316                   dir_name, i);
317           sprintf(command, "rm %s \n", test_file); 
318           system(command);
319         }
320
321         /*************************************\
322         |* Correct-input testing complete.   *|
323         |* Beginning improper-input testing. *|
324         \*************************************/
325         sprintf(test_file, "%s/DMAPI_attribute_test_file.ERRNO", 
326                 dir_name);
327         sprintf(command, "cp %s %s\n", ls_path, test_file); 
328         system(command);
329         
330         if (dm_path_to_handle(test_file, &hanp, &hlen)) {
331           fprintf(stderr, "can't get handle for %s; bypassing errno tests\n",
332                   test_file);
333         }
334         else {
335           
336           printf("\t(errno subtests beginning...)\n");
337           /**** SET tests ****/
338           /*---------------------------------------------------------*/
339           dm_get_config(hanp, hlen, DM_CONFIG_MAX_ATTRIBUTE_SIZE, 
340                         &config_retval);
341           
342           ERRTEST(E2BIG,
343                   "set", 
344                   dm_set_dmattr(sid, hanp, hlen, DM_NO_TOKEN,
345                                  attrnamep, setdtime, (config_retval+1), 
346                                 "foofoofoo"))
347           /*---------------------------------------------------------*/
348           EXCLTEST("set", hanp, hlen, test_token, 
349                    dm_set_dmattr(sid, hanp, hlen, test_token,
350                                  attrnamep, 0, buflen, "no right"))
351           /*---------------------------------------------------------*/
352           { void* test_vp;
353             if ((test_vp = handle_clone(hanp, hlen)) == NULL) {
354               fprintf(stderr, "Cannot create a test handle (%s); "
355                       "skipping EBADF test\n", ERR_NAME);
356             }
357             else {
358               ((char *) test_vp)[hlen/2]++;
359               ERRTEST(EBADF,
360                       "set",
361                       dm_set_dmattr(sid, test_vp, hlen, DM_NO_TOKEN,
362                                     attrnamep, 0, buflen, "EBADF"))
363                 dm_handle_free(test_vp, hlen);
364             }
365           }
366           /*---------------------------------------------------------*/
367           ERRTEST(EBADF,
368                   "set",
369                   dm_set_dmattr(sid, hanp, hlen-1, DM_NO_TOKEN,
370                                 attrnamep, 0, buflen, "EBADF"))
371           /*---------------------------------------------------------*/
372           ERRTEST(EFAULT,
373                   "set",
374                   dm_set_dmattr(sid, hanp, hlen, DM_NO_TOKEN,
375                                 (dm_attrname_t*)(-1000), 0,
376                                 buflen, "EFAULT_test" ))
377           ERRTEST(EFAULT,
378                   "set",
379                   dm_set_dmattr(sid, hanp, hlen, DM_NO_TOKEN,
380                                 attrnamep, 0, buflen, (void*)(-1000)))
381           /*---------------------------------------------------------*/
382           ERRTEST(EINVAL, 
383                   "set (bad token)",
384                   dm_set_dmattr(sid, hanp, hlen, (dm_token_t)(-1000), 
385                                 attrnamep, 0, buflen, 
386                                 "EINVAL_bad_token"))
387           /*---------------------------------------------------------*/
388           ERRTEST(EINVAL, 
389                   "set (bad session id)",
390                   dm_set_dmattr((dm_sessid_t)(-1000), hanp, hlen, 
391                                 DM_NO_TOKEN, attrnamep, 0, buflen, 
392                                 "EINVAL_bad_session_id"))
393             
394           /**** GET tests ****/
395           /*---------------------------------------------------------*/
396           dm_set_dmattr(sid, hanp, hlen, DM_NO_TOKEN,
397                         attrnamep, 0, buflen,
398                         "ERRNO for GET_DMATTR");
399           /*---------------------------------------------------------*/
400           ERRTEST(E2BIG,
401                   "get",
402                   dm_get_dmattr(sid, hanp, hlen, DM_NO_TOKEN,
403                                 attrnamep, 0, bufp, &rlenp))
404           /*---------------------------------------------------------*/
405           SHAREDTEST("get", hanp, hlen, test_token, 
406                      dm_get_dmattr(sid, hanp, hlen, test_token,
407                                    attrnamep, buflen, bufp, &rlenp))
408           /*---------------------------------------------------------*/
409           { void* test_vp;
410             if ((test_vp = handle_clone(hanp, hlen)) == NULL) {
411               fprintf(stderr, "Cannot create a test handle (%s); "
412                       "skipping EBADF test\n", ERR_NAME);
413             }
414             else {
415               ((char *) test_vp)[hlen/2]++;
416               ERRTEST(EBADF,
417                       "get",
418                       dm_get_dmattr(sid, test_vp, hlen, DM_NO_TOKEN,
419                                     attrnamep, buflen, bufp, &rlenp))
420                 dm_handle_free(test_vp, hlen);
421             }
422           }
423           /*---------------------------------------------------------*/
424           ERRTEST(EBADF,
425                   "get",
426                   dm_get_dmattr(sid, hanp, hlen-1, DM_NO_TOKEN,
427                                 attrnamep, buflen, bufp, &rlenp))
428           /*---------------------------------------------------------*/
429           ERRTEST(EINVAL,
430                   "get (invalid session)",
431                   dm_get_dmattr((dm_sessid_t)(-1000), hanp, hlen, DM_NO_TOKEN,
432                                 attrnamep, buflen, bufp, &rlenp))
433           /*---------------------------------------------------------*/
434           ERRTEST(EINVAL,
435                   "get (invalid token)",
436                   dm_get_dmattr(sid, hanp, hlen, (dm_token_t)(-1000),
437                                 attrnamep, buflen, bufp, &rlenp))
438           /*---------------------------------------------------------*/
439           ERRTEST(ENOENT,
440                   "get",
441                   dm_get_dmattr(sid, hanp, hlen, DM_NO_TOKEN,
442                                 (dm_attrname_t *)("NO_SUCH_ENTRY"),
443                                 buflen, bufp, &rlenp))
444           /*---------------------------------------------------------*/
445         
446           /**** REMOVE tests ****/
447           /*---------------------------------------------------------*/
448           dm_set_dmattr(sid, hanp, hlen, DM_NO_TOKEN,
449                         attrnamep, 0, buflen,
450                         "ERRNO for DMATTR");
451           EXCLTEST("remove", hanp, hlen, test_token,
452                    dm_remove_dmattr(sid, hanp, hlen, test_token, 
453                                     0, attrnamep))
454           /*---------------------------------------------------------*/
455           { void* test_vp;
456             if (dm_set_dmattr(sid, hanp, hlen, DM_NO_TOKEN, attrnamep, 
457                               0, buflen, "ERRNO for DMATTR")) {
458               printf("ERROR in setting dmattr for remove_dmattr test. (%s)\n",
459                      ERR_NAME);
460             } 
461             else if ((test_vp = handle_clone(hanp, hlen)) == NULL) {
462               fprintf(stderr, "Cannot create a test handle (%s); "
463                       "skipping EBADF test\n", ERR_NAME);
464             }
465             else {
466               ((char *) test_vp)[hlen/2]++;
467               ERRTEST(EBADF,
468                       "remove",
469                       dm_remove_dmattr(sid, test_vp, hlen, DM_NO_TOKEN,
470                                        0, attrnamep))
471                 dm_handle_free(test_vp, hlen);
472             }
473           }
474           /*---------------------------------------------------------*/
475           if (dm_set_dmattr(sid, hanp, hlen, DM_NO_TOKEN, attrnamep, 0, 
476                             buflen, "ERRNO for DMATTR")) {
477             printf("ERROR in setting dmattr for remove_dmattr test. (%s)\n",
478                    ERR_NAME);
479           } 
480           else {
481             ERRTEST(EBADF,
482                     "remove",
483                     dm_remove_dmattr(sid, hanp, hlen-1, DM_NO_TOKEN,
484                                      0, attrnamep))
485           }
486           /*---------------------------------------------------------*/
487           ERRTEST(EFAULT,
488                   "remove",
489                   dm_remove_dmattr(sid, hanp, hlen, DM_NO_TOKEN,
490                                  0, (void*)(-1000)))
491           /*---------------------------------------------------------*/
492           ERRTEST(EINVAL,
493                   "remove (bad token)",
494                   dm_remove_dmattr(sid, hanp, hlen, (dm_token_t)(-1000),
495                                  0, attrnamep))
496           /*---------------------------------------------------------*/
497           ERRTEST(EINVAL,
498                   "remove (bad session)",
499                   dm_remove_dmattr(-1, hanp, hlen, DM_NO_TOKEN,
500                                  0, attrnamep))
501           /*---------------------------------------------------------*/
502
503
504          sprintf(test_file, "%s/DMAPI_attribute_test_file.ERRNO", 
505                  dir_name);
506          sprintf(command, "rm %s\n", test_file); 
507          system(command);
508          printf("\t(errno subtests complete)\n");
509         }
510         /**********************************\
511         |* End of improper-input testing. *|
512         \**********************************/
513
514
515         printf("Attribute tests complete!\n");
516
517         dm_handle_free(hanp, hlen);
518         exit(0);
519 }