Initial project import
This commit is contained in:
commit
23f2d29e32
11957 files changed
+1754577
No files matched your search
@@ -0,0 +1,169 @@
|
||||
// vtest flaky: true
|
||||
// vtest retry: 3
|
||||
import os
|
||||
import os.notify
|
||||
|
||||
fn test_level_trigger() {
|
||||
// currently only linux and macos are supported
|
||||
$if linux || macos {
|
||||
mut notifier := notify.new()!
|
||||
mut pipe := os.pipe()!
|
||||
defer {
|
||||
pipe.close()
|
||||
notifier.close() or {}
|
||||
}
|
||||
notifier.add(pipe.read_fd, .read)!
|
||||
|
||||
pipe.write_string('foobar')!
|
||||
mut n := ¬ifier
|
||||
check_read_event(mut n, pipe.read_fd, 'foo')
|
||||
check_read_event(mut n, pipe.read_fd, 'bar')
|
||||
|
||||
assert notifier.wait(0).len == 0
|
||||
}
|
||||
}
|
||||
|
||||
fn test_edge_trigger() {
|
||||
// currently only linux and macos are supported
|
||||
$if linux || macos {
|
||||
mut notifier := notify.new()!
|
||||
mut pipe := os.pipe()!
|
||||
defer {
|
||||
pipe.close()
|
||||
notifier.close() or {}
|
||||
}
|
||||
notifier.add(pipe.read_fd, .read, .edge_trigger)!
|
||||
|
||||
mut n := ¬ifier
|
||||
|
||||
pipe.write_string('foobar')!
|
||||
check_read_event(mut n, pipe.read_fd, 'foo')
|
||||
|
||||
$if linux {
|
||||
assert notifier.wait(0).len == 0
|
||||
}
|
||||
$if macos {
|
||||
/*
|
||||
In the kqueue of macos, EV_CLEAR flag represents a clear event,
|
||||
which is mainly used for pipeline and socket class events. When this flag is set,
|
||||
kqueue will trigger the corresponding event when the data is readable or writable,
|
||||
but it is not guaranteed that the event will only be triggered once.
|
||||
Compared to EPOLLET, EV_CLEAR's behavior varies. In epoll, the edge triggered mode only triggers
|
||||
an event once when the state changes from unreadable/non writable to readable/writable,
|
||||
that is, when the data changes from unreadable to readable,
|
||||
or when the data changes from unreadable to writable. In the kqueue of macos,
|
||||
EV_CLEAR does not possess this precise edge triggering behavior.
|
||||
Therefore, in the kqueue of macos, even if the data is not completely read,
|
||||
it is possible to continue triggering read events. This means that if you don't process all the data,
|
||||
the next kqueue event notification may still be triggered
|
||||
*/
|
||||
|
||||
// notifier.wait(0).len == 1 or 0
|
||||
}
|
||||
|
||||
pipe.write_string('baz')!
|
||||
check_read_event(mut n, pipe.read_fd, 'barbaz')
|
||||
// we do not get an event because there is still data
|
||||
// to be read
|
||||
// assert notifier.wait(0).len == 0
|
||||
// TODO: investigage why the above assert suddenly started failing on the latest Ubuntu kernel update:
|
||||
// 5.11.0-37-generic #41~20.04.2-Ubuntu SMP Fri Sep 24 09:06:38 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
|
||||
}
|
||||
}
|
||||
|
||||
fn test_one_shot() {
|
||||
$if linux || macos {
|
||||
mut notifier := notify.new()!
|
||||
mut pipe := os.pipe()!
|
||||
defer {
|
||||
pipe.close()
|
||||
notifier.close() or {}
|
||||
}
|
||||
notifier.add(pipe.read_fd, .read, .one_shot)!
|
||||
|
||||
mut n := ¬ifier
|
||||
|
||||
pipe.write_string('foobar')!
|
||||
check_read_event(mut n, pipe.read_fd, 'foo')
|
||||
pipe.write_string('baz')!
|
||||
|
||||
assert notifier.wait(0).len == 0
|
||||
|
||||
// rearm
|
||||
notifier.modify(pipe.read_fd, .read)!
|
||||
check_read_event(mut n, pipe.read_fd, 'barbaz')
|
||||
}
|
||||
}
|
||||
|
||||
// Kqueue does not support 'hangup' event type.
|
||||
fn test_hangup() {
|
||||
$if linux {
|
||||
mut notifier := notify.new()!
|
||||
mut pipe := os.pipe()!
|
||||
defer {
|
||||
os.fd_close(pipe.read_fd)
|
||||
notifier.close() or {}
|
||||
}
|
||||
notifier.add(pipe.read_fd, .hangup)!
|
||||
|
||||
assert notifier.wait(0).len == 0
|
||||
|
||||
// closing on the writer end of the pipe will
|
||||
// cause a hangup on the reader end
|
||||
os.fd_close(pipe.write_fd)
|
||||
events := notifier.wait(0)
|
||||
assert events.len == 1
|
||||
assert events[0].fd == pipe.read_fd
|
||||
assert events[0].kind.has(.hangup)
|
||||
}
|
||||
}
|
||||
|
||||
fn test_write() {
|
||||
$if linux || macos {
|
||||
mut notifier := notify.new()!
|
||||
mut pipe := os.pipe()!
|
||||
defer {
|
||||
pipe.close()
|
||||
notifier.close() or {}
|
||||
}
|
||||
|
||||
notifier.add(pipe.read_fd, .write)!
|
||||
assert notifier.wait(0).len == 0
|
||||
|
||||
notifier.add(pipe.write_fd, .write)!
|
||||
events := notifier.wait(0)
|
||||
assert events.len == 1
|
||||
assert events[0].fd == pipe.write_fd
|
||||
assert events[0].kind.has(.write)
|
||||
}
|
||||
}
|
||||
|
||||
fn test_remove() {
|
||||
$if linux || macos {
|
||||
mut notifier := notify.new()!
|
||||
mut pipe := os.pipe()!
|
||||
defer {
|
||||
pipe.close()
|
||||
notifier.close() or {}
|
||||
}
|
||||
|
||||
// level triggered - will keep getting events while
|
||||
// there is data to read
|
||||
notifier.add(pipe.read_fd, .read)!
|
||||
pipe.write_string('foobar')!
|
||||
assert notifier.wait(0).len == 1
|
||||
assert notifier.wait(0).len == 1
|
||||
|
||||
notifier.remove(pipe.read_fd)!
|
||||
assert notifier.wait(0).len == 0
|
||||
}
|
||||
}
|
||||
|
||||
fn check_read_event(mut notifier notify.FdNotifier, reader_fd int, expected string) {
|
||||
events := notifier.wait(0)
|
||||
assert events.len == 1
|
||||
assert events[0].fd == reader_fd
|
||||
assert events[0].kind.has(.read)
|
||||
s, _ := os.fd_read(events[0].fd, expected.len)
|
||||
assert s == expected
|
||||
}
|
||||
Reference in new issue
Block a user