blob: a254a14d7b4b59213c1be9fc4c0c58bb0fcd5145 [file] [log] [blame]
/*
*
* Copyright (c) 2021 Project CHIP Authors
* All rights reserved.
*
* 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.
*/
// set this to 1 to enable DumpCache to see the state of the cache when needed
// #define MDNS_LOGGING 1
#include <cstdint>
#include <iostream>
#include <nlunit-test.h>
#include <inet/IPAddress.h>
#include <inet/InetInterface.h>
#include <inet/InetLayer.h>
#include <lib/core/CHIPError.h>
#include <lib/core/PeerId.h>
#include <lib/dnssd/DnssdCache.h>
#include <lib/support/UnitTestRegistration.h>
#include <lib/support/logging/CHIPLogging.h>
#include <system/SystemTimer.h>
#include <system/TimeSource.h>
#define NL_TEST_DEF_FN(fn) NL_TEST_DEF("Test " #fn, fn)
using namespace chip;
using namespace chip::Dnssd;
namespace {
class FakeClock : public System::Clock::ClockBase
{
public:
System::Clock::Microseconds64 GetMonotonicMicroseconds64() override { return mTime; }
System::Clock::Milliseconds64 GetMonotonicMilliseconds64() override { return mTime; }
System::Clock::Milliseconds64 mTime = System::Clock::kZero;
};
FakeClock fakeClock;
System::Clock::ClockBase * realClock;
} // namespace
void TestCreate(nlTestSuite * inSuite, void * inContext)
{
DnssdCache<10> tDnssdCache;
tDnssdCache.DumpCache();
}
void TestInsert(nlTestSuite * inSuite, void * inContext)
{
const int sizeOfCache = 5;
DnssdCache<sizeOfCache> tDnssdCache;
PeerId peerId;
int64_t id = 0x100;
uint16_t port = 2000;
const System::Clock::Timestamp ttl = System::Clock::Seconds16(2);
const uint64_t KNOWN_FABRIC = 0x100;
ResolvedNodeData nodeData;
ResolvedNodeData nodeDataOut;
Inet::IPAddress::FromString("1.0.0.1", nodeData.mAddress[nodeData.mNumIPs++]);
nodeData.mInterfaceId = Inet::InterfaceId::Null();
nodeData.mExpiryTime = fakeClock.mTime + ttl;
peerId.SetCompressedFabricId(KNOWN_FABRIC);
nodeData.mPeerId.SetCompressedFabricId(KNOWN_FABRIC);
for (uint16_t i = 0; i < 10; i++)
{
CHIP_ERROR result;
nodeData.mPeerId.SetNodeId(static_cast<NodeId>(id + i));
// Need to re-cast to uint16_t because of integer type promotion
nodeData.mPort = static_cast<uint16_t>(port + i);
result = tDnssdCache.Insert(nodeData);
if (i < sizeOfCache)
{
NL_TEST_ASSERT(inSuite, result == CHIP_NO_ERROR);
}
else
{
NL_TEST_ASSERT(inSuite, result != CHIP_NO_ERROR);
}
}
tDnssdCache.DumpCache();
fakeClock.mTime = nodeData.mExpiryTime + ttl + System::Clock::Seconds16(1);
nodeData.mExpiryTime = fakeClock.mTime + ttl;
id = 0x200;
port = 3000;
for (uint16_t i = 0; i < sizeOfCache; i++)
{
CHIP_ERROR result;
nodeData.mPeerId.SetNodeId(static_cast<NodeId>(id + i));
nodeData.mPort = static_cast<uint16_t>(port + i);
result = tDnssdCache.Insert(nodeData);
NL_TEST_ASSERT(inSuite, result == CHIP_NO_ERROR);
}
tDnssdCache.DumpCache();
for (uint16_t i = 0; i < sizeOfCache; i++)
{
CHIP_ERROR result;
peerId.SetNodeId(static_cast<NodeId>(id + i));
result = tDnssdCache.Delete(peerId);
NL_TEST_ASSERT(inSuite, result == CHIP_NO_ERROR);
}
tDnssdCache.DumpCache();
// ipv6 inserts
Inet::IPAddress::FromString("::1", nodeData.mAddress[nodeData.mNumIPs++]);
port = 4000;
for (uint16_t i = 0; i < sizeOfCache; i++)
{
CHIP_ERROR result;
nodeData.mPeerId.SetNodeId(static_cast<NodeId>(id + i));
nodeData.mPort = static_cast<uint16_t>(port + i);
result = tDnssdCache.Insert(nodeData);
NL_TEST_ASSERT(inSuite, result == CHIP_NO_ERROR);
}
tDnssdCache.DumpCache();
NL_TEST_ASSERT(inSuite, tDnssdCache.Lookup(peerId, nodeDataOut) == CHIP_NO_ERROR);
peerId.SetCompressedFabricId(KNOWN_FABRIC + 1);
NL_TEST_ASSERT(inSuite, tDnssdCache.Lookup(peerId, nodeDataOut) != CHIP_NO_ERROR);
}
static const nlTest sTests[] = { NL_TEST_DEF_FN(TestCreate), NL_TEST_DEF_FN(TestInsert), NL_TEST_SENTINEL() };
static int TestSetup(void * inContext)
{
realClock = &System::SystemClock();
System::Clock::Internal::SetSystemClockForTesting(&fakeClock);
return SUCCESS;
}
static int TestTeardown(void * inContext)
{
System::Clock::Internal::SetSystemClockForTesting(realClock);
return SUCCESS;
}
int TestDnssdCache(void)
{
nlTestSuite theSuite = { "MDNS Cache Creation", &sTests[0], TestSetup, TestTeardown };
nlTestRunner(&theSuite, nullptr);
return nlTestRunnerStats(&theSuite);
}
CHIP_REGISTER_TEST_SUITE(TestDnssdCache)