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