gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/test/util/test_util_test.cc (about) 1 // Copyright 2018 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include "test/util/test_util.h" 16 17 #include <errno.h> 18 19 #include <vector> 20 21 #include "gmock/gmock.h" 22 #include "gtest/gtest.h" 23 24 using ::testing::AnyOf; 25 using ::testing::Gt; 26 using ::testing::IsEmpty; 27 using ::testing::Lt; 28 using ::testing::Not; 29 using ::testing::TypedEq; 30 using ::testing::UnorderedElementsAre; 31 using ::testing::UnorderedElementsAreArray; 32 33 namespace gvisor { 34 namespace testing { 35 36 namespace { 37 38 TEST(KernelVersionParsing, ValidateParsing) { 39 KernelVersion v = ASSERT_NO_ERRNO_AND_VALUE( 40 ParseKernelVersion("4.18.10-1foo2-amd64 baz blah")); 41 ASSERT_TRUE(v == KernelVersion({4, 18, 10})); 42 43 v = ASSERT_NO_ERRNO_AND_VALUE(ParseKernelVersion("4.18.10-1foo2-amd64")); 44 ASSERT_TRUE(v == KernelVersion({4, 18, 10})); 45 46 v = ASSERT_NO_ERRNO_AND_VALUE(ParseKernelVersion("4.18.10-14-amd64")); 47 ASSERT_TRUE(v == KernelVersion({4, 18, 10})); 48 49 v = ASSERT_NO_ERRNO_AND_VALUE(ParseKernelVersion("4.18.10-amd64")); 50 ASSERT_TRUE(v == KernelVersion({4, 18, 10})); 51 52 v = ASSERT_NO_ERRNO_AND_VALUE(ParseKernelVersion("4.18.10")); 53 ASSERT_TRUE(v == KernelVersion({4, 18, 10})); 54 55 v = ASSERT_NO_ERRNO_AND_VALUE(ParseKernelVersion("4.0.10")); 56 ASSERT_TRUE(v == KernelVersion({4, 0, 10})); 57 58 v = ASSERT_NO_ERRNO_AND_VALUE(ParseKernelVersion("4.0")); 59 ASSERT_TRUE(v == KernelVersion({4, 0, 0})); 60 61 ASSERT_THAT(ParseKernelVersion("4.a"), PosixErrorIs(EINVAL, ::testing::_)); 62 ASSERT_THAT(ParseKernelVersion("3"), PosixErrorIs(EINVAL, ::testing::_)); 63 ASSERT_THAT(ParseKernelVersion(""), PosixErrorIs(EINVAL, ::testing::_)); 64 ASSERT_THAT(ParseKernelVersion("version 3.3.10"), 65 PosixErrorIs(EINVAL, ::testing::_)); 66 } 67 68 TEST(MatchersTest, SyscallSucceeds) { 69 EXPECT_THAT(0, SyscallSucceeds()); 70 EXPECT_THAT(0L, SyscallSucceeds()); 71 72 errno = 0; 73 EXPECT_THAT(-1, SyscallSucceeds()); 74 EXPECT_THAT(-1L, SyscallSucceeds()); 75 76 errno = ENOMEM; 77 EXPECT_THAT(-1, Not(SyscallSucceeds())); 78 EXPECT_THAT(-1L, Not(SyscallSucceeds())); 79 } 80 81 TEST(MatchersTest, SyscallSucceedsWithValue) { 82 EXPECT_THAT(0, SyscallSucceedsWithValue(0)); 83 EXPECT_THAT(1, SyscallSucceedsWithValue(Lt(3))); 84 EXPECT_THAT(-1, Not(SyscallSucceedsWithValue(Lt(3)))); 85 EXPECT_THAT(4, Not(SyscallSucceedsWithValue(Lt(3)))); 86 87 // Non-int -1 88 EXPECT_THAT(-1L, Not(SyscallSucceedsWithValue(0))); 89 90 // Non-int, truncates to -1 if converted to int, with expected value 91 EXPECT_THAT(0xffffffffL, SyscallSucceedsWithValue(0xffffffffL)); 92 93 // Non-int, truncates to -1 if converted to int, with monomorphic matcher 94 EXPECT_THAT(0xffffffffL, 95 SyscallSucceedsWithValue(TypedEq<long>(0xffffffffL))); 96 97 // Non-int, truncates to -1 if converted to int, with polymorphic matcher 98 EXPECT_THAT(0xffffffffL, SyscallSucceedsWithValue(Gt(1))); 99 } 100 101 TEST(MatchersTest, SyscallFails) { 102 EXPECT_THAT(0, Not(SyscallFails())); 103 EXPECT_THAT(0L, Not(SyscallFails())); 104 105 errno = 0; 106 EXPECT_THAT(-1, Not(SyscallFails())); 107 EXPECT_THAT(-1L, Not(SyscallFails())); 108 109 errno = ENOMEM; 110 EXPECT_THAT(-1, SyscallFails()); 111 EXPECT_THAT(-1L, SyscallFails()); 112 } 113 114 TEST(MatchersTest, SyscallFailsWithErrno) { 115 EXPECT_THAT(0, Not(SyscallFailsWithErrno(EINVAL))); 116 EXPECT_THAT(0L, Not(SyscallFailsWithErrno(EINVAL))); 117 118 errno = ENOMEM; 119 EXPECT_THAT(-1, Not(SyscallFailsWithErrno(EINVAL))); 120 EXPECT_THAT(-1L, Not(SyscallFailsWithErrno(EINVAL))); 121 122 errno = EINVAL; 123 EXPECT_THAT(-1, SyscallFailsWithErrno(EINVAL)); 124 EXPECT_THAT(-1L, SyscallFailsWithErrno(EINVAL)); 125 126 EXPECT_THAT(-1, SyscallFailsWithErrno(AnyOf(EINVAL, ENOMEM))); 127 EXPECT_THAT(-1L, SyscallFailsWithErrno(AnyOf(EINVAL, ENOMEM))); 128 129 std::vector<int> expected_errnos({EINVAL, ENOMEM}); 130 errno = ENOMEM; 131 EXPECT_THAT(-1, SyscallFailsWithErrno(ElementOf(expected_errnos))); 132 EXPECT_THAT(-1L, SyscallFailsWithErrno(ElementOf(expected_errnos))); 133 } 134 135 TEST(AllBitwiseCombinationsTest, NoArguments) { 136 EXPECT_THAT(AllBitwiseCombinations(), IsEmpty()); 137 } 138 139 TEST(AllBitwiseCombinationsTest, EmptyList) { 140 EXPECT_THAT(AllBitwiseCombinations(List<int>{}), IsEmpty()); 141 } 142 143 TEST(AllBitwiseCombinationsTest, SingleElementList) { 144 EXPECT_THAT(AllBitwiseCombinations(List<int>{5}), UnorderedElementsAre(5)); 145 } 146 147 TEST(AllBitwiseCombinationsTest, SingleList) { 148 EXPECT_THAT(AllBitwiseCombinations(List<int>{0, 1, 2, 4}), 149 UnorderedElementsAre(0, 1, 2, 4)); 150 } 151 152 TEST(AllBitwiseCombinationsTest, MultipleLists) { 153 EXPECT_THAT( 154 AllBitwiseCombinations(List<int>{0, 1, 2, 3}, List<int>{0, 4, 8, 12}), 155 UnorderedElementsAreArray( 156 {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15})); 157 } 158 159 TEST(RandomizeBuffer, Works) { 160 const std::vector<char> original(4096); 161 std::vector<char> buffer = original; 162 RandomizeBuffer(buffer.data(), buffer.size()); 163 EXPECT_NE(buffer, original); 164 } 165 166 // Enable comparison of vectors of iovec arrays for the following test. 167 MATCHER_P(IovecsListEq, expected, "") { 168 if (arg.size() != expected.size()) { 169 *result_listener << "sizes are different (actual: " << arg.size() 170 << ", expected: " << expected.size() << ")"; 171 return false; 172 } 173 174 for (uint64_t i = 0; i < expected.size(); ++i) { 175 const std::vector<struct iovec>& actual_iovecs = arg[i]; 176 const std::vector<struct iovec>& expected_iovecs = expected[i]; 177 if (actual_iovecs.size() != expected_iovecs.size()) { 178 *result_listener << "iovec array size at position " << i 179 << " is different (actual: " << actual_iovecs.size() 180 << ", expected: " << expected_iovecs.size() << ")"; 181 return false; 182 } 183 184 for (uint64_t j = 0; j < expected_iovecs.size(); ++j) { 185 const struct iovec& actual_iov = actual_iovecs[j]; 186 const struct iovec& expected_iov = expected_iovecs[j]; 187 if (actual_iov.iov_base != expected_iov.iov_base) { 188 *result_listener << "iovecs in array " << i << " at position " << j 189 << " are different (expected iov_base: " 190 << expected_iov.iov_base 191 << ", got: " << actual_iov.iov_base << ")"; 192 return false; 193 } 194 if (actual_iov.iov_len != expected_iov.iov_len) { 195 *result_listener << "iovecs in array " << i << " at position " << j 196 << " are different (expected iov_len: " 197 << expected_iov.iov_len 198 << ", got: " << actual_iov.iov_len << ")"; 199 return false; 200 } 201 } 202 } 203 204 return true; 205 } 206 207 // Verify empty iovec list generation. 208 TEST(GenerateIovecs, EmptyList) { 209 std::vector<char> buffer = {'a', 'b', 'c'}; 210 211 EXPECT_THAT(GenerateIovecs(0, buffer.data(), buffer.size()), 212 IovecsListEq(std::vector<std::vector<struct iovec>>())); 213 } 214 215 // Verify generating a single array of only one, partial, iovec. 216 TEST(GenerateIovecs, OneArray) { 217 std::vector<char> buffer = {'a', 'b', 'c'}; 218 219 std::vector<std::vector<struct iovec>> expected; 220 struct iovec iov = {}; 221 iov.iov_base = buffer.data(); 222 iov.iov_len = 2; 223 expected.push_back(std::vector<struct iovec>({iov})); 224 EXPECT_THAT(GenerateIovecs(2, buffer.data(), buffer.size()), 225 IovecsListEq(expected)); 226 } 227 228 // Verify that it wraps around after IOV_MAX iovecs. 229 TEST(GenerateIovecs, WrapsAtIovMax) { 230 std::vector<char> buffer = {'a', 'b', 'c'}; 231 232 std::vector<std::vector<struct iovec>> expected; 233 struct iovec iov = {}; 234 iov.iov_base = buffer.data(); 235 iov.iov_len = buffer.size(); 236 expected.emplace_back(); 237 for (int i = 0; i < IOV_MAX; ++i) { 238 expected[0].push_back(iov); 239 } 240 iov.iov_len = 1; 241 expected.push_back(std::vector<struct iovec>({iov})); 242 243 EXPECT_THAT( 244 GenerateIovecs(IOV_MAX * buffer.size() + 1, buffer.data(), buffer.size()), 245 IovecsListEq(expected)); 246 } 247 248 } // namespace 249 250 } // namespace testing 251 } // namespace gvisor