mirror of
https://github.com/espressif/openthread.git
synced 2026-10-12 18:57:37 +00:00
[nexus] migrate srp scale test to nexus (#12949)
This commit migrates the test_srp_register_500_services.py test from the thread-cert test suite to the Nexus platform. The new C++ test (tests/nexus/test_srp_scale.cpp) implements the same functionality: it verifies that 25 SRP clients (13 routers and 12 FEDs) can successfully register a total of 500 services (20 services per client) with a single SRP server (the leader). The commit includes: - Removal of the original Python test file. - Addition of the new Nexus C++ test file. - Integration of the new test into CMakeLists.txt and run_nexus_tests.sh.
This commit is contained in:
@@ -410,6 +410,7 @@ ot_nexus_test(srp_client_change_lease "core;nexus")
|
||||
ot_nexus_test(srp_client_remove_host "core;nexus")
|
||||
ot_nexus_test(srp_lease "core;nexus")
|
||||
ot_nexus_test(srp_many_services_mtu_check "core;nexus")
|
||||
ot_nexus_test(srp_scale "core;nexus")
|
||||
ot_nexus_test(zero_len_external_route "core;nexus")
|
||||
|
||||
# Trel
|
||||
|
||||
@@ -0,0 +1,243 @@
|
||||
/*
|
||||
* Copyright (c) 2026, The OpenThread Authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "platform/nexus_core.hpp"
|
||||
#include "platform/nexus_node.hpp"
|
||||
|
||||
namespace ot {
|
||||
namespace Nexus {
|
||||
|
||||
namespace {
|
||||
|
||||
const uint16_t kNumSrpClients = 25;
|
||||
const uint16_t kInstanceNumPerClient = 20;
|
||||
const uint16_t kServicePort = 12345;
|
||||
const char *kServiceName = "_srpclient._tcp";
|
||||
|
||||
struct ClientInfo
|
||||
{
|
||||
Srp::Client::Service mServices[kInstanceNumPerClient];
|
||||
String<32> mInstanceNames[kInstanceNumPerClient];
|
||||
};
|
||||
|
||||
static ClientInfo sClientInfo[kNumSrpClients + 1];
|
||||
|
||||
/**
|
||||
* This function registers SRP services from a given node.
|
||||
*
|
||||
* @param[in] aNode The node from which to register services.
|
||||
* @param[in] aClientId The client ID to use for host and instance names.
|
||||
*
|
||||
*/
|
||||
void RegisterServices(Node &aNode, uint16_t aClientId)
|
||||
{
|
||||
String<32> hostName;
|
||||
|
||||
hostName.Append("client%u", aClientId);
|
||||
|
||||
aNode.Get<Srp::Client>().EnableAutoStartMode(nullptr, nullptr);
|
||||
SuccessOrQuit(aNode.Get<Srp::Client>().SetHostName(hostName.AsCString()));
|
||||
SuccessOrQuit(aNode.Get<Srp::Client>().EnableAutoHostAddress());
|
||||
|
||||
for (uint16_t j = 1; j <= kInstanceNumPerClient; j++)
|
||||
{
|
||||
String<32> &instanceName = sClientInfo[aClientId].mInstanceNames[j - 1];
|
||||
|
||||
instanceName.Clear().Append("client%u_%u", aClientId, j);
|
||||
|
||||
Srp::Client::Service &service = sClientInfo[aClientId].mServices[j - 1];
|
||||
|
||||
// We use `memset` to zero-initialize the service object. This is
|
||||
// safer than `ClearAllBytes` as it correctly handles the
|
||||
// `LinkedListEntry` base class part.
|
||||
memset(&service, 0, sizeof(service));
|
||||
|
||||
service.mName = kServiceName;
|
||||
service.mInstanceName = instanceName.AsCString();
|
||||
service.mPort = kServicePort;
|
||||
|
||||
SuccessOrQuit(service.Init());
|
||||
|
||||
Error error = aNode.Get<Srp::Client>().AddService(service);
|
||||
if (error != kErrorNone)
|
||||
{
|
||||
Log("AddService failed with error %s (%d) for client %u, instance %u", ErrorToString(error), error,
|
||||
aClientId, j);
|
||||
}
|
||||
SuccessOrQuit(error);
|
||||
|
||||
if (j % 10 == 0 || j == kInstanceNumPerClient)
|
||||
{
|
||||
Core::Get().AdvanceTime(5 * 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function verifies registered services on a given SRP client node.
|
||||
*
|
||||
* @param[in] aNode The node to verify.
|
||||
*
|
||||
*/
|
||||
void VerifyClient(Node &aNode)
|
||||
{
|
||||
const Srp::Client::Service *service = aNode.Get<Srp::Client>().GetServices().GetHead();
|
||||
uint16_t count = 0;
|
||||
|
||||
while (service != nullptr)
|
||||
{
|
||||
VerifyOrQuit(service->GetState() == Srp::Client::kRegistered);
|
||||
count++;
|
||||
service = service->GetNext();
|
||||
}
|
||||
|
||||
VerifyOrQuit(count == kInstanceNumPerClient);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
/**
|
||||
* This test verifies SRP function that SRP clients can register up to 500 services to one SRP server.
|
||||
*
|
||||
* Topology:
|
||||
* LEADER (SRP server)
|
||||
* |
|
||||
* |
|
||||
* ROUTER1 ... ROUTER13 (SRP clients)
|
||||
* | |
|
||||
* FED14 ... FED25 (SRP clients)
|
||||
*
|
||||
*/
|
||||
void TestSrpScale(void)
|
||||
{
|
||||
const uint16_t kNumRouters = (kNumSrpClients / 2) + (kNumSrpClients % 2);
|
||||
const uint16_t kNumFeds = kNumSrpClients - kNumRouters;
|
||||
|
||||
Core nexus;
|
||||
Node &leader = nexus.CreateNode();
|
||||
Node *routers[kNumRouters];
|
||||
Node *feds[kNumFeds];
|
||||
|
||||
Log("Test SRP Scale: 500 services");
|
||||
|
||||
leader.Form();
|
||||
nexus.AdvanceTime(15 * 1000);
|
||||
VerifyOrQuit(leader.Get<Mle::Mle>().IsLeader());
|
||||
|
||||
leader.Get<Srp::Server>().SetEnabled(true);
|
||||
nexus.AdvanceTime(1000);
|
||||
|
||||
for (uint16_t i = 0; i < kNumRouters; i++)
|
||||
{
|
||||
routers[i] = &nexus.CreateNode();
|
||||
routers[i]->SetName("router", i + 1);
|
||||
routers[i]->Get<Mle::Mle>().SetRouterSelectionJitter(1);
|
||||
routers[i]->Join(leader);
|
||||
}
|
||||
|
||||
// Wait for routers to become routers
|
||||
nexus.AdvanceTime(20 * 1000);
|
||||
|
||||
for (uint16_t i = 0; i < kNumRouters; i++)
|
||||
{
|
||||
VerifyOrQuit(routers[i]->Get<Mle::Mle>().IsRouter());
|
||||
}
|
||||
|
||||
for (uint16_t i = 0; i < kNumFeds; i++)
|
||||
{
|
||||
feds[i] = &nexus.CreateNode();
|
||||
feds[i]->SetName("fed", i + kNumRouters + 1);
|
||||
feds[i]->Join(*routers[i], Node::kAsFed);
|
||||
}
|
||||
|
||||
nexus.AdvanceTime(10 * 1000);
|
||||
|
||||
for (uint16_t i = 0; i < kNumFeds; i++)
|
||||
{
|
||||
VerifyOrQuit(feds[i]->Get<Mle::Mle>().IsChild());
|
||||
}
|
||||
|
||||
Log("Registering services from routers...");
|
||||
for (uint16_t i = 0; i < kNumRouters; i++)
|
||||
{
|
||||
RegisterServices(*routers[i], i + 1);
|
||||
}
|
||||
|
||||
Log("Registering services from FEDs...");
|
||||
for (uint16_t i = 0; i < kNumFeds; i++)
|
||||
{
|
||||
RegisterServices(*feds[i], i + kNumRouters + 1);
|
||||
}
|
||||
|
||||
// Give it some more time to settle
|
||||
nexus.AdvanceTime(20 * 1000);
|
||||
|
||||
Log("Verifying registrations...");
|
||||
|
||||
for (uint16_t i = 0; i < kNumRouters; i++)
|
||||
{
|
||||
VerifyClient(*routers[i]);
|
||||
}
|
||||
|
||||
for (uint16_t i = 0; i < kNumFeds; i++)
|
||||
{
|
||||
VerifyClient(*feds[i]);
|
||||
}
|
||||
|
||||
uint32_t totalServices = 0;
|
||||
const Srp::Server::Host *host = nullptr;
|
||||
while ((host = leader.Get<Srp::Server>().GetNextHost(host)) != nullptr)
|
||||
{
|
||||
const Srp::Server::Service *service = nullptr;
|
||||
while ((service = host->GetNextService(service)) != nullptr)
|
||||
{
|
||||
if (!service->IsDeleted())
|
||||
{
|
||||
totalServices++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Log("Total services registered on server: %u", totalServices);
|
||||
VerifyOrQuit(totalServices == kNumSrpClients * kInstanceNumPerClient);
|
||||
|
||||
Log("Test passed!");
|
||||
}
|
||||
|
||||
} // namespace Nexus
|
||||
} // namespace ot
|
||||
|
||||
int main(void)
|
||||
{
|
||||
ot::Nexus::TestSrpScale();
|
||||
printf("All tests passed\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright (c) 2021, The OpenThread Authors.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# 3. Neither the name of the copyright holder nor the
|
||||
# names of its contributors may be used to endorse or promote products
|
||||
# derived from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
|
||||
import unittest
|
||||
|
||||
from test_srp_register_500_services import CLIENT_IDS, INSTANCE_IDS, SrpRegister500Services, SERVER, SERVICE_NAME
|
||||
|
||||
# Test description:
|
||||
# This test verifies SRP function that SRP clients can register up to 500 services to one SRP server.
|
||||
#
|
||||
# This test is same as test_srp_register_500_services.py, with the only difference that the SRP server
|
||||
# is running on an OTBR (Docker).
|
||||
#
|
||||
|
||||
HOST = SERVER + 1
|
||||
|
||||
|
||||
class SrpRegister500ServicesBR(SrpRegister500Services):
|
||||
TOPOLOGY = SrpRegister500Services.TOPOLOGY
|
||||
TOPOLOGY[SERVER]['is_otbr'] = True
|
||||
TOPOLOGY[HOST] = {
|
||||
'name': 'Host',
|
||||
'is_host': True,
|
||||
}
|
||||
|
||||
def test(self):
|
||||
self.nodes[HOST].start(start_radvd=False)
|
||||
|
||||
self._test_impl()
|
||||
|
||||
# Verify all SRP services are resolvable via mDNS
|
||||
host = self.nodes[HOST]
|
||||
|
||||
browse_retry = 3
|
||||
for i in range(browse_retry):
|
||||
try:
|
||||
service_instances = set(host.browse_mdns_services(SERVICE_NAME, timeout=10))
|
||||
print(service_instances)
|
||||
|
||||
for clientid in CLIENT_IDS:
|
||||
for instanceid in INSTANCE_IDS:
|
||||
self.assertIn(f'client{clientid}_{instanceid}', service_instances)
|
||||
|
||||
break
|
||||
|
||||
except Exception:
|
||||
if i < browse_retry - 1:
|
||||
self.simulator.go(3)
|
||||
continue
|
||||
|
||||
|
||||
del SrpRegister500Services
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -1,191 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright (c) 2021, The OpenThread Authors.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# 3. Neither the name of the copyright holder nor the
|
||||
# names of its contributors may be used to endorse or promote products
|
||||
# derived from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
|
||||
import unittest
|
||||
|
||||
import config
|
||||
import thread_cert
|
||||
|
||||
# Test description:
|
||||
# This test verifies SRP function that SRP clients can register up to 500 services to one SRP server.
|
||||
#
|
||||
# Topology:
|
||||
# LEADER (SRP server)
|
||||
# |
|
||||
# |
|
||||
# ROUTER1 ... ROUTER12 ROUTER13 (SRP clients)
|
||||
# | |
|
||||
# FED14 ... FED25 (SRP clients)
|
||||
#
|
||||
|
||||
NUM_SRP_CLIENTS = 25
|
||||
INSTANCE_NUM_PER_CLIENT = 20
|
||||
NUM_ROUTERS = (NUM_SRP_CLIENTS // 2) + (NUM_SRP_CLIENTS % 2)
|
||||
NUM_FEDS = NUM_SRP_CLIENTS - NUM_ROUTERS
|
||||
assert (NUM_FEDS <= NUM_ROUTERS)
|
||||
|
||||
SERVER = NUM_SRP_CLIENTS + 1
|
||||
CLIENT1 = 1
|
||||
|
||||
ROUTER_IDS = tuple(range(1, NUM_ROUTERS + 1))
|
||||
FED_IDS = tuple(range(NUM_ROUTERS + 1, NUM_SRP_CLIENTS + 1))
|
||||
assert len(FED_IDS) == NUM_FEDS
|
||||
CLIENT_IDS = tuple(range(1, NUM_SRP_CLIENTS + 1))
|
||||
INSTANCE_IDS = tuple(range(1, INSTANCE_NUM_PER_CLIENT + 1))
|
||||
SERVICE_NAME = '_srpclient._tcp'
|
||||
SERVICE_PORT = 12345
|
||||
|
||||
|
||||
class SrpRegister500Services(thread_cert.TestCase):
|
||||
USE_MESSAGE_FACTORY = False
|
||||
SUPPORT_NCP = False
|
||||
|
||||
TOPOLOGY = {
|
||||
SERVER: {
|
||||
'name': 'SRP_SERVER',
|
||||
'mode': 'rdn',
|
||||
'allowlist': [],
|
||||
},
|
||||
}
|
||||
|
||||
for nodeid in ROUTER_IDS:
|
||||
TOPOLOGY[nodeid] = {
|
||||
'name': f'SRP_CLIENT_{nodeid}',
|
||||
'mode': 'rdn',
|
||||
'allowlist': [SERVER],
|
||||
}
|
||||
TOPOLOGY[SERVER]['allowlist'].append(nodeid)
|
||||
|
||||
for nodeid in FED_IDS:
|
||||
parentid = nodeid - NUM_ROUTERS
|
||||
TOPOLOGY[nodeid] = {
|
||||
'name': f'SRP_CLIENT_{nodeid}',
|
||||
'mode': 'rdn',
|
||||
'router_eligible': False,
|
||||
'allowlist': [parentid],
|
||||
}
|
||||
TOPOLOGY[parentid]['allowlist'].append(nodeid)
|
||||
|
||||
def test(self):
|
||||
self._test_impl()
|
||||
|
||||
def _test_impl(self):
|
||||
server = self.nodes[SERVER]
|
||||
|
||||
def routers():
|
||||
for nodeid in ROUTER_IDS:
|
||||
yield self.nodes[nodeid]
|
||||
|
||||
def feds():
|
||||
for nodeid in FED_IDS:
|
||||
yield self.nodes[nodeid]
|
||||
|
||||
def clients():
|
||||
for nodeid in CLIENT_IDS:
|
||||
yield self.nodes[nodeid]
|
||||
|
||||
# Start the server & clients.
|
||||
server.srp_server_set_enabled(True)
|
||||
server.start()
|
||||
self.simulator.go(config.LEADER_STARTUP_DELAY)
|
||||
self.assertEqual(server.get_state(), 'leader')
|
||||
|
||||
for router in routers():
|
||||
router.srp_server_set_enabled(False)
|
||||
router.start()
|
||||
self.simulator.go(config.ROUTER_STARTUP_DELAY)
|
||||
|
||||
for router in routers():
|
||||
self.assertEqual(router.get_state(), 'router')
|
||||
|
||||
for fed in feds():
|
||||
fed.srp_server_set_enabled(False)
|
||||
fed.start()
|
||||
self.simulator.go(3)
|
||||
|
||||
for fed in feds():
|
||||
self.assertEqual(fed.get_state(), 'child')
|
||||
|
||||
for clientid in CLIENT_IDS:
|
||||
client = self.nodes[clientid]
|
||||
self.assertEqual(client.srp_client_get_auto_start_mode(), 'Enabled')
|
||||
client.srp_client_set_host_name(f'client{clientid}')
|
||||
client.srp_client_set_host_address(f'2001::{clientid}')
|
||||
|
||||
for instanceid in INSTANCE_IDS:
|
||||
client.srp_client_add_service(f'client{clientid}_{instanceid}', SERVICE_NAME, SERVICE_PORT)
|
||||
|
||||
if instanceid % 10 == 0 or instanceid == INSTANCE_IDS[-1]:
|
||||
self._wait_client_all_services_registered(client)
|
||||
|
||||
self._check_client_host_and_services(client, clientid)
|
||||
|
||||
# Make sure all service are registered successfully
|
||||
self._check_server_hosts_and_services(server)
|
||||
|
||||
def _wait_client_all_services_registered(self, client, timeout=60):
|
||||
all_registered = False
|
||||
while timeout > 0:
|
||||
self.simulator.go(3)
|
||||
timeout -= 3
|
||||
|
||||
client_services = client.srp_client_get_services()
|
||||
all_registered = all(service['state'] == 'Registered' for service in client_services)
|
||||
if all_registered:
|
||||
break
|
||||
|
||||
self.assertTrue(all_registered, "Some services are not registered successfully")
|
||||
|
||||
def _check_client_host_and_services(self, client, clientid):
|
||||
client_services = client.srp_client_get_services()
|
||||
self.assertEqual(len(client_services), INSTANCE_NUM_PER_CLIENT)
|
||||
service_instance_names = {f'client{clientid}_{instanceid}' for instanceid in INSTANCE_IDS}
|
||||
for service in client_services:
|
||||
self.assertEqual(service['name'], SERVICE_NAME)
|
||||
self.assertEqual(service['state'], 'Registered')
|
||||
self.assertEqual(int(service['port']), SERVICE_PORT)
|
||||
self.assertIn(service['instance'], service_instance_names)
|
||||
service_instance_names.discard(service['instance'])
|
||||
|
||||
def _check_server_hosts_and_services(self, server):
|
||||
server_services = server.srp_server_get_services()
|
||||
self.assertEqual(len(server_services), NUM_SRP_CLIENTS * INSTANCE_NUM_PER_CLIENT)
|
||||
|
||||
service_instance_names = {
|
||||
f'client{clientid}_{instanceid}' for clientid in CLIENT_IDS for instanceid in INSTANCE_IDS
|
||||
}
|
||||
|
||||
for service in server_services:
|
||||
self.assertEqual(service['name'], SERVICE_NAME)
|
||||
self.assertIn(service['instance'], service_instance_names)
|
||||
service_instance_names.discard(service['instance'])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user