diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/packetimpact/runner/dut.go | 5 | ||||
-rw-r--r-- | test/packetimpact/testbench/dut.go | 4 | ||||
-rw-r--r-- | test/packetimpact/testbench/layers.go | 2 | ||||
-rw-r--r-- | test/packetimpact/testbench/rawsockets.go | 20 | ||||
-rw-r--r-- | test/packetimpact/testbench/testbench.go | 1 | ||||
-rw-r--r-- | test/packetimpact/tests/BUILD | 1 | ||||
-rw-r--r-- | test/packetimpact/tests/tcp_syncookie_test.go | 18 | ||||
-rw-r--r-- | test/syscalls/linux/rename.cc | 56 | ||||
-rw-r--r-- | test/syscalls/linux/udp_socket.cc | 4 |
9 files changed, 95 insertions, 16 deletions
diff --git a/test/packetimpact/runner/dut.go b/test/packetimpact/runner/dut.go index 4fb2f5c4b..02678a76a 100644 --- a/test/packetimpact/runner/dut.go +++ b/test/packetimpact/runner/dut.go @@ -363,6 +363,9 @@ func TestWithDUT(ctx context.Context, t *testing.T, mkDevice func(*dockerutil.Co // and receives packets and also sends POSIX socket commands to the // posix_server to be executed on the DUT. testArgs := []string{containerTestbenchBinary} + if testing.Verbose() { + testArgs = append(testArgs, "-test.v") + } testArgs = append(testArgs, extraTestArgs...) testArgs = append(testArgs, fmt.Sprintf("--native=%t", native), @@ -395,6 +398,8 @@ func TestWithDUT(ctx context.Context, t *testing.T, mkDevice func(*dockerutil.Co } else if expectFailure { t.Logf(`test failed as expected: %v %s`, err, testLogs) + } else if testing.Verbose() { + t.Log(testLogs) } } diff --git a/test/packetimpact/testbench/dut.go b/test/packetimpact/testbench/dut.go index 269e163bb..0cac0bf1b 100644 --- a/test/packetimpact/testbench/dut.go +++ b/test/packetimpact/testbench/dut.go @@ -498,8 +498,8 @@ func (dut *DUT) PollOne(t *testing.T, fd int32, events int16, timeout time.Durat if readyFd := pfds[0].Fd; readyFd != fd { t.Fatalf("Poll returned an fd %d that was not requested (%d)", readyFd, fd) } - if got, want := pfds[0].Revents, int16(events); got&want == 0 { - t.Fatalf("Poll returned no events in our interest, got: %#b, want: %#b", got, want) + if got, want := pfds[0].Revents, int16(events); got&want != want { + t.Fatalf("Poll returned events does not include all of the interested events, got: %#b, want: %#b", got, want) } } diff --git a/test/packetimpact/testbench/layers.go b/test/packetimpact/testbench/layers.go index 078f500e4..2644b3248 100644 --- a/test/packetimpact/testbench/layers.go +++ b/test/packetimpact/testbench/layers.go @@ -357,7 +357,7 @@ func (l *IPv4) ToBytes() ([]byte, error) { case *ICMPv4: fields.Protocol = uint8(header.ICMPv4ProtocolNumber) default: - // TODO(b/150301488): Support more protocols as needed. + // We can add support for more protocols as needed. return nil, fmt.Errorf("ipv4 header's next layer is unrecognized: %#v", n) } } diff --git a/test/packetimpact/testbench/rawsockets.go b/test/packetimpact/testbench/rawsockets.go index feeb0888a..6d95c033d 100644 --- a/test/packetimpact/testbench/rawsockets.go +++ b/test/packetimpact/testbench/rawsockets.go @@ -17,7 +17,6 @@ package testbench import ( "encoding/binary" "fmt" - "math" "net" "testing" "time" @@ -81,19 +80,20 @@ func (s *Sniffer) Recv(t *testing.T, timeout time.Duration) []byte { deadline := time.Now().Add(timeout) for { - timeout = deadline.Sub(time.Now()) + timeout = time.Until(deadline) if timeout <= 0 { return nil } - whole, frac := math.Modf(timeout.Seconds()) - tv := unix.Timeval{ - Sec: int64(whole), - Usec: int64(frac * float64(time.Second/time.Microsecond)), + usec := timeout.Microseconds() + if usec == 0 { + // Timeout is less than a microsecond; set usec to 1 to avoid + // blocking indefinitely. + usec = 1 } - // The following should never happen, but having this guard here is better - // than blocking indefinitely in the future. - if tv.Sec == 0 && tv.Usec == 0 { - t.Fatal("setting SO_RCVTIMEO to 0 means blocking indefinitely") + const microsInOne = 1e6 + tv := unix.Timeval{ + Sec: usec / microsInOne, + Usec: usec % microsInOne, } if err := unix.SetsockoptTimeval(s.fd, unix.SOL_SOCKET, unix.SO_RCVTIMEO, &tv); err != nil { t.Fatalf("can't setsockopt SO_RCVTIMEO: %s", err) diff --git a/test/packetimpact/testbench/testbench.go b/test/packetimpact/testbench/testbench.go index d0efbcc08..caa389780 100644 --- a/test/packetimpact/testbench/testbench.go +++ b/test/packetimpact/testbench/testbench.go @@ -132,6 +132,7 @@ func registerFlags(fs *flag.FlagSet) { // Initialize initializes the testbench, it parse the flags and sets up the // pool of test networks for testbench's later use. func Initialize(fs *flag.FlagSet) { + testing.Init() registerFlags(fs) flag.Parse() if err := loadDUTInfos(); err != nil { diff --git a/test/packetimpact/tests/BUILD b/test/packetimpact/tests/BUILD index 37b59b1d9..4cff0cf4c 100644 --- a/test/packetimpact/tests/BUILD +++ b/test/packetimpact/tests/BUILD @@ -384,6 +384,7 @@ packetimpact_testbench( deps = [ "//pkg/tcpip/header", "//test/packetimpact/testbench", + "@com_github_google_go_cmp//cmp:go_default_library", "@org_golang_x_sys//unix:go_default_library", ], ) diff --git a/test/packetimpact/tests/tcp_syncookie_test.go b/test/packetimpact/tests/tcp_syncookie_test.go index 1a016bd1a..6be09996b 100644 --- a/test/packetimpact/tests/tcp_syncookie_test.go +++ b/test/packetimpact/tests/tcp_syncookie_test.go @@ -21,6 +21,7 @@ import ( "testing" "time" + "github.com/google/go-cmp/cmp" "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/tcpip/header" "gvisor.dev/gvisor/test/packetimpact/testbench" @@ -114,7 +115,10 @@ func TestTCPSynCookie(t *testing.T) { t.Fatalf("dut.Poll(...) = %d, want = %d", got, want) } - c.conn.Send(t, testbench.TCP{Flags: testbench.TCPFlags(test.flags)}) + sampleData := []byte("Sample Data") + samplePayload := &testbench.Payload{Bytes: sampleData} + + c.conn.Send(t, testbench.TCP{Flags: testbench.TCPFlags(test.flags)}, samplePayload) pfds = dut.Poll(t, []unix.PollFd{{Fd: listenFD, Events: unix.POLLIN}}, time.Second) want := 0 if test.accept { @@ -126,6 +130,18 @@ func TestTCPSynCookie(t *testing.T) { // Accept the connection to enable poll on any subsequent connection. if test.accept { fd, _ := dut.Accept(t, listenFD) + if test.flags.Contains(header.TCPFlagFin) { + if dut.Uname.IsLinux() { + dut.PollOne(t, fd, unix.POLLIN|unix.POLLRDHUP, time.Second) + } else { + // TODO(gvisor.dev/issue/6015): Notify POLLIN|POLLRDHUP on incoming FIN. + dut.PollOne(t, fd, unix.POLLIN, time.Second) + } + } + got := dut.Recv(t, fd, int32(len(sampleData)), 0) + if diff := cmp.Diff(got, sampleData); diff != "" { + t.Fatalf("dut.Recv: data mismatch (-want +got):\n%s", diff) + } dut.Close(t, fd) } }) diff --git a/test/syscalls/linux/rename.cc b/test/syscalls/linux/rename.cc index 76a8da65f..561eed99f 100644 --- a/test/syscalls/linux/rename.cc +++ b/test/syscalls/linux/rename.cc @@ -26,6 +26,8 @@ #include "test/util/temp_path.h" #include "test/util/test_util.h" +using ::testing::AnyOf; + namespace gvisor { namespace testing { @@ -438,6 +440,60 @@ TEST(RenameTest, SysfsDirectoryToSelf) { EXPECT_THAT(rename(path.c_str(), path.c_str()), SyscallSucceeds()); } +#ifndef SYS_renameat2 +#if defined(__x86_64__) +#define SYS_renameat2 316 +#elif defined(__aarch64__) +#define SYS_renameat2 276 +#else +#error "Unknown architecture" +#endif +#endif // SYS_renameat2 + +#ifndef RENAME_NOREPLACE +#define RENAME_NOREPLACE (1 << 0) +#endif // RENAME_NOREPLACE + +int renameat2(int olddirfd, const char* oldpath, int newdirfd, + const char* newpath, unsigned int flags) { + return syscall(SYS_renameat2, olddirfd, oldpath, newdirfd, newpath, flags); +} + +TEST(Renameat2Test, NoReplaceSuccess) { + auto f = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile()); + std::string const newpath = NewTempAbsPath(); + // renameat2 may fail with ENOSYS (if the syscall is unsupported) or EINVAL + // (if flags are unsupported), or succeed (if RENAME_NOREPLACE is operating + // correctly). + EXPECT_THAT( + renameat2(AT_FDCWD, f.path().c_str(), AT_FDCWD, newpath.c_str(), + RENAME_NOREPLACE), + AnyOf(SyscallFailsWithErrno(AnyOf(ENOSYS, EINVAL)), SyscallSucceeds())); +} + +TEST(Renameat2Test, NoReplaceExisting) { + auto f1 = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile()); + auto f2 = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile()); + // renameat2 may fail with ENOSYS (if the syscall is unsupported), EINVAL (if + // flags are unsupported), or EEXIST (if RENAME_NOREPLACE is operating + // correctly). + EXPECT_THAT(renameat2(AT_FDCWD, f1.path().c_str(), AT_FDCWD, + f2.path().c_str(), RENAME_NOREPLACE), + SyscallFailsWithErrno(AnyOf(ENOSYS, EINVAL, EEXIST))); +} + +TEST(Renameat2Test, NoReplaceDot) { + auto d1 = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir()); + auto d2 = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir()); + // renameat2 may fail with ENOSYS (if the syscall is unsupported), EINVAL (if + // flags are unsupported), or EEXIST (if RENAME_NOREPLACE is operating + // correctly). + EXPECT_THAT( + renameat2(AT_FDCWD, d1.path().c_str(), AT_FDCWD, + absl::StrCat(d2.path(), "/.").c_str(), RENAME_NOREPLACE), + SyscallFailsWithErrno(AnyOf(ENOSYS, EINVAL, EEXIST))); +} + } // namespace } // namespace testing diff --git a/test/syscalls/linux/udp_socket.cc b/test/syscalls/linux/udp_socket.cc index 29e174f71..2b687c198 100644 --- a/test/syscalls/linux/udp_socket.cc +++ b/test/syscalls/linux/udp_socket.cc @@ -791,14 +791,14 @@ TEST_P(UdpSocketTest, RecvErrorConnRefused) { iov.iov_len = kBufLen; size_t control_buf_len = CMSG_SPACE(sizeof(sock_extended_err) + addrlen_); - char* control_buf = static_cast<char*>(calloc(1, control_buf_len)); + std::vector<char> control_buf(control_buf_len); struct sockaddr_storage remote; memset(&remote, 0, sizeof(remote)); struct msghdr msg = {}; msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_flags = 0; - msg.msg_control = control_buf; + msg.msg_control = control_buf.data(); msg.msg_controllen = control_buf_len; msg.msg_name = reinterpret_cast<void*>(&remote); msg.msg_namelen = addrlen_; |