1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <cstdint> 18 19 #include <gtest/gtest.h> 20 21 #include "netdutils/MockSyscalls.h" 22 #include "netdutils/Status.h" 23 #include "netdutils/Syscalls.h" 24 25 using testing::Mock; 26 using testing::Return; 27 using testing::StrictMock; 28 29 namespace android { 30 namespace netdutils { 31 namespace { 32 33 // Force implicit conversion from UniqueFd -> Fd 34 inline Fd toFd(const UniqueFd& fd) { 35 return fd; 36 } 37 38 } // namespace 39 40 TEST(Fd, smoke) { 41 // Expect the following lines to compile 42 Fd fd1(1); 43 Fd fd2(fd1); 44 Fd fd3 = fd2; 45 const Fd fd4(8); 46 const Fd fd5(fd4); 47 const Fd fd6 = fd5; 48 EXPECT_TRUE(isWellFormed(fd3)); 49 EXPECT_TRUE(isWellFormed(fd6)); 50 51 // Corner case 52 Fd zero(0); 53 EXPECT_TRUE(isWellFormed(zero)); 54 55 // Invalid file descriptors 56 Fd bad(-1); 57 Fd weird(-9); 58 EXPECT_FALSE(isWellFormed(bad)); 59 EXPECT_FALSE(isWellFormed(weird)); 60 61 // Default constructor 62 EXPECT_EQ(Fd(-1), Fd()); 63 std::stringstream ss; 64 ss << fd3 << " " << fd6 << " " << bad << " " << weird; 65 EXPECT_EQ("Fd[1] Fd[8] Fd[-1] Fd[-9]", ss.str()); 66 } 67 68 class UniqueFdTest : public testing::Test { 69 protected: 70 StrictMock<ScopedMockSyscalls> mSyscalls; 71 }; 72 73 TEST_F(UniqueFdTest, operatorOstream) { 74 UniqueFd u(97); 75 EXPECT_CALL(mSyscalls, close(toFd(u))).WillOnce(Return(status::ok)); 76 std::stringstream ss; 77 ss << u; 78 EXPECT_EQ("UniqueFd[Fd[97]]", ss.str()); 79 u.reset(); 80 } 81 82 TEST_F(UniqueFdTest, destructor) { 83 { 84 UniqueFd u(98); 85 EXPECT_CALL(mSyscalls, close(toFd(u))).WillOnce(Return(status::ok)); 86 } 87 // Expectation above should be upon leaving nested scope 88 Mock::VerifyAndClearExpectations(&mSyscalls); 89 } 90 91 TEST_F(UniqueFdTest, reset) { 92 UniqueFd u(99); 93 EXPECT_CALL(mSyscalls, close(toFd(u))).WillOnce(Return(status::ok)); 94 u.reset(); 95 96 // Expectation above should be upon reset 97 Mock::VerifyAndClearExpectations(&mSyscalls); 98 } 99 100 TEST_F(UniqueFdTest, moveConstructor) { 101 constexpr Fd kFd(101); 102 UniqueFd u1(kFd); 103 { 104 UniqueFd u2(std::move(u1)); 105 // NOLINTNEXTLINE bugprone-use-after-move 106 EXPECT_FALSE(isWellFormed(u1)); 107 EXPECT_TRUE(isWellFormed(u2)); 108 EXPECT_CALL(mSyscalls, close(kFd)).WillOnce(Return(status::ok)); 109 } 110 // Expectation above should be upon leaving nested scope 111 Mock::VerifyAndClearExpectations(&mSyscalls); 112 } 113 114 TEST_F(UniqueFdTest, moveAssignment) { 115 constexpr Fd kFd(102); 116 UniqueFd u1(kFd); 117 { 118 UniqueFd u2 = std::move(u1); 119 // NOLINTNEXTLINE bugprone-use-after-move 120 EXPECT_FALSE(isWellFormed(u1)); 121 EXPECT_TRUE(isWellFormed(u2)); 122 UniqueFd u3; 123 u3 = std::move(u2); 124 // NOLINTNEXTLINE bugprone-use-after-move 125 EXPECT_FALSE(isWellFormed(u2)); 126 EXPECT_TRUE(isWellFormed(u3)); 127 EXPECT_CALL(mSyscalls, close(kFd)).WillOnce(Return(status::ok)); 128 } 129 // Expectation above should be upon leaving nested scope 130 Mock::VerifyAndClearExpectations(&mSyscalls); 131 } 132 133 TEST_F(UniqueFdTest, constConstructor) { 134 constexpr Fd kFd(103); 135 const UniqueFd u(kFd); 136 EXPECT_CALL(mSyscalls, close(toFd(u))).WillOnce(Return(status::ok)); 137 } 138 139 TEST_F(UniqueFdTest, closeFailure) { 140 constexpr Fd kFd(103); 141 UniqueFd u(kFd); 142 EXPECT_CALL(mSyscalls, close(toFd(u))).WillOnce(Return(statusFromErrno(EINTR, "test"))); 143 EXPECT_DEBUG_DEATH(u.reset(), ""); 144 } 145 146 } // namespace netdutils 147 } // namespace android 148