summaryrefslogtreecommitdiffhomepage
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/iptables/README.md12
-rw-r--r--test/root/testdata/BUILD2
-rw-r--r--test/syscalls/linux/BUILD4
-rw-r--r--test/syscalls/linux/inotify.cc9
-rw-r--r--test/syscalls/linux/socket_ipv4_tcp_unbound_external_networking_test.cc3
-rw-r--r--test/syscalls/linux/socket_ipv4_udp_unbound.cc21
-rw-r--r--test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.cc20
-rw-r--r--test/syscalls/linux/socket_ipv4_udp_unbound_external_networking_test.cc3
-rw-r--r--test/syscalls/linux/socket_test_util.cc18
-rw-r--r--test/syscalls/linux/socket_test_util.h5
-rw-r--r--test/syscalls/linux/xattr.cc294
11 files changed, 211 insertions, 180 deletions
diff --git a/test/iptables/README.md b/test/iptables/README.md
index c2b934e1f..cc8a2fcac 100644
--- a/test/iptables/README.md
+++ b/test/iptables/README.md
@@ -2,6 +2,9 @@
iptables tests are run via `scripts/iptables_test.sh`.
+iptables requires raw socket support, so you must add the `--net-raw=true` flag
+to `/etc/docker/daemon.json` in order to use it.
+
## Test Structure
Each test implements `TestCase`, providing (1) a function to run inside the
@@ -25,7 +28,14 @@ Your test is now runnable with bazel!
## Run individual tests
-Build the testing Docker container:
+Build and install `runsc`. Re-run this when you modify gVisor:
+
+```bash
+$ bazel build //runsc && sudo cp bazel-bin/runsc/linux_amd64_pure_stripped/runsc $(which runsc)
+```
+
+Build the testing Docker container. Re-run this when you modify the test code in
+this directory:
```bash
$ bazel run //test/iptables/runner:runner-image -- --norun
diff --git a/test/root/testdata/BUILD b/test/root/testdata/BUILD
index bca5f9cab..6859541ad 100644
--- a/test/root/testdata/BUILD
+++ b/test/root/testdata/BUILD
@@ -13,6 +13,6 @@ go_library(
"simple.go",
],
visibility = [
- "//visibility:public",
+ "//:sandbox",
],
)
diff --git a/test/syscalls/linux/BUILD b/test/syscalls/linux/BUILD
index f2e3c7072..ca1af209a 100644
--- a/test/syscalls/linux/BUILD
+++ b/test/syscalls/linux/BUILD
@@ -12,6 +12,9 @@ exports_files(
"socket_ip_loopback_blocking.cc",
"socket_ip_tcp_loopback.cc",
"socket_ip_udp_loopback.cc",
+ "socket_ip_unbound.cc",
+ "socket_ipv4_tcp_unbound_external_networking_test.cc",
+ "socket_ipv4_udp_unbound_external_networking_test.cc",
"socket_ipv4_udp_unbound_loopback.cc",
"tcp_socket.cc",
"udp_socket.cc",
@@ -3779,6 +3782,7 @@ cc_binary(
"//test/util:capability_util",
"//test/util:file_descriptor",
"//test/util:fs_util",
+ "@com_google_absl//absl/container:flat_hash_set",
"@com_google_absl//absl/strings",
gtest,
"//test/util:posix_error",
diff --git a/test/syscalls/linux/inotify.cc b/test/syscalls/linux/inotify.cc
index fdef646eb..0e13ad190 100644
--- a/test/syscalls/linux/inotify.cc
+++ b/test/syscalls/linux/inotify.cc
@@ -1055,9 +1055,9 @@ TEST(Inotify, ChmodGeneratesAttribEvent_NoRandomSave) {
const TempPath file1 =
ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFileIn(root.path()));
- const FileDescriptor root_fd =
+ FileDescriptor root_fd =
ASSERT_NO_ERRNO_AND_VALUE(Open(root.path(), O_RDONLY));
- const FileDescriptor file1_fd =
+ FileDescriptor file1_fd =
ASSERT_NO_ERRNO_AND_VALUE(Open(file1.path(), O_RDWR));
FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(InotifyInit1(IN_NONBLOCK));
@@ -1091,6 +1091,11 @@ TEST(Inotify, ChmodGeneratesAttribEvent_NoRandomSave) {
ASSERT_THAT(fchmodat(root_fd.get(), file1_basename.c_str(), S_IWGRP, 0),
SyscallSucceeds());
verify_chmod_events();
+
+ // Make sure the chmod'ed file descriptors are destroyed before DisableSave
+ // is destructed.
+ root_fd.reset();
+ file1_fd.reset();
}
TEST(Inotify, TruncateGeneratesModifyEvent) {
diff --git a/test/syscalls/linux/socket_ipv4_tcp_unbound_external_networking_test.cc b/test/syscalls/linux/socket_ipv4_tcp_unbound_external_networking_test.cc
index 3ac790873..797c4174e 100644
--- a/test/syscalls/linux/socket_ipv4_tcp_unbound_external_networking_test.cc
+++ b/test/syscalls/linux/socket_ipv4_tcp_unbound_external_networking_test.cc
@@ -22,6 +22,7 @@
namespace gvisor {
namespace testing {
+namespace {
std::vector<SocketKind> GetSockets() {
return ApplyVec<SocketKind>(
@@ -32,5 +33,7 @@ std::vector<SocketKind> GetSockets() {
INSTANTIATE_TEST_SUITE_P(IPv4TCPUnboundSockets,
IPv4TCPUnboundExternalNetworkingSocketTest,
::testing::ValuesIn(GetSockets()));
+
+} // namespace
} // namespace testing
} // namespace gvisor
diff --git a/test/syscalls/linux/socket_ipv4_udp_unbound.cc b/test/syscalls/linux/socket_ipv4_udp_unbound.cc
index aa6fb4e3f..990ccf23c 100644
--- a/test/syscalls/linux/socket_ipv4_udp_unbound.cc
+++ b/test/syscalls/linux/socket_ipv4_udp_unbound.cc
@@ -30,27 +30,6 @@
namespace gvisor {
namespace testing {
-constexpr char kMulticastAddress[] = "224.0.2.1";
-constexpr char kBroadcastAddress[] = "255.255.255.255";
-
-TestAddress V4Multicast() {
- TestAddress t("V4Multicast");
- t.addr.ss_family = AF_INET;
- t.addr_len = sizeof(sockaddr_in);
- reinterpret_cast<sockaddr_in*>(&t.addr)->sin_addr.s_addr =
- inet_addr(kMulticastAddress);
- return t;
-}
-
-TestAddress V4Broadcast() {
- TestAddress t("V4Broadcast");
- t.addr.ss_family = AF_INET;
- t.addr_len = sizeof(sockaddr_in);
- reinterpret_cast<sockaddr_in*>(&t.addr)->sin_addr.s_addr =
- inet_addr(kBroadcastAddress);
- return t;
-}
-
// Check that packets are not received without a group membership. Default send
// interface configured by bind.
TEST_P(IPv4UDPUnboundSocketTest, IpMulticastLoopbackNoGroup) {
diff --git a/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.cc b/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.cc
index 98ae414f3..40e673625 100644
--- a/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.cc
+++ b/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking.cc
@@ -41,26 +41,6 @@ TestAddress V4EmptyAddress() {
return t;
}
-constexpr char kMulticastAddress[] = "224.0.2.1";
-
-TestAddress V4Multicast() {
- TestAddress t("V4Multicast");
- t.addr.ss_family = AF_INET;
- t.addr_len = sizeof(sockaddr_in);
- reinterpret_cast<sockaddr_in*>(&t.addr)->sin_addr.s_addr =
- inet_addr(kMulticastAddress);
- return t;
-}
-
-TestAddress V4Broadcast() {
- TestAddress t("V4Broadcast");
- t.addr.ss_family = AF_INET;
- t.addr_len = sizeof(sockaddr_in);
- reinterpret_cast<sockaddr_in*>(&t.addr)->sin_addr.s_addr =
- htonl(INADDR_BROADCAST);
- return t;
-}
-
void IPv4UDPUnboundExternalNetworkingSocketTest::SetUp() {
got_if_infos_ = false;
diff --git a/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking_test.cc b/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking_test.cc
index 8f47952b0..f6e64c157 100644
--- a/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking_test.cc
+++ b/test/syscalls/linux/socket_ipv4_udp_unbound_external_networking_test.cc
@@ -22,6 +22,7 @@
namespace gvisor {
namespace testing {
+namespace {
std::vector<SocketKind> GetSockets() {
return ApplyVec<SocketKind>(
@@ -32,5 +33,7 @@ std::vector<SocketKind> GetSockets() {
INSTANTIATE_TEST_SUITE_P(IPv4UDPUnboundSockets,
IPv4UDPUnboundExternalNetworkingSocketTest,
::testing::ValuesIn(GetSockets()));
+
+} // namespace
} // namespace testing
} // namespace gvisor
diff --git a/test/syscalls/linux/socket_test_util.cc b/test/syscalls/linux/socket_test_util.cc
index c0c5ab3fe..5d3a39868 100644
--- a/test/syscalls/linux/socket_test_util.cc
+++ b/test/syscalls/linux/socket_test_util.cc
@@ -805,6 +805,24 @@ TestAddress V4MappedLoopback() {
return t;
}
+TestAddress V4Multicast() {
+ TestAddress t("V4Multicast");
+ t.addr.ss_family = AF_INET;
+ t.addr_len = sizeof(sockaddr_in);
+ reinterpret_cast<sockaddr_in*>(&t.addr)->sin_addr.s_addr =
+ inet_addr(kMulticastAddress);
+ return t;
+}
+
+TestAddress V4Broadcast() {
+ TestAddress t("V4Broadcast");
+ t.addr.ss_family = AF_INET;
+ t.addr_len = sizeof(sockaddr_in);
+ reinterpret_cast<sockaddr_in*>(&t.addr)->sin_addr.s_addr =
+ htonl(INADDR_BROADCAST);
+ return t;
+}
+
TestAddress V6Any() {
TestAddress t("V6Any");
t.addr.ss_family = AF_INET6;
diff --git a/test/syscalls/linux/socket_test_util.h b/test/syscalls/linux/socket_test_util.h
index bfaa6e397..734b48b96 100644
--- a/test/syscalls/linux/socket_test_util.h
+++ b/test/syscalls/linux/socket_test_util.h
@@ -484,10 +484,15 @@ struct TestAddress {
: description(std::move(description)), addr(), addr_len() {}
};
+constexpr char kMulticastAddress[] = "224.0.2.1";
+constexpr char kBroadcastAddress[] = "255.255.255.255";
+
TestAddress V4Any();
+TestAddress V4Broadcast();
TestAddress V4Loopback();
TestAddress V4MappedAny();
TestAddress V4MappedLoopback();
+TestAddress V4Multicast();
TestAddress V6Any();
TestAddress V6Loopback();
diff --git a/test/syscalls/linux/xattr.cc b/test/syscalls/linux/xattr.cc
index 85eb31847..8b00ef44c 100644
--- a/test/syscalls/linux/xattr.cc
+++ b/test/syscalls/linux/xattr.cc
@@ -24,6 +24,7 @@
#include "gmock/gmock.h"
#include "gtest/gtest.h"
+#include "absl/container/flat_hash_set.h"
#include "test/syscalls/linux/file_base.h"
#include "test/util/capability_util.h"
#include "test/util/file_descriptor.h"
@@ -38,36 +39,36 @@ namespace {
class XattrTest : public FileTest {};
-TEST_F(XattrTest, XattrNullName) {
- // TODO(gvisor.dev/issue/1636): Re-enable once list/remove xattr are
- // supported, and get/set have been added pack to the syscall table.
- SKIP_IF(IsRunningOnGvisor());
+TEST_F(XattrTest, XattrNonexistentFile) {
+ const char* path = "/does/not/exist";
+ EXPECT_THAT(setxattr(path, nullptr, nullptr, 0, /*flags=*/0),
+ SyscallFailsWithErrno(ENOENT));
+ EXPECT_THAT(getxattr(path, nullptr, nullptr, 0),
+ SyscallFailsWithErrno(ENOENT));
+ EXPECT_THAT(listxattr(path, nullptr, 0), SyscallFailsWithErrno(ENOENT));
+ EXPECT_THAT(removexattr(path, nullptr), SyscallFailsWithErrno(ENOENT));
+}
+TEST_F(XattrTest, XattrNullName) {
const char* path = test_file_name_.c_str();
EXPECT_THAT(setxattr(path, nullptr, nullptr, 0, /*flags=*/0),
SyscallFailsWithErrno(EFAULT));
EXPECT_THAT(getxattr(path, nullptr, nullptr, 0),
SyscallFailsWithErrno(EFAULT));
+ EXPECT_THAT(removexattr(path, nullptr), SyscallFailsWithErrno(EFAULT));
}
TEST_F(XattrTest, XattrEmptyName) {
- // TODO(gvisor.dev/issue/1636): Re-enable once list/remove xattr are
- // supported, and get/set have been added pack to the syscall table.
- SKIP_IF(IsRunningOnGvisor());
-
const char* path = test_file_name_.c_str();
EXPECT_THAT(setxattr(path, "", nullptr, 0, /*flags=*/0),
SyscallFailsWithErrno(ERANGE));
EXPECT_THAT(getxattr(path, "", nullptr, 0), SyscallFailsWithErrno(ERANGE));
+ EXPECT_THAT(removexattr(path, ""), SyscallFailsWithErrno(ERANGE));
}
TEST_F(XattrTest, XattrLargeName) {
- // TODO(gvisor.dev/issue/1636): Re-enable once list/remove xattr are
- // supported, and get/set have been added pack to the syscall table.
- SKIP_IF(IsRunningOnGvisor());
-
const char* path = test_file_name_.c_str();
std::string name = "user.";
name += std::string(XATTR_NAME_MAX - name.length(), 'a');
@@ -86,28 +87,23 @@ TEST_F(XattrTest, XattrLargeName) {
SyscallFailsWithErrno(ERANGE));
EXPECT_THAT(getxattr(path, name.c_str(), nullptr, 0),
SyscallFailsWithErrno(ERANGE));
+ EXPECT_THAT(removexattr(path, name.c_str()), SyscallFailsWithErrno(ERANGE));
}
TEST_F(XattrTest, XattrInvalidPrefix) {
- // TODO(gvisor.dev/issue/1636): Re-enable once list/remove xattr are
- // supported, and get/set have been added pack to the syscall table.
- SKIP_IF(IsRunningOnGvisor());
-
const char* path = test_file_name_.c_str();
std::string name(XATTR_NAME_MAX, 'a');
EXPECT_THAT(setxattr(path, name.c_str(), nullptr, 0, /*flags=*/0),
SyscallFailsWithErrno(EOPNOTSUPP));
EXPECT_THAT(getxattr(path, name.c_str(), nullptr, 0),
SyscallFailsWithErrno(EOPNOTSUPP));
+ EXPECT_THAT(removexattr(path, name.c_str()),
+ SyscallFailsWithErrno(EOPNOTSUPP));
}
// Do not allow save/restore cycles after making the test file read-only, as
// the restore will fail to open it with r/w permissions.
TEST_F(XattrTest, XattrReadOnly_NoRandomSave) {
- // TODO(gvisor.dev/issue/1636): Re-enable once list/remove xattr are
- // supported, and get/set have been added pack to the syscall table.
- SKIP_IF(IsRunningOnGvisor());
-
// Drop capabilities that allow us to override file and directory permissions.
ASSERT_NO_ERRNO(SetCapability(CAP_DAC_OVERRIDE, false));
ASSERT_NO_ERRNO(SetCapability(CAP_DAC_READ_SEARCH, false));
@@ -124,19 +120,21 @@ TEST_F(XattrTest, XattrReadOnly_NoRandomSave) {
EXPECT_THAT(setxattr(path, name, &val, size, /*flags=*/0),
SyscallFailsWithErrno(EACCES));
+ EXPECT_THAT(removexattr(path, name), SyscallFailsWithErrno(EACCES));
char buf = '-';
EXPECT_THAT(getxattr(path, name, &buf, size), SyscallSucceedsWithValue(size));
EXPECT_EQ(buf, val);
+
+ char list[sizeof(name)];
+ EXPECT_THAT(listxattr(path, list, sizeof(list)),
+ SyscallSucceedsWithValue(sizeof(name)));
+ EXPECT_STREQ(list, name);
}
// Do not allow save/restore cycles after making the test file write-only, as
// the restore will fail to open it with r/w permissions.
TEST_F(XattrTest, XattrWriteOnly_NoRandomSave) {
- // TODO(gvisor.dev/issue/1636): Re-enable once list/remove xattr are
- // supported, and get/set have been added pack to the syscall table.
- SKIP_IF(IsRunningOnGvisor());
-
// Drop capabilities that allow us to override file and directory permissions.
ASSERT_NO_ERRNO(SetCapability(CAP_DAC_OVERRIDE, false));
ASSERT_NO_ERRNO(SetCapability(CAP_DAC_READ_SEARCH, false));
@@ -152,6 +150,14 @@ TEST_F(XattrTest, XattrWriteOnly_NoRandomSave) {
EXPECT_THAT(setxattr(path, name, &val, size, /*flags=*/0), SyscallSucceeds());
EXPECT_THAT(getxattr(path, name, nullptr, 0), SyscallFailsWithErrno(EACCES));
+
+ // listxattr will succeed even without read permissions.
+ char list[sizeof(name)];
+ EXPECT_THAT(listxattr(path, list, sizeof(list)),
+ SyscallSucceedsWithValue(sizeof(name)));
+ EXPECT_STREQ(list, name);
+
+ EXPECT_THAT(removexattr(path, name), SyscallSucceeds());
}
TEST_F(XattrTest, XattrTrustedWithNonadmin) {
@@ -163,64 +169,66 @@ TEST_F(XattrTest, XattrTrustedWithNonadmin) {
const char name[] = "trusted.abc";
EXPECT_THAT(setxattr(path, name, nullptr, 0, /*flags=*/0),
SyscallFailsWithErrno(EPERM));
+ EXPECT_THAT(removexattr(path, name), SyscallFailsWithErrno(EPERM));
EXPECT_THAT(getxattr(path, name, nullptr, 0), SyscallFailsWithErrno(ENODATA));
}
TEST_F(XattrTest, XattrOnDirectory) {
- // TODO(gvisor.dev/issue/1636): Re-enable once list/remove xattr are
- // supported, and get/set have been added pack to the syscall table.
- SKIP_IF(IsRunningOnGvisor());
-
TempPath dir = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir());
const char name[] = "user.test";
- EXPECT_THAT(setxattr(dir.path().c_str(), name, NULL, 0, /*flags=*/0),
+ EXPECT_THAT(setxattr(dir.path().c_str(), name, nullptr, 0, /*flags=*/0),
SyscallSucceeds());
- EXPECT_THAT(getxattr(dir.path().c_str(), name, NULL, 0),
+ EXPECT_THAT(getxattr(dir.path().c_str(), name, nullptr, 0),
SyscallSucceedsWithValue(0));
+
+ char list[sizeof(name)];
+ EXPECT_THAT(listxattr(dir.path().c_str(), list, sizeof(list)),
+ SyscallSucceedsWithValue(sizeof(name)));
+ EXPECT_STREQ(list, name);
+
+ EXPECT_THAT(removexattr(dir.path().c_str(), name), SyscallSucceeds());
}
TEST_F(XattrTest, XattrOnSymlink) {
- // TODO(gvisor.dev/issue/1636): Re-enable once list/remove xattr are
- // supported, and get/set have been added pack to the syscall table.
- SKIP_IF(IsRunningOnGvisor());
-
TempPath dir = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir());
TempPath link = ASSERT_NO_ERRNO_AND_VALUE(
TempPath::CreateSymlinkTo(dir.path(), test_file_name_));
const char name[] = "user.test";
- EXPECT_THAT(setxattr(link.path().c_str(), name, NULL, 0, /*flags=*/0),
+ EXPECT_THAT(setxattr(link.path().c_str(), name, nullptr, 0, /*flags=*/0),
SyscallSucceeds());
- EXPECT_THAT(getxattr(link.path().c_str(), name, NULL, 0),
+ EXPECT_THAT(getxattr(link.path().c_str(), name, nullptr, 0),
SyscallSucceedsWithValue(0));
+
+ char list[sizeof(name)];
+ EXPECT_THAT(listxattr(link.path().c_str(), list, sizeof(list)),
+ SyscallSucceedsWithValue(sizeof(name)));
+ EXPECT_STREQ(list, name);
+
+ EXPECT_THAT(removexattr(link.path().c_str(), name), SyscallSucceeds());
}
TEST_F(XattrTest, XattrOnInvalidFileTypes) {
- // TODO(gvisor.dev/issue/1636): Re-enable once list/remove xattr are
- // supported, and get/set have been added pack to the syscall table.
- SKIP_IF(IsRunningOnGvisor());
-
const char name[] = "user.test";
char char_device[] = "/dev/zero";
- EXPECT_THAT(setxattr(char_device, name, NULL, 0, /*flags=*/0),
+ EXPECT_THAT(setxattr(char_device, name, nullptr, 0, /*flags=*/0),
SyscallFailsWithErrno(EPERM));
- EXPECT_THAT(getxattr(char_device, name, NULL, 0),
+ EXPECT_THAT(getxattr(char_device, name, nullptr, 0),
SyscallFailsWithErrno(ENODATA));
+ EXPECT_THAT(listxattr(char_device, nullptr, 0), SyscallSucceedsWithValue(0));
// Use tmpfs, where creation of named pipes is supported.
const std::string fifo = NewTempAbsPathInDir("/dev/shm");
const char* path = fifo.c_str();
EXPECT_THAT(mknod(path, S_IFIFO | S_IRUSR | S_IWUSR, 0), SyscallSucceeds());
- EXPECT_THAT(setxattr(path, name, NULL, 0, /*flags=*/0),
+ EXPECT_THAT(setxattr(path, name, nullptr, 0, /*flags=*/0),
SyscallFailsWithErrno(EPERM));
- EXPECT_THAT(getxattr(path, name, NULL, 0), SyscallFailsWithErrno(ENODATA));
+ EXPECT_THAT(getxattr(path, name, nullptr, 0), SyscallFailsWithErrno(ENODATA));
+ EXPECT_THAT(listxattr(path, nullptr, 0), SyscallSucceedsWithValue(0));
+ EXPECT_THAT(removexattr(path, name), SyscallFailsWithErrno(EPERM));
}
TEST_F(XattrTest, SetxattrSizeSmallerThanValue) {
- // TODO(gvisor.dev/issue/1636): Re-enable once list/remove xattr are
- // supported, and get/set have been added pack to the syscall table.
- SKIP_IF(IsRunningOnGvisor());
-
const char* path = test_file_name_.c_str();
const char name[] = "user.test";
std::vector<char> val = {'a', 'a'};
@@ -236,10 +244,6 @@ TEST_F(XattrTest, SetxattrSizeSmallerThanValue) {
}
TEST_F(XattrTest, SetxattrZeroSize) {
- // TODO(gvisor.dev/issue/1636): Re-enable once list/remove xattr are
- // supported, and get/set have been added pack to the syscall table.
- SKIP_IF(IsRunningOnGvisor());
-
const char* path = test_file_name_.c_str();
const char name[] = "user.test";
char val = 'a';
@@ -252,10 +256,6 @@ TEST_F(XattrTest, SetxattrZeroSize) {
}
TEST_F(XattrTest, SetxattrSizeTooLarge) {
- // TODO(gvisor.dev/issue/1636): Re-enable once list/remove xattr are
- // supported, and get/set have been added pack to the syscall table.
- SKIP_IF(IsRunningOnGvisor());
-
const char* path = test_file_name_.c_str();
const char name[] = "user.test";
@@ -271,10 +271,6 @@ TEST_F(XattrTest, SetxattrSizeTooLarge) {
}
TEST_F(XattrTest, SetxattrNullValueAndNonzeroSize) {
- // TODO(gvisor.dev/issue/1636): Re-enable once list/remove xattr are
- // supported, and get/set have been added pack to the syscall table.
- SKIP_IF(IsRunningOnGvisor());
-
const char* path = test_file_name_.c_str();
const char name[] = "user.test";
EXPECT_THAT(setxattr(path, name, nullptr, 1, /*flags=*/0),
@@ -284,10 +280,6 @@ TEST_F(XattrTest, SetxattrNullValueAndNonzeroSize) {
}
TEST_F(XattrTest, SetxattrNullValueAndZeroSize) {
- // TODO(gvisor.dev/issue/1636): Re-enable once list/remove xattr are
- // supported, and get/set have been added pack to the syscall table.
- SKIP_IF(IsRunningOnGvisor());
-
const char* path = test_file_name_.c_str();
const char name[] = "user.test";
EXPECT_THAT(setxattr(path, name, nullptr, 0, /*flags=*/0), SyscallSucceeds());
@@ -296,10 +288,6 @@ TEST_F(XattrTest, SetxattrNullValueAndZeroSize) {
}
TEST_F(XattrTest, SetxattrValueTooLargeButOKSize) {
- // TODO(gvisor.dev/issue/1636): Re-enable once list/remove xattr are
- // supported, and get/set have been added pack to the syscall table.
- SKIP_IF(IsRunningOnGvisor());
-
const char* path = test_file_name_.c_str();
const char name[] = "user.test";
std::vector<char> val(XATTR_SIZE_MAX + 1);
@@ -316,10 +304,6 @@ TEST_F(XattrTest, SetxattrValueTooLargeButOKSize) {
}
TEST_F(XattrTest, SetxattrReplaceWithSmaller) {
- // TODO(gvisor.dev/issue/1636): Re-enable once list/remove xattr are
- // supported, and get/set have been added pack to the syscall table.
- SKIP_IF(IsRunningOnGvisor());
-
const char* path = test_file_name_.c_str();
const char name[] = "user.test";
std::vector<char> val = {'a', 'a'};
@@ -335,10 +319,6 @@ TEST_F(XattrTest, SetxattrReplaceWithSmaller) {
}
TEST_F(XattrTest, SetxattrReplaceWithLarger) {
- // TODO(gvisor.dev/issue/1636): Re-enable once list/remove xattr are
- // supported, and get/set have been added pack to the syscall table.
- SKIP_IF(IsRunningOnGvisor());
-
const char* path = test_file_name_.c_str();
const char name[] = "user.test";
std::vector<char> val = {'a', 'a'};
@@ -353,10 +333,6 @@ TEST_F(XattrTest, SetxattrReplaceWithLarger) {
}
TEST_F(XattrTest, SetxattrCreateFlag) {
- // TODO(gvisor.dev/issue/1636): Re-enable once list/remove xattr are
- // supported, and get/set have been added pack to the syscall table.
- SKIP_IF(IsRunningOnGvisor());
-
const char* path = test_file_name_.c_str();
const char name[] = "user.test";
EXPECT_THAT(setxattr(path, name, nullptr, 0, XATTR_CREATE),
@@ -368,10 +344,6 @@ TEST_F(XattrTest, SetxattrCreateFlag) {
}
TEST_F(XattrTest, SetxattrReplaceFlag) {
- // TODO(gvisor.dev/issue/1636): Re-enable once list/remove xattr are
- // supported, and get/set have been added pack to the syscall table.
- SKIP_IF(IsRunningOnGvisor());
-
const char* path = test_file_name_.c_str();
const char name[] = "user.test";
EXPECT_THAT(setxattr(path, name, nullptr, 0, XATTR_REPLACE),
@@ -384,10 +356,6 @@ TEST_F(XattrTest, SetxattrReplaceFlag) {
}
TEST_F(XattrTest, SetxattrInvalidFlags) {
- // TODO(gvisor.dev/issue/1636): Re-enable once list/remove xattr are
- // supported, and get/set have been added pack to the syscall table.
- SKIP_IF(IsRunningOnGvisor());
-
const char* path = test_file_name_.c_str();
int invalid_flags = 0xff;
EXPECT_THAT(setxattr(path, nullptr, nullptr, 0, invalid_flags),
@@ -395,10 +363,6 @@ TEST_F(XattrTest, SetxattrInvalidFlags) {
}
TEST_F(XattrTest, Getxattr) {
- // TODO(gvisor.dev/issue/1636): Re-enable once list/remove xattr are
- // supported, and get/set have been added pack to the syscall table.
- SKIP_IF(IsRunningOnGvisor());
-
const char* path = test_file_name_.c_str();
const char name[] = "user.test";
int val = 1234;
@@ -411,10 +375,6 @@ TEST_F(XattrTest, Getxattr) {
}
TEST_F(XattrTest, GetxattrSizeSmallerThanValue) {
- // TODO(gvisor.dev/issue/1636): Re-enable once list/remove xattr are
- // supported, and get/set have been added pack to the syscall table.
- SKIP_IF(IsRunningOnGvisor());
-
const char* path = test_file_name_.c_str();
const char name[] = "user.test";
std::vector<char> val = {'a', 'a'};
@@ -427,10 +387,6 @@ TEST_F(XattrTest, GetxattrSizeSmallerThanValue) {
}
TEST_F(XattrTest, GetxattrSizeLargerThanValue) {
- // TODO(gvisor.dev/issue/1636): Re-enable once list/remove xattr are
- // supported, and get/set have been added pack to the syscall table.
- SKIP_IF(IsRunningOnGvisor());
-
const char* path = test_file_name_.c_str();
const char name[] = "user.test";
char val = 'a';
@@ -446,10 +402,6 @@ TEST_F(XattrTest, GetxattrSizeLargerThanValue) {
}
TEST_F(XattrTest, GetxattrZeroSize) {
- // TODO(gvisor.dev/issue/1636): Re-enable once list/remove xattr are
- // supported, and get/set have been added pack to the syscall table.
- SKIP_IF(IsRunningOnGvisor());
-
const char* path = test_file_name_.c_str();
const char name[] = "user.test";
char val = 'a';
@@ -463,10 +415,6 @@ TEST_F(XattrTest, GetxattrZeroSize) {
}
TEST_F(XattrTest, GetxattrSizeTooLarge) {
- // TODO(gvisor.dev/issue/1636): Re-enable once list/remove xattr are
- // supported, and get/set have been added pack to the syscall table.
- SKIP_IF(IsRunningOnGvisor());
-
const char* path = test_file_name_.c_str();
const char name[] = "user.test";
char val = 'a';
@@ -483,10 +431,6 @@ TEST_F(XattrTest, GetxattrSizeTooLarge) {
}
TEST_F(XattrTest, GetxattrNullValue) {
- // TODO(gvisor.dev/issue/1636): Re-enable once list/remove xattr are
- // supported, and get/set have been added pack to the syscall table.
- SKIP_IF(IsRunningOnGvisor());
-
const char* path = test_file_name_.c_str();
const char name[] = "user.test";
char val = 'a';
@@ -498,10 +442,6 @@ TEST_F(XattrTest, GetxattrNullValue) {
}
TEST_F(XattrTest, GetxattrNullValueAndZeroSize) {
- // TODO(gvisor.dev/issue/1636): Re-enable once list/remove xattr are
- // supported, and get/set have been added pack to the syscall table.
- SKIP_IF(IsRunningOnGvisor());
-
const char* path = test_file_name_.c_str();
const char name[] = "user.test";
char val = 'a';
@@ -518,35 +458,109 @@ TEST_F(XattrTest, GetxattrNullValueAndZeroSize) {
}
TEST_F(XattrTest, GetxattrNonexistentName) {
- // TODO(gvisor.dev/issue/1636): Re-enable once list/remove xattr are
- // supported, and get/set have been added pack to the syscall table.
- SKIP_IF(IsRunningOnGvisor());
+ const char* path = test_file_name_.c_str();
+ const char name[] = "user.test";
+ EXPECT_THAT(getxattr(path, name, nullptr, 0), SyscallFailsWithErrno(ENODATA));
+}
+
+TEST_F(XattrTest, Listxattr) {
+ const char* path = test_file_name_.c_str();
+ const std::string name = "user.test";
+ const std::string name2 = "user.test2";
+ const std::string name3 = "user.test3";
+ EXPECT_THAT(setxattr(path, name.c_str(), nullptr, 0, /*flags=*/0),
+ SyscallSucceeds());
+ EXPECT_THAT(setxattr(path, name2.c_str(), nullptr, 0, /*flags=*/0),
+ SyscallSucceeds());
+ EXPECT_THAT(setxattr(path, name3.c_str(), nullptr, 0, /*flags=*/0),
+ SyscallSucceeds());
+ std::vector<char> list(name.size() + 1 + name2.size() + 1 + name3.size() + 1);
+ char* buf = list.data();
+ EXPECT_THAT(listxattr(path, buf, XATTR_SIZE_MAX),
+ SyscallSucceedsWithValue(list.size()));
+
+ absl::flat_hash_set<std::string> got = {};
+ for (char* p = buf; p < buf + list.size(); p += strlen(p) + 1) {
+ got.insert(std::string{p});
+ }
+
+ absl::flat_hash_set<std::string> expected = {name, name2, name3};
+ EXPECT_EQ(got, expected);
+}
+
+TEST_F(XattrTest, ListxattrNoXattrs) {
+ const char* path = test_file_name_.c_str();
+
+ std::vector<char> list, expected;
+ EXPECT_THAT(listxattr(path, list.data(), sizeof(list)),
+ SyscallSucceedsWithValue(0));
+ EXPECT_EQ(list, expected);
+
+ // Listxattr should succeed if there are no attributes, even if the buffer
+ // passed in is a nullptr.
+ EXPECT_THAT(listxattr(path, nullptr, sizeof(list)),
+ SyscallSucceedsWithValue(0));
+}
+
+TEST_F(XattrTest, ListxattrNullBuffer) {
const char* path = test_file_name_.c_str();
const char name[] = "user.test";
+ EXPECT_THAT(setxattr(path, name, nullptr, 0, /*flags=*/0), SyscallSucceeds());
+
+ EXPECT_THAT(listxattr(path, nullptr, sizeof(name)),
+ SyscallFailsWithErrno(EFAULT));
+}
+
+TEST_F(XattrTest, ListxattrSizeTooSmall) {
+ const char* path = test_file_name_.c_str();
+ const char name[] = "user.test";
+ EXPECT_THAT(setxattr(path, name, nullptr, 0, /*flags=*/0), SyscallSucceeds());
+
+ char list[sizeof(name) - 1];
+ EXPECT_THAT(listxattr(path, list, sizeof(list)),
+ SyscallFailsWithErrno(ERANGE));
+}
+
+TEST_F(XattrTest, ListxattrZeroSize) {
+ const char* path = test_file_name_.c_str();
+ const char name[] = "user.test";
+ EXPECT_THAT(setxattr(path, name, nullptr, 0, /*flags=*/0), SyscallSucceeds());
+ EXPECT_THAT(listxattr(path, nullptr, 0),
+ SyscallSucceedsWithValue(sizeof(name)));
+}
+
+TEST_F(XattrTest, RemoveXattr) {
+ const char* path = test_file_name_.c_str();
+ const char name[] = "user.test";
+ EXPECT_THAT(setxattr(path, name, nullptr, 0, /*flags=*/0), SyscallSucceeds());
+ EXPECT_THAT(removexattr(path, name), SyscallSucceeds());
EXPECT_THAT(getxattr(path, name, nullptr, 0), SyscallFailsWithErrno(ENODATA));
}
-TEST_F(XattrTest, LGetSetxattrOnSymlink) {
- // TODO(gvisor.dev/issue/1636): Re-enable once list/remove xattr are
- // supported, and get/set have been added pack to the syscall table.
- SKIP_IF(IsRunningOnGvisor());
+TEST_F(XattrTest, RemoveXattrNonexistentName) {
+ const char* path = test_file_name_.c_str();
+ const char name[] = "user.test";
+ EXPECT_THAT(removexattr(path, name), SyscallFailsWithErrno(ENODATA));
+}
+TEST_F(XattrTest, LXattrOnSymlink) {
+ const char name[] = "user.test";
TempPath dir = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir());
TempPath link = ASSERT_NO_ERRNO_AND_VALUE(
TempPath::CreateSymlinkTo(dir.path(), test_file_name_));
- EXPECT_THAT(lsetxattr(link.path().c_str(), nullptr, nullptr, 0, 0),
+ EXPECT_THAT(lsetxattr(link.path().c_str(), name, nullptr, 0, 0),
SyscallFailsWithErrno(EPERM));
- EXPECT_THAT(lgetxattr(link.path().c_str(), nullptr, nullptr, 0),
+ EXPECT_THAT(lgetxattr(link.path().c_str(), name, nullptr, 0),
SyscallFailsWithErrno(ENODATA));
+ EXPECT_THAT(llistxattr(link.path().c_str(), nullptr, 0),
+ SyscallSucceedsWithValue(0));
+ EXPECT_THAT(lremovexattr(link.path().c_str(), name),
+ SyscallFailsWithErrno(EPERM));
}
-TEST_F(XattrTest, LGetSetxattrOnNonsymlink) {
- // TODO(gvisor.dev/issue/1636): Re-enable once list/remove xattr are
- // supported, and get/set have been added pack to the syscall table.
- SKIP_IF(IsRunningOnGvisor());
-
+TEST_F(XattrTest, LXattrOnNonsymlink) {
const char* path = test_file_name_.c_str();
const char name[] = "user.test";
int val = 1234;
@@ -558,13 +572,16 @@ TEST_F(XattrTest, LGetSetxattrOnNonsymlink) {
EXPECT_THAT(lgetxattr(path, name, &buf, size),
SyscallSucceedsWithValue(size));
EXPECT_EQ(buf, val);
-}
-TEST_F(XattrTest, FGetSetxattr) {
- // TODO(gvisor.dev/issue/1636): Re-enable once list/remove xattr are
- // supported, and get/set have been added pack to the syscall table.
- SKIP_IF(IsRunningOnGvisor());
+ char list[sizeof(name)];
+ EXPECT_THAT(llistxattr(path, list, sizeof(list)),
+ SyscallSucceedsWithValue(sizeof(name)));
+ EXPECT_STREQ(list, name);
+ EXPECT_THAT(lremovexattr(path, name), SyscallSucceeds());
+}
+
+TEST_F(XattrTest, XattrWithFD) {
const FileDescriptor fd =
ASSERT_NO_ERRNO_AND_VALUE(Open(test_file_name_.c_str(), 0));
const char name[] = "user.test";
@@ -577,6 +594,13 @@ TEST_F(XattrTest, FGetSetxattr) {
EXPECT_THAT(fgetxattr(fd.get(), name, &buf, size),
SyscallSucceedsWithValue(size));
EXPECT_EQ(buf, val);
+
+ char list[sizeof(name)];
+ EXPECT_THAT(flistxattr(fd.get(), list, sizeof(list)),
+ SyscallSucceedsWithValue(sizeof(name)));
+ EXPECT_STREQ(list, name);
+
+ EXPECT_THAT(fremovexattr(fd.get(), name), SyscallSucceeds());
}
} // namespace