blob: 01ef9db477b313254e90655538578e2a341227f5 [file] [log] [blame]
Chirantan Ekbotebccb4752018-10-31 13:53:08 -07001// Copyright 2018 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Garrick Evans4b66f632019-01-24 15:09:16 +09005#include "arc/network/subnet.h"
Chirantan Ekbotebccb4752018-10-31 13:53:08 -07006
7#include <arpa/inet.h>
8#include <stdint.h>
9
Chirantan Ekbote817b0c22018-11-14 16:55:10 -080010#include <utility>
11#include <vector>
12
Chirantan Ekbotebccb4752018-10-31 13:53:08 -070013#include <base/bind.h>
14#include <gtest/gtest.h>
15
Garrick Evans4b66f632019-01-24 15:09:16 +090016namespace arc_networkd {
Chirantan Ekbotebccb4752018-10-31 13:53:08 -070017namespace {
18
19constexpr size_t kContainerBaseAddress = 0x64735cc0; // 100.115.92.192
Stephen Barber41955312019-01-14 16:37:40 -080020constexpr size_t kVmBaseAddress = 0x64735c18; // 100.115.92.24
Chirantan Ekbote817b0c22018-11-14 16:55:10 -080021constexpr size_t kPluginBaseAddress = 0x64735c80; // 100.115.92.128
Chirantan Ekbotebccb4752018-10-31 13:53:08 -070022
23constexpr size_t kContainerSubnetPrefix = 28;
24constexpr size_t kVmSubnetPrefix = 30;
Chirantan Ekbote817b0c22018-11-14 16:55:10 -080025constexpr size_t kPluginSubnetPrefix = 28;
Chirantan Ekbotebccb4752018-10-31 13:53:08 -070026
Chirantan Ekbote7e4aa422018-11-05 12:24:57 -080027// kExpectedAvailableCount[i] == AvailableCount() for subnet with prefix i.
28constexpr size_t kExpectedAvailableCount[] = {
29 0xfffffffe, 0x7ffffffe, 0x3ffffffe, 0x1ffffffe, 0xffffffe, 0x7fffffe,
30 0x3fffffe, 0x1fffffe, 0xfffffe, 0x7ffffe, 0x3ffffe, 0x1ffffe,
31 0xffffe, 0x7fffe, 0x3fffe, 0x1fffe, 0xfffe, 0x7ffe,
32 0x3ffe, 0x1ffe, 0xffe, 0x7fe, 0x3fe, 0x1fe,
33 0xfe, 0x7e, 0x3e, 0x1e, 0xe, 0x6,
34 0x2, 0x0,
35};
36
37// kExpectedNetmask[i] == Netmask() for subnet with prefix i.
38constexpr uint32_t kExpectedNetmask[] = {
39 0x00000000, 0x80000000, 0xc0000000, 0xe0000000, 0xf0000000, 0xf8000000,
40 0xfc000000, 0xfe000000, 0xff000000, 0xff800000, 0xffc00000, 0xffe00000,
41 0xfff00000, 0xfff80000, 0xfffc0000, 0xfffe0000, 0xffff0000, 0xffff8000,
42 0xffffc000, 0xffffe000, 0xfffff000, 0xfffff800, 0xfffffc00, 0xfffffe00,
43 0xffffff00, 0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0, 0xfffffff8,
44 0xfffffffc, 0xfffffffe,
45};
46
Chirantan Ekbotebccb4752018-10-31 13:53:08 -070047class VmSubnetTest : public ::testing::TestWithParam<size_t> {};
48class ContainerSubnetTest : public ::testing::TestWithParam<size_t> {};
49class PrefixTest : public ::testing::TestWithParam<size_t> {};
50
51void DoNothing() {}
52
53void SetTrue(bool* value) {
54 *value = true;
55}
56
57} // namespace
58
59TEST_P(VmSubnetTest, AddressAtOffset) {
60 size_t index = GetParam();
61 Subnet subnet(kVmBaseAddress + index * 4, kVmSubnetPrefix,
62 base::Bind(&DoNothing));
63
64 for (uint32_t offset = 0; offset < subnet.AvailableCount(); ++offset) {
65 uint32_t address = htonl(kVmBaseAddress + index * 4 + offset + 1);
66 EXPECT_EQ(address, subnet.AddressAtOffset(offset));
67 }
68}
69
70INSTANTIATE_TEST_CASE_P(AllValues,
71 VmSubnetTest,
Stephen Barber41955312019-01-14 16:37:40 -080072 ::testing::Range(size_t{0}, size_t{26}));
Chirantan Ekbotebccb4752018-10-31 13:53:08 -070073
74TEST_P(ContainerSubnetTest, AddressAtOffset) {
75 size_t index = GetParam();
76 Subnet subnet(kContainerBaseAddress + index * 16, kContainerSubnetPrefix,
77 base::Bind(&DoNothing));
78
79 for (uint32_t offset = 0; offset < subnet.AvailableCount(); ++offset) {
80 uint32_t address = htonl(kContainerBaseAddress + index * 16 + offset + 1);
81 EXPECT_EQ(address, subnet.AddressAtOffset(offset));
82 }
83}
84
85INSTANTIATE_TEST_CASE_P(AllValues,
86 ContainerSubnetTest,
87 ::testing::Range(size_t{1}, size_t{4}));
88
89TEST_P(PrefixTest, AvailableCount) {
90 size_t prefix = GetParam();
91
92 Subnet subnet(0, prefix, base::Bind(&DoNothing));
Chirantan Ekbote7e4aa422018-11-05 12:24:57 -080093 EXPECT_EQ(kExpectedAvailableCount[prefix], subnet.AvailableCount());
Chirantan Ekbotebccb4752018-10-31 13:53:08 -070094}
95
96TEST_P(PrefixTest, Netmask) {
97 size_t prefix = GetParam();
98
99 Subnet subnet(0, prefix, base::Bind(&DoNothing));
Chirantan Ekbote7e4aa422018-11-05 12:24:57 -0800100 EXPECT_EQ(htonl(kExpectedNetmask[prefix]), subnet.Netmask());
Chirantan Ekbotebccb4752018-10-31 13:53:08 -0700101}
102
103INSTANTIATE_TEST_CASE_P(AllValues,
104 PrefixTest,
Chirantan Ekbote817b0c22018-11-14 16:55:10 -0800105 ::testing::Range(size_t{8}, size_t{32}));
Chirantan Ekbotebccb4752018-10-31 13:53:08 -0700106
107// Tests that the Subnet runs the provided cleanup callback when it gets
108// destroyed.
109TEST(Subnet, Cleanup) {
110 bool called = false;
111
112 { Subnet subnet(0, 24, base::Bind(&SetTrue, &called)); }
113
114 EXPECT_TRUE(called);
115}
116
Chirantan Ekbote817b0c22018-11-14 16:55:10 -0800117// Tests that the subnet rejects attempts to allocate addresses outside its
118// range.
119TEST(PluginSubnet, OutOfBounds) {
120 Subnet subnet(kPluginBaseAddress, kPluginSubnetPrefix,
121 base::Bind(&base::DoNothing));
122
123 EXPECT_FALSE(subnet.Allocate(kPluginBaseAddress - 1));
124 EXPECT_FALSE(subnet.Allocate(kPluginBaseAddress));
125 EXPECT_FALSE(subnet.Allocate(kPluginBaseAddress +
126 (1ull << (32 - kPluginSubnetPrefix)) - 1));
127 EXPECT_FALSE(subnet.Allocate(kPluginBaseAddress +
128 (1ull << (32 - kPluginSubnetPrefix))));
129}
130
131// Tests that the subnet rejects attempts to allocate the same address twice.
132TEST(PluginSubnet, DuplicateAddress) {
133 Subnet subnet(kPluginBaseAddress, kPluginSubnetPrefix,
134 base::Bind(&base::DoNothing));
135
136 auto addr = subnet.Allocate(kPluginBaseAddress + 1);
137 EXPECT_TRUE(addr);
138 EXPECT_FALSE(subnet.Allocate(kPluginBaseAddress + 1));
139}
140
141// Tests that the subnet allows allocating all addresses in the subnet's range.
142TEST(PluginSubnet, Allocate) {
143 Subnet subnet(kPluginBaseAddress, kPluginSubnetPrefix,
144 base::Bind(&base::DoNothing));
145
146 std::vector<std::unique_ptr<SubnetAddress>> addrs;
147 addrs.reserve(subnet.AvailableCount());
148
149 for (size_t offset = 0; offset < subnet.AvailableCount(); ++offset) {
150 // Offset by one since the network id is not allocatable.
151 auto addr = subnet.Allocate(kPluginBaseAddress + offset + 1);
152 EXPECT_TRUE(addr);
153 EXPECT_EQ(htonl(kPluginBaseAddress + offset + 1), addr->Address());
154 addrs.emplace_back(std::move(addr));
155 }
156}
Garrick Evans0dbd4182019-03-07 08:38:38 +0900157// Tests that the subnet allows allocating all addresses in the subnet's range
158// using an offset.
159TEST(PluginSubnet, AllocateAtOffset) {
160 Subnet subnet(kPluginBaseAddress, kPluginSubnetPrefix,
161 base::Bind(&base::DoNothing));
162
163 std::vector<std::unique_ptr<SubnetAddress>> addrs;
164 addrs.reserve(subnet.AvailableCount());
165
166 for (size_t offset = 0; offset < subnet.AvailableCount(); ++offset) {
167 auto addr = subnet.AllocateAtOffset(offset);
168 EXPECT_TRUE(addr);
169 EXPECT_EQ(htonl(kPluginBaseAddress + offset + 1), addr->Address());
170 addrs.emplace_back(std::move(addr));
171 }
172}
Chirantan Ekbote817b0c22018-11-14 16:55:10 -0800173
174// Tests that the subnet frees addresses when they are destroyed.
175TEST(PluginSubnet, Free) {
176 Subnet subnet(kPluginBaseAddress, kPluginSubnetPrefix,
177 base::Bind(&base::DoNothing));
178
179 {
180 auto addr = subnet.Allocate(kPluginBaseAddress + 1);
181 EXPECT_TRUE(addr);
182 }
183
184 EXPECT_TRUE(subnet.Allocate(kPluginBaseAddress + 1));
185}
186
Garrick Evans4b66f632019-01-24 15:09:16 +0900187} // namespace arc_networkd