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