| // Copyright 2023 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "net/base/fuchsia/network_interface_cache.h" |
| |
| #include <fuchsia/net/interfaces/cpp/fidl.h> |
| #include <fuchsia/net/interfaces/cpp/fidl_test_base.h> |
| |
| #include "net/base/network_change_notifier.h" |
| #include "net/base/network_interfaces.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace net::internal { |
| namespace { |
| |
| enum : InterfaceProperties::InterfaceId { |
| kDefaultInterfaceId = 1, |
| kSecondaryInterfaceId = 2 |
| }; |
| |
| using IPv4Octets = std::array<uint8_t, 4>; |
| |
| constexpr IPv4Octets kDefaultIPv4Address = {192, 168, 0, 2}; |
| constexpr uint8_t kDefaultIPv4Prefix = 16; |
| |
| constexpr const char kDefaultInterfaceName[] = "net1"; |
| |
| fuchsia::net::IpAddress IpAddressFrom(IPv4Octets octets) { |
| fuchsia::net::IpAddress output; |
| output.ipv4().addr = octets; |
| return output; |
| } |
| |
| template <typename T> |
| fuchsia::net::Subnet SubnetFrom(T octets, uint8_t prefix) { |
| fuchsia::net::Subnet output; |
| output.addr = IpAddressFrom(octets); |
| output.prefix_len = prefix; |
| return output; |
| } |
| |
| template <typename T> |
| fuchsia::net::interfaces::Address InterfaceAddressFrom(T octets, |
| uint8_t prefix) { |
| fuchsia::net::interfaces::Address addr; |
| addr.set_addr(SubnetFrom(octets, prefix)); |
| return addr; |
| } |
| |
| template <typename T> |
| std::vector<T> MakeSingleItemVec(T item) { |
| std::vector<T> vec; |
| vec.push_back(std::move(item)); |
| return vec; |
| } |
| |
| fuchsia::net::interfaces::Properties DefaultInterfaceProperties( |
| fuchsia::hardware::network::DeviceClass device_class = |
| fuchsia::hardware::network::DeviceClass::ETHERNET) { |
| // For most tests a live interface with an IPv4 address and ethernet class is |
| // sufficient. |
| fuchsia::net::interfaces::Properties properties; |
| properties.set_id(kDefaultInterfaceId); |
| properties.set_name(kDefaultInterfaceName); |
| properties.set_online(true); |
| properties.set_has_default_ipv4_route(true); |
| properties.set_has_default_ipv6_route(false); |
| properties.set_device_class(fuchsia::net::interfaces::DeviceClass::WithDevice( |
| std::move(device_class))); |
| properties.set_addresses(MakeSingleItemVec( |
| InterfaceAddressFrom(kDefaultIPv4Address, kDefaultIPv4Prefix))); |
| return properties; |
| } |
| |
| } // namespace |
| |
| class NetworkInterfaceCacheTest : public testing::Test {}; |
| |
| TEST_F(NetworkInterfaceCacheTest, AddInterface) { |
| NetworkInterfaceCache cache(false); |
| |
| auto change_bits = cache.AddInterface(DefaultInterfaceProperties()); |
| |
| ASSERT_TRUE(change_bits.has_value()); |
| EXPECT_EQ(change_bits.value(), |
| NetworkInterfaceCache::kIpAddressChanged | |
| NetworkInterfaceCache::kConnectionTypeChanged); |
| |
| NetworkInterfaceList networks; |
| EXPECT_TRUE(cache.GetOnlineInterfaces(&networks)); |
| EXPECT_EQ(networks.size(), 1u); |
| |
| EXPECT_EQ(cache.GetConnectionType(), |
| NetworkChangeNotifier::CONNECTION_ETHERNET); |
| } |
| |
| TEST_F(NetworkInterfaceCacheTest, RemoveInterface) { |
| NetworkInterfaceCache cache(false); |
| cache.AddInterface(DefaultInterfaceProperties()); |
| |
| auto change_bits = cache.RemoveInterface(kDefaultInterfaceId); |
| |
| ASSERT_TRUE(change_bits.has_value()); |
| EXPECT_EQ(change_bits.value(), |
| NetworkInterfaceCache::kIpAddressChanged | |
| NetworkInterfaceCache::kConnectionTypeChanged); |
| |
| NetworkInterfaceList networks; |
| EXPECT_TRUE(cache.GetOnlineInterfaces(&networks)); |
| EXPECT_EQ(networks.size(), 0u); |
| |
| EXPECT_EQ(cache.GetConnectionType(), NetworkChangeNotifier::CONNECTION_NONE); |
| } |
| |
| TEST_F(NetworkInterfaceCacheTest, ChangeInterface) { |
| NetworkInterfaceCache cache(false); |
| cache.AddInterface(DefaultInterfaceProperties()); |
| |
| fuchsia::net::interfaces::Properties properties; |
| properties.set_id(kDefaultInterfaceId); |
| properties.set_device_class( |
| fuchsia::net::interfaces::DeviceClass::WithLoopback( |
| fuchsia::net::interfaces::Empty())); |
| properties.set_addresses({}); |
| |
| auto change_bits = cache.ChangeInterface(std::move(properties)); |
| |
| ASSERT_TRUE(change_bits.has_value()); |
| EXPECT_EQ(change_bits.value(), |
| NetworkInterfaceCache::kIpAddressChanged | |
| NetworkInterfaceCache::kConnectionTypeChanged); |
| |
| NetworkInterfaceList networks; |
| EXPECT_TRUE(cache.GetOnlineInterfaces(&networks)); |
| EXPECT_EQ(networks.size(), 0u); |
| |
| EXPECT_EQ(cache.GetConnectionType(), NetworkChangeNotifier::CONNECTION_NONE); |
| } |
| |
| // TODO(crbug.com/1131238): Add more tests that exercise different error states. |
| |
| } // namespace net::internal |