blob: 74dc3bd81b29d2af74187af5989ecf230735ba16 [file] [log] [blame]
/*
* Copyright (c) 2021 Project CHIP Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <gtest/gtest.h>
#include <lib/address_resolve/AddressResolve_DefaultImpl.h>
using namespace chip;
using namespace chip::AddressResolve;
namespace {
using chip::Dnssd::IPAddressSorter::IpScore;
using chip::Dnssd::IPAddressSorter::ScoreIpAddress;
constexpr uint8_t kNumberOfAvailableSlots = CHIP_CONFIG_MDNS_RESOLVE_LOOKUP_RESULTS;
Transport::PeerAddress GetAddressWithLowScore(uint16_t port = CHIP_PORT, Inet::InterfaceId interfaceId = Inet::InterfaceId::Null())
{
// Unique Local - expect score "3"
Inet::IPAddress ipAddress;
if (!Inet::IPAddress::FromString("fdff:aabb:ccdd:1::4", ipAddress))
{
ChipLogError(NotSpecified, "!!!!!!!! IP Parse failure");
}
return Transport::PeerAddress::UDP(ipAddress, port, interfaceId);
}
Transport::PeerAddress GetAddressWithMediumScore(uint16_t port = CHIP_PORT,
Inet::InterfaceId interfaceId = Inet::InterfaceId::Null())
{
// Global Unicast - expect score '4'
Inet::IPAddress ipAddress;
if (!Inet::IPAddress::FromString("2001::aabb:ccdd:2233:4455", ipAddress))
{
ChipLogError(NotSpecified, "!!!!!!!! IP Parse failure");
}
return Transport::PeerAddress::UDP(ipAddress, port, interfaceId);
}
Transport::PeerAddress GetAddressWithHighScore(uint16_t port = CHIP_PORT, Inet::InterfaceId interfaceId = Inet::InterfaceId::Null())
{
// LinkLocal - expect score '7'
// Likely that the interfaceId is wrong (link local needs it),
// however we do not expect sorter to care
Inet::IPAddress ipAddress;
if (!Inet::IPAddress::FromString("fe80::aabb:ccdd:2233:4455", ipAddress))
{
ChipLogError(NotSpecified, "!!!!!!!! IP Parse failure");
}
return Transport::PeerAddress::UDP(ipAddress, port, interfaceId);
}
TEST(TestAddressResolveDefaultImpl, TestLookupResult)
{
ResolveResult lowResult;
lowResult.address = GetAddressWithLowScore();
ResolveResult mediumResult;
mediumResult.address = GetAddressWithMediumScore();
ResolveResult highResult;
highResult.address = GetAddressWithHighScore();
// Ensure test expectations regarding ordering is matched
IpScore lowScore = ScoreIpAddress(lowResult.address.GetIPAddress(), Inet::InterfaceId::Null());
IpScore mediumScore = ScoreIpAddress(mediumResult.address.GetIPAddress(), Inet::InterfaceId::Null());
IpScore highScore = ScoreIpAddress(highResult.address.GetIPAddress(), Inet::InterfaceId::Null());
EXPECT_LT(to_underlying(lowScore), to_underlying(mediumScore));
EXPECT_LT(to_underlying(mediumScore), to_underlying(highScore));
ResolveResult outResult;
AddressResolve::NodeLookupHandle handle;
auto now = System::SystemClock().GetMonotonicTimestamp();
auto request = NodeLookupRequest(chip::PeerId(1, 2));
handle.ResetForLookup(now, request);
// Check that no result exists.
EXPECT_FALSE(handle.HasLookupResult());
// Fill a single slot.
handle.LookupResult(lowResult);
// Check that a result exists.
EXPECT_TRUE(handle.HasLookupResult());
// Check that the result match what has been inserted.
outResult = handle.TakeLookupResult();
EXPECT_EQ(lowResult.address, outResult.address);
// Check that the result has been consumed properly
EXPECT_FALSE(handle.HasLookupResult());
handle.ResetForLookup(now, request);
// Fill all the possible slots.
for (auto i = 0; i < kNumberOfAvailableSlots; i++)
{
handle.LookupResult(lowResult);
}
// Read back all results and validate that they match the input.
for (auto i = 0; i < kNumberOfAvailableSlots; i++)
{
EXPECT_TRUE(handle.HasLookupResult());
outResult = handle.TakeLookupResult();
EXPECT_EQ(lowResult.address, outResult.address);
}
// Check that the results has been consumed properly.
EXPECT_FALSE(handle.HasLookupResult());
handle.ResetForLookup(now, request);
// Fill all the possible slots by giving it 2 times more results than the available slots.
for (auto i = 0; i < kNumberOfAvailableSlots * 2; i++)
{
handle.LookupResult(lowResult);
}
// Read back all results and validate that they match the input.
for (auto i = 0; i < kNumberOfAvailableSlots; i++)
{
EXPECT_TRUE(handle.HasLookupResult());
outResult = handle.TakeLookupResult();
EXPECT_EQ(lowResult.address, outResult.address);
}
// Check that the results has been consumed properly.
EXPECT_FALSE(handle.HasLookupResult());
handle.ResetForLookup(now, request);
// Fill all the possible slots.
for (auto i = 0; i < kNumberOfAvailableSlots; i++)
{
handle.LookupResult(lowResult);
}
// Add a result with a medium score and ensure it sits at the top.
handle.LookupResult(mediumResult);
EXPECT_TRUE(handle.HasLookupResult());
outResult = handle.TakeLookupResult();
EXPECT_EQ(mediumResult.address, outResult.address);
handle.ResetForLookup(now, request);
// Fill all the possible slots.
for (auto i = 0; i < kNumberOfAvailableSlots; i++)
{
handle.LookupResult(lowResult);
}
// Add a result with a medium score and a result with a high score and ensure the result with the high score comes first.
handle.LookupResult(mediumResult);
handle.LookupResult(highResult);
EXPECT_TRUE(handle.HasLookupResult());
outResult = handle.TakeLookupResult();
EXPECT_EQ(highResult.address, outResult.address);
if (kNumberOfAvailableSlots > 1)
{
// Ensure the second result is the medium result.
EXPECT_TRUE(handle.HasLookupResult());
outResult = handle.TakeLookupResult();
EXPECT_EQ(mediumResult.address, outResult.address);
}
if (kNumberOfAvailableSlots > 2)
{
// Ensure that all the other results are low results.
for (auto i = 2; i < kNumberOfAvailableSlots; i++)
{
EXPECT_TRUE(handle.HasLookupResult());
outResult = handle.TakeLookupResult();
EXPECT_EQ(lowResult.address, outResult.address);
}
}
// Check that the results has been consumed properly.
EXPECT_FALSE(handle.HasLookupResult());
}
} // namespace