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