xref: /xnu-11215/tests/kqueue_file_tests.c (revision 8d741a5d)
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 *
get_action_name(action_id_t a)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
init_action(action_t * act,int sleep,action_id_t call,int nargs,...)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 *
open_fifo_readside(void * arg)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
open_fifo(const char * path,int * readfd,int * writefd)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
makepath(char * buf,const char * dir,const char * file)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*
execute_action(void * actionptr)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
read_to_end(int fd)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
execute_action_list(action_t * actions,int nactions,int failout)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
execute_test(test_t * test)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
init_test_common(test_t * tst,char * testname,char * watchfile,int nprep,int nclean,int event,int want,int ispoll)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
init_test(test_t * tst,char * testname,char * watchfile,int nprep,int nclean,int event,int want)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
init_poll_test(test_t * tst,char * testname,char * watchfile,int nprep,int nclean,int event,int want)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
run_note_delete_tests()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
path_on_apfs(const char * path)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
run_note_write_tests()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
run_note_extend_tests()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
run_note_attrib_tests()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
run_note_link_tests()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
run_note_rename_tests()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
run_note_revoke_tests()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
run_evfilt_read_tests()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*
read_from_fd(void * arg)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*
write_to_fd(void * arg)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
run_evfilt_write_tests()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
run_poll_tests()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
run_note_funlock_tests()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
run_all_tests()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", T_META_TAG_VM_PREFERRED)
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 }
1831