| /* |
| * |
| * 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 <lib/address_resolve/AddressResolve_DefaultImpl.h> |
| |
| #include <lib/support/UnitTestRegistration.h> |
| |
| #include <nlunit-test.h> |
| |
| using namespace chip; |
| using namespace chip::AddressResolve; |
| |
| namespace { |
| |
| constexpr uint8_t kNumberOfAvailableSlots = CHIP_CONFIG_MDNS_RESOLVE_LOOKUP_RESULTS; |
| |
| Transport::PeerAddress GetAddressWithLowScore(uint16_t port = CHIP_PORT, Inet::InterfaceId interfaceId = Inet::InterfaceId::Null()) |
| { |
| // Embedded IPv4 |
| Inet::IPAddress ipAddress; |
| Inet::IPAddress::FromString("0:0:0:0:0:0:111.22.33.44", ipAddress); |
| |
| return Transport::PeerAddress::UDP(ipAddress, port, interfaceId); |
| } |
| |
| Transport::PeerAddress GetAddressWithMediumScore(uint16_t port = CHIP_PORT, |
| Inet::InterfaceId interfaceId = Inet::InterfaceId::Null()) |
| { |
| // Unique Local |
| Inet::IPAddress ipAddress; |
| Inet::IPAddress::FromString("fdff:aabb:ccdd:1::4", ipAddress); |
| |
| return Transport::PeerAddress::UDP(ipAddress, port, interfaceId); |
| } |
| |
| Transport::PeerAddress GetAddressWithHighScore(uint16_t port = CHIP_PORT, Inet::InterfaceId interfaceId = Inet::InterfaceId::Null()) |
| { |
| // Global Unicast |
| Inet::IPAddress ipAddress; |
| Inet::IPAddress::FromString("2001::aabb:ccdd:2233:4455", ipAddress); |
| |
| return Transport::PeerAddress::UDP(ipAddress, port, interfaceId); |
| } |
| |
| void TestLookupResult(nlTestSuite * inSuite, void * inContext) |
| { |
| ResolveResult lowResult; |
| lowResult.address = GetAddressWithLowScore(); |
| |
| ResolveResult mediumResult; |
| mediumResult.address = GetAddressWithMediumScore(); |
| |
| ResolveResult highResult; |
| highResult.address = GetAddressWithHighScore(); |
| |
| 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. |
| NL_TEST_ASSERT(inSuite, !handle.HasLookupResult()); |
| |
| // Fill a single slot. |
| handle.LookupResult(lowResult); |
| |
| // Check that a result exists. |
| NL_TEST_ASSERT(inSuite, handle.HasLookupResult()); |
| |
| // Check that the result match what has been inserted. |
| outResult = handle.TakeLookupResult(); |
| NL_TEST_ASSERT(inSuite, lowResult.address == outResult.address); |
| |
| // Check that the result has been consumed properly |
| NL_TEST_ASSERT(inSuite, !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++) |
| { |
| NL_TEST_ASSERT(inSuite, handle.HasLookupResult()); |
| outResult = handle.TakeLookupResult(); |
| NL_TEST_ASSERT(inSuite, lowResult.address == outResult.address); |
| } |
| |
| // Check that the results has been consumed properly. |
| NL_TEST_ASSERT(inSuite, !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++) |
| { |
| NL_TEST_ASSERT(inSuite, handle.HasLookupResult()); |
| outResult = handle.TakeLookupResult(); |
| NL_TEST_ASSERT(inSuite, lowResult.address == outResult.address); |
| } |
| |
| // Check that the results has been consumed properly. |
| NL_TEST_ASSERT(inSuite, !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); |
| NL_TEST_ASSERT(inSuite, handle.HasLookupResult()); |
| outResult = handle.TakeLookupResult(); |
| NL_TEST_ASSERT(inSuite, 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); |
| NL_TEST_ASSERT(inSuite, handle.HasLookupResult()); |
| outResult = handle.TakeLookupResult(); |
| NL_TEST_ASSERT(inSuite, highResult.address == outResult.address); |
| |
| if (kNumberOfAvailableSlots > 1) |
| { |
| // Ensure the second result is the medium result. |
| NL_TEST_ASSERT(inSuite, handle.HasLookupResult()); |
| outResult = handle.TakeLookupResult(); |
| NL_TEST_ASSERT(inSuite, mediumResult.address == outResult.address); |
| } |
| |
| if (kNumberOfAvailableSlots > 2) |
| { |
| // Ensure that all the other results are low results. |
| for (auto i = 2; i < kNumberOfAvailableSlots; i++) |
| { |
| NL_TEST_ASSERT(inSuite, handle.HasLookupResult()); |
| outResult = handle.TakeLookupResult(); |
| NL_TEST_ASSERT(inSuite, lowResult.address == outResult.address); |
| } |
| } |
| |
| // Check that the results has been consumed properly. |
| NL_TEST_ASSERT(inSuite, !handle.HasLookupResult()); |
| } |
| |
| const nlTest sTests[] = { |
| NL_TEST_DEF("TestLookupResult", TestLookupResult), // |
| NL_TEST_SENTINEL() // |
| }; |
| |
| } // namespace |
| |
| int TestAddressResolve_DefaultImpl() |
| { |
| nlTestSuite theSuite = { "AddressResolve_DefaultImpl", sTests, nullptr, nullptr }; |
| nlTestRunner(&theSuite, nullptr); |
| return nlTestRunnerStats(&theSuite); |
| } |
| |
| CHIP_REGISTER_TEST_SUITE(TestAddressResolve_DefaultImpl) |