blob: cbc20f4ac593f1c7f01fdf9d6084f66f709714f4 [file] [log] [blame]
// Copyright 2017 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <stdint.h>
#include <map>
#include <vector>
#include <gtest/gtest.h>
#include "patchpanel/mac_address_generator.h"
namespace patchpanel {
// Tests that the mac addresses created by the generator have the proper flags.
TEST(MacAddressGenerator, Flags) {
MacAddressGenerator generator;
const std::vector<uint8_t> addr = generator.Generate().ToBytes();
EXPECT_EQ(static_cast<uint8_t>(0x02), addr[0] & static_cast<uint8_t>(0x02));
EXPECT_EQ(static_cast<uint8_t>(0), addr[0] & static_cast<uint8_t>(0x01));
}
// Tests that the generator does not create duplicate addresses. Obviously due
// the vast range of possible addresses it's expensive to do an exhaustive
// search in this test. However, we can take advantage of the birthday paradox
// to reduce the number of addresses we need to generate. We know that the 2
// least significant bits of the first octet in the address are fixed. This
// leaves 2^46 possible addresses. Generating 2^25 addresses gives us a 99.96%
// chance of triggering a collision in this range. So if the generator returns
// 2^25 unique addresses then we can be fairly certain that it won't give out
// duplicate addresses.
// This test is currently disabled because it takes a long time to run
// (~minutes). We ran it on the CQ for several months without issue so we can
// be pretty confident that the current implementation does not produce
// duplicates. If you make any changes to the mac address generation code,
// please re-enable this test.
TEST(MacAddressGenerator, DISABLED_Duplicates) {
constexpr uint32_t kNumAddresses = (1 << 25);
MacAddressGenerator generator;
net_base::MacAddress::UnorderedSet addrs;
addrs.reserve(kNumAddresses);
for (uint32_t i = 0; i < kNumAddresses; ++i) {
const net_base::MacAddress addr = generator.Generate();
EXPECT_EQ(addrs.end(), addrs.find(addr));
addrs.insert(addr);
}
}
TEST(MacAddressGenerator, Stable) {
MacAddressGenerator generator1, generator2;
std::map<uint8_t, net_base::MacAddress> addrs;
for (uint8_t i = 0;; ++i) {
addrs[i] = generator1.GetStable(i);
EXPECT_EQ(static_cast<uint8_t>(0x02),
addrs[i].ToBytes()[0] & static_cast<uint8_t>(0x02));
EXPECT_EQ(static_cast<uint8_t>(0),
addrs[i].ToBytes()[0] & static_cast<uint8_t>(0x01));
if (i == 255) {
break;
}
}
EXPECT_EQ(addrs.size(), 256);
for (const auto addr : addrs) {
EXPECT_EQ(addr.second, generator2.GetStable(addr.first));
}
}
} // namespace patchpanel