1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2000-2001 Silicon Graphics, Inc.
15 #include <lib/dmport.h>
17 #include <lib/errtest.h>
25 /*---------------------------------------------------------------------------
26 Automated test of the DMAPI functions:
33 test_fileattr [-s sid] [-n num_files] [-v] ls_path pathname
37 is the session ID whose events you you are interested in.
39 is the number of test files to create.
41 is the path to a copy of ls, which will be copied as a test file.
43 is the filesystem to use for the test.
44 ----------------------------------------------------------------------------*/
46 #define SET_MASK DM_AT_ATIME|DM_AT_MTIME|DM_AT_CTIME|DM_AT_DTIME|\
47 DM_AT_UID|DM_AT_GID|DM_AT_MODE|DM_AT_SIZE
49 #define GET_MASK DM_AT_EMASK|DM_AT_PMANR|DM_AT_PATTR|\
50 DM_AT_DTIME|DM_AT_CFLAG|DM_AT_STAT
61 comp_stat ( dm_stat_t expected,
66 if (found.dt_mode != expected.dt_mode) {
68 "ERROR: get #%d, expected mode %ld, but found %ld\n",
69 i, (long)expected.dt_mode, (long)found.dt_mode);
72 if (found.dt_uid != expected.dt_uid) {
74 "ERROR: get #%d, expected uid %ld, but found %ld\n",
75 i, (long)expected.dt_uid, (long)found.dt_uid);
78 if (found.dt_gid != expected.dt_gid) {
80 "ERROR: get #%d, expected gid %ld, but found %ld\n",
81 i, (long)expected.dt_gid, (long)found.dt_gid);
84 if (found.dt_atime != expected.dt_atime) {
86 "ERROR: get #%d, expected atime %ld, but found %ld\n",
87 i, expected.dt_atime, found.dt_atime);
90 if (found.dt_mtime != expected.dt_mtime) {
92 "ERROR: get #%d, expected mtime %ld, but found %ld\n",
93 i, expected.dt_mtime, found.dt_mtime);
96 if (found.dt_ctime != expected.dt_ctime) {
98 "ERROR: get #%d, expected ctime %ld, but found %ld\n",
99 i, expected.dt_ctime, found.dt_ctime);
103 /* NOTE: dtime gets set to ctime */
105 if (found.dt_dtime != expected.dt_ctime) {
107 "ERROR: get #%d, expected dtime %ld, but found %ld\n",
108 i, expected.dt_ctime, found.dt_dtime);
111 if (found.dt_size != expected.dt_size) {
113 "ERROR: get #%d, expected size %lld, but found %lld\n",
114 i, (long long) expected.dt_size, (long long) found.dt_size);
119 fprintf(stderr, "report: get #%d had no errors.\n",i);
121 fprintf(stderr, "report: %d tests correct for get #%d.\n",
133 "Usage: %s [-v] [-s sid] [-n num_files] ls_path pathname\n",
144 dm_sessid_t sid = DM_NO_SESSION;
145 dm_token_t test_token = DM_NO_TOKEN;
155 dm_fileattr_t fileattr;
161 size_t buflen = 16*sizeof(dm_stat_t);
170 char check_name[100];
174 Progname = strrchr(argv[0], '/');
182 while ((opt = getopt(argc, argv, "vn:s:")) != EOF) {
188 num_files = atoi(optarg);
197 if (optind + 2 != argc) {
200 ls_path = argv[optind];
201 pathname = argv[optind+1];
203 /* Seed the random number generator */
204 srand((unsigned int)time(NULL));
206 if (dm_init_service(&name) == -1) {
207 fprintf(stderr, "Can't initialize the DMAPI\n");
210 if (sid == DM_NO_SESSION)
211 find_test_session(&sid);
213 /* Dynamically allocate stat_arr; */
215 (dm_stat_t *)malloc(num_files * sizeof(dm_stat_t));
217 printf("Beginning file attribute tests...\n");
219 /* Fill in the dm_stat blocks with lots of junk...
221 for (i=0; i<num_files; i++) {
223 * XFS inode timestamp t_sec is a 32 bit signed value. rand() only
224 * returns 15 bits of random number, and so the rand()*0x10000 is
225 * really a rand() << 16 to populate the upper 16 bits of
226 * the timestamp.IOWs, linux does not need this but irix does.
228 stat_arr[i].dt_atime=((time_t)(rand()+rand()*0x10000) & 0x7FFFFFFF);
229 stat_arr[i].dt_mtime=((time_t)(rand()+rand()*0x10000) & 0x7FFFFFFF);
230 stat_arr[i].dt_ctime=((time_t)(rand()+rand()*0x10000) & 0x7FFFFFFF);
231 stat_arr[i].dt_dtime=((time_t)(rand()+rand()*0x10000) & 0x7FFFFFFF);
233 stat_arr[i].dt_uid=(uid_t)(rand()+rand()*0x10000);
234 stat_arr[i].dt_gid=(gid_t)(rand()+rand()*0x10000);
235 stat_arr[i].dt_mode=(mode_t)((rand()%4096)+32768);
236 stat_arr[i].dt_size=((dm_off_t)(rand()+rand()*0x10000)) & 0x1FFFFFFFFFFULL; /* 1 TB max */
239 /*-----------------------------------------------------*\
240 |* File creation and set_fileattr loop *|
241 \*-----------------------------------------------------*/
242 if (Vflag) fprintf(stderr, "\nCreating/setting up test files.\n");
243 for (i=0; i < num_files; i++) {
244 sprintf(test_file, "%s/DMAPI_fileattr_test.%d",
246 sprintf(command, "cp %s %s \n", ls_path, test_file);
249 if (dm_path_to_handle(test_file, &hanp, &hlen)) {
250 fprintf(stderr, "ERROR: can't get handle for %s; %s\n",
251 test_file, ERR_NAME);
254 fileattr.fa_mode = stat_arr[i].dt_mode;
255 fileattr.fa_uid = stat_arr[i].dt_uid;
256 fileattr.fa_gid = stat_arr[i].dt_gid;
257 fileattr.FA_ATIME = stat_arr[i].dt_atime;
258 fileattr.FA_MTIME = stat_arr[i].dt_mtime;
259 fileattr.FA_CTIME = stat_arr[i].dt_ctime;
260 fileattr.FA_DTIME = stat_arr[i].dt_dtime;
261 fileattr.fa_size = stat_arr[i].dt_size;
262 if (dm_set_fileattr(sid, hanp, hlen, DM_NO_TOKEN,
263 SET_MASK, &fileattr)) {
264 fprintf(stderr, "ERROR: set_fileattr failed on pass #%d; %s.\n",
268 fprintf(stderr, "report: set #%d was successful.\n", i);
273 /*-----------------------------------------------------*\
274 |* Get_fileattr loop *|
275 \*-----------------------------------------------------*/
276 if (Vflag) fprintf(stderr, "\nRunning get_fileattr test\n");
277 for (i=0; i < num_files; i++) {
278 sprintf(test_file, "%s/DMAPI_fileattr_test.%d",
280 if (dm_path_to_handle(test_file, &hanp, &hlen)) {
281 fprintf(stderr, "ERROR: can't get handle for %s; %s\n",
282 test_file, ERR_NAME);
284 if (dm_get_fileattr(sid, hanp, hlen, DM_NO_TOKEN,
285 GET_MASK, &dmstat)) {
287 "ERROR: dm_get_fileattr failed on pass #%d, %s\n",
291 comp_stat(stat_arr[i], dmstat, i);
295 /*-----------------------------------------------------*\
296 |* Get_dirattrs loop *|
297 \*-----------------------------------------------------*/
298 if (Vflag) fprintf(stderr, "\nRunning get_dirattrs test\n");
299 if (dm_path_to_handle(pathname, &hanp, &hlen)) {
300 fprintf(stderr, "ERROR: can't get handle for %s; %s\n",
304 if ((bufp = (void*)malloc(buflen)) == NULL) {
305 fprintf(stderr, "Can't allocate memory for buffer.\n");
308 if (dm_init_attrloc(sid, hanp, hlen, DM_NO_TOKEN, &loc)){
310 "ERROR: dm_init_attrloc failed with %s.\n",
317 /* printf("About to call get_dirattrs;\tloops=%d\n", loops);
321 oops=dm_get_dirattrs(sid, hanp, hlen, DM_NO_TOKEN,
322 GET_MASK, &loc, buflen,
325 for (statbuf = bufp; statbuf != NULL;
326 statbuf = DM_STEP_TO_NEXT(statbuf, dm_stat_t *)) {
327 chk_name_p = DM_GET_VALUE(statbuf, dt_compname, void *);
328 if (strncmp(chk_name_p, "DMAPI_fileattr_test.", 20)==0) {
329 sscanf(chk_name_p, "DMAPI_fileattr_test.%d", &chk_num);
330 if (comp_stat(stat_arr[chk_num], *statbuf, chk_num)==8) i++;
338 "ERROR: dm_get_dirattrs failed with %s.\n",
343 "ERROR: get_dirattrs found %d matching file%s "
344 "(expected %d).\n", i, (i==1)?"":"s", num_files);
347 fprintf(stderr, "report: get_dirattrs successfully "
348 "found %d files in %d loops.\n", i, loops);
351 /*-----------------------------------------------------*\
352 |* Get_bulkattr loop *|
353 \*-----------------------------------------------------*/
354 if (Vflag) fprintf(stderr, "\nRunning get_bulkattr test\n");
355 if (dm_path_to_handle(pathname, &hanp, &hlen)) {
356 fprintf(stderr, "ERROR: can't get handle for %s; %s\n",
360 if (dm_path_to_fshandle(pathname, &fs_hanp, &fs_hlen)) {
361 fprintf(stderr, "ERROR: can't get filesystem handle for %s; %s\n",
366 buflen = 16*sizeof(dm_stat_t); /* 100000000; */
367 if ((bufp = (void*)malloc(buflen)) == NULL) {
368 fprintf(stderr, "Can't allocate memory for buffer.\n");
371 if (dm_init_attrloc(sid, fs_hanp, fs_hlen,
374 "ERROR: dm_init_attrloc failed with %s.\n",
382 oops=dm_get_bulkattr(sid, fs_hanp, fs_hlen, DM_NO_TOKEN,
383 GET_MASK, &loc, buflen, bufp, &rlen);
385 for( statbuf = bufp; statbuf != NULL;
386 statbuf = DM_STEP_TO_NEXT(statbuf, dm_stat_t *) ) {
387 targhanp = DM_GET_VALUE(statbuf, dt_handle, void *);
388 targhlen = DM_GET_LEN(statbuf, dt_handle);
389 if (dm_handle_to_path(hanp, hlen, targhanp, targhlen,
390 (size_t)100, check_name, &rlen)){
392 "Warning: Couldn't get name from handle. (%s)\n",
396 /* Put JUST name (not path) from check_name into chk_name_p */
397 chk_name_p = strrchr(check_name, '/');
398 if (chk_name_p) chk_name_p++;
399 else chk_name_p = check_name;
400 /* Verify that check_name_p holds a testfile name */
401 if (strncmp(chk_name_p, "DMAPI_fileattr_test.",20)==0) {
402 /* Get the test file's number and compare. */
403 sscanf(chk_name_p, "DMAPI_fileattr_test.%d", &chk_num);
404 if (comp_stat(stat_arr[chk_num], *statbuf, chk_num)==8)i++;
413 "ERROR: dm_get_bulkattr failed with %s.\n",
416 /* printf("All_file_count: %d. BUFLEN: %d\n",
417 * all_file_count, buflen);
421 "ERROR: get_bulkattr found %d matching file%s "
422 "(expected %d) in %d loops.\n", i, (i==1)?"":"s",
426 fprintf(stderr, "report: get_bulkattr successfully "
427 "found %d files in %d loops.\n", i, loops);
430 /*------------------------*\
431 |* ## Errno subtests ## *|
432 \*------------------------*/
433 printf("\t(errno subtests beginning...)\n");
434 sprintf(test_file, "%s/DMAPI_fileattr_test.ERRNO",
436 sprintf(command, "cp %s %s\n", ls_path, test_file);
439 if (dm_path_to_handle(test_file, &hanp, &hlen)) {
440 fprintf(stderr, "ERROR: can't get handle for %s; %s\n",
441 test_file, ERR_NAME);
445 /*------------------------------------*\
446 |* ## dm_set_fileattr() subtests ## *|
447 \*------------------------------------*/
448 /*---------------------------------------------------------*/
449 EXCLTEST("set", hanp, hlen, test_token,
450 dm_set_fileattr(sid, hanp, hlen, test_token,
451 SET_MASK, &fileattr))
452 /*---------------------------------------------------------*/
454 if ((test_vp = handle_clone(hanp, hlen)) == NULL) {
456 "Cannot create a test handle (%s); skipping EBADF test\n",
460 ((char *) test_vp)[hlen/2]++;
463 dm_set_fileattr(sid, test_vp, hlen, DM_NO_TOKEN,
464 SET_MASK, &fileattr))
465 dm_handle_free(test_vp, hlen);
468 /*---------------------------------------------------------*/
471 dm_set_fileattr(sid, NULL, hlen, DM_NO_TOKEN,
472 SET_MASK, &fileattr))
473 /*---------------------------------------------------------*/
475 PROBLEM: 32 ones as a mask does not produce a "bad mask"
476 EINVAL. If it does not, I suspect nothing will.
479 "set (bad mask) [BROKEN]",
480 dm_set_fileattr(sid, hanp, hlen, DM_NO_TOKEN,
481 0xFFFFFFFF, &fileattr))
483 /*---------------------------------------------------------*/
486 dm_set_fileattr(sid, hanp, hlen, 0,
487 SET_MASK, &fileattr))
488 /*---------------------------------------------------------*/
491 dm_set_fileattr(-100, hanp, hlen, DM_NO_TOKEN,
492 SET_MASK, &fileattr))
493 /*---------------------------------------------------------*/
496 /*------------------------------------*\
497 |* ## dm_get_fileattr() subtests ## *|
498 \*------------------------------------*/
499 /*---------------------------------------------------------*/
500 SHAREDTEST("get", hanp, hlen, test_token,
501 dm_get_fileattr(sid, hanp, hlen, test_token,
503 /*---------------------------------------------------------*/
505 if ((test_vp = handle_clone(hanp, hlen)) == NULL) {
507 "Cannot create a test handle (%s); skipping EBADF test\n",
511 ((char *) test_vp)[hlen/2]++;
514 dm_get_fileattr(sid, test_vp, hlen, DM_NO_TOKEN,
516 dm_handle_free(test_vp, hlen);
519 /*---------------------------------------------------------*/
522 dm_get_fileattr(sid, NULL, hlen, DM_NO_TOKEN,
526 dm_get_fileattr(sid, hanp, hlen, DM_NO_TOKEN,
527 GET_MASK, (dm_stat_t *)(-1000)))
528 /*---------------------------------------------------------*/
530 PROBLEM: 32 ones as a mask does not produce a "bad mask"
531 EINVAL. If it does not, I suspect nothing will.
534 "get (bad mask) [BROKEN]",
535 dm_get_fileattr(sid, hanp, hlen, DM_NO_TOKEN,
536 0xFFFFFFFF, &dmstat))
538 /*---------------------------------------------------------*/
541 dm_get_fileattr(sid, hanp, hlen, 0,
543 /*---------------------------------------------------------*/
546 dm_get_fileattr(-100, hanp, hlen, DM_NO_TOKEN,
548 /*---------------------------------------------------------*/
551 dm_handle_free(hanp, hlen);
553 /*------------------------------------*\
554 |* ## dm_get_dirattrs() subtests ## *|
555 \*------------------------------------*/
556 if (dm_path_to_handle(pathname, &hanp, &hlen)) {
557 fprintf(stderr, "ERROR: can't get handle for %s; %s\n",
560 else if ((bufp = (void*)malloc(buflen)) == NULL) {
561 fprintf(stderr, "Can't allocate memory for buffer.\n");
564 /*---------------------------------------------------------*/
565 if (dm_init_attrloc(sid, hanp, hlen, DM_NO_TOKEN, &loc)){
567 "ERROR: dm_init_attrloc failed with %s.\n",
570 SHAREDTEST("get_dir", hanp, hlen, test_token,
571 dm_get_dirattrs(sid, hanp, hlen, test_token,
572 GET_MASK, &loc, buflen, bufp, &rlen))
574 /*---------------------------------------------------------*/
576 if (dm_init_attrloc(sid, hanp, hlen, DM_NO_TOKEN, &loc)){
577 fprintf(stderr, "ERROR: dm_init_attrloc failed with %s.\n",
580 else if ((test_vp = handle_clone(hanp, hlen)) == NULL) {
581 fprintf(stderr, "Cannot create a test handle (%s); "
582 "skipping EBADF test\n", ERR_NAME);
585 ((char *) test_vp)[hlen/2]++;
588 dm_get_dirattrs(sid, test_vp, hlen, DM_NO_TOKEN,
589 GET_MASK, &loc, buflen, bufp, &rlen))
590 dm_handle_free(test_vp, hlen);
593 /*---------------------------------------------------------*/
595 if (dm_init_attrloc(sid, hanp, hlen, DM_NO_TOKEN, &loc)){
597 "ERROR: dm_init_attrloc failed with %s.\n",
602 This would test alignment. Right now, no error occurs
603 when the buffer is "out of sync" with struct size.
604 It makes it tough to read from the buffer, tho!
606 "get_dir (bad bufp)",
607 dm_get_dirattrs(sid, hanp, hlen, DM_NO_TOKEN,
608 GET_MASK, &loc, buflen, p, &rlen))
611 "get_dir (bad locp)",
612 dm_get_dirattrs(sid, hanp, hlen, DM_NO_TOKEN,
613 GET_MASK, (dm_attrloc_t*)(-1000),
614 buflen, bufp, &rlen))
616 "get_dir (bad bufp)",
617 dm_get_dirattrs(sid, hanp, hlen, DM_NO_TOKEN,
618 GET_MASK, &loc, buflen,
619 (void*)(-1000), &rlen))
621 "get_dir (bad rlenp)",
622 dm_get_dirattrs(sid, hanp, hlen, DM_NO_TOKEN,
623 GET_MASK, &loc, buflen, bufp,
627 /*---------------------------------------------------------*/
628 /*---------------------------------------------------------*/
631 /*------------------------------------*\
632 |* ## dm_get_bulkattr() subtests ## *|
633 \*------------------------------------*/
634 if (dm_path_to_fshandle(pathname, &fs_hanp, &fs_hlen)) {
635 fprintf(stderr, "ERROR: can't get handle for %s; %s\n",
638 else if ((bufp = (void*)malloc(buflen)) == NULL) {
639 fprintf(stderr, "Can't allocate memory for buffer.\n");
642 /*---------------------------------------------------------*/
643 if (dm_init_attrloc(sid, fs_hanp, fs_hlen, DM_NO_TOKEN, &loc)){
645 "ERROR: dm_init_attrloc failed with %s.\n",
649 SHAREDTEST("get_bulk", fs_hanp, fs_hlen, test_token,
650 dm_get_bulkattr(sid, fs_hanp, fs_hlen, test_token,
651 GET_MASK, &loc, buflen, bufp, &rlen))
653 /*---------------------------------------------------------*/
654 if (dm_init_attrloc(sid, fs_hanp, fs_hlen, DM_NO_TOKEN, &loc)){
656 "ERROR: dm_init_attrloc failed with %s.\n",
660 void *p = (void *)(((char *)bufp)+1);
661 ERRTEST(EFAULT, "get_bulk (bad bufp)",
662 dm_get_bulkattr(sid, fs_hanp, fs_hlen, DM_NO_TOKEN,
663 GET_MASK, &loc, buflen,
664 (void *)(-1000), &rlen))
665 ERRTEST(EFAULT, "get_bulk (bad locp)",
666 dm_get_bulkattr(sid, fs_hanp, fs_hlen, DM_NO_TOKEN,
667 GET_MASK, (dm_attrloc_t *)(-1000),
668 buflen, bufp, &rlen))
669 ERRTEST(EFAULT, "get_bulk (bad rlenp)",
670 dm_get_bulkattr(sid, fs_hanp, fs_hlen, DM_NO_TOKEN,
671 GET_MASK, &loc, buflen, bufp,
673 ERRTEST(EFAULT, "get_bulk (bad bufp)",
674 dm_get_bulkattr(sid, fs_hanp, fs_hlen, DM_NO_TOKEN,
675 GET_MASK, &loc, buflen, p, &rlen))
677 /*---------------------------------------------------------*/
680 sprintf(command, "rm %s/DMAPI_fileattr_test.ERRNO\n", pathname);
682 printf("\t(errno subtests complete)\n");
683 /*---------------------*\
684 |* End of errno tests *|
685 \*---------------------*/
688 /* File deletion loop */
689 if (Vflag) printf("(Deleting test files...)\n");
690 for (i=0; i < num_files; i++) {
691 sprintf(test_file, "%s/DMAPI_fileattr_test.%d",
693 sprintf(command, "rm %s\n", test_file);
696 printf("File attribute tests complete.\n");