summaryrefslogtreecommitdiffhomepage
path: root/test/syscalls/linux/readv_common.cc
diff options
context:
space:
mode:
authorBrian Geffon <bgeffon@google.com>2018-12-10 14:41:40 -0800
committerShentubot <shentubot@google.com>2018-12-10 14:42:34 -0800
commitd3bc79bc8438206ac6a14fde4eaa288fc07eee82 (patch)
treee820398591bfd1503456e877fa0c2bdd0f994959 /test/syscalls/linux/readv_common.cc
parent833edbd10b49db1f934dcb2495dcb41c1310eea4 (diff)
Open source system call tests.
PiperOrigin-RevId: 224886231 Change-Id: I0fccb4d994601739d8b16b1d4e6b31f40297fb22
Diffstat (limited to 'test/syscalls/linux/readv_common.cc')
-rw-r--r--test/syscalls/linux/readv_common.cc180
1 files changed, 180 insertions, 0 deletions
diff --git a/test/syscalls/linux/readv_common.cc b/test/syscalls/linux/readv_common.cc
new file mode 100644
index 000000000..349b80d7f
--- /dev/null
+++ b/test/syscalls/linux/readv_common.cc
@@ -0,0 +1,180 @@
+// 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 <errno.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "gtest/gtest.h"
+#include "gtest/gtest.h"
+#include "test/syscalls/linux/file_base.h"
+#include "test/util/test_util.h"
+
+namespace gvisor {
+namespace testing {
+
+extern const char kReadvTestData[] =
+ "127.0.0.1 localhost"
+ ""
+ "# The following lines are desirable for IPv6 capable hosts"
+ "::1 ip6-localhost ip6-loopback"
+ "fe00::0 ip6-localnet"
+ "ff00::0 ip6-mcastprefix"
+ "ff02::1 ip6-allnodes"
+ "ff02::2 ip6-allrouters"
+ "ff02::3 ip6-allhosts"
+ "192.168.1.100 a"
+ "93.184.216.34 foo.bar.example.com xcpu";
+extern const size_t kReadvTestDataSize = sizeof(kReadvTestData);
+
+static void ReadAllOneProvidedBuffer(int fd, std::vector<char>* buffer) {
+ struct iovec iovs[1];
+ iovs[0].iov_base = buffer->data();
+ iovs[0].iov_len = kReadvTestDataSize;
+
+ ASSERT_THAT(readv(fd, iovs, 1), SyscallSucceedsWithValue(kReadvTestDataSize));
+
+ std::pair<struct iovec*, int> iovec_desc(iovs, 1);
+ EXPECT_THAT(iovec_desc, MatchesStringLength(kReadvTestDataSize));
+ EXPECT_THAT(iovec_desc, MatchesStringValue(kReadvTestData));
+}
+
+void ReadAllOneBuffer(int fd) {
+ std::vector<char> buffer(kReadvTestDataSize);
+ ReadAllOneProvidedBuffer(fd, &buffer);
+}
+
+void ReadAllOneLargeBuffer(int fd) {
+ std::vector<char> buffer(10 * kReadvTestDataSize);
+ ReadAllOneProvidedBuffer(fd, &buffer);
+}
+
+void ReadOneHalfAtATime(int fd) {
+ int len0 = kReadvTestDataSize / 2;
+ int len1 = kReadvTestDataSize - len0;
+ std::vector<char> buffer0(len0);
+ std::vector<char> buffer1(len1);
+
+ struct iovec iovs[2];
+ iovs[0].iov_base = buffer0.data();
+ iovs[0].iov_len = len0;
+ iovs[1].iov_base = buffer1.data();
+ iovs[1].iov_len = len1;
+
+ ASSERT_THAT(readv(fd, iovs, 2), SyscallSucceedsWithValue(kReadvTestDataSize));
+
+ std::pair<struct iovec*, int> iovec_desc(iovs, 2);
+ EXPECT_THAT(iovec_desc, MatchesStringLength(kReadvTestDataSize));
+ EXPECT_THAT(iovec_desc, MatchesStringValue(kReadvTestData));
+}
+
+void ReadOneBufferPerByte(int fd) {
+ std::vector<char> buffer(kReadvTestDataSize);
+ std::vector<struct iovec> iovs(kReadvTestDataSize);
+ char* buffer_ptr = buffer.data();
+ struct iovec* iovs_ptr = iovs.data();
+
+ for (int i = 0; i < static_cast<int>(kReadvTestDataSize); i++) {
+ struct iovec iov = {
+ .iov_base = &buffer_ptr[i],
+ .iov_len = 1,
+ };
+ iovs_ptr[i] = iov;
+ }
+
+ ASSERT_THAT(readv(fd, iovs_ptr, kReadvTestDataSize),
+ SyscallSucceedsWithValue(kReadvTestDataSize));
+
+ std::pair<struct iovec*, int> iovec_desc(iovs.data(), kReadvTestDataSize);
+ EXPECT_THAT(iovec_desc, MatchesStringLength(kReadvTestDataSize));
+ EXPECT_THAT(iovec_desc, MatchesStringValue(kReadvTestData));
+}
+
+void ReadBuffersOverlapping(int fd) {
+ // overlap the first overlap_bytes.
+ int overlap_bytes = 8;
+ std::vector<char> buffer(kReadvTestDataSize);
+
+ // overlapping causes us to get more data.
+ int expected_size = kReadvTestDataSize + overlap_bytes;
+ std::vector<char> expected(expected_size);
+ char* expected_ptr = expected.data();
+ memcpy(expected_ptr, &kReadvTestData[overlap_bytes], overlap_bytes);
+ memcpy(&expected_ptr[overlap_bytes], &kReadvTestData[overlap_bytes],
+ kReadvTestDataSize);
+
+ struct iovec iovs[2];
+ iovs[0].iov_base = buffer.data();
+ iovs[0].iov_len = overlap_bytes;
+ iovs[1].iov_base = buffer.data();
+ iovs[1].iov_len = kReadvTestDataSize;
+
+ ASSERT_THAT(readv(fd, iovs, 2), SyscallSucceedsWithValue(kReadvTestDataSize));
+
+ std::pair<struct iovec*, int> iovec_desc(iovs, 2);
+ EXPECT_THAT(iovec_desc, MatchesStringLength(expected_size));
+ EXPECT_THAT(iovec_desc, MatchesStringValue(expected_ptr));
+}
+
+void ReadBuffersDiscontinuous(int fd) {
+ // Each iov is 1 byte separated by 1 byte.
+ std::vector<char> buffer(kReadvTestDataSize * 2);
+ std::vector<struct iovec> iovs(kReadvTestDataSize);
+
+ char* buffer_ptr = buffer.data();
+ struct iovec* iovs_ptr = iovs.data();
+
+ for (int i = 0; i < static_cast<int>(kReadvTestDataSize); i++) {
+ struct iovec iov = {
+ .iov_base = &buffer_ptr[i * 2],
+ .iov_len = 1,
+ };
+ iovs_ptr[i] = iov;
+ }
+
+ ASSERT_THAT(readv(fd, iovs_ptr, kReadvTestDataSize),
+ SyscallSucceedsWithValue(kReadvTestDataSize));
+
+ std::pair<struct iovec*, int> iovec_desc(iovs.data(), kReadvTestDataSize);
+ EXPECT_THAT(iovec_desc, MatchesStringLength(kReadvTestDataSize));
+ EXPECT_THAT(iovec_desc, MatchesStringValue(kReadvTestData));
+}
+
+void ReadIovecsCompletelyFilled(int fd) {
+ int half = kReadvTestDataSize / 2;
+ std::vector<char> buffer(kReadvTestDataSize);
+ char* buffer_ptr = buffer.data();
+ memset(buffer.data(), '\0', kReadvTestDataSize);
+
+ struct iovec iovs[2];
+ iovs[0].iov_base = buffer.data();
+ iovs[0].iov_len = half;
+ iovs[1].iov_base = &buffer_ptr[half];
+ iovs[1].iov_len = half;
+
+ ASSERT_THAT(readv(fd, iovs, 2), SyscallSucceedsWithValue(half * 2));
+
+ std::pair<struct iovec*, int> iovec_desc(iovs, 2);
+ EXPECT_THAT(iovec_desc, MatchesStringLength(half * 2));
+ EXPECT_THAT(iovec_desc, MatchesStringValue(kReadvTestData));
+
+ char* str = static_cast<char*>(iovs[0].iov_base);
+ str[iovs[0].iov_len - 1] = '\0';
+ ASSERT_EQ(half - 1, strlen(str));
+}
+
+} // namespace testing
+} // namespace gvisor