]> git.saurik.com Git - apple/xnu.git/blob - tests/kqueue_file_tests.c
xnu-7195.101.1.tar.gz
[apple/xnu.git] / tests / kqueue_file_tests.c
1 #include <string.h>
2 #include <errno.h>
3 #include <pwd.h>
4 #include <stdarg.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <unistd.h>
8 #include <fcntl.h>
9 #include <pthread.h>
10 #include <poll.h>
11 #include <sys/types.h>
12 #include <sys/event.h>
13 #include <sys/time.h>
14 #include <sys/stat.h>
15 #include <sys/mman.h>
16 #include <sys/param.h>
17 #include <sys/mount.h>
18 #include <sys/xattr.h>
19 #include <sys/file.h>
20
21 #include <TargetConditionals.h>
22 #include <darwintest.h>
23
24 T_GLOBAL_META(
25 T_META_NAMESPACE("xnu.kevent")
26 );
27
28 #define PDIR "/tmp"
29 #define DIR1 PDIR "/dir1"
30 #define DOTDOT ".."
31 #define DIR2 PDIR "/dir2"
32 #define FILE1 PDIR "/file1"
33 #define FILE2 PDIR "/file2"
34
35 #define KEY "somekey"
36 #define VAL "someval"
37
38 #define NOSLEEP 0
39 #define SLEEP 1
40 #define NO_EVENT 0
41 #define YES_EVENT 1
42
43
44 #define OUTPUT_LEVEL 0
45 #define RESULT_LEVEL 3
46
47 #define TEST_STRING "Some text!!! Yes indeed, some of that very structure which has passed on man's knowledge for generations."
48 #define HELLO_WORLD "Hello, World!"
49 #define USLEEP_TIME 5000
50 #define WAIT_TIME (4l)
51 #define LENGTHEN_SIZE 500
52 #define FIFO_SPACE 8192 /* FIFOS have 8K of buffer space */
53
54 /*
55 * These two variables are the non local memory for holding the return
56 * values from functions with which pthread_create is called.
57 */
58 int thread_status;
59 int fifo_read_fd;
60
61 /*
62 * Types of actions for setup, cleanup, and execution of tests
63 */
64 typedef enum {CREAT, MKDIR, READ, WRITE, WRITEFD, FILLFD, UNLINK, LSKEE, RMDIR, MKFIFO, LENGTHEN, TRUNC,
65 SYMLINK, CHMOD, CHOWN, EXCHANGEDATA, RENAME, LSEEK, OPEN, MMAP, NOTHING,
66 SETXATTR, UTIMES, STAT, HARDLINK, REVOKE, FUNLOCK} action_id_t;
67
68 /*
69 * Directs an action as mentioned above
70 */
71 typedef struct _action {
72 int act_dosleep;
73 action_id_t act_id;
74 void *act_args[5];
75 int act_fd;
76 } action_t;
77
78 /*
79 * A test case. Specifies setup, an event to look for, an action to take to
80 * cause (or not cause) that event, and cleanup.
81 */
82 typedef struct _test {
83 char *t_testname;
84
85 /* Is this test an expected failure? */
86 int t_known_failure;
87
88 /* Is this test behaving non-deterministically? */
89 int t_nondeterministic;
90
91 /* Test kevent() or poll() */
92 int t_is_poll_test;
93
94 /* Actions for setting up test */
95 int t_n_prep_actions;
96 action_t t_prep_actions[5];
97
98 /* Actions for cleaning up test */
99 int t_n_cleanup_actions;
100 action_t t_cleanup_actions[5];
101
102 /* Action for thred to take while we wait */
103 action_t t_helpthreadact;
104
105 /* File to look for event on */
106 char *t_watchfile; /* set event ident IN TEST (can't know fd beforehand)*/
107 int t_file_is_fifo;/* FIFOs are handled in a special manner */
108
109 /* Different parameters for poll() vs kevent() */
110 union {
111 struct kevent tu_kev;
112 short tu_pollevents;
113 } t_union;
114
115 /* Do we expect results? */
116 int t_want_event;
117
118 /* Not always used--how much data should we find (EVFILT_{READ,WRITE}) */
119 int t_nbytes;
120
121 /* Hacks for FILT_READ and pipes */
122 int t_read_to_end_first; /* Consume all data in file before waiting for event */
123 int t_write_some_data; /* Write some data to file before waiting for event (FIFO hack) */
124 int t_extra_sleep_hack; /* Sleep before waiting, to let a fifo fill up with data */
125 } test_t;
126
127 char *
128 get_action_name(action_id_t a)
129 {
130 switch (a) {
131 case CREAT:
132 return "CREAT";
133 case MKDIR:
134 return "MKDIR";
135 case READ:
136 return "READ";
137 case WRITE:
138 return "WRITE";
139 case WRITEFD:
140 return "WRITEFD";
141 case FILLFD:
142 return "FILLFD";
143 case UNLINK:
144 return "UNLINK";
145 case LSKEE:
146 return "LSKEE";
147 case RMDIR:
148 return "RMDIR";
149 case MKFIFO:
150 return "MKFIFO";
151 case LENGTHEN:
152 return "LENGTHEN";
153 case TRUNC:
154 return "TRUNC";
155 case SYMLINK:
156 return "SYMLINK";
157 case CHMOD:
158 return "CHMOD";
159 case CHOWN:
160 return "CHOWN";
161 case EXCHANGEDATA:
162 return "EXCHANGEDATA";
163 case RENAME:
164 return "RENAME";
165 case LSEEK:
166 return "LSEEK";
167 case OPEN:
168 return "OPEN";
169 case MMAP:
170 return "MMAP";
171 case NOTHING:
172 return "NOTHING";
173 case SETXATTR:
174 return "SETXATTR";
175 case UTIMES:
176 return "UTIMES";
177 case STAT:
178 return "STAT";
179 case HARDLINK:
180 return "HARDLINK";
181 case REVOKE:
182 return "REVOKE";
183 case FUNLOCK:
184 return "FUNLOCK";
185 }
186 return "Unknown";
187 }
188 /*
189 * Initialize an action struct. Whether to sleep, what action to take,
190 * and arguments for that action.
191 */
192 void
193 init_action(action_t *act, int sleep, action_id_t call, int nargs, ...)
194 {
195 int i;
196 va_list ap;
197 va_start(ap, nargs);
198 act->act_dosleep = sleep;
199 act->act_id = call;
200
201 for (i = 0; i < nargs; i++) {
202 act->act_args[i] = va_arg(ap, void*);
203 }
204
205 va_end(ap);
206 }
207
208 /*
209 * Opening a fifo is complicated: need to open both sides at once
210 */
211 void *
212 open_fifo_readside(void *arg)
213 {
214 if ((fifo_read_fd = open((char*)arg, O_RDONLY)) == -1) {
215 T_LOG("open(%s, O_RDONLY) failed: %d (%s)\n", arg, errno, strerror(errno));
216 }
217 return &fifo_read_fd;
218 }
219
220 /*
221 * Open a fifo, setting read and write descriptors. Return 0 for success, -1 for failure.
222 * Only set FD args upon success; they will be unmodified on failure.
223 */
224 int
225 open_fifo(const char *path, int *readfd, int *writefd)
226 {
227 pthread_t thread;
228 int waitres;
229 int res;
230 int *tmpreadfd, tmpwritefd;
231
232 fifo_read_fd = -1;
233 res = pthread_create(&thread, 0, open_fifo_readside, (void*)path);
234 if (res == 0) {
235 if ((tmpwritefd = open(path, O_WRONLY)) == -1) {
236 T_LOG("open(%s, O_WRONLY) failed: %d (%s)\n", path, errno, strerror(errno));
237 return -1;
238 }
239 waitres = pthread_join(thread, (void**) &tmpreadfd);
240
241 fcntl(tmpwritefd, F_SETFL, O_WRONLY | O_NONBLOCK);
242
243 if ((waitres == 0) && (tmpwritefd >= 0) && (*tmpreadfd >= 0)) {
244 *readfd = *tmpreadfd;
245 *writefd = tmpwritefd;
246 } else {
247 res = -1;
248 }
249 }
250
251 return res;
252 }
253
254 /*
255 * Just concatenate a directory and a filename, sticking a "/" betwixt them
256 */
257 void
258 makepath(char *buf, const char *dir, const char *file)
259 {
260 strcpy(buf, dir);
261 strcat(buf, "/");
262 strcat(buf, file);
263 }
264
265
266 /* Execute a prep, cleanup, or test action; specific tricky notes below.
267 *
268 * CREAT: comes to life and given length 1
269 * READ: try to read one char
270 * WRITE: try to write TEST_STRING to file
271 * LENGTHEN: make longer by LENGTHEN_SIZE
272 * MMAP: mmap first 20 bytes of file, write HELLO_WORLD in
273 * SETXATTR: set the KEY attribute to value VAL
274 * WRITEFD: instead of opening fresh, take an FD in the action struct (FIFOs)
275 * FILLFD: write a file until you can no longer. for filling FIFOS.
276 *
277 * * Several of these have hard-coded sizes.
278 */
279 void*
280 execute_action(void *actionptr)
281 {
282 action_t *act = (action_t*)actionptr;
283 void **args = act->act_args;
284 char c;
285 int res = -1, tmpfd, tmpfd2;
286 static int lastfd;
287 void *addr;
288 struct timeval tv;
289 struct stat sstat;
290
291 T_LOG("Beginning action of type %d: %s\n", act->act_id, get_action_name(act->act_id));
292
293 /* Let other thread get into kevent() sleep */
294 if (SLEEP == act->act_dosleep) {
295 usleep(USLEEP_TIME);
296 }
297 switch (act->act_id) {
298 case NOTHING:
299 res = 0;
300 break;
301 case CREAT:
302 if ((tmpfd = creat((char*)args[0], 0755)) == -1) {
303 T_LOG("creat() failed on \"%s\": %d (%s)\n", args[0], errno, strerror(errno));
304 res = -1;
305 break;
306 }
307 ftruncate(tmpfd, 1); /* So that mmap() doesn't fool us */
308 close(tmpfd);
309 res = 0;
310 break;
311 case MKDIR:
312 res = mkdir((char*)args[0], 0755);
313 break;
314 case READ:
315 if ((tmpfd = open((char*)args[0], O_RDONLY)) == -1) {
316 T_LOG("open(%s, O_RDONLY) failed: %d (%s)\n", args[0], errno, strerror(errno));
317 res = -1;
318 break;
319 }
320 res = read(tmpfd, &c, 1);
321 res = (res == 1 ? 0 : -1);
322 close(tmpfd);
323 break;
324 case WRITE:
325 if ((tmpfd = open((char*)args[0], O_RDWR)) == -1) {
326 T_LOG("open(%s, O_RDWR) failed: %d (%s)\n", args[0], errno, strerror(errno));
327 res = -1;
328 break;
329 }
330 res = write(tmpfd, TEST_STRING, strlen(TEST_STRING));
331 if (res == strlen(TEST_STRING)) {
332 res = 0;
333 } else {
334 res = -1;
335 }
336 close(tmpfd);
337 break;
338 case WRITEFD:
339 res = write((int)act->act_fd, TEST_STRING, strlen(TEST_STRING));
340 if (res == strlen(TEST_STRING)) {
341 res = 0;
342 } else {
343 res = -1;
344 }
345 break;
346 case FILLFD:
347 while (write((int)act->act_fd, "a", 1) > 0) {
348 ;
349 }
350 res = 0;
351 break;
352 case UNLINK:
353 res = unlink((char*)args[0]);
354 break;
355 case LSEEK:
356 res = lseek((int)act->act_fd, (int)args[0], SEEK_SET);
357 res = (res == (int)args[0] ? 0 : -1);
358 break;
359 case RMDIR:
360 res = rmdir((char*)args[0]);
361 break;
362 case MKFIFO:
363 res = mkfifo((char*)args[0], 0755);
364 break;
365 case LENGTHEN:
366 res = truncate((char*)args[0], LENGTHEN_SIZE);
367 break;
368 case TRUNC:
369 res = truncate((char*)args[0], 0);
370 break;
371 case SYMLINK:
372 res = symlink((char*)args[0], (char*)args[1]);
373 break;
374 case CHMOD:
375 res = chmod((char*)args[0], (int)args[1]);
376 break;
377 case CHOWN:
378 /* path, uid, gid */
379 res = chown((char*)args[0], (int) args[1], (int) args[2]);
380 break;
381 case EXCHANGEDATA:
382 res = exchangedata((char*)args[0], (char*)args[1], 0);
383 break;
384 case RENAME:
385 res = rename((char*)args[0], (char*)args[1]);
386 break;
387 case OPEN:
388 if ((tmpfd = open((char*)args[0], O_RDONLY | O_CREAT)) == -1) {
389 T_LOG("open(%s, O_RDONLY | O_CREAT) failed: %d (%s)\n", args[0], errno, strerror(errno));
390 res = -1;
391 break;
392 }
393 res = close(tmpfd);
394 break;
395 case MMAP:
396 /* It had best already exist with nonzero size */
397 if ((tmpfd = open((char*)args[0], O_RDWR)) == -1) {
398 T_LOG("open(%s, O_RDWR) failed: %d (%s)\n", args[0], errno, strerror(errno));
399 res = -1;
400 break;
401 }
402 addr = mmap(0, 20, PROT_WRITE | PROT_READ, MAP_FILE | MAP_SHARED, tmpfd, 0);
403 if (addr != ((void*)-1)) {
404 res = 0;
405 if ((int)args[1]) {
406 strcpy((char*)addr, HELLO_WORLD);
407 msync(addr, 20, MS_SYNC);
408 }
409 }
410 close(tmpfd);
411 munmap(addr, 20);
412 break;
413 case SETXATTR:
414 res = setxattr((char*)args[0], KEY, (void*)VAL, strlen(VAL),
415 0, 0);
416 break;
417 case UTIMES:
418 tv.tv_sec = time(NULL);
419 tv.tv_usec = 0;
420 res = utimes((char*)args[0], &tv);
421 break;
422 case STAT:
423 res = lstat((char*)args[0], &sstat);
424 break;
425 case HARDLINK:
426 res = link((char*)args[0], (char*)args[1]);
427 break;
428 case REVOKE:
429 if ((tmpfd = open((char*)args[0], O_RDONLY)) == -1) {
430 T_LOG("open(%s, O_RDONLY) failed: %d (%s)\n", args[0], errno, strerror(errno));
431 res = -1;
432 break;
433 }
434 res = revoke((char*)args[0]);
435 close(tmpfd);
436 break;
437 case FUNLOCK:
438 if ((tmpfd = open((char*)args[0], O_RDONLY)) == -1) {
439 T_LOG("open(%s, O_RDONLY) failed: %d (%s)\n", args[0], errno, strerror(errno));
440 res = -1;
441 break;
442 }
443 if ((res = flock(tmpfd, LOCK_EX)) == -1) {
444 T_LOG("flock() LOCK_EX failed: %d (%s)\n", errno, strerror(errno));
445 close(tmpfd);
446 break;
447 }
448 if ((res = flock(tmpfd, LOCK_UN)) == -1) {
449 T_LOG("flock() LOCK_UN failed: %d (%s)\n", errno, strerror(errno));
450 close(tmpfd);
451 break;
452 }
453 close(tmpfd);
454 break;
455 default:
456 res = -1;
457 break;
458 }
459
460 thread_status = res;
461 return &thread_status;
462 }
463
464 /*
465 * Read until the end of a file, for EVFILT_READ purposes (considers file position)
466 */
467 void
468 read_to_end(int fd)
469 {
470 char buf[50];
471 while (read(fd, buf, sizeof(buf)) > 0) {
472 ;
473 }
474 }
475
476 /*
477 * Helper for setup and cleanup; just execute every action in an array
478 * of actions. "failout" parameter indicates whether to stop if one fails.
479 */
480 int
481 execute_action_list(action_t *actions, int nactions, int failout)
482 {
483 int i, res;
484 for (i = 0, res = 0; (0 == res || (!failout)) && (i < nactions); i++) {
485 T_LOG("Starting prep action %d\n", i);
486 res = *((int *) execute_action(&(actions[i])));
487 if (res != 0) {
488 T_LOG("Action list failed on step %d. res = %d errno = %d (%s)\n", i, res,
489 errno, strerror(errno));
490 } else {
491 T_LOG("Action list work succeeded on step %d.\n", i);
492 }
493 }
494
495 return res;
496 }
497
498 /*
499 * Execute a full test, return success value.
500 */
501 int
502 execute_test(test_t *test)
503 {
504 int i, kqfd, filefd = -1, res2, res, cnt, writefd = -1;
505 int retval = -1;
506 pthread_t thr;
507 struct kevent evlist;
508 struct timespec ts = {WAIT_TIME, 0l};
509 int *status;
510
511 memset(&evlist, 0, sizeof(evlist));
512
513 T_LOG("[BEGIN] %s\n", test->t_testname);
514
515 T_LOG(test->t_want_event ? "Expecting an event.\n" : "Not expecting events.\n");
516
517 res = execute_action_list(test->t_prep_actions, test->t_n_prep_actions, 1);
518
519 /* If prep succeeded */
520 if (0 == res) {
521 /* Create kqueue for kqueue tests*/
522 if (!test->t_is_poll_test) {
523 if ((kqfd = kqueue()) == -1) {
524 T_LOG("kqueue() failed: %d (%s)\n", errno, strerror(errno));
525 }
526 }
527
528 if ((test->t_is_poll_test) || kqfd >= 0) {
529 /* Open the file we're to monitor. Fifos get special handling */
530 if (test->t_file_is_fifo) {
531 filefd = -1;
532 open_fifo(test->t_watchfile, &filefd, &writefd);
533 } else {
534 if ((filefd = open(test->t_watchfile, O_RDONLY | O_SYMLINK)) == -1) {
535 T_LOG("open() of watchfile %s failed: %d (%s)\n", test->t_watchfile,
536 errno, strerror(errno));
537 res = -1;
538 }
539 }
540
541 if (filefd >= 0) {
542 T_LOG("Opened file to monitor.\n");
543
544 /*
545 * Fill in the fd to monitor once you know it
546 * If it's a fifo test, then the helper is definitely going to want the write end.
547 */
548 test->t_helpthreadact.act_fd = (writefd >= 0 ? writefd : filefd);
549
550 if (test->t_read_to_end_first) {
551 read_to_end(filefd);
552 } else if (test->t_write_some_data) {
553 action_t dowr;
554 init_action(&dowr, NOSLEEP, WRITEFD, 0);
555 dowr.act_fd = writefd;
556 (void)execute_action(&dowr);
557 }
558
559 /* Helper modifies the file that we're listening on (sleeps first, in general) */
560 thread_status = 0;
561 res = pthread_create(&thr, NULL, execute_action, (void*) &test->t_helpthreadact);
562 if (0 == res) {
563 T_LOG("Created helper thread.\n");
564
565 /* This is ugly business to hack on filling up a FIFO */
566 if (test->t_extra_sleep_hack) {
567 usleep(USLEEP_TIME);
568 }
569
570 if (test->t_is_poll_test) {
571 struct pollfd pl;
572 pl.fd = filefd;
573 pl.events = test->t_union.tu_pollevents;
574 cnt = poll(&pl, 1, WAIT_TIME);
575 T_LOG("Finished poll() call.\n");
576 if ((cnt < 0)) {
577 T_LOG("error is in errno, %s\n", strerror(errno));
578 res = cnt;
579 }
580 } else {
581 test->t_union.tu_kev.ident = filefd;
582 cnt = kevent(kqfd, &test->t_union.tu_kev, 1, &evlist, 1, &ts);
583 T_LOG("Finished kevent() call.\n");
584
585 if ((cnt < 0) || (evlist.flags & EV_ERROR)) {
586 T_LOG("kevent() call failed.\n");
587 if (cnt < 0) {
588 T_LOG("error is in errno, %s\n", strerror(errno));
589 } else {
590 T_LOG("error is in data, %s\n", strerror(evlist.data));
591 }
592 res = cnt;
593 }
594 }
595
596 /* Success only if you've succeeded to this point AND joined AND other thread is happy*/
597 status = NULL;
598 res2 = pthread_join(thr, (void **)&status);
599 if (res2 != 0) {
600 T_LOG("Couldn't join helper thread: %d (%s).\n", res2,
601 strerror(res2));
602 } else if (*status) {
603 T_LOG("Helper action had result %d\n", *status);
604 }
605 res = ((res == 0) && (res2 == 0) && (*status == 0)) ? 0 : -1;
606 } else {
607 T_LOG("Couldn't start thread: %d (%s).\n", res, strerror(res));
608 }
609
610 close(filefd);
611 if (test->t_file_is_fifo) {
612 close(writefd);
613 }
614 }
615 if (!test->t_is_poll_test) {
616 close(kqfd);
617 }
618 } else {
619 T_LOG("Couldn't open kqueue.\n");
620 res = -1;
621 }
622 }
623
624 /* Cleanup work */
625 execute_action_list(test->t_cleanup_actions, test->t_n_cleanup_actions, 0);
626
627 /* Success if nothing failed and we either received or did not receive event,
628 * as expected
629 */
630 if (0 == res) {
631 T_LOG(cnt > 0 ? "Got an event.\n" : "Did not get an event.\n");
632 if (((cnt > 0) && (test->t_want_event)) || ((cnt == 0) && (!test->t_want_event))) {
633 if ((!test->t_is_poll_test) && (test->t_union.tu_kev.filter == EVFILT_READ || test->t_union.tu_kev.filter == EVFILT_WRITE)
634 && (test->t_nbytes) && (test->t_nbytes != evlist.data)) {
635 T_LOG("Read wrong number of bytes available. Wanted %d, got %d\n", test->t_nbytes, evlist.data);
636 retval = -1;
637 } else {
638 retval = 0;
639 }
640 } else {
641 T_LOG("Got unexpected event or lack thereof.\n");
642 retval = -1;
643 }
644 } else {
645 T_LOG("Failed to execute test. res = %d\n", res);
646 retval = -1;
647 }
648
649 if (test->t_nondeterministic) {
650 T_LOG("XXX non-deterministic test result = %d (%s)\n", retval,
651 (retval == 0) ? "pass" : "fail");
652 T_MAYFAIL;
653 } else {
654 if (test->t_known_failure) {
655 // Signal to harness that this test is expected to fail.
656 T_EXPECTFAIL;
657 }
658 }
659
660 if (retval == 0) {
661 T_PASS("%s", test->t_testname);
662 } else {
663 T_FAIL("%s", test->t_testname);
664 }
665
666 T_LOG("Test %s done with result %d.\n", test->t_testname, retval);
667 return retval;
668 }
669
670
671
672 void
673 init_test_common(test_t *tst, char *testname, char *watchfile, int nprep, int nclean, int event, int want, int ispoll)
674 {
675 memset(tst, 0, sizeof(test_t));
676 tst->t_testname = testname;
677 tst->t_known_failure = 0;
678 tst->t_nondeterministic = 0;
679 tst->t_watchfile = watchfile;
680 tst->t_n_prep_actions = nprep;
681 tst->t_n_cleanup_actions = nclean;
682 tst->t_want_event = (want > 0);
683
684 if (ispoll) {
685 tst->t_is_poll_test = 1;
686 tst->t_union.tu_pollevents = (short)event;
687 } else {
688 /* Can do this because filter is negative, notes are positive */
689 if (event == EVFILT_READ || event == EVFILT_WRITE) {
690 EV_SET(&tst->t_union.tu_kev, 0, event, EV_ADD | EV_ENABLE, 0, 0, NULL);
691 tst->t_nbytes = want;
692 } else {
693 EV_SET(&tst->t_union.tu_kev, 0, EVFILT_VNODE, EV_ADD | EV_ENABLE, event, 0, NULL);
694 }
695 }
696 }
697
698 /*
699 * Initialize a test case, not including its actions. Meaning: a name for it, what filename to watch,
700 * counts of prep and cleanup actions, what event to watch for, and whether you want an event/how many bytes read.
701 *
702 * "want" does double duty as whether you want an event and how many bytes you might want to read
703 * "event" is either an event flag (e.g. NOTE_WRITE) or EVFILT_READ
704 */
705 void
706 init_test(test_t *tst, char *testname, char *watchfile, int nprep, int nclean, int event, int want)
707 {
708 init_test_common(tst, testname, watchfile, nprep, nclean, event, want, 0);
709 }
710
711 /*
712 * Same as above, but for a poll() test
713 */
714 void
715 init_poll_test(test_t *tst, char *testname, char *watchfile, int nprep, int nclean, int event, int want)
716 {
717 init_test_common(tst, testname, watchfile, nprep, nclean, event, want, 1);
718 }
719
720 void
721 run_note_delete_tests()
722 {
723 test_t test;
724
725 init_test(&test, "1.1.2: unlink a file", FILE1, 1, 0, NOTE_DELETE, YES_EVENT);
726 test.t_nondeterministic = 1;
727 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
728 init_action(&test.t_helpthreadact, SLEEP, UNLINK, 2, (void*)FILE1, NULL);
729 execute_test(&test);
730
731 init_test(&test, "1.1.3: rmdir a dir", DIR1, 1, 0, NOTE_DELETE, YES_EVENT);
732 test.t_nondeterministic = 1;
733 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
734 init_action(&test.t_helpthreadact, SLEEP, RMDIR, 2, (void*)DIR1, NULL);
735 execute_test(&test);
736
737 init_test(&test, "1.1.4: rename one file over another", FILE2, 2, 1, NOTE_DELETE, YES_EVENT);
738 test.t_nondeterministic = 1;
739 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
740 init_action(&(test.t_prep_actions[1]), NOSLEEP, CREAT, 2, (void*)FILE2, (void*)NULL);
741 init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)FILE1, (void*)FILE2);
742 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE2, NULL);
743 execute_test(&test);
744
745 init_test(&test, "1.1.5: rename one dir over another", DIR2, 2, 1, NOTE_DELETE, YES_EVENT);
746 test.t_nondeterministic = 1;
747 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
748 init_action(&(test.t_prep_actions[1]), NOSLEEP, MKDIR, 2, (void*)DIR2, (void*)NULL);
749 init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)DIR1, (void*)DIR2);
750 init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)DIR2, NULL);
751 execute_test(&test);
752
753 /* Do FIFO stuff here */
754 init_test(&test, "1.1.6: make a fifo, unlink it", FILE1, 1, 0, NOTE_DELETE, YES_EVENT);
755 test.t_file_is_fifo = 1;
756 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKFIFO, 2, (void*)FILE1, (void*)NULL);
757 init_action(&test.t_helpthreadact, SLEEP, UNLINK, 1, (void*)FILE1);
758 execute_test(&test);
759
760 init_test(&test, "1.1.7: rename a file over a fifo", FILE1, 2, 1, NOTE_DELETE, YES_EVENT);
761 test.t_nondeterministic = 1;
762 test.t_file_is_fifo = 1;
763 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKFIFO, 2, (void*)FILE1, (void*)NULL);
764 init_action(&(test.t_prep_actions[1]), NOSLEEP, CREAT, 2, (void*)FILE2, (void*)NULL);
765 init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)FILE2, (void*)FILE1);
766 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
767 execute_test(&test);
768
769 init_test(&test, "1.1.8: unlink a symlink to a file", FILE2, 2, 1, NOTE_DELETE, YES_EVENT);
770 test.t_nondeterministic = 1;
771 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
772 init_action(&(test.t_prep_actions[1]), NOSLEEP, SYMLINK, 2, (void*)FILE1, (void*)FILE2);
773 init_action(&test.t_helpthreadact, SLEEP, UNLINK, 2, (void*)FILE2, NULL);
774 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
775 execute_test(&test);
776
777 /* ================= */
778
779 init_test(&test, "1.2.1: Straight-up rename file", FILE1, 1, 1, NOTE_DELETE, NO_EVENT);
780 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
781 init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)FILE1, (void*)FILE2);
782 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE2, (void*)NULL);
783 execute_test(&test);
784
785 init_test(&test, "1.2.2: Straight-up rename dir", DIR1, 1, 1, NOTE_DELETE, NO_EVENT);
786 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
787 init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)DIR1, (void*)DIR2);
788 init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)DIR2, (void*)NULL);
789 execute_test(&test);
790
791 init_test(&test, "1.2.3: Null action on file", FILE1, 1, 1, NOTE_DELETE, NO_EVENT);
792 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
793 init_action(&test.t_helpthreadact, SLEEP, NOTHING, 2, NULL, NULL); /* The null action */
794 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, (void*)NULL);
795 execute_test(&test);
796
797 init_test(&test, "1.2.4: Rename one file over another: watch the file that lives", FILE1, 2, 1, NOTE_DELETE, NO_EVENT);
798 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
799 init_action(&(test.t_prep_actions[1]), NOSLEEP, CREAT, 2, (void*)FILE2, (void*)NULL);
800 init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)FILE1, (void*)FILE2);
801 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE2, NULL);
802 execute_test(&test);
803
804 init_test(&test, "1.2.5: Rename one dir over another, watch the dir that lives", DIR1, 2, 1, NOTE_DELETE, NO_EVENT);
805 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
806 init_action(&(test.t_prep_actions[1]), NOSLEEP, MKDIR, 2, (void*)DIR2, (void*)NULL);
807 init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)DIR1, (void*)DIR2);
808 init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)DIR2, NULL);
809 }
810
811 static bool
812 path_on_apfs(const char *path)
813 {
814 struct statfs sfs = {};
815 T_QUIET; T_ASSERT_POSIX_SUCCESS(statfs(path, &sfs), NULL);
816 return memcmp(&sfs.f_fstypename[0], "apfs", strlen("apfs")) == 0;
817 }
818
819 void
820 run_note_write_tests()
821 {
822 char pathbuf[50];
823 char otherpathbuf[50];
824
825 test_t test;
826
827 init_test(&test, "2.1.1: Straight-up write to a file", FILE1, 1, 1, NOTE_WRITE, YES_EVENT);
828 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
829 init_action(&test.t_helpthreadact, SLEEP, WRITE, 2, (void*)FILE1, NULL);
830 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, (void*)NULL);
831 execute_test(&test);
832
833
834 makepath(pathbuf, DIR1, FILE1);
835 init_test(&test, "2.1.2: creat() file inside a dir", DIR1, 1, 2, NOTE_WRITE, YES_EVENT);
836 test.t_known_failure = 1;
837 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
838 init_action(&test.t_helpthreadact, SLEEP, CREAT, 2, (void*)pathbuf, NULL);
839 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)pathbuf, (void*)NULL);
840 init_action(&test.t_cleanup_actions[1], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
841 execute_test(&test);
842
843 makepath(pathbuf, DIR1, FILE1);
844 init_test(&test, "2.1.3: open() file inside a dir", DIR1, 1, 2, NOTE_WRITE, YES_EVENT);
845 test.t_known_failure = 1;
846 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
847 init_action(&test.t_helpthreadact, SLEEP, OPEN, 2, (void*)pathbuf, NULL);
848 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)pathbuf, (void*)NULL);
849 init_action(&test.t_cleanup_actions[1], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
850 execute_test(&test);
851
852 makepath(pathbuf, DIR1, FILE1);
853 init_test(&test, "2.1.4: unlink a file from a dir", DIR1, 2, 1, NOTE_WRITE, YES_EVENT);
854 test.t_known_failure = 1;
855 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
856 init_action(&(test.t_prep_actions[1]), NOSLEEP, CREAT, 2, (void*)pathbuf, (void*)NULL);
857 init_action(&test.t_helpthreadact, SLEEP, UNLINK, 2, (void*)pathbuf, NULL);
858 init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
859 execute_test(&test);
860
861 makepath(pathbuf, DIR1, FILE1);
862 makepath(otherpathbuf, DIR1, FILE2);
863 init_test(&test, "2.1.5: rename a file in a dir", DIR1, 2, 2, NOTE_WRITE, YES_EVENT);
864 test.t_known_failure = 1;
865 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
866 init_action(&(test.t_prep_actions[1]), NOSLEEP, CREAT, 2, (void*)pathbuf, (void*)NULL);
867 init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)pathbuf, (void*)otherpathbuf);
868 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)otherpathbuf, (void*)NULL);
869 init_action(&test.t_cleanup_actions[1], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
870 execute_test(&test);
871
872 makepath(pathbuf, DIR1, FILE1);
873 init_test(&test, "2.1.6: rename a file to outside of a dir", DIR1, 2, 2, NOTE_WRITE, YES_EVENT);
874 test.t_known_failure = 1;
875 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
876 init_action(&(test.t_prep_actions[1]), NOSLEEP, CREAT, 2, (void*)pathbuf, (void*)NULL);
877 init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)pathbuf, (void*)FILE1);
878 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, (void*)NULL);
879 init_action(&test.t_cleanup_actions[1], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
880 execute_test(&test);
881
882 makepath(pathbuf, DIR1, FILE1);
883 init_test(&test, "2.1.7: rename a file into a dir", DIR1, 2, 2, NOTE_WRITE, YES_EVENT);
884 test.t_known_failure = 1;
885 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
886 init_action(&(test.t_prep_actions[1]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
887 init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)FILE1, (void*)pathbuf);
888 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)pathbuf, (void*)NULL);
889 init_action(&test.t_cleanup_actions[1], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
890 execute_test(&test);
891
892 makepath(pathbuf, DIR1, FILE1);
893 init_test(&test, "2.1.9: unlink a fifo from a dir", DIR1, 2, 1, NOTE_WRITE, YES_EVENT);
894 test.t_known_failure = 1;
895 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
896 init_action(&(test.t_prep_actions[1]), NOSLEEP, MKFIFO, 2, (void*)pathbuf, (void*)NULL);
897 init_action(&test.t_helpthreadact, SLEEP, UNLINK, 2, (void*)pathbuf, NULL);
898 init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
899 execute_test(&test);
900
901 makepath(pathbuf, DIR1, FILE1);
902 init_test(&test, "2.1.10: make symlink in a dir", DIR1, 1, 2, NOTE_WRITE, YES_EVENT);
903 test.t_known_failure = 1;
904 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
905 init_action(&test.t_helpthreadact, SLEEP, SYMLINK, 2, (void*)DOTDOT, (void*)pathbuf);
906 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)pathbuf, (void*)NULL);
907 init_action(&test.t_cleanup_actions[1], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
908 execute_test(&test);
909
910 init_test(&test, "2.1.12: write to a FIFO", FILE1, 1, 1, NOTE_WRITE, YES_EVENT);
911 test.t_known_failure = 1;
912 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKFIFO, 2, (void*)FILE1, (void*)NULL);
913 test.t_file_is_fifo = 1;
914 init_action(&test.t_helpthreadact, SLEEP, WRITEFD, 0);
915 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, (void*)NULL);
916 execute_test(&test);
917
918
919 makepath(pathbuf, DIR1, FILE1);
920 init_test(&test, "2.1.13: delete a symlink in a dir", DIR1, 2, 1, NOTE_WRITE, YES_EVENT);
921 test.t_known_failure = 1;
922 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
923 init_action(&(test.t_prep_actions[1]), NOSLEEP, SYMLINK, 2, (void*)DOTDOT, (void*)pathbuf);
924 init_action(&test.t_helpthreadact, SLEEP, UNLINK, 2, (void*)pathbuf, (void*)FILE1);
925 init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
926 execute_test(&test);
927
928 /* exchangedata is not supported on APFS volumes */
929 if (!path_on_apfs(PDIR)) {
930 /* This actually should not generate an event, though it's in this section */
931 makepath(pathbuf, DIR1, FILE1);
932 makepath(otherpathbuf, DIR1, FILE2);
933 init_test(&test, "2.1.14: exchangedata two files in a dir", DIR1, 3, 3, NOTE_WRITE, NO_EVENT);
934 test.t_known_failure = 1;
935 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
936 init_action(&(test.t_prep_actions[1]), NOSLEEP, CREAT, 2, (void*)pathbuf, (void*)NULL);
937 init_action(&(test.t_prep_actions[2]), NOSLEEP, CREAT, 2, (void*)otherpathbuf, (void*)NULL);
938 init_action(&test.t_helpthreadact, SLEEP, EXCHANGEDATA, 2, (void*)pathbuf, (void*)otherpathbuf);
939 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)pathbuf, (void*)NULL);
940 init_action(&test.t_cleanup_actions[1], NOSLEEP, UNLINK, 2, (void*)otherpathbuf, (void*)NULL);
941 init_action(&test.t_cleanup_actions[2], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
942 execute_test(&test);
943 }
944
945 init_test(&test, "2.1.15: Change a file with mmap()", FILE1, 1, 1, NOTE_WRITE, YES_EVENT);
946 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
947 init_action(&test.t_helpthreadact, SLEEP, MMAP, 2, (void*)FILE1, (void*)1); /* 1 -> "modify it"*/
948 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, (void*)NULL);
949 execute_test(&test);
950
951 /*================= no-event tests ==================*/
952 init_test(&test, "2.2.1: just open and close existing file", FILE1, 1, 1, NOTE_WRITE, NO_EVENT);
953 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
954 init_action(&test.t_helpthreadact, SLEEP, OPEN, 2, (void*)FILE1, NULL);
955 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, (void*)NULL);
956 execute_test(&test);
957
958 init_test(&test, "2.2.2: read from existing file", FILE1, 1, 1, NOTE_WRITE, NO_EVENT);
959 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
960 init_action(&test.t_helpthreadact, SLEEP, READ, 2, (void*)FILE1, NULL);
961 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, (void*)NULL);
962 execute_test(&test);
963
964 init_test(&test, "2.2.3: rename existing file", FILE1, 1, 1, NOTE_WRITE, NO_EVENT);
965 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
966 init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)FILE1, (void*)FILE2);
967 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE2, (void*)NULL);
968 execute_test(&test);
969
970 init_test(&test, "2.2.4: just open and close dir", DIR1, 1, 1, NOTE_WRITE, NO_EVENT);
971 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
972 init_action(&test.t_helpthreadact, SLEEP, OPEN, 2, (void*)DIR1, (void*)NULL);
973 init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
974 execute_test(&test);
975
976 /* There are no tests 2.2.5 or 2.2.6 */
977
978 init_test(&test, "2.2.7: rename a dir", DIR1, 1, 1, NOTE_WRITE, NO_EVENT);
979 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
980 init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)DIR1, (void*)DIR2);
981 init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)DIR2, (void*)NULL);
982 execute_test(&test);
983
984 init_test(&test, "2.2.8: rename a fifo", FILE1, 1, 1, NOTE_WRITE, NO_EVENT);
985 test.t_file_is_fifo = 1;
986 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKFIFO, 2, (void*)FILE1, (void*)NULL);
987 init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)FILE1, (void*)FILE2);
988 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE2, (void*)NULL);
989 execute_test(&test);
990
991 init_test(&test, "2.2.9: unlink a fifo", FILE1, 1, 0, NOTE_WRITE, NO_EVENT);
992 test.t_file_is_fifo = 1;
993 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKFIFO, 2, (void*)FILE1, (void*)NULL);
994 init_action(&test.t_helpthreadact, SLEEP, UNLINK, 1, (void*)FILE1);
995 execute_test(&test);
996
997 init_test(&test, "2.2.10: chmod a file", FILE1, 1, 1, NOTE_WRITE, NO_EVENT);
998 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
999 init_action(&test.t_helpthreadact, SLEEP, CHMOD, 2, (void*)FILE1, (void*)0700);
1000 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, (void*)NULL);
1001 execute_test(&test);
1002
1003 struct passwd *pwd = getpwnam("local");
1004
1005 if (pwd != NULL) {
1006 init_test(&test, "2.2.11: chown a file", FILE1, 2, 1, NOTE_WRITE, NO_EVENT);
1007 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1008 init_action(&test.t_prep_actions[1], NOSLEEP, CHOWN, 3, (void*)FILE1, (void*)pwd->pw_uid, (void*)pwd->pw_gid);
1009 init_action(&test.t_helpthreadact, SLEEP, CHOWN, 3, (void*)FILE1, (void*)getuid(), (void*)getgid());
1010 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, (void*)NULL);
1011 execute_test(&test);
1012 }
1013
1014 init_test(&test, "2.2.12: chmod a dir", DIR1, 1, 1, NOTE_WRITE, NO_EVENT);
1015 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1016 init_action(&test.t_helpthreadact, SLEEP, CHMOD, 2, (void*)DIR1, (void*)0700);
1017 init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
1018 execute_test(&test);
1019
1020 if (pwd != NULL) {
1021 init_test(&test, "2.2.13: chown a dir", DIR1, 2, 1, NOTE_WRITE, NO_EVENT);
1022 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1023 init_action(&test.t_prep_actions[1], NOSLEEP, CHOWN, 3, (void*)DIR1, (void*)pwd->pw_uid, (void*)pwd->pw_gid);
1024 init_action(&test.t_helpthreadact, SLEEP, CHOWN, 3, (void*)DIR1, (void*)getuid(), (void*)getgid());
1025 init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
1026 execute_test(&test);
1027 }
1028
1029 T_LOG("MMAP will never give a notification on HFS.\n");
1030 init_test(&test, "2.1.14: mmap() a file but do not change it", FILE1, 1, 1, NOTE_WRITE, NO_EVENT);
1031 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1032 init_action(&test.t_helpthreadact, SLEEP, MMAP, 2, (void*)FILE1, (void*)0);
1033 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, (void*)NULL);
1034 execute_test(&test);
1035 }
1036
1037 void
1038 run_note_extend_tests()
1039 {
1040 test_t test;
1041 char pathbuf[50];
1042
1043 T_LOG("THESE TESTS MAY FAIL ON HFS\n");
1044
1045 init_test(&test, "3.1.1: write beyond the end of a file", FILE1, 1, 1, NOTE_EXTEND, YES_EVENT);
1046 test.t_nondeterministic = 1;
1047 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1048 init_action(&test.t_helpthreadact, SLEEP, WRITE, 2, (void*)FILE1, (void*)NULL);
1049 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, (void*)NULL);
1050 execute_test(&test);
1051
1052 /*
1053 * We won't concern ourselves with lengthening directories: commenting these out
1054 *
1055 *
1056 * makepath(pathbuf, DIR1, FILE1);
1057 * init_test(&test, "3.1.2: add a file to a directory with creat()", DIR1, 1, 2, NOTE_EXTEND, YES_EVENT);
1058 * init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1059 * init_action(&test.t_helpthreadact, SLEEP, CREAT, 2, (void*)pathbuf, (void*)NULL);
1060 * init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)pathbuf, (void*)NULL);
1061 * init_action(&test.t_cleanup_actions[1], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
1062 * execute_test(&test);
1063 *
1064 * makepath(pathbuf, DIR1, FILE1);
1065 * init_test(&test, "3.1.3: add a file to a directory with open()", DIR1, 1, 2, NOTE_EXTEND, YES_EVENT);
1066 * init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1067 * init_action(&test.t_helpthreadact, SLEEP, CREAT, 2, (void*)pathbuf, (void*)NULL);
1068 * init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)pathbuf, (void*)NULL);
1069 * init_action(&test.t_cleanup_actions[1], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
1070 * execute_test(&test);
1071 *
1072 * makepath(pathbuf, DIR1, FILE1);
1073 * init_test(&test, "3.1.4: add a file to a directory with rename()", DIR1, 2, 2, NOTE_EXTEND, YES_EVENT);
1074 * init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1075 * init_action(&(test.t_prep_actions[1]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1076 * init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)FILE1, (void*)pathbuf);
1077 * init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)pathbuf, (void*)NULL);
1078 * init_action(&test.t_cleanup_actions[1], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
1079 * execute_test(&test);
1080 */
1081
1082 /* 3.1.5: a placeholder for a potential kernel test */
1083 /*
1084 * makepath(pathbuf, DIR1, DIR2);
1085 * init_test(&test, "3.1.6: add a file to a directory with mkdir()", DIR1, 1, 2, NOTE_EXTEND, YES_EVENT);
1086 * init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1087 * init_action(&test.t_helpthreadact, SLEEP, MKDIR, 2, (void*)pathbuf, (void*)NULL);
1088 * init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)pathbuf, (void*)NULL);
1089 * init_action(&test.t_cleanup_actions[1], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
1090 * execute_test(&test);
1091 */
1092 init_test(&test, "3.1.7: lengthen a file with truncate()", FILE1, 1, 1, NOTE_EXTEND, YES_EVENT);
1093 test.t_nondeterministic = 1;
1094 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1095 init_action(&test.t_helpthreadact, SLEEP, LENGTHEN, 2, FILE1, (void*)NULL);
1096 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, (void*)NULL);
1097 execute_test(&test);
1098
1099
1100 /** ========== NO EVENT SECTION ============== **/
1101 init_test(&test, "3.2.1: setxattr() a file", FILE1, 1, 1, NOTE_EXTEND, NO_EVENT);
1102 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1103 init_action(&test.t_helpthreadact, SLEEP, SETXATTR, 2, FILE1, (void*)NULL);
1104 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, (void*)NULL);
1105 execute_test(&test);
1106
1107 init_test(&test, "3.2.2: chmod a file", FILE1, 1, 1, NOTE_EXTEND, NO_EVENT);
1108 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1109 init_action(&test.t_helpthreadact, SLEEP, CHMOD, 2, (void*)FILE1, (void*)0700);
1110 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, (void*)NULL);
1111 execute_test(&test);
1112
1113 struct passwd *pwd = getpwnam("local");
1114 if (pwd != NULL) {
1115 init_test(&test, "3.2.3: chown a file", FILE1, 2, 1, NOTE_EXTEND, NO_EVENT);
1116 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1117 init_action(&test.t_prep_actions[1], NOSLEEP, CHOWN, 3, (void*)FILE1, (void*)pwd->pw_uid, (void*)pwd->pw_gid);
1118 init_action(&test.t_helpthreadact, SLEEP, CHOWN, 3, (void*)FILE1, (void*)getuid(), (void*)getgid());
1119 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, (void*)NULL);
1120 execute_test(&test);
1121 } else {
1122 T_LOG("Couldn't getpwnam for user \"local\"\n");
1123 }
1124
1125 init_test(&test, "3.2.4: chmod a dir", DIR1, 1, 1, NOTE_EXTEND, NO_EVENT);
1126 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1127 init_action(&test.t_helpthreadact, SLEEP, CHMOD, 2, (void*)DIR1, (void*)0700);
1128 init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
1129 execute_test(&test);
1130
1131 if (pwd != NULL) {
1132 init_test(&test, "3.2.5: chown a dir", DIR1, 2, 1, NOTE_EXTEND, NO_EVENT);
1133 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1134 init_action(&test.t_prep_actions[1], NOSLEEP, CHOWN, 3, (void*)DIR1, (void*)pwd->pw_uid, (void*)pwd->pw_gid);
1135 init_action(&test.t_helpthreadact, SLEEP, CHOWN, 3, (void*)DIR1, (void*)getuid(), (void*)getgid());
1136 init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
1137 execute_test(&test);
1138 }
1139
1140 init_test(&test, "3.2.6: TRUNC a file with truncate()", FILE1, 1, 1, NOTE_EXTEND, NO_EVENT);
1141 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1142 init_action(&test.t_helpthreadact, SLEEP, TRUNC, 2, FILE1, (void*)NULL);
1143 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, (void*)NULL);
1144 execute_test(&test);
1145 }
1146
1147 void
1148 run_note_attrib_tests()
1149 {
1150 test_t test;
1151 char pathbuf[50];
1152
1153 init_test(&test, "4.1.1: chmod a file", FILE1, 1, 1, NOTE_ATTRIB, YES_EVENT);
1154 test.t_nondeterministic = 1;
1155 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1156 init_action(&test.t_helpthreadact, SLEEP, CHMOD, 2, FILE1, (void*)0700);
1157 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, (void*)NULL);
1158 execute_test(&test);
1159
1160 struct passwd *pwd = getpwnam("local");
1161 if (pwd != NULL) {
1162 init_test(&test, "4.1.2: chown a file", FILE1, 2, 1, NOTE_ATTRIB, YES_EVENT);
1163 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1164 init_action(&(test.t_prep_actions[1]), NOSLEEP, CHOWN, 3, (void*)FILE1, (void*)pwd->pw_uid, (void*)pwd->pw_gid);
1165 init_action(&test.t_helpthreadact, SLEEP, CHOWN, 3, FILE1, (void*)getuid(), (void*)pwd->pw_gid);
1166 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, (void*)NULL);
1167 execute_test(&test);
1168 }
1169
1170 init_test(&test, "4.1.3: chmod a dir", DIR1, 1, 1, NOTE_ATTRIB, YES_EVENT);
1171 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1172 init_action(&(test.t_helpthreadact), SLEEP, CHMOD, 2, (void*)DIR1, (void*)0700);
1173 init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
1174 execute_test(&test);
1175
1176 if (pwd != NULL) {
1177 init_test(&test, "4.1.4: chown a dir", DIR1, 2, 1, NOTE_ATTRIB, YES_EVENT);
1178 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1179 init_action(&(test.t_prep_actions[1]), NOSLEEP, CHOWN, 3, (void*)DIR1, (void*) pwd->pw_uid, (void*)pwd->pw_gid);
1180 init_action(&test.t_helpthreadact, SLEEP, CHOWN, 3, DIR1, (void*)getuid(), (void*)getgid());
1181 init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
1182 execute_test(&test);
1183 }
1184
1185 init_test(&test, "4.1.5: setxattr on a file", FILE1, 1, 1, NOTE_ATTRIB, YES_EVENT);
1186 test.t_nondeterministic = 1;
1187 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1188 init_action(&test.t_helpthreadact, SLEEP, SETXATTR, 2, (void*)FILE1, (void*)NULL);
1189 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, (void*)NULL);
1190 execute_test(&test);
1191
1192 init_test(&test, "4.1.6: setxattr on a dir", DIR1, 1, 1, NOTE_ATTRIB, YES_EVENT);
1193 test.t_nondeterministic = 1;
1194 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1195 init_action(&test.t_helpthreadact, SLEEP, SETXATTR, 2, (void*)DIR1, (void*)NULL);
1196 init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
1197 execute_test(&test);
1198
1199 /* exchangedata is not supported on APFS volumes */
1200 if (!path_on_apfs(PDIR)) {
1201 init_test(&test, "4.1.7: exchangedata", FILE1, 2, 2, NOTE_ATTRIB, YES_EVENT);
1202 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1203 init_action(&(test.t_prep_actions[1]), NOSLEEP, CREAT, 2, (void*)FILE2, (void*)NULL);
1204 init_action(&test.t_helpthreadact, SLEEP, EXCHANGEDATA, 2, (void*)FILE1, (void*)FILE2);
1205 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, (void*)NULL);
1206 init_action(&test.t_cleanup_actions[1], NOSLEEP, UNLINK, 2, (void*)FILE2, (void*)NULL);
1207 execute_test(&test);
1208 }
1209
1210 init_test(&test, "4.1.8: utimes on a file", FILE1, 1, 1, NOTE_ATTRIB, YES_EVENT);
1211 test.t_nondeterministic = 1;
1212 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1213 init_action(&test.t_helpthreadact, SLEEP, UTIMES, 2, (void*)FILE1, (void*)NULL);
1214 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, (void*)NULL);
1215 execute_test(&test);
1216
1217 init_test(&test, "4.1.9: utimes on a dir", DIR1, 1, 1, NOTE_ATTRIB, YES_EVENT);
1218 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1219 init_action(&test.t_helpthreadact, SLEEP, UTIMES, 2, (void*)DIR1, (void*)NULL);
1220 init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
1221 execute_test(&test);
1222
1223
1224 /* ====== NO EVENT TESTS ========== */
1225
1226 init_test(&test, "4.2.1: rename a file", FILE1, 1, 1, NOTE_ATTRIB, NO_EVENT);
1227 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1228 init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)FILE1, (void*)FILE2);
1229 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE2, NULL);
1230 execute_test(&test);
1231
1232 init_test(&test, "4.2.2: open (do not change) a file", FILE1, 1, 1, NOTE_ATTRIB, NO_EVENT);
1233 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1234 init_action(&test.t_helpthreadact, SLEEP, OPEN, 2, (void*)FILE1, NULL);
1235 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
1236 execute_test(&test);
1237
1238 init_test(&test, "4.2.3: stat a file", FILE1, 1, 1, NOTE_ATTRIB, NO_EVENT);
1239 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1240 init_action(&test.t_helpthreadact, SLEEP, STAT, 2, (void*)FILE1, NULL);
1241 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
1242 execute_test(&test);
1243
1244 init_test(&test, "4.2.4: unlink a file", FILE1, 1, 0, NOTE_ATTRIB, NO_EVENT);
1245 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1246 init_action(&test.t_helpthreadact, SLEEP, UNLINK, 2, (void*)FILE1, NULL);
1247 execute_test(&test);
1248
1249 init_test(&test, "4.2.5: write to a file", FILE1, 1, 1, NOTE_ATTRIB, NO_EVENT);
1250 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1251 init_action(&test.t_helpthreadact, SLEEP, WRITE, 2, (void*)FILE1, (void*)NULL);
1252 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, (void*)NULL);
1253 execute_test(&test);
1254
1255 T_LOG("EXPECT SPURIOUS NOTE_ATTRIB EVENTS FROM DIRECTORY OPERATIONS on HFS.\n");
1256 init_test(&test, "4.2.6: add a file to a directory with creat()", DIR1, 1, 2, NOTE_ATTRIB, NO_EVENT);
1257 test.t_known_failure = 1;
1258 makepath(pathbuf, DIR1, FILE1);
1259 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1260 init_action(&test.t_helpthreadact, SLEEP, CREAT, 2, (void*)pathbuf, (void*)NULL);
1261 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)pathbuf, (void*)NULL);
1262 init_action(&test.t_cleanup_actions[1], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
1263 execute_test(&test);
1264
1265 init_test(&test, "4.2.7: mkdir in a dir", DIR1, 1, 2, NOTE_ATTRIB, NO_EVENT);
1266 test.t_known_failure = 1;
1267 makepath(pathbuf, DIR1, DIR2);
1268 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1269 init_action(&test.t_helpthreadact, SLEEP, MKDIR, 2, (void*)pathbuf, (void*)NULL);
1270 init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)pathbuf, (void*)NULL);
1271 init_action(&test.t_cleanup_actions[1], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
1272 execute_test(&test);
1273
1274 init_test(&test, "4.2.8: add a symlink to a directory", DIR1, 1, 2, NOTE_ATTRIB, NO_EVENT);
1275 test.t_known_failure = 1;
1276 makepath(pathbuf, DIR1, FILE1);
1277 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1278 init_action(&test.t_helpthreadact, SLEEP, SYMLINK, 2, (void*)DOTDOT, (void*)pathbuf);
1279 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)pathbuf, (void*)NULL);
1280 init_action(&test.t_cleanup_actions[1], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
1281 execute_test(&test);
1282
1283 init_test(&test, "4.2.9: rename into a dir()", DIR1, 2, 2, NOTE_ATTRIB, NO_EVENT);
1284 test.t_known_failure = 1;
1285 makepath(pathbuf, DIR1, FILE1);
1286 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1287 init_action(&(test.t_prep_actions[1]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1288 init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)FILE1, (void*)pathbuf);
1289 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)pathbuf, (void*)NULL);
1290 init_action(&test.t_cleanup_actions[1], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
1291 execute_test(&test);
1292
1293 init_test(&test, "4.2.10: unlink() file from dir", DIR1, 2, 1, NOTE_ATTRIB, NO_EVENT);
1294 test.t_known_failure = 1;
1295 makepath(pathbuf, DIR1, FILE1);
1296 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1297 init_action(&(test.t_prep_actions[1]), NOSLEEP, CREAT, 2, (void*)pathbuf, (void*)NULL);
1298 init_action(&test.t_helpthreadact, SLEEP, UNLINK, 2, (void*)pathbuf, (void*)NULL);
1299 init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
1300 execute_test(&test);
1301
1302 init_test(&test, "4.2.11: mkfifo in a directory", DIR1, 1, 2, NOTE_ATTRIB, NO_EVENT);
1303 test.t_known_failure = 1;
1304 makepath(pathbuf, DIR1, FILE1);
1305 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1306 init_action(&test.t_helpthreadact, SLEEP, MKFIFO, 1, (void*)pathbuf);
1307 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)pathbuf, (void*)NULL);
1308 init_action(&test.t_cleanup_actions[1], NOSLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
1309 execute_test(&test);
1310 }
1311
1312
1313 void
1314 run_note_link_tests()
1315 {
1316 test_t test;
1317 char pathbuf[50];
1318 char otherpathbuf[50];
1319
1320 T_LOG("HFS DOES NOT HANDLE UNLINK CORRECTLY...\n");
1321 init_test(&test, "5.1.1: unlink() a file", FILE1, 1, 0, NOTE_LINK, YES_EVENT);
1322 test.t_nondeterministic = 1;
1323 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1324 init_action(&test.t_helpthreadact, SLEEP, UNLINK, 2, (void*)FILE1, (void*)NULL);
1325 execute_test(&test);
1326
1327
1328 init_test(&test, "5.1.1.5: link A to B, watch A, remove B", FILE1, 2, 1, NOTE_LINK, YES_EVENT);
1329 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1330 init_action(&(test.t_prep_actions[1]), NOSLEEP, HARDLINK, 2, (void*)FILE1, (void*)FILE2);
1331 init_action(&test.t_helpthreadact, SLEEP, UNLINK, 2, (void*)FILE2, (void*)NULL);
1332 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
1333 execute_test(&test);
1334
1335 init_test(&test, "5.1.2: link() to a file", FILE1, 1, 2, NOTE_LINK, YES_EVENT);
1336 #if TARGET_OS_WATCH
1337 test.t_nondeterministic = 1;
1338 #endif
1339 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1340 init_action(&test.t_helpthreadact, SLEEP, HARDLINK, 2, (void*)FILE1, (void*)FILE2);
1341 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
1342 init_action(&test.t_cleanup_actions[1], NOSLEEP, UNLINK, 2, (void*)FILE2, NULL);
1343 execute_test(&test);
1344
1345 makepath(pathbuf, DIR1, DIR2);
1346 init_test(&test, "5.1.3: make one dir in another", DIR1, 1, 2, NOTE_LINK, YES_EVENT);
1347 test.t_known_failure = 1;
1348 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1349 init_action(&test.t_helpthreadact, SLEEP, MKDIR, 2, (void*)pathbuf, (void*)NULL);
1350 init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)pathbuf, NULL);
1351 init_action(&test.t_cleanup_actions[1], NOSLEEP, RMDIR, 2, (void*)DIR1, NULL);
1352 execute_test(&test);
1353
1354 makepath(pathbuf, DIR1, DIR2);
1355 init_test(&test, "5.1.4: rmdir a dir from within another", DIR1, 2, 1, NOTE_LINK, YES_EVENT);
1356 test.t_known_failure = 1;
1357 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1358 init_action(&(test.t_prep_actions[1]), NOSLEEP, MKDIR, 2, (void*)pathbuf, (void*)NULL);
1359 init_action(&test.t_helpthreadact, SLEEP, RMDIR, 2, (void*)pathbuf, (void*)NULL);
1360 init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)DIR1, NULL);
1361 execute_test(&test);
1362
1363 makepath(pathbuf, DIR1, DIR2);
1364 makepath(otherpathbuf, DIR1, DIR1);
1365 init_test(&test, "5.1.5: rename dir A over dir B inside dir C", DIR1, 3, 2, NOTE_LINK, YES_EVENT);
1366 test.t_known_failure = 1;
1367 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1368 init_action(&(test.t_prep_actions[1]), NOSLEEP, MKDIR, 2, (void*)pathbuf, (void*)NULL);
1369 init_action(&(test.t_prep_actions[2]), NOSLEEP, MKDIR, 2, (void*)otherpathbuf, (void*)NULL);
1370 init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)pathbuf, (void*)otherpathbuf);
1371 init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)otherpathbuf, NULL);
1372 init_action(&test.t_cleanup_actions[1], NOSLEEP, RMDIR, 2, (void*)DIR1, NULL);
1373 execute_test(&test);
1374
1375 T_LOG("HFS bypasses hfs_makenode to create in target, so misses knote.\n");
1376 makepath(pathbuf, DIR1, DIR2);
1377 init_test(&test, "5.1.6: rename one dir into another", DIR1, 2, 2, NOTE_LINK, YES_EVENT);
1378 test.t_known_failure = 1;
1379 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1380 init_action(&(test.t_prep_actions[1]), NOSLEEP, MKDIR, 2, (void*)DIR2, (void*)NULL);
1381 init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)DIR2, (void*)pathbuf);
1382 init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)pathbuf, NULL);
1383 init_action(&test.t_cleanup_actions[1], NOSLEEP, RMDIR, 2, (void*)DIR1, NULL);
1384 execute_test(&test);
1385
1386 T_LOG("HFS bypasses hfs_removedir to remove from source, so misses knote.\n");
1387 makepath(pathbuf, DIR1, DIR2);
1388 init_test(&test, "5.1.7: rename one dir out of another", DIR1, 2, 2, NOTE_LINK, YES_EVENT);
1389 test.t_known_failure = 1;
1390 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1391 init_action(&(test.t_prep_actions[1]), NOSLEEP, MKDIR, 2, (void*)pathbuf, (void*)NULL);
1392 init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)pathbuf, (void*)DIR2);
1393 init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)DIR2, NULL);
1394 init_action(&test.t_cleanup_actions[1], NOSLEEP, RMDIR, 2, (void*)DIR1, NULL);
1395 execute_test(&test);
1396
1397 init_test(&test, "5.1.8: rmdir a dir", DIR1, 1, 0, NOTE_LINK, YES_EVENT);
1398 test.t_nondeterministic = 1;
1399 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1400 init_action(&test.t_helpthreadact, SLEEP, RMDIR, 2, (void*)DIR1, (void*)NULL);
1401 execute_test(&test);
1402
1403 /* ============= NO EVENT SECTION ============== */
1404 makepath(pathbuf, DIR1, FILE1);
1405 init_test(&test, "5.2.1: make a file in a dir", DIR1, 1, 2, NOTE_LINK, NO_EVENT);
1406 test.t_known_failure = 1;
1407 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1408 init_action(&test.t_helpthreadact, SLEEP, CREAT, 2, (void*)pathbuf, (void*)NULL);
1409 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)pathbuf, NULL);
1410 init_action(&test.t_cleanup_actions[1], NOSLEEP, RMDIR, 2, (void*)DIR1, NULL);
1411 execute_test(&test);
1412
1413 makepath(pathbuf, DIR1, FILE1);
1414 init_test(&test, "5.2.2: unlink a file in a dir", DIR1, 2, 1, NOTE_LINK, NO_EVENT);
1415 test.t_known_failure = 1;
1416 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1417 init_action(&(test.t_prep_actions[1]), NOSLEEP, CREAT, 2, (void*)pathbuf, (void*)NULL);
1418 init_action(&test.t_helpthreadact, SLEEP, UNLINK, 2, (void*)pathbuf, (void*)NULL);
1419 init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)DIR1, NULL);
1420 execute_test(&test);
1421
1422 makepath(pathbuf, DIR1, FILE1);
1423 makepath(otherpathbuf, DIR1, FILE2);
1424 init_test(&test, "5.2.3: rename a file within a dir", DIR1, 2, 2, NOTE_LINK, NO_EVENT);
1425 test.t_known_failure = 1;
1426 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1427 init_action(&(test.t_prep_actions[1]), NOSLEEP, CREAT, 2, (void*)pathbuf, (void*)NULL);
1428 init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)pathbuf, (void*)otherpathbuf);
1429 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)otherpathbuf, NULL);
1430 init_action(&test.t_cleanup_actions[1], NOSLEEP, RMDIR, 2, (void*)DIR1, NULL);
1431 execute_test(&test);
1432
1433 makepath(pathbuf, DIR1, FILE1);
1434 init_test(&test, "5.2.4: rename a file into a dir", DIR1, 2, 2, NOTE_LINK, NO_EVENT);
1435 test.t_known_failure = 1;
1436 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1437 init_action(&(test.t_prep_actions[1]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1438 init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)FILE1, (void*)pathbuf);
1439 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)pathbuf, NULL);
1440 init_action(&test.t_cleanup_actions[1], NOSLEEP, RMDIR, 2, (void*)DIR1, NULL);
1441 execute_test(&test);
1442
1443 makepath(pathbuf, DIR1, FILE1);
1444 init_test(&test, "5.2.5: make a symlink in a dir", DIR1, 1, 2, NOTE_LINK, NO_EVENT);
1445 test.t_known_failure = 1;
1446 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1447 init_action(&test.t_helpthreadact, SLEEP, SYMLINK, 2, (void*)DOTDOT, (void*)pathbuf);
1448 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)pathbuf, NULL);
1449 init_action(&test.t_cleanup_actions[1], NOSLEEP, RMDIR, 2, (void*)DIR1, NULL);
1450 execute_test(&test);
1451
1452 init_test(&test, "5.2.6: make a symlink to a dir", DIR1, 1, 2, NOTE_LINK, NO_EVENT);
1453 test.t_known_failure = 1;
1454 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1455 init_action(&test.t_helpthreadact, SLEEP, SYMLINK, 2, (void*)DIR1, (void*)FILE1);
1456 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
1457 init_action(&test.t_cleanup_actions[1], NOSLEEP, RMDIR, 2, (void*)DIR1, NULL);
1458 execute_test(&test);
1459
1460 init_test(&test, "5.2.7: make a symlink to a file", FILE1, 1, 2, NOTE_LINK, NO_EVENT);
1461 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1462 init_action(&test.t_helpthreadact, SLEEP, SYMLINK, 2, (void*)FILE1, (void*)FILE2);
1463 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE2, NULL);
1464 init_action(&test.t_cleanup_actions[1], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
1465 execute_test(&test);
1466 }
1467
1468 void
1469 run_note_rename_tests()
1470 {
1471 test_t test;
1472
1473 init_test(&test, "6.1.1: rename a file", FILE1, 1, 1, NOTE_RENAME, YES_EVENT);
1474 test.t_nondeterministic = 1;
1475 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1476 init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)FILE1, (void*)FILE2);
1477 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE2, NULL);
1478 execute_test(&test);
1479
1480 init_test(&test, "6.1.2: rename a dir", DIR1, 1, 1, NOTE_RENAME, YES_EVENT);
1481 test.t_nondeterministic = 1;
1482 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1483 init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)DIR1, (void*)DIR2);
1484 init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)DIR2, NULL);
1485 execute_test(&test);
1486
1487 init_test(&test, "6.1.3: rename one file over another", FILE1, 2, 1, NOTE_RENAME, YES_EVENT);
1488 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1489 init_action(&(test.t_prep_actions[1]), NOSLEEP, CREAT, 2, (void*)FILE2, (void*)NULL);
1490 init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)FILE1, (void*)FILE2);
1491 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE2, NULL);
1492 execute_test(&test);
1493
1494 init_test(&test, "6.1.4: rename one dir over another", DIR1, 2, 1, NOTE_RENAME, YES_EVENT);
1495 test.t_nondeterministic = 1;
1496 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1497 init_action(&(test.t_prep_actions[1]), NOSLEEP, MKDIR, 2, (void*)DIR2, (void*)NULL);
1498 init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)DIR1, (void*)DIR2);
1499 init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)DIR2, NULL);
1500 execute_test(&test);
1501
1502 /* ========= NO EVENT SECTION =========== */
1503
1504 init_test(&test, "6.2.1: unlink a file", FILE1, 1, 0, NOTE_RENAME, NO_EVENT);
1505 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1506 init_action(&test.t_helpthreadact, SLEEP, UNLINK, 2, (void*)FILE1, NULL);
1507 execute_test(&test);
1508
1509 init_test(&test, "6.2.2: rmdir a dir", DIR1, 1, 0, NOTE_RENAME, NO_EVENT);
1510 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1511 init_action(&test.t_helpthreadact, SLEEP, RMDIR, 2, (void*)DIR1, NULL);
1512 execute_test(&test);
1513
1514 init_test(&test, "6.2.3: link() to a file", FILE1, 1, 2, NOTE_RENAME, NO_EVENT);
1515 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1516 init_action(&test.t_helpthreadact, SLEEP, HARDLINK, 2, (void*)FILE1, (void*)FILE2);
1517 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
1518 init_action(&test.t_cleanup_actions[1], NOSLEEP, UNLINK, 2, (void*)FILE2, NULL);
1519 execute_test(&test);
1520
1521 init_test(&test, "6.2.4: rename one file over another: watch deceased",
1522 FILE2, 2, 1, NOTE_RENAME, NO_EVENT);
1523 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1524 init_action(&(test.t_prep_actions[1]), NOSLEEP, CREAT, 2, (void*)FILE2, (void*)NULL);
1525 init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)FILE1, (void*)FILE2);
1526 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE2, NULL);
1527 execute_test(&test);
1528
1529 init_test(&test, "6.2.5: rename one dir over another: watch deceased",
1530 DIR2, 2, 1, NOTE_RENAME, NO_EVENT);
1531 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1532 init_action(&(test.t_prep_actions[1]), NOSLEEP, MKDIR, 2, (void*)DIR2, (void*)NULL);
1533 init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)DIR1, (void*)DIR2);
1534 init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)DIR2, NULL);
1535 execute_test(&test);
1536
1537 init_test(&test, "6.2.6: rename a file to itself", FILE1, 1, 1, NOTE_RENAME, NO_EVENT);
1538 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1539 init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)FILE1, (void*)FILE1);
1540 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
1541 execute_test(&test);
1542
1543 init_test(&test, "6.2.7: rename a dir to itself", DIR1, 1, 1, NOTE_RENAME, NO_EVENT);
1544 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKDIR, 2, (void*)DIR1, (void*)NULL);
1545 init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)DIR1, (void*)DIR1);
1546 init_action(&test.t_cleanup_actions[0], NOSLEEP, RMDIR, 2, (void*)DIR1, NULL);
1547 execute_test(&test);
1548 }
1549
1550 void
1551 run_note_revoke_tests()
1552 {
1553 test_t test;
1554 init_test(&test, "7.1.1: revoke file", FILE1, 1, 1, NOTE_REVOKE, YES_EVENT);
1555 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 1, (void*)FILE1);
1556 init_action(&test.t_helpthreadact, SLEEP, REVOKE, 1, (void*)FILE1);
1557 init_action(&(test.t_cleanup_actions[0]), NOSLEEP, UNLINK, 1, (void*)FILE1);
1558 execute_test(&test);
1559
1560 init_test(&test, "7.2.1: delete file", FILE1, 1, 0, NOTE_REVOKE, NO_EVENT);
1561 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 1, (void*)FILE1);
1562 init_action(&test.t_helpthreadact, SLEEP, UNLINK, 1, (void*)FILE1);
1563 execute_test(&test);
1564 }
1565
1566
1567 void
1568 run_evfilt_read_tests()
1569 {
1570 test_t test;
1571 init_test(&test, "8.1.1: how much data in file of length LENGTHEN_SIZE?", FILE1, 2, 1, EVFILT_READ, LENGTHEN_SIZE);
1572 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void*)NULL);
1573 init_action(&(test.t_prep_actions[1]), NOSLEEP, LENGTHEN, 2, (void*)FILE1, (void*)NULL);
1574 init_action(&test.t_helpthreadact, SLEEP, NOTHING, 0);
1575 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
1576 execute_test(&test);
1577
1578 init_test(&test, "8.1.2: block, then write to file", FILE1, 2, 1, EVFILT_READ, strlen(TEST_STRING));
1579 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 1, (void*)FILE1);
1580 init_action(&(test.t_prep_actions[1]), NOSLEEP, TRUNC, 1, (void*)FILE1);
1581 init_action(&test.t_helpthreadact, SLEEP, WRITE, 1, (void*)FILE1);
1582 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
1583 execute_test(&test);
1584
1585 init_test(&test, "8.1.3: block, then extend", FILE1, 2, 1, EVFILT_READ, LENGTHEN_SIZE);
1586 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 1, (void*)FILE1);
1587 init_action(&(test.t_prep_actions[1]), NOSLEEP, TRUNC, 1, (void*)FILE1);
1588 init_action(&test.t_helpthreadact, SLEEP, LENGTHEN, 1, (void*)FILE1);
1589 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
1590 execute_test(&test);
1591
1592 init_test(&test, "8.1.4: block, then seek to beginning", FILE1, 2, 1, EVFILT_READ, strlen(TEST_STRING));
1593 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 1, (void*)FILE1);
1594 init_action(&(test.t_prep_actions[1]), NOSLEEP, WRITE, 1, (void*)FILE1);
1595 test.t_read_to_end_first = 1; /* hack means that we've gotten to EOF before we block */
1596 init_action(&test.t_helpthreadact, SLEEP, LSEEK, 1, (void*)0);
1597 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
1598 execute_test(&test);
1599
1600
1601 init_test(&test, "8.1.5: block, then write to fifo", FILE1, 1, 1, EVFILT_READ, strlen(TEST_STRING));
1602 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKFIFO, 1, (void*)FILE1);
1603 test.t_file_is_fifo = 1;
1604 init_action(&test.t_helpthreadact, SLEEP, WRITE, 1, (void*)FILE1);
1605 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
1606 execute_test(&test);
1607
1608 /* No result section... */
1609 init_test(&test, "8.2.1: just rename", FILE1, 2, 1, EVFILT_READ, NO_EVENT);
1610 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 1, (void*)FILE1);
1611 init_action(&(test.t_prep_actions[1]), NOSLEEP, TRUNC, 1, (void*)FILE1);
1612 init_action(&test.t_helpthreadact, SLEEP, RENAME, 2, (void*)FILE1, (void*)FILE2);
1613 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE2, NULL);
1614 execute_test(&test);
1615
1616 init_test(&test, "8.2.2: delete file", FILE1, 2, 0, EVFILT_READ, NO_EVENT);
1617 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 1, (void*)FILE1);
1618 init_action(&(test.t_prep_actions[1]), NOSLEEP, TRUNC, 1, (void*)FILE1);
1619 init_action(&test.t_helpthreadact, SLEEP, UNLINK, 1, (void*)FILE1);
1620 execute_test(&test);
1621
1622 init_test(&test, "8.2.3: write to beginning", FILE1, 2, 1, EVFILT_READ, NO_EVENT);
1623 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 1, (void*)FILE1);
1624 init_action(&(test.t_prep_actions[1]), NOSLEEP, WRITE, 1, (void*)FILE1);
1625 test.t_read_to_end_first = 1; /* hack means that we've gotten to EOF before we block */
1626 init_action(&test.t_helpthreadact, SLEEP, WRITE, 1, (void*)FILE1);
1627 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 1, (void*)FILE1);
1628 execute_test(&test);
1629
1630 init_test(&test, "8.1.4: block, then seek to current location", FILE1, 2, 1, EVFILT_READ, 0);
1631 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 1, (void*)FILE1);
1632 init_action(&(test.t_prep_actions[1]), NOSLEEP, WRITE, 1, (void*)FILE1);
1633 test.t_read_to_end_first = 1; /* hack means that we've gotten to EOF before we block */
1634 init_action(&test.t_helpthreadact, SLEEP, LSEEK, 1, (void*)strlen(TEST_STRING));
1635 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
1636 execute_test(&test);
1637
1638 init_test(&test, "8.2.5: trying to read from empty fifo", FILE1, 1, 1, EVFILT_READ, 0);
1639 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKFIFO, 1, (void*)FILE1);
1640 test.t_file_is_fifo = 1;
1641 init_action(&test.t_helpthreadact, SLEEP, NOTHING, 1, (void*)0);
1642 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
1643 execute_test(&test);
1644 }
1645
1646
1647
1648 void*
1649 read_from_fd(void *arg)
1650 {
1651 char buf[50];
1652 int fd = (int) arg;
1653 usleep(USLEEP_TIME);
1654 return (void*) read(fd, buf, sizeof(buf));
1655 }
1656
1657 void*
1658 write_to_fd(void *arg)
1659 {
1660 char buf[50];
1661 int fd = (int) arg;
1662 usleep(USLEEP_TIME);
1663 return (void*) write(fd, buf, sizeof(buf));
1664 }
1665
1666 /*
1667 * We don't (in principle) support EVFILT_WRITE for vnodes; thusly, no tests here
1668 */
1669 void
1670 run_evfilt_write_tests()
1671 {
1672 test_t test;
1673 init_test(&test, "9.1.1: how much space in empty fifo?", FILE1, 1, 1, EVFILT_WRITE, FIFO_SPACE);
1674 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKFIFO, 1, (void*)FILE1, (void*)NULL);
1675 test.t_file_is_fifo = 1;
1676 init_action(&test.t_helpthreadact, SLEEP, NOTHING, 0);
1677 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
1678 execute_test(&test);
1679
1680 init_test(&test, "9.1.2: how much space in slightly written fifo?", FILE1, 1, 1, EVFILT_WRITE, FIFO_SPACE - strlen(TEST_STRING));
1681 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKFIFO, 1, (void*)FILE1, (void*)NULL);
1682 test.t_file_is_fifo = 1;
1683 test.t_write_some_data = 1;
1684 init_action(&(test.t_helpthreadact), NOSLEEP, NOTHING, 0);
1685 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
1686 execute_test(&test);
1687
1688 init_test(&test, "9.2.1: how much space in a full fifo?", FILE1, 1, 1, EVFILT_WRITE, 0);
1689 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKFIFO, 1, (void*)FILE1, (void*)NULL);
1690 test.t_nondeterministic = 1;
1691 test.t_file_is_fifo = 1;
1692 test.t_extra_sleep_hack = 1;
1693 init_action(&(test.t_helpthreadact), NOSLEEP, FILLFD, 1, (void*)FILE1, (void*)NULL);
1694 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
1695 execute_test(&test);
1696 }
1697
1698 void
1699 run_poll_tests()
1700 {
1701 test_t test;
1702 init_poll_test(&test, "10.1.1: does poll say I can write a regular file?", FILE1, 1, 1, POLLWRNORM, 1);
1703 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 1, (void*)FILE1, (void*)NULL);
1704 init_action(&test.t_helpthreadact, SLEEP, NOTHING, 0);
1705 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
1706 execute_test(&test);
1707
1708 init_poll_test(&test, "10.1.2: does poll say I can write an empty FIFO?", FILE1, 1, 1, POLLWRNORM, 1);
1709 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKFIFO, 1, (void*)FILE1, (void*)NULL);
1710 test.t_file_is_fifo = 1;
1711 init_action(&test.t_helpthreadact, SLEEP, NOTHING, 0);
1712 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
1713 execute_test(&test);
1714
1715 init_poll_test(&test, "10.1.3: does poll say I can read a nonempty FIFO?", FILE1, 1, 1, POLLRDNORM, 1);
1716 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKFIFO, 1, (void*)FILE1, (void*)NULL);
1717 test.t_file_is_fifo = 1;
1718 test.t_write_some_data = 1;
1719 init_action(&test.t_helpthreadact, SLEEP, NOTHING, 0);
1720 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
1721 execute_test(&test);
1722
1723 init_poll_test(&test, "10.1.4: does poll say I can read a nonempty regular file?", FILE1, 2, 1, POLLRDNORM, 1);
1724 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 1, (void*)FILE1, (void*)NULL);
1725 init_action(&(test.t_prep_actions[1]), NOSLEEP, LENGTHEN, 1, (void*)FILE1, (void*)NULL);
1726 init_action(&test.t_helpthreadact, SLEEP, NOTHING, 0);
1727 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
1728 execute_test(&test);
1729
1730 init_poll_test(&test, "10.1.5: does poll say I can read an empty file?", FILE1, 1, 1, POLLRDNORM, 1);
1731 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 1, (void*)FILE1, (void*)NULL);
1732 init_action(&test.t_helpthreadact, SLEEP, NOTHING, 0);
1733 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
1734 execute_test(&test);
1735
1736
1737
1738
1739 init_poll_test(&test, "10.2.2: does poll say I can read an empty FIFO?", FILE1, 1, 1, POLLRDNORM, 0);
1740 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKFIFO, 1, (void*)FILE1, (void*)NULL);
1741 test.t_file_is_fifo = 1;
1742 init_action(&test.t_helpthreadact, SLEEP, NOTHING, 0);
1743 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
1744 execute_test(&test);
1745
1746 init_poll_test(&test, "10.2.3: does poll say I can write a full FIFO?", FILE1, 1, 1, POLLWRNORM, 0);
1747 init_action(&(test.t_prep_actions[0]), NOSLEEP, MKFIFO, 1, (void*)FILE1, (void*)NULL);
1748 test.t_nondeterministic = 1;
1749 test.t_file_is_fifo = 1;
1750 test.t_extra_sleep_hack = 1;
1751 init_action(&(test.t_helpthreadact), NOSLEEP, FILLFD, 1, (void*)FILE1, (void*)NULL);
1752 init_action(&test.t_cleanup_actions[0], NOSLEEP, UNLINK, 2, (void*)FILE1, NULL);
1753 test.t_known_failure = 1;
1754 execute_test(&test);
1755 }
1756
1757 void
1758 run_note_funlock_tests()
1759 {
1760 test_t test;
1761 init_test(&test, "11.1.1: unlock file", FILE1, 1, 1, NOTE_FUNLOCK, YES_EVENT);
1762 test.t_nondeterministic = 1;
1763 init_action(&(test.t_prep_actions[0]), NOSLEEP, CREAT, 2, (void*)FILE1, (void *)NULL);
1764 init_action(&test.t_helpthreadact, SLEEP, FUNLOCK, 2, (void*)FILE1, (void *)NULL);
1765 init_action(&(test.t_cleanup_actions[0]), NOSLEEP, UNLINK, 2, (void*)FILE1, (void *)NULL);
1766 execute_test(&test);
1767 }
1768
1769 void
1770 run_all_tests()
1771 {
1772 run_note_delete_tests();
1773 run_note_write_tests();
1774 run_note_extend_tests();
1775 run_note_attrib_tests();
1776 run_note_link_tests();
1777 run_note_rename_tests();
1778 #if 0
1779 run_note_revoke_tests(); /* Can no longer revoke a regular file--need an unmount test */
1780 #endif /* 0 */
1781 run_evfilt_read_tests();
1782 run_evfilt_write_tests();
1783 run_poll_tests();
1784 run_note_funlock_tests();
1785 }
1786
1787 T_DECL(kqueue_file_tests,
1788 "Tests assorted kqueue operations for file-related events")
1789 {
1790 char *which = NULL;
1791 if (argc > 1) {
1792 which = argv[1];
1793 }
1794
1795 T_SETUPBEGIN;
1796 rmdir(DIR1);
1797 rmdir(DIR2);
1798 T_SETUPEND;
1799
1800 if ((!which) || (strcmp(which, "all") == 0)) {
1801 run_all_tests();
1802 } else if (strcmp(which, "delete") == 0) {
1803 run_note_delete_tests();
1804 } else if (strcmp(which, "write") == 0) {
1805 run_note_write_tests();
1806 } else if (strcmp(which, "extend") == 0) {
1807 run_note_extend_tests();
1808 } else if (strcmp(which, "attrib") == 0) {
1809 run_note_attrib_tests();
1810 } else if (strcmp(which, "link") == 0) {
1811 run_note_link_tests();
1812 } else if (strcmp(which, "rename") == 0) {
1813 run_note_rename_tests();
1814 } else if (strcmp(which, "revoke") == 0) {
1815 run_note_revoke_tests();
1816 } else if (strcmp(which, "evfiltread") == 0) {
1817 run_evfilt_read_tests();
1818 } else if (strcmp(which, "evfiltwrite") == 0) {
1819 run_evfilt_write_tests();
1820 } else if (strcmp(which, "poll") == 0) {
1821 run_poll_tests();
1822 } else if (strcmp(which, "funlock") == 0) {
1823 run_note_funlock_tests();
1824 } else {
1825 fprintf(stderr, "Valid options are:\n\tdelete, write, extend, "
1826 "attrib, link, rename, revoke, evfiltread, "
1827 "fifo, all, evfiltwrite, funlock<none>\n");
1828 exit(1);
1829 }
1830 }