Serenity Operating System
at master 169 lines 4.3 kB view raw
1/* 2 * Copyright (c) 2021, sin-ack <sin-ack@protonmail.com> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <AK/NumericLimits.h> 8#include <Kernel/API/InodeWatcherEvent.h> 9#include <Kernel/API/InodeWatcherFlags.h> 10#include <LibTest/TestCase.h> 11#include <errno.h> 12#include <fcntl.h> 13#include <stdio.h> 14#include <unistd.h> 15#include <utime.h> 16 17u8 buffer[MAXIMUM_EVENT_SIZE]; 18InodeWatcherEvent* event = reinterpret_cast<InodeWatcherEvent*>(buffer); 19 20static int read_event(int fd) 21{ 22 int rc = read(fd, &buffer, MAXIMUM_EVENT_SIZE); 23 return rc; 24} 25 26static DeprecatedString get_event_name() 27{ 28 if (event->name_length == 0) 29 return DeprecatedString(); 30 31 return DeprecatedString { event->name, event->name_length - 1 }; 32} 33 34TEST_CASE(inode_watcher_metadata_modified_event) 35{ 36 int fd = create_inode_watcher(0); 37 EXPECT_NE(fd, -1); 38 39 int test_fd = creat("/tmp/testfile", 0777); 40 EXPECT_NE(test_fd, -1); 41 42 int wd = inode_watcher_add_watch(fd, "/tmp/testfile", 13, static_cast<unsigned>(InodeWatcherEvent::Type::MetadataModified)); 43 EXPECT_NE(wd, -1); 44 45 // "touch" the file 46 int rc = utime("/tmp/testfile", nullptr); 47 EXPECT_NE(rc, -1); 48 49 rc = read_event(fd); 50 EXPECT_EQ(event->watch_descriptor, wd); 51 EXPECT_EQ(event->type, InodeWatcherEvent::Type::MetadataModified); 52 53 close(fd); 54 close(test_fd); 55 unlink("/tmp/testfile"); 56} 57 58TEST_CASE(inode_watcher_content_modified_event) 59{ 60 int fd = create_inode_watcher(0); 61 EXPECT_NE(fd, -1); 62 63 int test_fd = creat("/tmp/testfile", 0777); 64 EXPECT_NE(test_fd, -1); 65 66 int wd = inode_watcher_add_watch(fd, "/tmp/testfile", 13, static_cast<unsigned>(InodeWatcherEvent::Type::ContentModified)); 67 EXPECT_NE(wd, -1); 68 69 int rc = write(test_fd, "test", 4); 70 EXPECT_NE(rc, -1); 71 72 rc = read_event(fd); 73 EXPECT_NE(rc, -1); 74 EXPECT_EQ(event->watch_descriptor, wd); 75 EXPECT_EQ(event->type, InodeWatcherEvent::Type::ContentModified); 76 77 close(fd); 78 close(test_fd); 79 unlink("/tmp/testfile"); 80} 81 82TEST_CASE(inode_watcher_deleted_event) 83{ 84 int fd = create_inode_watcher(0); 85 EXPECT_NE(fd, -1); 86 87 int test_fd = creat("/tmp/testfile", 0777); 88 EXPECT_NE(test_fd, -1); 89 90 int wd = inode_watcher_add_watch(fd, "/tmp/testfile", 13, static_cast<unsigned>(InodeWatcherEvent::Type::Deleted)); 91 EXPECT_NE(wd, -1); 92 93 int rc = unlink("/tmp/testfile"); 94 EXPECT_NE(rc, -1); 95 96 rc = read_event(fd); 97 EXPECT_NE(rc, -1); 98 EXPECT_EQ(event->watch_descriptor, wd); 99 EXPECT_EQ(event->type, InodeWatcherEvent::Type::Deleted); 100 101 close(fd); 102 close(test_fd); 103} 104 105TEST_CASE(inode_watcher_child_events) 106{ 107 int fd = create_inode_watcher(0); 108 EXPECT_NE(fd, -1); 109 110 int wd = inode_watcher_add_watch(fd, "/tmp/", 5, static_cast<unsigned>(InodeWatcherEvent::Type::ChildCreated | InodeWatcherEvent::Type::ChildDeleted)); 111 EXPECT_NE(fd, -1); 112 113 int rc = creat("/tmp/testfile", 0777); 114 EXPECT_NE(rc, -1); 115 116 rc = read_event(fd); 117 EXPECT_NE(rc, -1); 118 EXPECT_EQ(event->watch_descriptor, wd); 119 EXPECT_EQ(event->type, InodeWatcherEvent::Type::ChildCreated); 120 VERIFY(event->name_length > 0); 121 EXPECT_EQ(get_event_name(), "testfile"); 122 123 rc = unlink("/tmp/testfile"); 124 EXPECT_NE(rc, -1); 125 126 rc = read_event(fd); 127 EXPECT_NE(rc, -1); 128 EXPECT_EQ(event->watch_descriptor, wd); 129 EXPECT_EQ(event->type, InodeWatcherEvent::Type::ChildDeleted); 130 VERIFY(event->name_length > 0); 131 EXPECT_EQ(get_event_name(), "testfile"); 132 133 close(fd); 134} 135 136TEST_CASE(inode_watcher_closes_children_on_close) 137{ 138 int fd = create_inode_watcher(0); 139 EXPECT_NE(fd, -1); 140 141 int test_fd = creat("/tmp/testfile", 0777); 142 EXPECT_NE(test_fd, -1); 143 int wd = inode_watcher_add_watch(fd, "/tmp/testfile", 13, static_cast<unsigned>(InodeWatcherEvent::Type::MetadataModified)); 144 EXPECT_NE(wd, -1); 145 146 int rc = utime("/tmp/testfile", nullptr); 147 EXPECT_NE(rc, -1); 148 149 close(fd); 150 151 rc = read_event(fd); 152 EXPECT_EQ(rc, -1); 153 EXPECT_EQ(errno, EBADF); 154 155 close(test_fd); 156 unlink("/tmp/testfile"); 157} 158 159TEST_CASE(inode_watcher_nonblock) 160{ 161 int fd = create_inode_watcher(static_cast<unsigned>(InodeWatcherFlags::Nonblock)); 162 EXPECT_NE(fd, -1); 163 164 int rc = read_event(fd); 165 EXPECT_EQ(rc, -1); 166 EXPECT_EQ(errno, EAGAIN); 167 168 close(fd); 169}