Serenity Operating System
1/*
2 * Copyright (c) 2021, the SerenityOS developers.
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#include <Kernel/API/InodeWatcherEvent.h>
8#include <LibCore/EventLoop.h>
9#include <LibCore/FileWatcher.h>
10#include <LibCore/Timer.h>
11#include <LibTest/TestCase.h>
12#include <fcntl.h>
13#include <unistd.h>
14
15TEST_CASE(file_watcher_child_events)
16{
17 auto event_loop = Core::EventLoop();
18 auto maybe_file_watcher = Core::FileWatcher::create();
19 EXPECT_NE(maybe_file_watcher.is_error(), true);
20
21 auto file_watcher = maybe_file_watcher.release_value();
22 auto watch_result = file_watcher->add_watch("/tmp/",
23 Core::FileWatcherEvent::Type::ChildCreated
24 | Core::FileWatcherEvent::Type::ChildDeleted);
25 EXPECT_NE(watch_result.is_error(), true);
26
27 int event_count = 0;
28 file_watcher->on_change = [&](Core::FileWatcherEvent const& event) {
29 // Ignore path events under /tmp that can occur for anything else the OS is
30 // doing to create/delete files there.
31 if (event.event_path != "/tmp/testfile"sv)
32 return;
33
34 if (event_count == 0) {
35 EXPECT(has_flag(event.type, Core::FileWatcherEvent::Type::ChildCreated));
36 } else if (event_count == 1) {
37 EXPECT(has_flag(event.type, Core::FileWatcherEvent::Type::ChildDeleted));
38 EXPECT(MUST(file_watcher->remove_watch("/tmp/"sv)));
39
40 event_loop.quit(0);
41 }
42
43 event_count++;
44 };
45
46 auto timer1 = MUST(Core::Timer::create_single_shot(500, [&] {
47 int rc = creat("/tmp/testfile", 0777);
48 EXPECT_NE(rc, -1);
49 }));
50 timer1->start();
51
52 auto timer2 = MUST(Core::Timer::create_single_shot(1000, [&] {
53 int rc = unlink("/tmp/testfile");
54 EXPECT_NE(rc, -1);
55 }));
56 timer2->start();
57
58 auto catchall_timer = MUST(Core::Timer::create_single_shot(2000, [&] {
59 VERIFY_NOT_REACHED();
60 }));
61 catchall_timer->start();
62
63 event_loop.exec();
64}