11 * Test cases for events triggered by manipulating a target directory
12 * content. Using EVFILT_VNODE filter on the target directory descriptor.
16 static const char *dir_target
= "foo";
17 static const char *dir_inside1
= "foo/bar1";
18 static const char *dir_inside2
= "foo/bar2";
19 static const char *dir_outside
= "bar";
20 static const char *file_inside1
= "foo/baz1";
21 static const char *file_inside2
= "foo/baz2";
22 static const char *file_outside
= "qux";
23 static const struct timespec ts
= {0, 0};
25 static int target
= -1;
27 int init_target(void);
28 int init_kqueue(void);
29 int create_file(const char *);
35 if (mkdir(dir_target
, S_IRWXU
) < 0) {
38 target
= open(dir_target
, O_RDONLY
, 0);
45 struct kevent eventlist
[1];
51 EV_SET(&eventlist
[0], (uintptr_t)target
, EVFILT_VNODE
,
52 EV_ADD
| EV_ONESHOT
, NOTE_DELETE
|
53 NOTE_WRITE
| NOTE_EXTEND
| NOTE_ATTRIB
|
54 NOTE_LINK
| NOTE_RENAME
| NOTE_REVOKE
, 0, 0);
55 return kevent(kq
, eventlist
, 1, NULL
, 0, NULL
);
59 create_file(const char *file
)
63 fd
= open(file
, O_WRONLY
| O_CREAT
, S_IRUSR
| S_IWUSR
);
73 (void)unlink(file_inside1
);
74 (void)unlink(file_inside2
);
75 (void)unlink(file_outside
);
76 (void)rmdir(dir_inside1
);
77 (void)rmdir(dir_inside2
);
78 (void)rmdir(dir_outside
);
79 (void)rmdir(dir_target
);
84 ATF_TC_WITH_CLEANUP(dir_no_note_link_create_file_in
);
85 ATF_TC_HEAD(dir_no_note_link_create_file_in
, tc
)
87 atf_tc_set_md_var(tc
, "descr", "This test case ensures "
88 "that kevent(2) does not return NOTE_LINK for the directory "
89 "'foo' if a file 'foo/baz' is created.");
91 ATF_TC_BODY(dir_no_note_link_create_file_in
, tc
)
93 struct kevent changelist
[1];
95 ATF_REQUIRE(init_target() != -1);
96 ATF_REQUIRE(init_kqueue() != -1);
98 ATF_REQUIRE(create_file(file_inside1
) != -1);
99 ATF_REQUIRE(kevent(kq
, NULL
, 0, changelist
, 1, &ts
) != -1);
100 ATF_CHECK_EQ(changelist
[0].fflags
& NOTE_LINK
, 0);
102 ATF_TC_CLEANUP(dir_no_note_link_create_file_in
, tc
)
107 ATF_TC_WITH_CLEANUP(dir_no_note_link_delete_file_in
);
108 ATF_TC_HEAD(dir_no_note_link_delete_file_in
, tc
)
110 atf_tc_set_md_var(tc
, "descr", "This test case ensures "
111 "that kevent(2) does not return NOTE_LINK for the directory "
112 "'foo' if a file 'foo/baz' is deleted.");
114 ATF_TC_BODY(dir_no_note_link_delete_file_in
, tc
)
116 struct kevent changelist
[1];
118 ATF_REQUIRE(init_target() != -1);
119 ATF_REQUIRE(create_file(file_inside1
) != -1);
120 ATF_REQUIRE(init_kqueue() != -1);
122 ATF_REQUIRE(unlink(file_inside1
) != -1);
123 ATF_REQUIRE(kevent(kq
, NULL
, 0, changelist
, 1, &ts
) != -1);
124 ATF_CHECK_EQ(changelist
[0].fflags
& NOTE_LINK
, 0);
126 ATF_TC_CLEANUP(dir_no_note_link_delete_file_in
, tc
)
131 ATF_TC_WITH_CLEANUP(dir_no_note_link_mv_dir_within
);
132 ATF_TC_HEAD(dir_no_note_link_mv_dir_within
, tc
)
134 atf_tc_set_md_var(tc
, "descr", "This test case ensures "
135 "that kevent(2) does not return NOTE_LINK for the directory "
136 "'foo' if a directory 'foo/bar' is renamed to 'foo/baz'.");
138 ATF_TC_BODY(dir_no_note_link_mv_dir_within
, tc
)
140 struct kevent changelist
[1];
142 ATF_REQUIRE(init_target() != -1);
143 ATF_REQUIRE(mkdir(dir_inside1
, S_IRWXU
) != -1);
144 ATF_REQUIRE(init_kqueue() != -1);
146 ATF_REQUIRE(rename(dir_inside1
, dir_inside2
) != -1);
147 ATF_REQUIRE(kevent(kq
, NULL
, 0, changelist
, 1, &ts
) != -1);
148 ATF_CHECK_EQ(changelist
[0].fflags
& NOTE_LINK
, 0);
150 ATF_TC_CLEANUP(dir_no_note_link_mv_dir_within
, tc
)
155 ATF_TC_WITH_CLEANUP(dir_no_note_link_mv_file_within
);
156 ATF_TC_HEAD(dir_no_note_link_mv_file_within
, tc
)
158 atf_tc_set_md_var(tc
, "descr", "This test case ensures "
159 "that kevent(2) does not return NOTE_LINK for the directory "
160 "'foo' if a file 'foo/baz' is renamed to 'foo/qux'.");
162 ATF_TC_BODY(dir_no_note_link_mv_file_within
, tc
)
164 struct kevent changelist
[1];
166 ATF_REQUIRE(init_target() != -1);
167 ATF_REQUIRE(create_file(file_inside1
) != -1);
168 ATF_REQUIRE(init_kqueue() != -1);
170 ATF_REQUIRE(rename(file_inside1
, file_inside2
) != -1);
171 ATF_REQUIRE(kevent(kq
, NULL
, 0, changelist
, 1, &ts
) != -1);
172 ATF_CHECK_EQ(changelist
[0].fflags
& NOTE_LINK
, 0);
174 ATF_TC_CLEANUP(dir_no_note_link_mv_file_within
, tc
)
179 ATF_TC_WITH_CLEANUP(dir_note_link_create_dir_in
);
180 ATF_TC_HEAD(dir_note_link_create_dir_in
, tc
)
182 atf_tc_set_md_var(tc
, "descr", "This test case ensures "
183 "that kevent(2) returns NOTE_LINK for the directory "
184 "'foo' if a directory 'foo/bar' is created.");
186 ATF_TC_BODY(dir_note_link_create_dir_in
, tc
)
188 struct kevent changelist
[1];
190 ATF_REQUIRE(init_target() != -1);
191 ATF_REQUIRE(init_kqueue() != -1);
193 ATF_REQUIRE(mkdir(dir_inside1
, S_IRWXU
) != -1);
194 ATF_REQUIRE(kevent(kq
, NULL
, 0, changelist
, 1, &ts
) != -1);
195 ATF_CHECK_EQ(changelist
[0].fflags
& NOTE_LINK
, NOTE_LINK
);
197 ATF_TC_CLEANUP(dir_note_link_create_dir_in
, tc
)
202 ATF_TC_WITH_CLEANUP(dir_note_link_delete_dir_in
);
203 ATF_TC_HEAD(dir_note_link_delete_dir_in
, tc
)
205 atf_tc_set_md_var(tc
, "descr", "This test case ensures "
206 "that kevent(2) returns NOTE_LINK for the directory "
207 "'foo' if a directory 'foo/bar' is deleted.");
209 ATF_TC_BODY(dir_note_link_delete_dir_in
, tc
)
211 struct kevent changelist
[1];
213 ATF_REQUIRE(init_target() != -1);
214 ATF_REQUIRE(mkdir(dir_inside1
, S_IRWXU
) != -1);
215 ATF_REQUIRE(init_kqueue() != -1);
217 ATF_REQUIRE(rmdir(dir_inside1
) != -1);
218 ATF_REQUIRE(kevent(kq
, NULL
, 0, changelist
, 1, &ts
) != -1);
219 ATF_CHECK_EQ(changelist
[0].fflags
& NOTE_LINK
, NOTE_LINK
);
221 ATF_TC_CLEANUP(dir_note_link_delete_dir_in
, tc
)
226 ATF_TC_WITH_CLEANUP(dir_note_link_mv_dir_in
);
227 ATF_TC_HEAD(dir_note_link_mv_dir_in
, tc
)
229 atf_tc_set_md_var(tc
, "descr", "This test case ensures "
230 "that kevent(2) returns NOTE_LINK for the directory "
231 "'foo' if a directory 'bar' is renamed to 'foo/bar'.");
233 ATF_TC_BODY(dir_note_link_mv_dir_in
, tc
)
235 struct kevent changelist
[1];
237 ATF_REQUIRE(init_target() != -1);
238 ATF_REQUIRE(mkdir(dir_outside
, S_IRWXU
) != -1);
239 ATF_REQUIRE(init_kqueue() != -1);
241 ATF_REQUIRE(rename(dir_outside
, dir_inside1
) != -1);
242 ATF_REQUIRE(kevent(kq
, NULL
, 0, changelist
, 1, &ts
) != -1);
243 ATF_CHECK_EQ(changelist
[0].fflags
& NOTE_LINK
, NOTE_LINK
);
245 ATF_TC_CLEANUP(dir_note_link_mv_dir_in
, tc
)
250 ATF_TC_WITH_CLEANUP(dir_note_link_mv_dir_out
);
251 ATF_TC_HEAD(dir_note_link_mv_dir_out
, tc
)
253 atf_tc_set_md_var(tc
, "descr", "This test case ensures "
254 "that kevent(2) returns NOTE_LINK for the directory "
255 "'foo' if a directory 'foo/bar' is renamed to 'bar'.");
257 ATF_TC_BODY(dir_note_link_mv_dir_out
, tc
)
259 struct kevent changelist
[1];
261 ATF_REQUIRE(init_target() != -1);
262 ATF_REQUIRE(mkdir(dir_inside1
, S_IRWXU
) != -1);
263 ATF_REQUIRE(init_kqueue() != -1);
265 ATF_REQUIRE(rename(dir_inside1
, dir_outside
) != -1);
266 ATF_REQUIRE(kevent(kq
, NULL
, 0, changelist
, 1, &ts
) != -1);
267 ATF_CHECK_EQ(changelist
[0].fflags
& NOTE_LINK
, NOTE_LINK
);
269 ATF_TC_CLEANUP(dir_note_link_mv_dir_out
, tc
)
274 ATF_TC_WITH_CLEANUP(dir_note_write_create_dir_in
);
275 ATF_TC_HEAD(dir_note_write_create_dir_in
, tc
)
277 atf_tc_set_md_var(tc
, "descr", "This test case ensures "
278 "that kevent(2) returns NOTE_WRITE for the directory "
279 "'foo' if a directory 'foo/bar' is created.");
281 ATF_TC_BODY(dir_note_write_create_dir_in
, tc
)
283 struct kevent changelist
[1];
285 ATF_REQUIRE(init_target() != -1);
286 ATF_REQUIRE(init_kqueue() != -1);
288 ATF_REQUIRE(mkdir(dir_inside1
, S_IRWXU
) != -1);
289 ATF_REQUIRE(kevent(kq
, NULL
, 0, changelist
, 1, &ts
) != -1);
290 ATF_CHECK_EQ(changelist
[0].fflags
& NOTE_WRITE
, NOTE_WRITE
);
292 ATF_TC_CLEANUP(dir_note_write_create_dir_in
, tc
)
297 ATF_TC_WITH_CLEANUP(dir_note_write_create_file_in
);
298 ATF_TC_HEAD(dir_note_write_create_file_in
, tc
)
300 atf_tc_set_md_var(tc
, "descr", "This test case ensures "
301 "that kevent(2) returns NOTE_WRITE for the directory "
302 "'foo' if a file 'foo/baz' is created.");
304 ATF_TC_BODY(dir_note_write_create_file_in
, tc
)
306 struct kevent changelist
[1];
308 ATF_REQUIRE(init_target() != -1);
309 ATF_REQUIRE(init_kqueue() != -1);
311 ATF_REQUIRE(create_file(file_inside1
) != -1);
312 ATF_REQUIRE(kevent(kq
, NULL
, 0, changelist
, 1, &ts
) != -1);
313 ATF_CHECK_EQ(changelist
[0].fflags
& NOTE_WRITE
, NOTE_WRITE
);
315 ATF_TC_CLEANUP(dir_note_write_create_file_in
, tc
)
320 ATF_TC_WITH_CLEANUP(dir_note_write_delete_dir_in
);
321 ATF_TC_HEAD(dir_note_write_delete_dir_in
, tc
)
323 atf_tc_set_md_var(tc
, "descr", "This test case ensures "
324 "that kevent(2) returns NOTE_WRITE for the directory "
325 "'foo' if a directory 'foo/bar' is deleted.");
327 ATF_TC_BODY(dir_note_write_delete_dir_in
, tc
)
329 struct kevent changelist
[1];
331 ATF_REQUIRE(init_target() != -1);
332 ATF_REQUIRE(mkdir(dir_inside1
, S_IRWXU
) != -1);
333 ATF_REQUIRE(init_kqueue() != -1);
335 ATF_REQUIRE(rmdir(dir_inside1
) != -1);
336 ATF_REQUIRE(kevent(kq
, NULL
, 0, changelist
, 1, &ts
) != -1);
337 ATF_CHECK_EQ(changelist
[0].fflags
& NOTE_WRITE
, NOTE_WRITE
);
339 ATF_TC_CLEANUP(dir_note_write_delete_dir_in
, tc
)
344 ATF_TC_WITH_CLEANUP(dir_note_write_delete_file_in
);
345 ATF_TC_HEAD(dir_note_write_delete_file_in
, tc
)
347 atf_tc_set_md_var(tc
, "descr", "This test case ensures "
348 "that kevent(2) returns NOTE_WRITE for the directory "
349 "'foo' if a file 'foo/baz' is deleted.");
351 ATF_TC_BODY(dir_note_write_delete_file_in
, tc
)
353 struct kevent changelist
[1];
355 ATF_REQUIRE(init_target() != -1);
356 ATF_REQUIRE(create_file(file_inside1
) != -1);
357 ATF_REQUIRE(init_kqueue() != -1);
359 ATF_REQUIRE(unlink(file_inside1
) != -1);
360 ATF_REQUIRE(kevent(kq
, NULL
, 0, changelist
, 1, &ts
) != -1);
361 ATF_CHECK_EQ(changelist
[0].fflags
& NOTE_WRITE
, NOTE_WRITE
);
363 ATF_TC_CLEANUP(dir_note_write_delete_file_in
, tc
)
368 ATF_TC_WITH_CLEANUP(dir_note_write_mv_dir_in
);
369 ATF_TC_HEAD(dir_note_write_mv_dir_in
, tc
)
371 atf_tc_set_md_var(tc
, "descr", "This test case ensures "
372 "that kevent(2) returns NOTE_WRITE for the directory "
373 "'foo' if a directory 'bar' is renamed to 'foo/bar'.");
375 ATF_TC_BODY(dir_note_write_mv_dir_in
, tc
)
377 struct kevent changelist
[1];
379 ATF_REQUIRE(init_target() != -1);
380 ATF_REQUIRE(mkdir(dir_outside
, S_IRWXU
) != -1);
381 ATF_REQUIRE(init_kqueue() != -1);
383 ATF_REQUIRE(rename(dir_outside
, dir_inside1
) != -1);
384 ATF_REQUIRE(kevent(kq
, NULL
, 0, changelist
, 1, &ts
) != -1);
385 ATF_CHECK_EQ(changelist
[0].fflags
& NOTE_WRITE
, NOTE_WRITE
);
387 ATF_TC_CLEANUP(dir_note_write_mv_dir_in
, tc
)
392 ATF_TC_WITH_CLEANUP(dir_note_write_mv_dir_out
);
393 ATF_TC_HEAD(dir_note_write_mv_dir_out
, tc
)
395 atf_tc_set_md_var(tc
, "descr", "This test case ensures "
396 "that kevent(2) returns NOTE_WRITE for the directory "
397 "'foo' if a directory 'foo/bar' is renamed to 'bar'.");
399 ATF_TC_BODY(dir_note_write_mv_dir_out
, tc
)
401 struct kevent changelist
[1];
403 ATF_REQUIRE(init_target() != -1);
404 ATF_REQUIRE(mkdir(dir_inside1
, S_IRWXU
) != -1);
405 ATF_REQUIRE(init_kqueue() != -1);
407 ATF_REQUIRE(rename(dir_inside1
, dir_outside
) != -1);
408 ATF_REQUIRE(kevent(kq
, NULL
, 0, changelist
, 1, &ts
) != -1);
409 ATF_CHECK_EQ(changelist
[0].fflags
& NOTE_WRITE
, NOTE_WRITE
);
411 ATF_TC_CLEANUP(dir_note_write_mv_dir_out
, tc
)
416 ATF_TC_WITH_CLEANUP(dir_note_write_mv_dir_within
);
417 ATF_TC_HEAD(dir_note_write_mv_dir_within
, tc
)
419 atf_tc_set_md_var(tc
, "descr", "This test case ensures "
420 "that kevent(2) returns NOTE_WRITE for the directory "
421 "'foo' if a directory 'foo/bar' is renamed to 'foo/baz'.");
423 ATF_TC_BODY(dir_note_write_mv_dir_within
, tc
)
425 struct kevent changelist
[1];
427 ATF_REQUIRE(init_target() != -1);
428 ATF_REQUIRE(mkdir(dir_inside1
, S_IRWXU
) != -1);
429 ATF_REQUIRE(init_kqueue() != -1);
431 ATF_REQUIRE(rename(dir_inside1
, dir_inside2
) != -1);
432 ATF_REQUIRE(kevent(kq
, NULL
, 0, changelist
, 1, &ts
) != -1);
433 ATF_CHECK_EQ(changelist
[0].fflags
& NOTE_WRITE
, NOTE_WRITE
);
435 ATF_TC_CLEANUP(dir_note_write_mv_dir_within
, tc
)
440 ATF_TC_WITH_CLEANUP(dir_note_write_mv_file_in
);
441 ATF_TC_HEAD(dir_note_write_mv_file_in
, tc
)
443 atf_tc_set_md_var(tc
, "descr", "This test case ensures "
444 "that kevent(2) returns NOTE_WRITE for the directory "
445 "'foo' if a file 'qux' is renamed to 'foo/baz'.");
447 ATF_TC_BODY(dir_note_write_mv_file_in
, tc
)
449 struct kevent changelist
[1];
451 ATF_REQUIRE(init_target() != -1);
452 ATF_REQUIRE(create_file(file_outside
) != -1);
453 ATF_REQUIRE(init_kqueue() != -1);
455 ATF_REQUIRE(rename(file_outside
, file_inside1
) != -1);
456 ATF_REQUIRE(kevent(kq
, NULL
, 0, changelist
, 1, &ts
) != -1);
457 ATF_CHECK_EQ(changelist
[0].fflags
& NOTE_WRITE
, NOTE_WRITE
);
459 ATF_TC_CLEANUP(dir_note_write_mv_file_in
, tc
)
464 ATF_TC_WITH_CLEANUP(dir_note_write_mv_file_out
);
465 ATF_TC_HEAD(dir_note_write_mv_file_out
, tc
)
467 atf_tc_set_md_var(tc
, "descr", "This test case ensures "
468 "that kevent(2) returns NOTE_WRITE for the directory "
469 "'foo' if a file 'foo/baz' is renamed to 'qux'.");
471 ATF_TC_BODY(dir_note_write_mv_file_out
, tc
)
473 struct kevent changelist
[1];
475 ATF_REQUIRE(init_target() != -1);
476 ATF_REQUIRE(create_file(file_inside1
) != -1);
477 ATF_REQUIRE(init_kqueue() != -1);
479 ATF_REQUIRE(rename(file_inside1
, file_outside
) != -1);
480 ATF_REQUIRE(kevent(kq
, NULL
, 0, changelist
, 1, &ts
) != -1);
481 ATF_CHECK_EQ(changelist
[0].fflags
& NOTE_WRITE
, NOTE_WRITE
);
483 ATF_TC_CLEANUP(dir_note_write_mv_file_out
, tc
)
488 ATF_TC_WITH_CLEANUP(dir_note_write_mv_file_within
);
489 ATF_TC_HEAD(dir_note_write_mv_file_within
, tc
)
491 atf_tc_set_md_var(tc
, "descr", "This test case ensures "
492 "that kevent(2) returns NOTE_WRITE for the directory "
493 "'foo' if a file 'foo/baz' is renamed to 'foo/qux'.");
495 ATF_TC_BODY(dir_note_write_mv_file_within
, tc
)
497 struct kevent changelist
[1];
499 ATF_REQUIRE(init_target() != -1);
500 ATF_REQUIRE(create_file(file_inside1
) != -1);
501 ATF_REQUIRE(init_kqueue() != -1);
503 ATF_REQUIRE(rename(file_inside1
, file_inside2
) != -1);
504 ATF_REQUIRE(kevent(kq
, NULL
, 0, changelist
, 1, &ts
) != -1);
505 ATF_CHECK_EQ(changelist
[0].fflags
& NOTE_WRITE
, NOTE_WRITE
);
507 ATF_TC_CLEANUP(dir_note_write_mv_file_within
, tc
)
514 ATF_TP_ADD_TC(tp
, dir_no_note_link_create_file_in
);
515 ATF_TP_ADD_TC(tp
, dir_no_note_link_delete_file_in
);
516 ATF_TP_ADD_TC(tp
, dir_no_note_link_mv_dir_within
);
517 ATF_TP_ADD_TC(tp
, dir_no_note_link_mv_file_within
);
518 ATF_TP_ADD_TC(tp
, dir_note_link_create_dir_in
);
519 ATF_TP_ADD_TC(tp
, dir_note_link_delete_dir_in
);
520 ATF_TP_ADD_TC(tp
, dir_note_link_mv_dir_in
);
521 ATF_TP_ADD_TC(tp
, dir_note_link_mv_dir_out
);
522 ATF_TP_ADD_TC(tp
, dir_note_write_create_dir_in
);
523 ATF_TP_ADD_TC(tp
, dir_note_write_create_file_in
);
524 ATF_TP_ADD_TC(tp
, dir_note_write_delete_dir_in
);
525 ATF_TP_ADD_TC(tp
, dir_note_write_delete_file_in
);
526 ATF_TP_ADD_TC(tp
, dir_note_write_mv_dir_in
);
527 ATF_TP_ADD_TC(tp
, dir_note_write_mv_dir_out
);
528 ATF_TP_ADD_TC(tp
, dir_note_write_mv_dir_within
);
529 ATF_TP_ADD_TC(tp
, dir_note_write_mv_file_in
);
530 ATF_TP_ADD_TC(tp
, dir_note_write_mv_file_out
);
531 ATF_TP_ADD_TC(tp
, dir_note_write_mv_file_within
);
532 return atf_no_error();