From f74eed464b55d9640432432cd96d811578e9081e Mon Sep 17 00:00:00 2001 From: Ian Gudger Date: Fri, 14 Dec 2018 22:10:19 -0800 Subject: [PATCH] Add blocking recv tests PiperOrigin-RevId: 225646045 Change-Id: Ic712ebc627587ef4a9486f0b39fe8c96100f10ff --- test/syscalls/BUILD | 4 + test/syscalls/linux/BUILD | 75 ++++++++++++++++--- test/syscalls/linux/socket_blocking.cc | 60 +++++++++++++++ test/syscalls/linux/socket_blocking.h | 29 +++++++ .../linux/socket_ip_loopback_blocking.cc | 51 +++++++++++++ .../linux/socket_unix_blocking_local.cc | 52 +++++++++++++ 6 files changed, 261 insertions(+), 10 deletions(-) create mode 100644 test/syscalls/linux/socket_blocking.cc create mode 100644 test/syscalls/linux/socket_blocking.h create mode 100644 test/syscalls/linux/socket_ip_loopback_blocking.cc create mode 100644 test/syscalls/linux/socket_unix_blocking_local.cc diff --git a/test/syscalls/BUILD b/test/syscalls/BUILD index f3a7cc715..711b68c76 100644 --- a/test/syscalls/BUILD +++ b/test/syscalls/BUILD @@ -356,6 +356,10 @@ syscall_test(test = "//test/syscalls/linux:socket_netdevice_test") syscall_test(test = "//test/syscalls/linux:socket_netlink_route_test") +syscall_test(test = "//test/syscalls/linux:socket_blocking_local_test") + +syscall_test(test = "//test/syscalls/linux:socket_blocking_ip_test") + syscall_test(test = "//test/syscalls/linux:socket_non_stream_blocking_local_test") syscall_test(test = "//test/syscalls/linux:socket_non_stream_blocking_udp_test") diff --git a/test/syscalls/linux/BUILD b/test/syscalls/linux/BUILD index 1c48a2a43..784997c18 100644 --- a/test/syscalls/linux/BUILD +++ b/test/syscalls/linux/BUILD @@ -2148,6 +2148,27 @@ cc_library( alwayslink = 1, ) +cc_library( + name = "socket_blocking_test_cases", + testonly = 1, + srcs = [ + "socket_blocking.cc", + ], + hdrs = [ + "socket_blocking.h", + ], + deps = [ + ":socket_test_util", + ":unix_domain_socket_test_util", + "//test/util:test_util", + "//test/util:thread_util", + "//test/util:timer_util", + "@com_google_absl//absl/time", + "@com_google_googletest//:gtest", + ], + alwayslink = 1, +) + cc_library( name = "socket_unix_test_cases", testonly = 1, @@ -2207,6 +2228,27 @@ cc_library( alwayslink = 1, ) +cc_library( + name = "socket_non_stream_blocking_test_cases", + testonly = 1, + srcs = [ + "socket_non_stream_blocking.cc", + ], + hdrs = [ + "socket_non_stream_blocking.h", + ], + deps = [ + ":socket_test_util", + ":unix_domain_socket_test_util", + "//test/util:test_util", + "//test/util:thread_util", + "//test/util:timer_util", + "@com_google_absl//absl/time", + "@com_google_googletest//:gtest", + ], + alwayslink = 1, +) + cc_binary( name = "socket_stream_local_test", testonly = 1, @@ -2346,25 +2388,38 @@ cc_binary( ], ) -cc_library( - name = "socket_non_stream_blocking_test_cases", +cc_binary( + name = "socket_blocking_local_test", testonly = 1, srcs = [ - "socket_non_stream_blocking.cc", - ], - hdrs = [ - "socket_non_stream_blocking.h", + "socket_unix_blocking_local.cc", ], + linkstatic = 1, deps = [ + ":socket_blocking_test_cases", ":socket_test_util", ":unix_domain_socket_test_util", + "//test/util:test_main", + "//test/util:test_util", + "@com_google_googletest//:gtest", + ], +) + +cc_binary( + name = "socket_blocking_ip_test", + testonly = 1, + srcs = [ + "socket_ip_loopback_blocking.cc", + ], + linkstatic = 1, + deps = [ + ":ip_socket_test_util", + ":socket_blocking_test_cases", + ":socket_test_util", + "//test/util:test_main", "//test/util:test_util", - "//test/util:thread_util", - "//test/util:timer_util", - "@com_google_absl//absl/time", "@com_google_googletest//:gtest", ], - alwayslink = 1, ) cc_binary( diff --git a/test/syscalls/linux/socket_blocking.cc b/test/syscalls/linux/socket_blocking.cc new file mode 100644 index 000000000..c1bca467f --- /dev/null +++ b/test/syscalls/linux/socket_blocking.cc @@ -0,0 +1,60 @@ +// Copyright 2018 Google LLC +// +// 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 "test/syscalls/linux/socket_blocking.h" + +#include +#include +#include +#include + +#include "gtest/gtest.h" +#include "gtest/gtest.h" +#include "absl/time/clock.h" +#include "absl/time/time.h" +#include "test/syscalls/linux/socket_test_util.h" +#include "test/syscalls/linux/unix_domain_socket_test_util.h" +#include "test/util/test_util.h" +#include "test/util/thread_util.h" +#include "test/util/timer_util.h" + +namespace gvisor { +namespace testing { + +TEST_P(BlockingSocketPairTest, RecvBlocks) { + auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); + + char sent_data[100]; + RandomizeBuffer(sent_data, sizeof(sent_data)); + + constexpr auto kDuration = absl::Milliseconds(200); + auto before = Now(CLOCK_MONOTONIC); + + const ScopedThread t([&]() { + absl::SleepFor(kDuration); + ASSERT_THAT(write(sockets->first_fd(), sent_data, sizeof(sent_data)), + SyscallSucceedsWithValue(sizeof(sent_data))); + }); + + char received_data[sizeof(sent_data)] = {}; + ASSERT_THAT(RetryEINTR(recv)(sockets->second_fd(), received_data, + sizeof(received_data), 0), + SyscallSucceedsWithValue(sizeof(received_data))); + + auto after = Now(CLOCK_MONOTONIC); + EXPECT_GE(after - before, kDuration); +} + +} // namespace testing +} // namespace gvisor diff --git a/test/syscalls/linux/socket_blocking.h b/test/syscalls/linux/socket_blocking.h new file mode 100644 index 000000000..5cddee54b --- /dev/null +++ b/test/syscalls/linux/socket_blocking.h @@ -0,0 +1,29 @@ +// Copyright 2018 Google LLC +// +// 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. + +#ifndef GVISOR_TEST_SYSCALLS_LINUX_SOCKET_BLOCKING_H_ +#define GVISOR_TEST_SYSCALLS_LINUX_SOCKET_BLOCKING_H_ + +#include "test/syscalls/linux/socket_test_util.h" + +namespace gvisor { +namespace testing { + +// Test fixture for tests that apply to pairs of blocking connected sockets. +using BlockingSocketPairTest = SocketPairTest; + +} // namespace testing +} // namespace gvisor + +#endif // GVISOR_TEST_SYSCALLS_LINUX_SOCKET_BLOCKING_H_ diff --git a/test/syscalls/linux/socket_ip_loopback_blocking.cc b/test/syscalls/linux/socket_ip_loopback_blocking.cc new file mode 100644 index 000000000..a7effeab0 --- /dev/null +++ b/test/syscalls/linux/socket_ip_loopback_blocking.cc @@ -0,0 +1,51 @@ +// Copyright 2018 Google LLC +// +// 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 +#include + +#include "test/syscalls/linux/ip_socket_test_util.h" +#include "test/syscalls/linux/socket_blocking.h" +#include "test/syscalls/linux/socket_test_util.h" +#include "test/util/test_util.h" + +namespace gvisor { +namespace testing { + +std::vector GetSocketPairs() { + return VecCat( + ApplyVec( + IPv6UDPBidirectionalBindSocketPair, + AllBitwiseCombinations(List{0, SOCK_CLOEXEC})), + ApplyVec( + IPv4UDPBidirectionalBindSocketPair, + AllBitwiseCombinations(List{0, SOCK_CLOEXEC})), + ApplyVecToVec( + std::vector{ + NoOp, SetSockOpt(IPPROTO_TCP, TCP_NODELAY, &kSockOptOn)}, + VecCat( + ApplyVec( + IPv6TCPAcceptBindSocketPair, + AllBitwiseCombinations(List{0, SOCK_CLOEXEC})), + ApplyVec( + IPv4TCPAcceptBindSocketPair, + AllBitwiseCombinations(List{0, SOCK_CLOEXEC}))))); +} + +INSTANTIATE_TEST_CASE_P( + AllUnixDomainSockets, BlockingSocketPairTest, + ::testing::ValuesIn(IncludeReversals(GetSocketPairs()))); + +} // namespace testing +} // namespace gvisor diff --git a/test/syscalls/linux/socket_unix_blocking_local.cc b/test/syscalls/linux/socket_unix_blocking_local.cc new file mode 100644 index 000000000..f79e04b33 --- /dev/null +++ b/test/syscalls/linux/socket_unix_blocking_local.cc @@ -0,0 +1,52 @@ +// Copyright 2018 Google LLC +// +// 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 "test/syscalls/linux/socket_blocking.h" + +#include + +#include "test/syscalls/linux/socket_test_util.h" +#include "test/syscalls/linux/unix_domain_socket_test_util.h" +#include "test/util/test_util.h" + +namespace gvisor { +namespace testing { + +std::vector GetSocketPairs() { + return VecCat( + ApplyVec( + UnixDomainSocketPair, + AllBitwiseCombinations( + List{SOCK_STREAM, SOCK_SEQPACKET, SOCK_DGRAM}, + List{0, SOCK_CLOEXEC})), + ApplyVec( + FilesystemBoundUnixDomainSocketPair, + AllBitwiseCombinations( + // FIXME: Add SOCK_DGRAM once blocking is fixed. + List{SOCK_STREAM, SOCK_SEQPACKET}, + List{0, SOCK_CLOEXEC})), + ApplyVec( + AbstractBoundUnixDomainSocketPair, + AllBitwiseCombinations( + // FIXME: Add SOCK_DGRAM once blocking is fixed. + List{SOCK_STREAM, SOCK_SEQPACKET}, + List{0, SOCK_CLOEXEC}))); +} + +INSTANTIATE_TEST_CASE_P( + AllUnixDomainSockets, BlockingSocketPairTest, + ::testing::ValuesIn(IncludeReversals(GetSocketPairs()))); + +} // namespace testing +} // namespace gvisor