blob: fc8abbd2f6a0a78f4410cd7098e872497cf37c69 [file] [log] [blame]
KH Shid97a3082022-12-06 19:46:31 +08001/*
2 * Copyright (C) 2022 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#define LOG_TAG "tetheroffload_aidl_hal_test"
18
19#include <aidl/Gtest.h>
20#include <aidl/Vintf.h>
21#include <aidl/android/hardware/tetheroffload/BnOffload.h>
22#include <aidl/android/hardware/tetheroffload/BnTetheringOffloadCallback.h>
23#include <android-base/logging.h>
24#include <android-base/unique_fd.h>
25#include <android/binder_manager.h>
26#include <android/binder_process.h>
27#include <gmock/gmock.h>
28#include <gtest/gtest.h>
29#include <linux/netfilter/nfnetlink.h>
30#include <linux/netlink.h>
31#include <linux/rtnetlink.h>
32#include <log/log.h>
33#include <net/if.h>
34#include <sys/socket.h>
35
36namespace aidl::android::hardware::tetheroffload {
37
38namespace {
39
40using ::android::base::unique_fd;
41using android::hardware::tetheroffload::ForwardedStats;
42using android::hardware::tetheroffload::IOffload;
43using android::hardware::tetheroffload::NatTimeoutUpdate;
44using android::hardware::tetheroffload::OffloadCallbackEvent;
45using ::testing::AnyOf;
46using ::testing::Eq;
47
48const std::string TEST_IFACE = "rmnet_data0";
49const unsigned kFd1Groups = NF_NETLINK_CONNTRACK_NEW | NF_NETLINK_CONNTRACK_DESTROY;
50const unsigned kFd2Groups = NF_NETLINK_CONNTRACK_UPDATE | NF_NETLINK_CONNTRACK_DESTROY;
51
52enum class ExpectBoolean {
53 Ignored = -1,
54 False = 0,
55 True = 1,
56};
57
58inline const sockaddr* asSockaddr(const sockaddr_nl* nladdr) {
59 return reinterpret_cast<const sockaddr*>(nladdr);
60}
61
62int netlinkSocket(int protocol, unsigned groups) {
63 unique_fd s(socket(AF_NETLINK, SOCK_DGRAM, protocol));
64 if (s.get() < 0) {
65 return -errno;
66 }
67
68 const struct sockaddr_nl bind_addr = {
69 .nl_family = AF_NETLINK,
70 .nl_pad = 0,
71 .nl_pid = 0,
72 .nl_groups = groups,
73 };
74 if (bind(s.get(), asSockaddr(&bind_addr), sizeof(bind_addr)) != 0) {
75 return -errno;
76 }
77
78 const struct sockaddr_nl kernel_addr = {
79 .nl_family = AF_NETLINK,
80 .nl_pad = 0,
81 .nl_pid = 0,
82 .nl_groups = groups,
83 };
84 if (connect(s.get(), asSockaddr(&kernel_addr), sizeof(kernel_addr)) != 0) {
85 return -errno;
86 }
87
88 return s.release();
89}
90
91int netlinkSocket(unsigned groups) {
92 return netlinkSocket(NETLINK_NETFILTER, groups);
93}
94
95// Check whether the specified interface is up.
96bool interfaceIsUp(const std::string name) {
97 struct ifreq ifr = {};
98 strlcpy(ifr.ifr_name, name.c_str(), sizeof(ifr.ifr_name));
99 int sock = socket(AF_INET6, SOCK_DGRAM, 0);
100 if (sock == -1) return false;
101 int ret = ioctl(sock, SIOCGIFFLAGS, &ifr, sizeof(ifr));
102 close(sock);
103 return (ret == 0) && (ifr.ifr_flags & IFF_UP);
104}
105
106// Callback class for both events and NAT timeout updates.
107class TetheringOffloadCallback : public BnTetheringOffloadCallback {
108 public:
109 ndk::ScopedAStatus onEvent(OffloadCallbackEvent in_event) override {
110 auto lock = std::lock_guard{mMutex};
111 mOnEventInvoked = true;
112 mLastEvent = in_event;
113 mNotifyCv.notify_all();
114 return ndk::ScopedAStatus::ok();
115 }
116
117 ndk::ScopedAStatus updateTimeout(const NatTimeoutUpdate& in_params) override {
118 auto lock = std::lock_guard{mMutex};
119 mOnUpdateTimeoutInvoked = true;
120 mNatTimeout = in_params;
121 mNotifyCv.notify_all();
122 return ndk::ScopedAStatus::ok();
123 }
124
125 private:
126 std::mutex mMutex;
127 std::condition_variable mNotifyCv;
128 OffloadCallbackEvent mLastEvent;
129 NatTimeoutUpdate mNatTimeout;
130 bool mOnEventInvoked = false;
131 bool mOnUpdateTimeoutInvoked = false;
132};
133
134// The common base class for tetheroffload AIDL HAL tests.
135class TetheroffloadAidlTestBase : public testing::TestWithParam<std::string> {
136 public:
137 virtual void SetUp() override { getService(); }
138 virtual void TearDown() override {
139 // For good measure, the teardown should try stopOffload() once more, since
140 // different HAL call test cycles might enter this function. Also the
141 // return code cannot be actually expected for all cases, hence ignore it.
142 stopOffload(ExpectBoolean::Ignored);
143 };
144
145 protected:
146 void getService() {
147 AIBinder* binder = AServiceManager_waitForService(GetParam().c_str());
148 ASSERT_NE(binder, nullptr);
149 mOffload = IOffload::fromBinder(ndk::SpAIBinder(binder));
150 }
151
152 void initOffload(const bool expectedResult) {
153 unique_fd ufd1(netlinkSocket(kFd1Groups));
154 if (ufd1.get() < 0) {
155 ALOGE("Unable to create conntrack sockets: %d/%s", errno, strerror(errno));
156 FAIL();
157 }
158 ndk::ScopedFileDescriptor fd1 = ndk::ScopedFileDescriptor(ufd1.release());
159
160 unique_fd ufd2(netlinkSocket(kFd2Groups));
161 if (ufd2.get() < 0) {
162 ALOGE("Unable to create conntrack sockets: %d/%s", errno, strerror(errno));
163 FAIL();
164 }
165 ndk::ScopedFileDescriptor fd2 = ndk::ScopedFileDescriptor(ufd2.release());
166
167 mTetheringOffloadCallback = ndk::SharedRefBase::make<TetheringOffloadCallback>();
168 ASSERT_NE(mTetheringOffloadCallback, nullptr) << "Could not get offload callback";
169
170 ASSERT_EQ(mOffload->initOffload(fd1, fd2, mTetheringOffloadCallback).getExceptionCode(),
171 expectedResult ? EX_NONE : EX_ILLEGAL_STATE);
172 }
173
174 void stopOffload(const ExpectBoolean expectedResult) {
175 ndk::ScopedAStatus status = mOffload->stopOffload();
176 if (expectedResult == ExpectBoolean::Ignored) return;
177 ASSERT_EQ(status.getExceptionCode(),
178 expectedResult == ExpectBoolean::True ? EX_NONE : EX_ILLEGAL_STATE);
179 }
180
181 std::shared_ptr<IOffload> mOffload;
182 std::shared_ptr<TetheringOffloadCallback> mTetheringOffloadCallback;
183};
184
185// The test class for tetheroffload before initialization.
186class TetheroffloadAidlPreInitTest : public TetheroffloadAidlTestBase {
187 public:
188 virtual void SetUp() override { getService(); }
189};
190
191// The main test class for tetheroffload AIDL HAL.
192class TetheroffloadAidlGeneralTest : public TetheroffloadAidlTestBase {
193 public:
194 virtual void SetUp() override {
195 getService();
196 initOffload(true);
197 }
198};
199
200// Passing invalid file descriptor to initOffload() should return an error.
201// Check that this occurs when both FDs are empty.
202TEST_P(TetheroffloadAidlPreInitTest, TestInitOffloadInvalidFdsReturnsError) {
203 ndk::ScopedFileDescriptor fd1 = ndk::ScopedFileDescriptor(-1);
204 ndk::ScopedFileDescriptor fd2 = ndk::ScopedFileDescriptor(-1);
205 mTetheringOffloadCallback = ndk::SharedRefBase::make<TetheringOffloadCallback>();
206 ASSERT_NE(mTetheringOffloadCallback, nullptr) << "Could not get offload callback";
207 EXPECT_THAT(mOffload->initOffload(fd1, fd2, mTetheringOffloadCallback).getExceptionCode(),
208 AnyOf(Eq(EX_ILLEGAL_ARGUMENT), Eq(EX_TRANSACTION_FAILED)));
209}
210
211// Passing invalid file descriptor to initOffload() should return an error.
212// Check that this occurs when FD1 is empty.
213TEST_P(TetheroffloadAidlPreInitTest, TestInitOffloadInvalidFd1ReturnsError) {
214 ndk::ScopedFileDescriptor fd1 = ndk::ScopedFileDescriptor(-1);
215 unique_fd ufd2(netlinkSocket(kFd2Groups));
216 if (ufd2.get() < 0) {
217 ALOGE("Unable to create conntrack sockets: %d/%s", errno, strerror(errno));
218 FAIL();
219 }
220 ndk::ScopedFileDescriptor fd2 = ndk::ScopedFileDescriptor(ufd2.release());
221 mTetheringOffloadCallback = ndk::SharedRefBase::make<TetheringOffloadCallback>();
222 ASSERT_NE(mTetheringOffloadCallback, nullptr) << "Could not get offload callback";
223 EXPECT_THAT(mOffload->initOffload(fd1, fd2, mTetheringOffloadCallback).getExceptionCode(),
224 AnyOf(Eq(EX_ILLEGAL_ARGUMENT), Eq(EX_TRANSACTION_FAILED)));
225}
226
227// Passing invalid file descriptor to initOffload() should return an error.
228// Check that this occurs when FD2 is empty.
229TEST_P(TetheroffloadAidlPreInitTest, TestInitOffloadInvalidFd2ReturnsError) {
230 unique_fd ufd1(netlinkSocket(kFd1Groups));
231 if (ufd1.get() < 0) {
232 ALOGE("Unable to create conntrack sockets: %d/%s", errno, strerror(errno));
233 FAIL();
234 }
235 ndk::ScopedFileDescriptor fd1 = ndk::ScopedFileDescriptor(ufd1.release());
236 ndk::ScopedFileDescriptor fd2 = ndk::ScopedFileDescriptor(-1);
237 mTetheringOffloadCallback = ndk::SharedRefBase::make<TetheringOffloadCallback>();
238 ASSERT_NE(mTetheringOffloadCallback, nullptr) << "Could not get offload callback";
239 EXPECT_THAT(mOffload->initOffload(fd1, fd2, mTetheringOffloadCallback).getExceptionCode(),
240 AnyOf(Eq(EX_ILLEGAL_ARGUMENT), Eq(EX_TRANSACTION_FAILED)));
241}
242
243// Call initOffload() multiple times. Check that non-first initOffload() calls return error.
244TEST_P(TetheroffloadAidlPreInitTest, AdditionalInitsWithoutStopReturnError) {
245 initOffload(true);
246 initOffload(false);
247 initOffload(false);
248 initOffload(false);
249}
250
251// Check that calling stopOffload() without first having called initOffload() returns error.
252TEST_P(TetheroffloadAidlPreInitTest, MultipleStopsWithoutInitReturnError) {
253 stopOffload(ExpectBoolean::False);
254 stopOffload(ExpectBoolean::False);
255 stopOffload(ExpectBoolean::False);
256}
257
258// Check that calling stopOffload() after a complete init/stop cycle returns error.
259TEST_P(TetheroffloadAidlPreInitTest, AdditionalStopsWithInitReturnError) {
260 initOffload(true);
261 // Call setUpstreamParameters() so that "offload" can be reasonably said
262 // to be both requested and operational.
263 const std::string iface(TEST_IFACE);
264 const std::string v4Addr("192.0.0.2");
265 const std::string v4Gw("192.0.0.1");
266 const std::vector<std::string> v6Gws{std::string("fe80::db8:1"), std::string("fe80::db8:2")};
267 EXPECT_TRUE(mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws).isOk());
268 if (!interfaceIsUp(TEST_IFACE)) {
269 return;
270 }
271 SCOPED_TRACE("Expecting stopOffload to succeed");
272 stopOffload(ExpectBoolean::True); // balance out initOffload(true)
273 SCOPED_TRACE("Expecting stopOffload to fail the first time");
274 stopOffload(ExpectBoolean::False);
275 SCOPED_TRACE("Expecting stopOffload to fail the second time");
276 stopOffload(ExpectBoolean::False);
277}
278
279// Check that calling setLocalPrefixes() without first having called initOffload() returns error.
280TEST_P(TetheroffloadAidlPreInitTest, SetLocalPrefixesWithoutInitReturnsError) {
281 const std::vector<std::string> prefixes{std::string("2001:db8::/64")};
282 EXPECT_EQ(mOffload->setLocalPrefixes(prefixes).getExceptionCode(), EX_ILLEGAL_STATE);
283}
284
285// Check that calling getForwardedStats() without first having called initOffload()
286// returns zero bytes statistics.
287TEST_P(TetheroffloadAidlPreInitTest, GetForwardedStatsWithoutInitReturnsZeroValues) {
288 const std::string upstream(TEST_IFACE);
289 ForwardedStats stats;
290 EXPECT_TRUE(mOffload->getForwardedStats(upstream, &stats).isOk());
291 EXPECT_EQ(stats.rxBytes, 0ULL);
292 EXPECT_EQ(stats.txBytes, 0ULL);
293}
294
295// Check that calling setDataWarningAndLimit() without first having called initOffload() returns
296// error.
297TEST_P(TetheroffloadAidlPreInitTest, SetDataWarningAndLimitWithoutInitReturnsError) {
298 const std::string upstream(TEST_IFACE);
299 const int64_t warning = 5000LL;
300 const int64_t limit = 5000LL;
301 EXPECT_EQ(mOffload->setDataWarningAndLimit(upstream, warning, limit).getExceptionCode(),
302 EX_ILLEGAL_STATE);
303}
304
305// Check that calling setUpstreamParameters() without first having called initOffload()
306// returns error.
307TEST_P(TetheroffloadAidlPreInitTest, SetUpstreamParametersWithoutInitReturnsError) {
308 const std::string iface(TEST_IFACE);
309 const std::string v4Addr("192.0.2.0/24");
310 const std::string v4Gw("192.0.2.1");
311 const std::vector<std::string> v6Gws{std::string("fe80::db8:1")};
312 EXPECT_EQ(mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws).getExceptionCode(),
313 EX_ILLEGAL_STATE);
314}
315
316// Check that calling addDownstream() with an IPv4 prefix without first having called
317// initOffload() returns error.
318TEST_P(TetheroffloadAidlPreInitTest, AddIPv4DownstreamWithoutInitReturnsError) {
319 const std::string iface(TEST_IFACE);
320 const std::string prefix("192.0.2.0/24");
321 EXPECT_EQ(mOffload->addDownstream(iface, prefix).getExceptionCode(), EX_ILLEGAL_STATE);
322}
323
324// Check that calling addDownstream() with an IPv6 prefix without first having called
325// initOffload() returns error.
326TEST_P(TetheroffloadAidlPreInitTest, AddIPv6DownstreamWithoutInitReturnsError) {
327 const std::string iface(TEST_IFACE);
328 const std::string prefix("2001:db8::/64");
329 EXPECT_EQ(mOffload->addDownstream(iface, prefix).getExceptionCode(), EX_ILLEGAL_STATE);
330}
331
332// Check that calling removeDownstream() with an IPv4 prefix without first having called
333// initOffload() returns error.
334TEST_P(TetheroffloadAidlPreInitTest, RemoveIPv4DownstreamWithoutInitReturnsError) {
335 const std::string iface(TEST_IFACE);
336 const std::string prefix("192.0.2.0/24");
337 EXPECT_EQ(mOffload->removeDownstream(iface, prefix).getExceptionCode(), EX_ILLEGAL_STATE);
338}
339
340// Check that calling removeDownstream() with an IPv6 prefix without first having called
341// initOffload() returns error.
342TEST_P(TetheroffloadAidlPreInitTest, RemoveIPv6DownstreamWithoutInitReturnsError) {
343 const std::string iface(TEST_IFACE);
344 const std::string prefix("2001:db8::/64");
345 EXPECT_EQ(mOffload->removeDownstream(iface, prefix).getExceptionCode(), EX_ILLEGAL_STATE);
346}
347
348/*
349 * Tests for IOffload::setLocalPrefixes().
350 */
351
352// Test setLocalPrefixes() rejects an IPv4 address.
353TEST_P(TetheroffloadAidlGeneralTest, SetLocalPrefixesIPv4AddressFails) {
354 const std::vector<std::string> prefixes{std::string("192.0.2.1")};
355 EXPECT_EQ(mOffload->setLocalPrefixes(prefixes).getExceptionCode(), EX_ILLEGAL_ARGUMENT);
356}
357
358// Test setLocalPrefixes() rejects an IPv6 address.
359TEST_P(TetheroffloadAidlGeneralTest, SetLocalPrefixesIPv6AddressFails) {
360 const std::vector<std::string> prefixes{std::string("fe80::1")};
361 EXPECT_EQ(mOffload->setLocalPrefixes(prefixes).getExceptionCode(), EX_ILLEGAL_ARGUMENT);
362}
363
364// Test setLocalPrefixes() accepts both IPv4 and IPv6 prefixes.
365TEST_P(TetheroffloadAidlGeneralTest, SetLocalPrefixesIPv4v6PrefixesOk) {
366 const std::vector<std::string> prefixes{std::string("192.0.2.0/24"), std::string("fe80::/64")};
367 EXPECT_TRUE(mOffload->setLocalPrefixes(prefixes).isOk());
368}
369
370// Test that setLocalPrefixes() fails given empty input. There is always
371// a non-empty set of local prefixes; when all networking interfaces are down
372// we still apply {127.0.0.0/8, ::1/128, fe80::/64} here.
373TEST_P(TetheroffloadAidlGeneralTest, SetLocalPrefixesEmptyFails) {
374 const std::vector<std::string> prefixes{};
375 EXPECT_EQ(mOffload->setLocalPrefixes(prefixes).getExceptionCode(), EX_ILLEGAL_ARGUMENT);
376}
377
378// Test setLocalPrefixes() fails on incorrectly formed input strings.
379TEST_P(TetheroffloadAidlGeneralTest, SetLocalPrefixesInvalidFails) {
380 const std::vector<std::string> prefixes{std::string("192.0.2.0/24"), std::string("invalid")};
381 EXPECT_EQ(mOffload->setLocalPrefixes(prefixes).getExceptionCode(), EX_ILLEGAL_ARGUMENT);
382}
383
384/*
385 * Tests for IOffload::getForwardedStats().
386 */
387
388// Test that getForwardedStats() for a non-existent upstream yields zero bytes statistics.
389TEST_P(TetheroffloadAidlGeneralTest, GetForwardedStatsInvalidUpstreamIface) {
390 const std::string upstream("invalid");
391 ForwardedStats stats;
392 EXPECT_TRUE(mOffload->getForwardedStats(upstream, &stats).isOk());
393 EXPECT_EQ(stats.rxBytes, 0ULL);
394 EXPECT_EQ(stats.txBytes, 0ULL);
395}
396
397// TEST_IFACE is presumed to exist on the device and be up. No packets
398// are ever actually caused to be forwarded.
399TEST_P(TetheroffloadAidlGeneralTest, GetForwardedStatsDummyIface) {
400 const std::string upstream(TEST_IFACE);
401 ForwardedStats stats;
402 EXPECT_TRUE(mOffload->getForwardedStats(upstream, &stats).isOk());
403 EXPECT_EQ(stats.rxBytes, 0ULL);
404 EXPECT_EQ(stats.txBytes, 0ULL);
405}
406
407/*
408 * Tests for IOffload::setDataWarningAndLimit().
409 */
410
411// Test that setDataWarningAndLimit() for an empty interface name fails.
412TEST_P(TetheroffloadAidlGeneralTest, SetDataWarningAndLimitEmptyUpstreamIfaceFails) {
413 const std::string upstream("");
414 const int64_t warning = 12345LL;
415 const int64_t limit = 67890LL;
416 EXPECT_THAT(mOffload->setDataWarningAndLimit(upstream, warning, limit).getExceptionCode(),
417 AnyOf(Eq(EX_ILLEGAL_ARGUMENT), Eq(EX_UNSUPPORTED_OPERATION)));
418}
419
420// TEST_IFACE is presumed to exist on the device and be up. No packets
421// are ever actually caused to be forwarded.
422TEST_P(TetheroffloadAidlGeneralTest, SetDataWarningAndLimitNonZeroOk) {
423 const std::string upstream(TEST_IFACE);
424 const int64_t warning = 4000LL;
425 const int64_t limit = 5000LL;
426 EXPECT_THAT(mOffload->setDataWarningAndLimit(upstream, warning, limit).getExceptionCode(),
427 AnyOf(Eq(EX_NONE), Eq(EX_UNSUPPORTED_OPERATION)));
428}
429
430// TEST_IFACE is presumed to exist on the device and be up. No packets
431// are ever actually caused to be forwarded.
432TEST_P(TetheroffloadAidlGeneralTest, SetDataWarningAndLimitZeroOk) {
433 const std::string upstream(TEST_IFACE);
434 const int64_t warning = 0LL;
435 const int64_t limit = 0LL;
436 EXPECT_THAT(mOffload->setDataWarningAndLimit(upstream, warning, limit).getExceptionCode(),
437 AnyOf(Eq(EX_NONE), Eq(EX_UNSUPPORTED_OPERATION)));
438}
439
440// TEST_IFACE is presumed to exist on the device and be up. No packets
441// are ever actually caused to be forwarded.
442TEST_P(TetheroffloadAidlGeneralTest, SetDataWarningAndLimitUnlimitedWarningOk) {
443 const std::string upstream(TEST_IFACE);
444 const int64_t warning = LLONG_MAX;
445 const int64_t limit = 5000LL;
446 EXPECT_TRUE(mOffload->setDataWarningAndLimit(upstream, warning, limit).isOk());
447}
448
449// Test that setDataWarningAndLimit() with negative thresholds fails.
450TEST_P(TetheroffloadAidlGeneralTest, SetDataWarningAndLimitNegativeFails) {
451 const std::string upstream(TEST_IFACE);
452 const int64_t warning = -1LL;
453 const int64_t limit = -1LL;
454 EXPECT_THAT(mOffload->setDataWarningAndLimit(upstream, warning, limit).getExceptionCode(),
455 AnyOf(Eq(EX_ILLEGAL_ARGUMENT), Eq(EX_UNSUPPORTED_OPERATION)));
456}
457
458/*
459 * Tests for IOffload::setUpstreamParameters().
460 */
461
462// TEST_IFACE is presumed to exist on the device and be up. No packets
463// are ever actually caused to be forwarded.
464TEST_P(TetheroffloadAidlGeneralTest, SetUpstreamParametersIPv6OnlyOk) {
465 const std::string iface(TEST_IFACE);
466 const std::string v4Addr("");
467 const std::string v4Gw("");
468 const std::vector<std::string> v6Gws{std::string("fe80::db8:1"), std::string("fe80::db8:2")};
469 EXPECT_TRUE(mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws).isOk());
470}
471
472// TEST_IFACE is presumed to exist on the device and be up. No packets
473// are ever actually caused to be forwarded.
474TEST_P(TetheroffloadAidlGeneralTest, SetUpstreamParametersAlternateIPv6OnlyOk) {
475 const std::string iface(TEST_IFACE);
476 const std::string v4Addr("");
477 const std::string v4Gw("");
478 const std::vector<std::string> v6Gws{std::string("fe80::db8:1"), std::string("fe80::db8:3")};
479 EXPECT_TRUE(mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws).isOk());
480}
481
482// TEST_IFACE is presumed to exist on the device and be up. No packets
483// are ever actually caused to be forwarded.
484TEST_P(TetheroffloadAidlGeneralTest, SetUpstreamParametersIPv4OnlyOk) {
485 const std::string iface(TEST_IFACE);
486 const std::string v4Addr("192.0.2.2");
487 const std::string v4Gw("192.0.2.1");
488 const std::vector<std::string> v6Gws{};
489 EXPECT_TRUE(mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws).isOk());
490}
491
492// TEST_IFACE is presumed to exist on the device and be up. No packets
493// are ever actually caused to be forwarded.
494TEST_P(TetheroffloadAidlGeneralTest, SetUpstreamParametersIPv4v6Ok) {
495 const std::string iface(TEST_IFACE);
496 const std::string v4Addr("192.0.2.2");
497 const std::string v4Gw("192.0.2.1");
498 const std::vector<std::string> v6Gws{std::string("fe80::db8:1"), std::string("fe80::db8:2")};
499 EXPECT_TRUE(mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws).isOk());
500}
501
502// Test that setUpstreamParameters() fails when all parameters are empty.
503TEST_P(TetheroffloadAidlGeneralTest, SetUpstreamParametersEmptyFails) {
504 const std::string iface("");
505 const std::string v4Addr("");
506 const std::string v4Gw("");
507 const std::vector<std::string> v6Gws{};
508 EXPECT_EQ(mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws).getExceptionCode(),
509 EX_ILLEGAL_ARGUMENT);
510}
511
512// Test that setUpstreamParameters() fails when given empty or non-existent interface names.
513TEST_P(TetheroffloadAidlGeneralTest, SetUpstreamParametersBogusIfaceFails) {
514 const std::string v4Addr("192.0.2.2");
515 const std::string v4Gw("192.0.2.1");
516 const std::vector<std::string> v6Gws{std::string("fe80::db8:1")};
517 for (const auto& bogus : {"", "invalid"}) {
518 SCOPED_TRACE(testing::Message() << "upstream: " << bogus);
519 const std::string iface(bogus);
520 EXPECT_EQ(mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws).getExceptionCode(),
521 EX_ILLEGAL_ARGUMENT);
522 }
523}
524
525// Test that setUpstreamParameters() fails when given unparseable IPv4 addresses.
526TEST_P(TetheroffloadAidlGeneralTest, SetUpstreamParametersInvalidIPv4AddrFails) {
527 const std::string iface(TEST_IFACE);
528 const std::string v4Gw("192.0.2.1");
529 const std::vector<std::string> v6Gws{std::string("fe80::db8:1")};
530 for (const auto& bogus : {"invalid", "192.0.2"}) {
531 SCOPED_TRACE(testing::Message() << "v4addr: " << bogus);
532 const std::string v4Addr(bogus);
533 EXPECT_EQ(mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws).getExceptionCode(),
534 EX_ILLEGAL_ARGUMENT);
535 }
536}
537
538// Test that setUpstreamParameters() fails when given unparseable IPv4 gateways.
539TEST_P(TetheroffloadAidlGeneralTest, SetUpstreamParametersInvalidIPv4GatewayFails) {
540 const std::string iface(TEST_IFACE);
541 const std::string v4Addr("192.0.2.2");
542 const std::vector<std::string> v6Gws{std::string("fe80::db8:1")};
543 for (const auto& bogus : {"invalid", "192.0.2"}) {
544 SCOPED_TRACE(testing::Message() << "v4gateway: " << bogus);
545 const std::string v4Gw(bogus);
546 EXPECT_EQ(mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws).getExceptionCode(),
547 EX_ILLEGAL_ARGUMENT);
548 }
549}
550
551// Test that setUpstreamParameters() fails when given unparseable IPv6 gateways.
552TEST_P(TetheroffloadAidlGeneralTest, SetUpstreamParametersBadIPv6GatewaysFail) {
553 const std::string iface(TEST_IFACE);
554 const std::string v4Addr("192.0.2.2");
555 const std::string v4Gw("192.0.2.1");
556 for (const auto& bogus : {"", "invalid", "fe80::bogus", "192.0.2.66"}) {
557 SCOPED_TRACE(testing::Message() << "v6gateway: " << bogus);
558 const std::vector<std::string> v6Gws{std::string("fe80::1"), std::string(bogus)};
559 EXPECT_EQ(mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws).getExceptionCode(),
560 EX_ILLEGAL_ARGUMENT);
561 }
562}
563
564/*
565 * Tests for IOffload::addDownstream().
566 */
567
568// Test addDownstream() works given an IPv4 prefix.
569TEST_P(TetheroffloadAidlGeneralTest, AddDownstreamIPv4) {
570 const std::string iface("dummy0");
571 const std::string prefix("192.0.2.0/24");
572 EXPECT_TRUE(mOffload->addDownstream(iface, prefix).isOk());
573}
574
575// Test addDownstream() works given an IPv6 prefix.
576TEST_P(TetheroffloadAidlGeneralTest, AddDownstreamIPv6) {
577 const std::string iface("dummy0");
578 const std::string prefix("2001:db8::/64");
579 EXPECT_TRUE(mOffload->addDownstream(iface, prefix).isOk());
580}
581
582// Test addDownstream() fails given all empty parameters.
583TEST_P(TetheroffloadAidlGeneralTest, AddDownstreamEmptyFails) {
584 const std::string iface("");
585 const std::string prefix("");
586 EXPECT_EQ(mOffload->addDownstream(iface, prefix).getExceptionCode(), EX_ILLEGAL_ARGUMENT);
587}
588
589// Test addDownstream() fails given empty or non-existent interface names.
590TEST_P(TetheroffloadAidlGeneralTest, AddDownstreamInvalidIfaceFails) {
591 const std::string prefix("192.0.2.0/24");
592 for (const auto& bogus : {"", "invalid"}) {
593 SCOPED_TRACE(testing::Message() << "iface: " << bogus);
594 const std::string iface(bogus);
595 EXPECT_EQ(mOffload->addDownstream(iface, prefix).getExceptionCode(), EX_ILLEGAL_ARGUMENT);
596 }
597}
598
599// Test addDownstream() fails given unparseable prefix arguments.
600TEST_P(TetheroffloadAidlGeneralTest, AddDownstreamBogusPrefixFails) {
601 const std::string iface("dummy0");
602 for (const auto& bogus : {"", "192.0.2/24", "2001:db8/64"}) {
603 SCOPED_TRACE(testing::Message() << "prefix: " << bogus);
604 const std::string prefix(bogus);
605 EXPECT_EQ(mOffload->addDownstream(iface, prefix).getExceptionCode(), EX_ILLEGAL_ARGUMENT);
606 }
607}
608
609/*
610 * Tests for IOffload::removeDownstream().
611 */
612
613// Test removeDownstream() works given an IPv4 prefix.
614TEST_P(TetheroffloadAidlGeneralTest, RemoveDownstreamIPv4) {
615 const std::string iface("dummy0");
616 const std::string prefix("192.0.2.0/24");
617 // First add the downstream, otherwise removeDownstream logic can reasonably
618 // return error for downstreams not previously added.
619 EXPECT_TRUE(mOffload->addDownstream(iface, prefix).isOk());
620 EXPECT_TRUE(mOffload->removeDownstream(iface, prefix).isOk());
621}
622
623// Test removeDownstream() works given an IPv6 prefix.
624TEST_P(TetheroffloadAidlGeneralTest, RemoveDownstreamIPv6) {
625 const std::string iface("dummy0");
626 const std::string prefix("2001:db8::/64");
627 // First add the downstream, otherwise removeDownstream logic can reasonably
628 // return error for downstreams not previously added.
629 EXPECT_TRUE(mOffload->addDownstream(iface, prefix).isOk());
630 EXPECT_TRUE(mOffload->removeDownstream(iface, prefix).isOk());
631}
632
633// Test removeDownstream() fails given all empty parameters.
634TEST_P(TetheroffloadAidlGeneralTest, RemoveDownstreamEmptyFails) {
635 const std::string iface("");
636 const std::string prefix("");
637 EXPECT_EQ(mOffload->removeDownstream(iface, prefix).getExceptionCode(), EX_ILLEGAL_ARGUMENT);
638}
639
640// Test removeDownstream() fails given empty or non-existent interface names.
641TEST_P(TetheroffloadAidlGeneralTest, RemoveDownstreamBogusIfaceFails) {
642 const std::string prefix("192.0.2.0/24");
643 for (const auto& bogus : {"", "invalid"}) {
644 SCOPED_TRACE(testing::Message() << "iface: " << bogus);
645 const std::string iface(bogus);
646 EXPECT_EQ(mOffload->removeDownstream(iface, prefix).getExceptionCode(),
647 EX_ILLEGAL_ARGUMENT);
648 }
649}
650
651// Test removeDownstream() fails given unparseable prefix arguments.
652TEST_P(TetheroffloadAidlGeneralTest, RemoveDownstreamBogusPrefixFails) {
653 const std::string iface("dummy0");
654 for (const auto& bogus : {"", "192.0.2/24", "2001:db8/64"}) {
655 SCOPED_TRACE(testing::Message() << "prefix: " << bogus);
656 const std::string prefix(bogus);
657 EXPECT_EQ(mOffload->removeDownstream(iface, prefix).getExceptionCode(),
658 EX_ILLEGAL_ARGUMENT);
659 }
660}
661
662GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TetheroffloadAidlTestBase);
663INSTANTIATE_TEST_SUITE_P(
664 IOffload, TetheroffloadAidlTestBase,
665 testing::ValuesIn(::android::getAidlHalInstanceNames(IOffload::descriptor)),
666 ::android::PrintInstanceNameToString);
667
668GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TetheroffloadAidlPreInitTest);
669INSTANTIATE_TEST_SUITE_P(
670 IOffload, TetheroffloadAidlPreInitTest,
671 testing::ValuesIn(::android::getAidlHalInstanceNames(IOffload::descriptor)),
672 ::android::PrintInstanceNameToString);
673
674GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TetheroffloadAidlGeneralTest);
675INSTANTIATE_TEST_SUITE_P(
676 IOffload, TetheroffloadAidlGeneralTest,
677 testing::ValuesIn(::android::getAidlHalInstanceNames(IOffload::descriptor)),
678 ::android::PrintInstanceNameToString);
679
680} // namespace
681
682int main(int argc, char** argv) {
683 ::testing::InitGoogleTest(&argc, argv);
684 ABinderProcess_setThreadPoolMaxThreadCount(1);
685 ABinderProcess_startThreadPool();
686 return RUN_ALL_TESTS();
687}
688
689} // namespace aidl::android::hardware::tetheroffload