mirror of
https://github.com/google/sandboxed-api.git
synced 2024-03-22 13:11:30 +08:00
Add tests for util.cc
PiperOrigin-RevId: 516439597 Change-Id: I2ac88b6188738e47f0e0bdb04382a50aa5aa9366
This commit is contained in:
parent
10d44614fd
commit
cb63dfead5
|
@ -975,6 +975,9 @@ cc_test(
|
||||||
copts = sapi_platform_copts(),
|
copts = sapi_platform_copts(),
|
||||||
deps = [
|
deps = [
|
||||||
":util",
|
":util",
|
||||||
|
"//sandboxed_api/util:status_matchers",
|
||||||
|
"@com_google_absl//absl/cleanup",
|
||||||
|
"@com_google_absl//absl/strings",
|
||||||
"@com_google_googletest//:gtest_main",
|
"@com_google_googletest//:gtest_main",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
|
@ -1071,6 +1071,9 @@ if(BUILD_TESTING AND SAPI_BUILD_TESTING)
|
||||||
)
|
)
|
||||||
target_link_libraries(sandbox2_util_test PRIVATE
|
target_link_libraries(sandbox2_util_test PRIVATE
|
||||||
sandbox2::util
|
sandbox2::util
|
||||||
|
absl::strings
|
||||||
|
absl::cleanup
|
||||||
|
sapi::status_matchers
|
||||||
sapi::test_main
|
sapi::test_main
|
||||||
)
|
)
|
||||||
gtest_discover_tests_xcompile(sandbox2_util_test)
|
gtest_discover_tests_xcompile(sandbox2_util_test)
|
||||||
|
|
|
@ -14,16 +14,32 @@
|
||||||
|
|
||||||
#include "sandboxed_api/sandbox2/util.h"
|
#include "sandboxed_api/sandbox2/util.h"
|
||||||
|
|
||||||
|
#include <sys/mman.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
#include "gmock/gmock.h"
|
#include "gmock/gmock.h"
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
#include "absl/cleanup/cleanup.h"
|
||||||
|
#include "absl/strings/string_view.h"
|
||||||
|
#include "sandboxed_api/util/status_matchers.h"
|
||||||
|
|
||||||
namespace sandbox2::util {
|
namespace sandbox2::util {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
using ::sapi::IsOk;
|
||||||
|
using ::testing::ElementsAre;
|
||||||
|
using ::testing::Eq;
|
||||||
using ::testing::Gt;
|
using ::testing::Gt;
|
||||||
|
using ::testing::IsEmpty;
|
||||||
using ::testing::IsTrue;
|
using ::testing::IsTrue;
|
||||||
|
using ::testing::Ne;
|
||||||
|
using ::testing::Not;
|
||||||
|
using ::testing::StrEq;
|
||||||
|
|
||||||
|
constexpr absl::string_view kTestString = "This is a test string";
|
||||||
|
|
||||||
TEST(UtilTest, TestCreateMemFd) {
|
TEST(UtilTest, TestCreateMemFd) {
|
||||||
int fd = 0;
|
int fd = 0;
|
||||||
|
@ -32,5 +48,116 @@ TEST(UtilTest, TestCreateMemFd) {
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(CharPtrArrayTest, FromStringVector) {
|
||||||
|
std::vector<std::string> strings = {"a", "b", "c"};
|
||||||
|
CharPtrArray array = CharPtrArray::FromStringVector(strings);
|
||||||
|
EXPECT_THAT(array.ToStringVector(), Eq(strings));
|
||||||
|
EXPECT_THAT(array.array(),
|
||||||
|
ElementsAre(StrEq("a"), StrEq("b"), StrEq("c"), nullptr));
|
||||||
|
EXPECT_THAT(array.data(), Eq(array.array().data()));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(CharPtrArrayTest, FromCharPtrArray) {
|
||||||
|
std::vector<std::string> strings = {"a", "b", "c"};
|
||||||
|
std::vector<char*> string_arr;
|
||||||
|
for (std::string& s : strings) {
|
||||||
|
string_arr.push_back(s.data());
|
||||||
|
}
|
||||||
|
string_arr.push_back(nullptr);
|
||||||
|
CharPtrArray array(string_arr.data());
|
||||||
|
EXPECT_THAT(array.ToStringVector(), Eq(strings));
|
||||||
|
EXPECT_THAT(array.array(),
|
||||||
|
ElementsAre(StrEq("a"), StrEq("b"), StrEq("c"), nullptr));
|
||||||
|
EXPECT_THAT(array.data(), Eq(array.array().data()));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(GetProcStatusLineTest, Pid) {
|
||||||
|
std::string line = GetProcStatusLine(getpid(), "Pid");
|
||||||
|
EXPECT_THAT(line, Eq(absl::StrCat(getpid())));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(GetProcStatusLineTest, NonExisting) {
|
||||||
|
std::string line =
|
||||||
|
GetProcStatusLine(getpid(), "__N_o_n_ExistingStatusSetting");
|
||||||
|
EXPECT_THAT(line, IsEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ForkWithFlagsTest, DoesForkNormally) {
|
||||||
|
int pfds[2];
|
||||||
|
ASSERT_THAT(pipe(pfds), Eq(0));
|
||||||
|
pid_t child = ForkWithFlags(SIGCHLD);
|
||||||
|
ASSERT_THAT(child, Ne(-1));
|
||||||
|
if (child == 0) {
|
||||||
|
char c = 'a';
|
||||||
|
if (!write(pfds[1], &c, 1)) {
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
close(pfds[1]);
|
||||||
|
char c = ' ';
|
||||||
|
EXPECT_THAT(read(pfds[0], &c, 1), Eq(1));
|
||||||
|
close(pfds[0]);
|
||||||
|
EXPECT_THAT(c, Eq('a'));
|
||||||
|
int status;
|
||||||
|
ASSERT_THAT(TEMP_FAILURE_RETRY(waitpid(child, &status, 0)), Eq(child));
|
||||||
|
EXPECT_TRUE(WIFEXITED(status));
|
||||||
|
EXPECT_THAT(WEXITSTATUS(status), Eq(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ForkWithFlagsTest, UnsupportedFlag) {
|
||||||
|
EXPECT_THAT(ForkWithFlags(CLONE_CHILD_CLEARTID), Eq(-1));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ReadCPathFromPidSplitPageTest, Normal) {
|
||||||
|
std::string test_str(kTestString);
|
||||||
|
absl::StatusOr<std::string> read =
|
||||||
|
ReadCPathFromPid(getpid(), reinterpret_cast<uintptr_t>(test_str.data()));
|
||||||
|
ASSERT_THAT(read, IsOk());
|
||||||
|
EXPECT_THAT(*read, Eq(kTestString));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ReadCPathFromPidSplitPageTest, Overlong) {
|
||||||
|
std::string test_str(PATH_MAX + 1, 'a');
|
||||||
|
absl::StatusOr<std::string> read =
|
||||||
|
ReadCPathFromPid(getpid(), reinterpret_cast<uintptr_t>(test_str.data()));
|
||||||
|
EXPECT_THAT(read, Not(IsOk()));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ReadCPathFromPidSplitPageTest, SplitPage) {
|
||||||
|
const uintptr_t page_size = getpagesize();
|
||||||
|
char* res = reinterpret_cast<char*>(mmap(nullptr, 2 * page_size,
|
||||||
|
PROT_READ | PROT_WRITE,
|
||||||
|
MAP_ANONYMOUS | MAP_PRIVATE, 0, 0));
|
||||||
|
ASSERT_THAT(res, Ne(MAP_FAILED));
|
||||||
|
absl::Cleanup cleanup = [res, page_size]() {
|
||||||
|
ASSERT_THAT(munmap(res, 2 * page_size), Eq(0));
|
||||||
|
};
|
||||||
|
char* str = &res[page_size - kTestString.size() / 2];
|
||||||
|
memcpy(str, kTestString.data(), kTestString.size());
|
||||||
|
absl::StatusOr<std::string> read =
|
||||||
|
ReadCPathFromPid(getpid(), reinterpret_cast<uintptr_t>(str));
|
||||||
|
ASSERT_THAT(read, IsOk());
|
||||||
|
EXPECT_THAT(*read, Eq(kTestString));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ReadCPathFromPidSplitPageTest, NearUnreadableMemory) {
|
||||||
|
const uintptr_t page_size = getpagesize();
|
||||||
|
char* res = reinterpret_cast<char*>(mmap(nullptr, 2 * page_size,
|
||||||
|
PROT_READ | PROT_WRITE,
|
||||||
|
MAP_ANONYMOUS | MAP_PRIVATE, 0, 0));
|
||||||
|
ASSERT_THAT(res, Ne(MAP_FAILED));
|
||||||
|
absl::Cleanup cleanup = [res, page_size]() {
|
||||||
|
ASSERT_THAT(munmap(res, 2 * page_size), Eq(0));
|
||||||
|
};
|
||||||
|
ASSERT_THAT(mprotect(&res[page_size], page_size, PROT_NONE), Eq(0));
|
||||||
|
char* str = &res[page_size - kTestString.size() - 1];
|
||||||
|
memcpy(str, kTestString.data(), kTestString.size());
|
||||||
|
absl::StatusOr<std::string> read =
|
||||||
|
ReadCPathFromPid(getpid(), reinterpret_cast<uintptr_t>(str));
|
||||||
|
ASSERT_THAT(read, IsOk());
|
||||||
|
EXPECT_THAT(*read, Eq(kTestString));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace sandbox2::util
|
} // namespace sandbox2::util
|
||||||
|
|
Loading…
Reference in New Issue
Block a user