blob: 50bc5d81dca055dfeeabb6032753ba0b426be123 [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "net/dns/esni_content.h"
#include "base/strings/string_number_conversions.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
namespace {
IPAddress MakeIPAddress() {
// Introduce some (deterministic) variation in the IP addresses
// generated.
static uint8_t next_octet = 0;
next_octet += 4;
return IPAddress(next_octet, next_octet + 1, next_octet + 2, next_octet + 3);
}
// Make sure we can add keys.
TEST(EsniContentTest, AddKey) {
EsniContent c1;
c1.AddKey("a");
EXPECT_THAT(c1.keys(), ::testing::UnorderedElementsAre("a"));
c1.AddKey("a");
EXPECT_THAT(c1.keys(), ::testing::UnorderedElementsAre("a"));
c1.AddKey("b");
EXPECT_THAT(c1.keys(), ::testing::UnorderedElementsAre("a", "b"));
}
// Make sure we can add key-address pairs.
TEST(EsniContentTest, AddKeyForAddress) {
EsniContent c1;
auto address = MakeIPAddress();
c1.AddKeyForAddress(address, "a");
EXPECT_THAT(c1.keys(), ::testing::UnorderedElementsAre("a"));
EXPECT_THAT(c1.keys_for_addresses(),
::testing::UnorderedElementsAre(::testing::Pair(
address, ::testing::UnorderedElementsAre("a"))));
}
TEST(EsniContentTest, AssociateAddressWithExistingKey) {
EsniContent c1;
auto address = MakeIPAddress();
c1.AddKey("a");
c1.AddKeyForAddress(address, "a");
EXPECT_THAT(c1.keys(), ::testing::UnorderedElementsAre("a"));
EXPECT_THAT(c1.keys_for_addresses(),
::testing::UnorderedElementsAre(::testing::Pair(
address, ::testing::UnorderedElementsAre("a"))));
}
// Merging to an empty EsniContent should make the result equal the source of
// the merge.
TEST(EsniContentTest, MergeToEmpty) {
EsniContent c1;
c1.AddKey("c");
IPAddress address = MakeIPAddress();
c1.AddKeyForAddress(address, "a");
c1.AddKeyForAddress(address, "b");
EsniContent empty;
empty.MergeFrom(c1);
EXPECT_EQ(c1, empty);
}
TEST(EsniContentTest, MergeFromEmptyNoOp) {
EsniContent c1, c2;
c1.AddKey("a");
c2.AddKey("a");
EsniContent empty;
c1.MergeFrom(empty);
EXPECT_EQ(c1, c2);
}
// Test that merging multiple keys corresponding to a single address works.
TEST(EsniContentTest, MergeKeysForSingleHost) {
EsniContent c1, c2;
IPAddress address = MakeIPAddress();
c1.AddKeyForAddress(address, "a");
c1.AddKeyForAddress(address, "b");
c2.AddKeyForAddress(address, "b");
c2.AddKeyForAddress(address, "c");
c1.MergeFrom(c2);
EXPECT_THAT(c1.keys(), ::testing::UnorderedElementsAre("a", "b", "c"));
EXPECT_THAT(c1.keys_for_addresses(),
::testing::UnorderedElementsAre(::testing::Pair(
address, ::testing::UnorderedElementsAre("a", "b", "c"))));
}
// Test that merging multiple addresss corresponding to a single key works.
TEST(EsniContentTest, MergeHostsForSingleKey) {
EsniContent c1, c2;
IPAddress address = MakeIPAddress();
IPAddress second_address = MakeIPAddress();
c1.AddKeyForAddress(address, "a");
c2.AddKeyForAddress(second_address, "a");
c1.MergeFrom(c2);
EXPECT_THAT(c1.keys(), ::testing::UnorderedElementsAre("a"));
EXPECT_THAT(
c1.keys_for_addresses(),
::testing::UnorderedElementsAre(
::testing::Pair(address, ::testing::UnorderedElementsAre("a")),
::testing::Pair(second_address,
::testing::UnorderedElementsAre("a"))));
}
// Test merging some more complex instances of the class.
TEST(EsniContentTest, MergeSeveralHostsAndKeys) {
EsniContent c1, c2, expected;
for (int i = 0; i < 50; ++i) {
IPAddress address = MakeIPAddress();
std::string key = base::NumberToString(i);
switch (i % 3) {
case 0:
c1.AddKey(key);
expected.AddKey(key);
break;
case 1:
c2.AddKey(key);
expected.AddKey(key);
break;
}
// Associate each address with a subset of the keys seen so far
{
int j = 0;
for (auto key : c1.keys()) {
if (j % 2) {
c1.AddKeyForAddress(address, key);
expected.AddKeyForAddress(address, key);
}
++j;
}
}
{
int j = 0;
for (auto key : c2.keys()) {
if (j % 3 == 1) {
c2.AddKeyForAddress(address, key);
expected.AddKeyForAddress(address, key);
}
++j;
}
}
}
{
EsniContent merge_dest = c1;
EsniContent merge_src = c2;
merge_dest.MergeFrom(merge_src);
EXPECT_EQ(merge_dest, expected);
}
{
EsniContent merge_dest = c2;
EsniContent merge_src = c1;
merge_dest.MergeFrom(merge_src);
EXPECT_EQ(merge_dest, expected);
}
}
} // namespace
} // namespace net