blob: 5dda9cca9a71c71991c7f3968ebf351c6c17ee92 [file] [log] [blame]
Joel Scherpelzf3fa5cc2017-05-22 12:30:03 +09001/*
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 <array>
18#include <cstdint>
19#include <memory>
20
21#include <gtest/gtest.h>
22
23#include "netdutils/Handle.h"
24#include "netdutils/Math.h"
25#include "netdutils/MockSyscalls.h"
26#include "netdutils/Netfilter.h"
27#include "netdutils/Netlink.h"
28#include "netdutils/Slice.h"
29#include "netdutils/Status.h"
30#include "netdutils/StatusOr.h"
31#include "netdutils/Syscalls.h"
32
33using testing::DoAll;
34using testing::Mock;
35using testing::Invoke;
36using testing::Return;
37using testing::StrictMock;
38using testing::_;
39
40namespace android {
41namespace netdutils {
42
43class SyscallsTest : public testing::Test {
44 protected:
45 StrictMock<ScopedMockSyscalls> mSyscalls;
46};
47
48TEST(syscalls, scopedMock) {
49 auto& old = sSyscalls.get();
50 {
51 StrictMock<ScopedMockSyscalls> s;
52 EXPECT_EQ(&s, &sSyscalls.get());
53 }
54 EXPECT_EQ(&old, &sSyscalls.get());
55}
56
57TEST_F(SyscallsTest, getsockname) {
58 constexpr Fd kFd(40);
59 sockaddr_nl expected = {};
60 auto& sys = sSyscalls.get();
61
62 // Success
63 EXPECT_CALL(mSyscalls, getsockname(kFd, _, _))
64 .WillOnce(Invoke([expected](Fd, sockaddr* addr, socklen_t* addrlen) {
65 memcpy(addr, &expected, sizeof(expected));
66 EXPECT_EQ(*addrlen, static_cast<socklen_t>(sizeof(expected)));
67 return status::ok;
68 }));
69 const auto result = sys.getsockname<sockaddr_nl>(kFd);
70 EXPECT_TRUE(isOk(result));
71 EXPECT_EQ(expected, result.value());
72
73 // Failure
74 const Status kError = statusFromErrno(EINVAL, "test");
75 EXPECT_CALL(mSyscalls, getsockname(kFd, _, _)).WillOnce(Return(kError));
76 EXPECT_EQ(kError, sys.getsockname<sockaddr_nl>(kFd).status());
77}
78
79TEST_F(SyscallsTest, setsockopt) {
80 constexpr Fd kFd(40);
81 constexpr int kLevel = 50;
82 constexpr int kOptname = 70;
83 sockaddr_nl expected = {};
84 auto& sys = sSyscalls.get();
85
86 // Success
87 EXPECT_CALL(mSyscalls, setsockopt(kFd, kLevel, kOptname, &expected, sizeof(expected)))
88 .WillOnce(Return(status::ok));
89 EXPECT_EQ(status::ok, sys.setsockopt(kFd, kLevel, kOptname, expected));
90
91 // Failure
92 const Status kError = statusFromErrno(EINVAL, "test");
93 EXPECT_CALL(mSyscalls, setsockopt(kFd, kLevel, kOptname, &expected, sizeof(expected)))
94 .WillOnce(Return(kError));
95 EXPECT_EQ(kError, sys.setsockopt(kFd, kLevel, kOptname, expected));
96}
97
98TEST_F(SyscallsTest, bind) {
99 constexpr Fd kFd(40);
100 sockaddr_nl expected = {};
101 auto& sys = sSyscalls.get();
102
103 // Success
104 EXPECT_CALL(mSyscalls, bind(kFd, asSockaddrPtr(&expected), sizeof(expected)))
105 .WillOnce(Return(status::ok));
106 EXPECT_EQ(status::ok, sys.bind(kFd, expected));
107
108 // Failure
109 const Status kError = statusFromErrno(EINVAL, "test");
110 EXPECT_CALL(mSyscalls, bind(kFd, asSockaddrPtr(&expected), sizeof(expected)))
111 .WillOnce(Return(kError));
112 EXPECT_EQ(kError, sys.bind(kFd, expected));
113}
114
115TEST_F(SyscallsTest, connect) {
116 constexpr Fd kFd(40);
117 sockaddr_nl expected = {};
118 auto& sys = sSyscalls.get();
119
120 // Success
121 EXPECT_CALL(mSyscalls, connect(kFd, asSockaddrPtr(&expected), sizeof(expected)))
122 .WillOnce(Return(status::ok));
123 EXPECT_EQ(status::ok, sys.connect(kFd, expected));
124
125 // Failure
126 const Status kError = statusFromErrno(EINVAL, "test");
127 EXPECT_CALL(mSyscalls, connect(kFd, asSockaddrPtr(&expected), sizeof(expected)))
128 .WillOnce(Return(kError));
129 EXPECT_EQ(kError, sys.connect(kFd, expected));
130}
131
132TEST_F(SyscallsTest, sendto) {
133 constexpr Fd kFd(40);
134 constexpr int kFlags = 0;
135 std::array<char, 10> payload;
136 const auto slice = makeSlice(payload);
137 sockaddr_nl expected = {};
138 auto& sys = sSyscalls.get();
139
140 // Success
141 EXPECT_CALL(mSyscalls, sendto(kFd, slice, kFlags, asSockaddrPtr(&expected), sizeof(expected)))
142 .WillOnce(Return(slice.size()));
143 EXPECT_EQ(status::ok, sys.sendto(kFd, slice, kFlags, expected));
144}
145
146TEST_F(SyscallsTest, recvfrom) {
147 constexpr Fd kFd(40);
148 constexpr int kFlags = 0;
149 std::array<char, 10> payload;
150 const auto dst = makeSlice(payload);
151 const auto used = take(dst, 8);
152 sockaddr_nl expected = {};
153 auto& sys = sSyscalls.get();
154
155 // Success
156 EXPECT_CALL(mSyscalls, recvfrom(kFd, dst, kFlags, _, _))
157 .WillOnce(Invoke([expected, used](Fd, const Slice, int, sockaddr* src, socklen_t* srclen) {
158 memcpy(src, &expected, sizeof(src));
159 *srclen = sizeof(expected);
160 return used;
161 }));
162 auto result = sys.recvfrom<sockaddr_nl>(kFd, dst, kFlags);
163 EXPECT_EQ(status::ok, result.status());
164 EXPECT_EQ(used, result.value().first);
165 EXPECT_EQ(expected, result.value().second);
166}
167
168} // namespace netdutils
169} // namespace android