• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2023 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/base/fuchsia/network_interface_cache.h"
6 
7 #include <fuchsia/net/interfaces/cpp/fidl.h>
8 #include <fuchsia/net/interfaces/cpp/fidl_test_base.h>
9 
10 #include "net/base/network_change_notifier.h"
11 #include "net/base/network_interfaces.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 
14 namespace net::internal {
15 namespace {
16 
17 enum : InterfaceProperties::InterfaceId {
18   kDefaultInterfaceId = 1,
19   kSecondaryInterfaceId = 2
20 };
21 
22 using IPv4Octets = std::array<uint8_t, 4>;
23 
24 constexpr IPv4Octets kDefaultIPv4Address = {192, 168, 0, 2};
25 constexpr uint8_t kDefaultIPv4Prefix = 16;
26 
27 constexpr const char kDefaultInterfaceName[] = "net1";
28 
IpAddressFrom(IPv4Octets octets)29 fuchsia::net::IpAddress IpAddressFrom(IPv4Octets octets) {
30   fuchsia::net::IpAddress output;
31   output.ipv4().addr = octets;
32   return output;
33 }
34 
35 template <typename T>
SubnetFrom(T octets,uint8_t prefix)36 fuchsia::net::Subnet SubnetFrom(T octets, uint8_t prefix) {
37   fuchsia::net::Subnet output;
38   output.addr = IpAddressFrom(octets);
39   output.prefix_len = prefix;
40   return output;
41 }
42 
43 template <typename T>
InterfaceAddressFrom(T octets,uint8_t prefix)44 fuchsia::net::interfaces::Address InterfaceAddressFrom(T octets,
45                                                        uint8_t prefix) {
46   fuchsia::net::interfaces::Address addr;
47   addr.set_addr(SubnetFrom(octets, prefix));
48   return addr;
49 }
50 
51 template <typename T>
MakeSingleItemVec(T item)52 std::vector<T> MakeSingleItemVec(T item) {
53   std::vector<T> vec;
54   vec.push_back(std::move(item));
55   return vec;
56 }
57 
DefaultInterfaceProperties(fuchsia::hardware::network::PortClass device_class=fuchsia::hardware::network::PortClass::ETHERNET)58 fuchsia::net::interfaces::Properties DefaultInterfaceProperties(
59     fuchsia::hardware::network::PortClass device_class =
60         fuchsia::hardware::network::PortClass::ETHERNET) {
61   // For most tests a live interface with an IPv4 address and ethernet class is
62   // sufficient.
63   fuchsia::net::interfaces::Properties properties;
64   properties.set_id(kDefaultInterfaceId);
65   properties.set_name(kDefaultInterfaceName);
66   properties.set_online(true);
67   properties.set_has_default_ipv4_route(true);
68   properties.set_has_default_ipv6_route(false);
69   properties.set_port_class(fuchsia::net::interfaces::PortClass::WithDevice(
70       std::move(device_class)));
71   properties.set_addresses(MakeSingleItemVec(
72       InterfaceAddressFrom(kDefaultIPv4Address, kDefaultIPv4Prefix)));
73   return properties;
74 }
75 
76 }  // namespace
77 
78 class NetworkInterfaceCacheTest : public testing::Test {};
79 
TEST_F(NetworkInterfaceCacheTest,AddInterface)80 TEST_F(NetworkInterfaceCacheTest, AddInterface) {
81   NetworkInterfaceCache cache(false);
82 
83   auto change_bits = cache.AddInterface(DefaultInterfaceProperties());
84 
85   ASSERT_TRUE(change_bits.has_value());
86   EXPECT_EQ(change_bits.value(),
87             NetworkInterfaceCache::kIpAddressChanged |
88                 NetworkInterfaceCache::kConnectionTypeChanged);
89 
90   NetworkInterfaceList networks;
91   EXPECT_TRUE(cache.GetOnlineInterfaces(&networks));
92   EXPECT_EQ(networks.size(), 1u);
93 
94   EXPECT_EQ(cache.GetConnectionType(),
95             NetworkChangeNotifier::CONNECTION_ETHERNET);
96 }
97 
TEST_F(NetworkInterfaceCacheTest,RemoveInterface)98 TEST_F(NetworkInterfaceCacheTest, RemoveInterface) {
99   NetworkInterfaceCache cache(false);
100   cache.AddInterface(DefaultInterfaceProperties());
101 
102   auto change_bits = cache.RemoveInterface(kDefaultInterfaceId);
103 
104   ASSERT_TRUE(change_bits.has_value());
105   EXPECT_EQ(change_bits.value(),
106             NetworkInterfaceCache::kIpAddressChanged |
107                 NetworkInterfaceCache::kConnectionTypeChanged);
108 
109   NetworkInterfaceList networks;
110   EXPECT_TRUE(cache.GetOnlineInterfaces(&networks));
111   EXPECT_EQ(networks.size(), 0u);
112 
113   EXPECT_EQ(cache.GetConnectionType(), NetworkChangeNotifier::CONNECTION_NONE);
114 }
115 
TEST_F(NetworkInterfaceCacheTest,ChangeInterface)116 TEST_F(NetworkInterfaceCacheTest, ChangeInterface) {
117   NetworkInterfaceCache cache(false);
118   cache.AddInterface(DefaultInterfaceProperties());
119 
120   fuchsia::net::interfaces::Properties properties;
121   properties.set_id(kDefaultInterfaceId);
122   properties.set_port_class(
123       fuchsia::net::interfaces::PortClass::WithLoopback(
124           fuchsia::net::interfaces::Empty()));
125   properties.set_addresses({});
126 
127   auto change_bits = cache.ChangeInterface(std::move(properties));
128 
129   ASSERT_TRUE(change_bits.has_value());
130   EXPECT_EQ(change_bits.value(),
131             NetworkInterfaceCache::kIpAddressChanged |
132                 NetworkInterfaceCache::kConnectionTypeChanged);
133 
134   NetworkInterfaceList networks;
135   EXPECT_TRUE(cache.GetOnlineInterfaces(&networks));
136   EXPECT_EQ(networks.size(), 0u);
137 
138   EXPECT_EQ(cache.GetConnectionType(), NetworkChangeNotifier::CONNECTION_NONE);
139 }
140 
141 // TODO(crbug.com/40721278): Add more tests that exercise different error
142 // states.
143 
144 }  // namespace net::internal
145