diff options
Diffstat (limited to 'test/syscalls/linux/eventfd.cc')
-rw-r--r-- | test/syscalls/linux/eventfd.cc | 222 |
1 files changed, 0 insertions, 222 deletions
diff --git a/test/syscalls/linux/eventfd.cc b/test/syscalls/linux/eventfd.cc deleted file mode 100644 index dc794415e..000000000 --- a/test/syscalls/linux/eventfd.cc +++ /dev/null @@ -1,222 +0,0 @@ -// Copyright 2018 The gVisor Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include <errno.h> -#include <pthread.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/epoll.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <unistd.h> - -#include "gtest/gtest.h" -#include "test/util/epoll_util.h" -#include "test/util/eventfd_util.h" -#include "test/util/test_util.h" -#include "test/util/thread_util.h" - -namespace gvisor { -namespace testing { - -namespace { - -TEST(EventfdTest, Nonblock) { - FileDescriptor efd = - ASSERT_NO_ERRNO_AND_VALUE(NewEventFD(0, EFD_NONBLOCK | EFD_SEMAPHORE)); - - uint64_t l; - ASSERT_THAT(read(efd.get(), &l, sizeof(l)), SyscallFailsWithErrno(EAGAIN)); - - l = 1; - ASSERT_THAT(write(efd.get(), &l, sizeof(l)), SyscallSucceeds()); - - l = 0; - ASSERT_THAT(read(efd.get(), &l, sizeof(l)), SyscallSucceeds()); - EXPECT_EQ(l, 1); - - ASSERT_THAT(read(efd.get(), &l, sizeof(l)), SyscallFailsWithErrno(EAGAIN)); -} - -void* read_three_times(void* arg) { - int efd = *reinterpret_cast<int*>(arg); - uint64_t l; - EXPECT_THAT(read(efd, &l, sizeof(l)), SyscallSucceedsWithValue(sizeof(l))); - EXPECT_THAT(read(efd, &l, sizeof(l)), SyscallSucceedsWithValue(sizeof(l))); - EXPECT_THAT(read(efd, &l, sizeof(l)), SyscallSucceedsWithValue(sizeof(l))); - return nullptr; -} - -TEST(EventfdTest, BlockingWrite) { - FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(NewEventFD(0, EFD_SEMAPHORE)); - int efd = fd.get(); - - pthread_t p; - ASSERT_THAT(pthread_create(&p, nullptr, read_three_times, - reinterpret_cast<void*>(&efd)), - SyscallSucceeds()); - - uint64_t l = 1; - ASSERT_THAT(write(efd, &l, sizeof(l)), SyscallSucceeds()); - EXPECT_EQ(l, 1); - - ASSERT_THAT(write(efd, &l, sizeof(l)), SyscallSucceeds()); - EXPECT_EQ(l, 1); - - ASSERT_THAT(write(efd, &l, sizeof(l)), SyscallSucceeds()); - EXPECT_EQ(l, 1); - - ASSERT_THAT(pthread_join(p, nullptr), SyscallSucceeds()); -} - -TEST(EventfdTest, SmallWrite) { - FileDescriptor efd = - ASSERT_NO_ERRNO_AND_VALUE(NewEventFD(0, EFD_NONBLOCK | EFD_SEMAPHORE)); - - uint64_t l = 16; - ASSERT_THAT(write(efd.get(), &l, 4), SyscallFailsWithErrno(EINVAL)); -} - -TEST(EventfdTest, SmallRead) { - FileDescriptor efd = - ASSERT_NO_ERRNO_AND_VALUE(NewEventFD(0, EFD_NONBLOCK | EFD_SEMAPHORE)); - - uint64_t l = 1; - ASSERT_THAT(write(efd.get(), &l, sizeof(l)), SyscallSucceeds()); - - l = 0; - ASSERT_THAT(read(efd.get(), &l, 4), SyscallFailsWithErrno(EINVAL)); -} - -TEST(EventfdTest, IllegalSeek) { - FileDescriptor efd = ASSERT_NO_ERRNO_AND_VALUE(NewEventFD(0, 0)); - EXPECT_THAT(lseek(efd.get(), 0, SEEK_SET), SyscallFailsWithErrno(ESPIPE)); -} - -TEST(EventfdTest, IllegalPread) { - FileDescriptor efd = ASSERT_NO_ERRNO_AND_VALUE(NewEventFD(0, 0)); - int l; - EXPECT_THAT(pread(efd.get(), &l, sizeof(l), 0), - SyscallFailsWithErrno(ESPIPE)); -} - -TEST(EventfdTest, IllegalPwrite) { - FileDescriptor efd = ASSERT_NO_ERRNO_AND_VALUE(NewEventFD(0, 0)); - EXPECT_THAT(pwrite(efd.get(), "x", 1, 0), SyscallFailsWithErrno(ESPIPE)); -} - -TEST(EventfdTest, BigWrite) { - FileDescriptor efd = - ASSERT_NO_ERRNO_AND_VALUE(NewEventFD(0, EFD_NONBLOCK | EFD_SEMAPHORE)); - - uint64_t big[16]; - big[0] = 16; - ASSERT_THAT(write(efd.get(), big, sizeof(big)), SyscallSucceeds()); -} - -TEST(EventfdTest, BigRead) { - FileDescriptor efd = - ASSERT_NO_ERRNO_AND_VALUE(NewEventFD(0, EFD_NONBLOCK | EFD_SEMAPHORE)); - - uint64_t l = 1; - ASSERT_THAT(write(efd.get(), &l, sizeof(l)), SyscallSucceeds()); - - uint64_t big[16]; - ASSERT_THAT(read(efd.get(), big, sizeof(big)), SyscallSucceeds()); - EXPECT_EQ(big[0], 1); -} - -TEST(EventfdTest, BigWriteBigRead) { - FileDescriptor efd = - ASSERT_NO_ERRNO_AND_VALUE(NewEventFD(0, EFD_NONBLOCK | EFD_SEMAPHORE)); - - uint64_t l[16]; - l[0] = 16; - ASSERT_THAT(write(efd.get(), l, sizeof(l)), SyscallSucceeds()); - ASSERT_THAT(read(efd.get(), l, sizeof(l)), SyscallSucceeds()); - EXPECT_EQ(l[0], 1); -} - -TEST(EventfdTest, SpliceFromPipePartialSucceeds) { - int pipes[2]; - ASSERT_THAT(pipe2(pipes, O_NONBLOCK), SyscallSucceeds()); - const FileDescriptor pipe_rfd(pipes[0]); - const FileDescriptor pipe_wfd(pipes[1]); - constexpr uint64_t kVal{1}; - - FileDescriptor efd = ASSERT_NO_ERRNO_AND_VALUE(NewEventFD(0, EFD_NONBLOCK)); - - uint64_t event_array[2]; - event_array[0] = kVal; - event_array[1] = kVal; - ASSERT_THAT(write(pipe_wfd.get(), event_array, sizeof(event_array)), - SyscallSucceedsWithValue(sizeof(event_array))); - EXPECT_THAT(splice(pipe_rfd.get(), /*__offin=*/nullptr, efd.get(), - /*__offout=*/nullptr, sizeof(event_array[0]) + 1, - SPLICE_F_NONBLOCK), - SyscallSucceedsWithValue(sizeof(event_array[0]))); - - uint64_t val; - ASSERT_THAT(read(efd.get(), &val, sizeof(val)), - SyscallSucceedsWithValue(sizeof(val))); - EXPECT_EQ(val, kVal); -} - -// NotifyNonZero is inherently racy, so random save is disabled. -TEST(EventfdTest, NotifyNonZero_NoRandomSave) { - // Waits will time out at 10 seconds. - constexpr int kEpollTimeoutMs = 10000; - // Create an eventfd descriptor. - FileDescriptor efd = - ASSERT_NO_ERRNO_AND_VALUE(NewEventFD(7, EFD_NONBLOCK | EFD_SEMAPHORE)); - // Create an epoll fd to listen to efd. - FileDescriptor epollfd = ASSERT_NO_ERRNO_AND_VALUE(NewEpollFD()); - // Add efd to epoll. - ASSERT_NO_ERRNO( - RegisterEpollFD(epollfd.get(), efd.get(), EPOLLIN | EPOLLET, efd.get())); - - // Use epoll to get a value from efd. - struct epoll_event out_ev; - int wait_out = epoll_wait(epollfd.get(), &out_ev, 1, kEpollTimeoutMs); - EXPECT_EQ(wait_out, 1); - EXPECT_EQ(efd.get(), out_ev.data.fd); - uint64_t val = 0; - ASSERT_THAT(read(efd.get(), &val, sizeof(val)), SyscallSucceeds()); - EXPECT_EQ(val, 1); - - // Start a thread that, after this thread blocks on epoll_wait, will write to - // efd. This is racy -- it's possible that this write will happen after - // epoll_wait times out. - ScopedThread t([&efd] { - sleep(5); - uint64_t val = 1; - EXPECT_THAT(write(efd.get(), &val, sizeof(val)), - SyscallSucceedsWithValue(sizeof(val))); - }); - - // epoll_wait should return once the thread writes. - wait_out = epoll_wait(epollfd.get(), &out_ev, 1, kEpollTimeoutMs); - EXPECT_EQ(wait_out, 1); - EXPECT_EQ(efd.get(), out_ev.data.fd); - - val = 0; - ASSERT_THAT(read(efd.get(), &val, sizeof(val)), SyscallSucceeds()); - EXPECT_EQ(val, 1); -} - -} // namespace - -} // namespace testing -} // namespace gvisor |