summaryrefslogtreecommitdiffhomepage
path: root/test/util
diff options
context:
space:
mode:
Diffstat (limited to 'test/util')
-rw-r--r--test/util/BUILD32
-rw-r--r--test/util/capability_util.cc8
-rw-r--r--test/util/fs_util.cc2
-rw-r--r--test/util/fs_util.h11
-rw-r--r--test/util/mount_util.h8
-rw-r--r--test/util/multiprocess_util.h6
-rw-r--r--test/util/platform_util.cc49
-rw-r--r--test/util/platform_util.h56
-rw-r--r--test/util/save_util_linux.cc18
-rw-r--r--test/util/save_util_other.cc4
-rw-r--r--test/util/test_util.cc11
-rw-r--r--test/util/test_util.h27
-rw-r--r--test/util/test_util_runfiles.cc4
13 files changed, 188 insertions, 48 deletions
diff --git a/test/util/BUILD b/test/util/BUILD
index cbc728159..1ac8b3fd6 100644
--- a/test/util/BUILD
+++ b/test/util/BUILD
@@ -1,5 +1,4 @@
-load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test")
-load("//test/syscalls:build_defs.bzl", "select_for_linux")
+load("//tools:defs.bzl", "cc_library", "cc_test", "select_system")
package(
default_visibility = ["//:sandbox"],
@@ -142,12 +141,13 @@ cc_library(
cc_library(
name = "save_util",
testonly = 1,
- srcs = ["save_util.cc"] +
- select_for_linux(
- ["save_util_linux.cc"],
- ["save_util_other.cc"],
- ),
+ srcs = [
+ "save_util.cc",
+ "save_util_linux.cc",
+ "save_util_other.cc",
+ ],
hdrs = ["save_util.h"],
+ defines = select_system(),
)
cc_library(
@@ -166,6 +166,14 @@ cc_library(
)
cc_library(
+ name = "platform_util",
+ testonly = 1,
+ srcs = ["platform_util.cc"],
+ hdrs = ["platform_util.h"],
+ deps = [":test_util"],
+)
+
+cc_library(
name = "posix_error",
testonly = 1,
srcs = ["posix_error.cc"],
@@ -234,13 +242,11 @@ cc_library(
testonly = 1,
srcs = [
"test_util.cc",
- ] + select_for_linux(
- [
- "test_util_impl.cc",
- "test_util_runfiles.cc",
- ],
- ),
+ "test_util_impl.cc",
+ "test_util_runfiles.cc",
+ ],
hdrs = ["test_util.h"],
+ defines = select_system(),
deps = [
":fs_util",
":logging",
diff --git a/test/util/capability_util.cc b/test/util/capability_util.cc
index 5d733887b..9fee52fbb 100644
--- a/test/util/capability_util.cc
+++ b/test/util/capability_util.cc
@@ -36,10 +36,10 @@ PosixErrorOr<bool> CanCreateUserNamespace() {
ASSIGN_OR_RETURN_ERRNO(
auto child_stack,
MmapAnon(kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE));
- int const child_pid =
- clone(+[](void*) { return 0; },
- reinterpret_cast<void*>(child_stack.addr() + kPageSize),
- CLONE_NEWUSER | SIGCHLD, /* arg = */ nullptr);
+ int const child_pid = clone(
+ +[](void*) { return 0; },
+ reinterpret_cast<void*>(child_stack.addr() + kPageSize),
+ CLONE_NEWUSER | SIGCHLD, /* arg = */ nullptr);
if (child_pid > 0) {
int status;
int const ret = waitpid(child_pid, &status, /* options = */ 0);
diff --git a/test/util/fs_util.cc b/test/util/fs_util.cc
index 042cec94a..052781445 100644
--- a/test/util/fs_util.cc
+++ b/test/util/fs_util.cc
@@ -452,7 +452,7 @@ PosixErrorOr<std::string> MakeAbsolute(absl::string_view filename,
std::string CleanPath(const absl::string_view unclean_path) {
std::string path = std::string(unclean_path);
- const char *src = path.c_str();
+ const char* src = path.c_str();
std::string::iterator dst = path.begin();
// Check for absolute path and determine initial backtrack limit.
diff --git a/test/util/fs_util.h b/test/util/fs_util.h
index ee1b341d7..caf19b24d 100644
--- a/test/util/fs_util.h
+++ b/test/util/fs_util.h
@@ -26,6 +26,17 @@
namespace gvisor {
namespace testing {
+
+// O_LARGEFILE as defined by Linux. glibc tries to be clever by setting it to 0
+// because "it isn't needed", even though Linux can return it via F_GETFL.
+#if defined(__x86_64__)
+constexpr int kOLargeFile = 00100000;
+#elif defined(__aarch64__)
+constexpr int kOLargeFile = 00400000;
+#else
+#error "Unknown architecture"
+#endif
+
// Returns a status or the current working directory.
PosixErrorOr<std::string> GetCWD();
diff --git a/test/util/mount_util.h b/test/util/mount_util.h
index 484de560e..09e2281eb 100644
--- a/test/util/mount_util.h
+++ b/test/util/mount_util.h
@@ -31,10 +31,10 @@ namespace testing {
// Mount mounts the filesystem, and unmounts when the returned reference is
// destroyed.
-inline PosixErrorOr<Cleanup> Mount(const std::string &source,
- const std::string &target,
- const std::string &fstype, uint64_t mountflags,
- const std::string &data,
+inline PosixErrorOr<Cleanup> Mount(const std::string& source,
+ const std::string& target,
+ const std::string& fstype,
+ uint64_t mountflags, const std::string& data,
uint64_t umountflags) {
if (mount(source.c_str(), target.c_str(), fstype.c_str(), mountflags,
data.c_str()) == -1) {
diff --git a/test/util/multiprocess_util.h b/test/util/multiprocess_util.h
index 61526b4e7..2f3bf4a6f 100644
--- a/test/util/multiprocess_util.h
+++ b/test/util/multiprocess_util.h
@@ -99,11 +99,13 @@ inline PosixErrorOr<Cleanup> ForkAndExec(const std::string& filename,
const ExecveArray& argv,
const ExecveArray& envv, pid_t* child,
int* execve_errno) {
- return ForkAndExec(filename, argv, envv, [] {}, child, execve_errno);
+ return ForkAndExec(
+ filename, argv, envv, [] {}, child, execve_errno);
}
// Equivalent to ForkAndExec, except using dirfd and flags with execveat.
-PosixErrorOr<Cleanup> ForkAndExecveat(int32_t dirfd, const std::string& pathname,
+PosixErrorOr<Cleanup> ForkAndExecveat(int32_t dirfd,
+ const std::string& pathname,
const ExecveArray& argv,
const ExecveArray& envv, int flags,
const std::function<void()>& fn,
diff --git a/test/util/platform_util.cc b/test/util/platform_util.cc
new file mode 100644
index 000000000..2724e63f3
--- /dev/null
+++ b/test/util/platform_util.cc
@@ -0,0 +1,49 @@
+// Copyright 2020 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 "test/util/platform_util.h"
+
+#include "test/util/test_util.h"
+
+namespace gvisor {
+namespace testing {
+
+PlatformSupport PlatformSupport32Bit() {
+ if (GvisorPlatform() == Platform::kPtrace) {
+ return PlatformSupport::NotSupported;
+ } else if (GvisorPlatform() == Platform::kKVM) {
+ return PlatformSupport::Segfault;
+ } else {
+ return PlatformSupport::Allowed;
+ }
+}
+
+PlatformSupport PlatformSupportAlignmentCheck() {
+ return PlatformSupport::Allowed;
+}
+
+PlatformSupport PlatformSupportMultiProcess() {
+ return PlatformSupport::Allowed;
+}
+
+PlatformSupport PlatformSupportInt3() {
+ if (GvisorPlatform() == Platform::kKVM) {
+ return PlatformSupport::NotSupported;
+ } else {
+ return PlatformSupport::Allowed;
+ }
+}
+
+} // namespace testing
+} // namespace gvisor
diff --git a/test/util/platform_util.h b/test/util/platform_util.h
new file mode 100644
index 000000000..28cc92371
--- /dev/null
+++ b/test/util/platform_util.h
@@ -0,0 +1,56 @@
+// Copyright 2020 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.
+
+#ifndef GVISOR_TEST_UTIL_PLATFORM_UTIL_H_
+#define GVISOR_TEST_UTIL_PLATFORM_UTIL_H_
+
+namespace gvisor {
+namespace testing {
+
+// PlatformSupport is a generic enumeration of classes of support.
+//
+// It is up to the individual functions and callers to agree on the precise
+// definition for each case. The document here generally refers to 32-bit
+// as an example. Many cases will use only NotSupported and Allowed.
+enum class PlatformSupport {
+ // The feature is not supported on the current platform.
+ //
+ // In the case of 32-bit, this means that calls will generally be interpreted
+ // as 64-bit calls, and there is no support for 32-bit binaries, long calls,
+ // etc. This usually means that the underlying implementation just pretends
+ // that 32-bit doesn't exist.
+ NotSupported,
+
+ // Calls will be ignored by the kernel with a fixed error.
+ Ignored,
+
+ // Calls will result in a SIGSEGV or similar fault.
+ Segfault,
+
+ // The feature is supported as expected.
+ //
+ // In the case of 32-bit, this means that the system call or far call will be
+ // handled properly.
+ Allowed,
+};
+
+PlatformSupport PlatformSupport32Bit();
+PlatformSupport PlatformSupportAlignmentCheck();
+PlatformSupport PlatformSupportMultiProcess();
+PlatformSupport PlatformSupportInt3();
+
+} // namespace testing
+} // namespace gvisor
+
+#endif // GVISOR_TEST_UTIL_PLATFORM_UTL_H_
diff --git a/test/util/save_util_linux.cc b/test/util/save_util_linux.cc
index 7a0f14342..d0aea8e6a 100644
--- a/test/util/save_util_linux.cc
+++ b/test/util/save_util_linux.cc
@@ -12,22 +12,38 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#ifdef __linux__
+
#include <errno.h>
#include <sys/syscall.h>
#include <unistd.h>
#include "test/util/save_util.h"
+#if defined(__x86_64__) || defined(__i386__)
+#define SYS_TRIGGER_SAVE SYS_create_module
+#elif defined(__aarch64__)
+#define SYS_TRIGGER_SAVE SYS_finit_module
+#else
+#error "Unknown architecture"
+#endif
+
namespace gvisor {
namespace testing {
void MaybeSave() {
if (internal::ShouldSave()) {
int orig_errno = errno;
- syscall(SYS_create_module, nullptr, 0);
+ // We use it to trigger saving the sentry state
+ // when this syscall is called.
+ // Notice: this needs to be a valid syscall
+ // that is not used in any of the syscall tests.
+ syscall(SYS_TRIGGER_SAVE, nullptr, 0);
errno = orig_errno;
}
}
} // namespace testing
} // namespace gvisor
+
+#endif
diff --git a/test/util/save_util_other.cc b/test/util/save_util_other.cc
index 1aca663b7..931af2c29 100644
--- a/test/util/save_util_other.cc
+++ b/test/util/save_util_other.cc
@@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#ifndef __linux__
+
namespace gvisor {
namespace testing {
@@ -21,3 +23,5 @@ void MaybeSave() {
} // namespace testing
} // namespace gvisor
+
+#endif
diff --git a/test/util/test_util.cc b/test/util/test_util.cc
index a4f78eec2..95e1e0c96 100644
--- a/test/util/test_util.cc
+++ b/test/util/test_util.cc
@@ -45,20 +45,13 @@ namespace testing {
bool IsRunningOnGvisor() { return GvisorPlatform() != Platform::kNative; }
-Platform GvisorPlatform() {
+const std::string GvisorPlatform() {
// Set by runner.go.
char* env = getenv(TEST_ON_GVISOR);
if (!env) {
return Platform::kNative;
}
- if (strcmp(env, "ptrace") == 0) {
- return Platform::kPtrace;
- }
- if (strcmp(env, "kvm") == 0) {
- return Platform::kKVM;
- }
- std::cerr << "unknown platform " << env;
- abort();
+ return std::string(env);
}
bool IsRunningWithHostinet() {
diff --git a/test/util/test_util.h b/test/util/test_util.h
index b3235c7e3..2d22b0eb8 100644
--- a/test/util/test_util.h
+++ b/test/util/test_util.h
@@ -26,16 +26,13 @@
// IsRunningOnGvisor returns true if the test is known to be running on gVisor.
// GvisorPlatform can be used to get more detail:
//
-// switch (GvisorPlatform()) {
-// case Platform::kNative:
-// case Platform::kGvisor:
-// EXPECT_THAT(mmap(...), SyscallSucceeds());
-// break;
-// case Platform::kPtrace:
-// EXPECT_THAT(mmap(...), SyscallFailsWithErrno(ENOSYS));
-// break;
+// if (GvisorPlatform() == Platform::kPtrace) {
+// ...
// }
//
+// SetupGvisorDeathTest ensures that signal handling does not interfere with
+/// tests that rely on fatal signals.
+//
// Matchers
// ========
//
@@ -213,13 +210,15 @@ void TestInit(int* argc, char*** argv);
if (expr) GTEST_SKIP() << #expr; \
} while (0)
-enum class Platform {
- kNative,
- kKVM,
- kPtrace,
-};
+// Platform contains platform names.
+namespace Platform {
+constexpr char kNative[] = "native";
+constexpr char kPtrace[] = "ptrace";
+constexpr char kKVM[] = "kvm";
+} // namespace Platform
+
bool IsRunningOnGvisor();
-Platform GvisorPlatform();
+const std::string GvisorPlatform();
bool IsRunningWithHostinet();
#ifdef __linux__
diff --git a/test/util/test_util_runfiles.cc b/test/util/test_util_runfiles.cc
index 7210094eb..694d21692 100644
--- a/test/util/test_util_runfiles.cc
+++ b/test/util/test_util_runfiles.cc
@@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#ifndef __fuchsia__
+
#include <iostream>
#include <string>
@@ -44,3 +46,5 @@ std::string RunfilePath(std::string path) {
} // namespace testing
} // namespace gvisor
+
+#endif // __fuchsia__