From 0cf450af44dbd86a47281f0fd89b2e92279ca985 Mon Sep 17 00:00:00 2001 From: Jonathan Hui Date: Tue, 21 Apr 2026 07:31:49 -0700 Subject: [PATCH] [nexus] migrate SRP diff lease test to Nexus (#12950) This commit migrates the SRP register services with different lease test from the thread-cert Python framework to the Nexus test framework. The new Nexus test (test_srp_register_services_diff_lease.cpp) reproduces the functionality of the original Python test: - Registration of multiple services with different lease/key-lease intervals. - Verification of per-service lease values on the SRP server. - Ensuring key-lease is always at least as long as the lease. - Validating lease renewal and expiry behaviors. - Testing dynamic changes to default client lease and TTL. Migrating to Nexus allows for faster and more scalable network simulations within a single process. --- tests/nexus/CMakeLists.txt | 1 + .../test_srp_register_services_diff_lease.cpp | 473 +++++++++++++++++ .../test_srp_register_services_diff_lease.py | 481 ------------------ 3 files changed, 474 insertions(+), 481 deletions(-) create mode 100644 tests/nexus/test_srp_register_services_diff_lease.cpp delete mode 100755 tests/scripts/thread-cert/test_srp_register_services_diff_lease.py diff --git a/tests/nexus/CMakeLists.txt b/tests/nexus/CMakeLists.txt index 6a710dddd..e6a79b845 100644 --- a/tests/nexus/CMakeLists.txt +++ b/tests/nexus/CMakeLists.txt @@ -411,6 +411,7 @@ ot_nexus_test(srp_client_remove_host "core;nexus") ot_nexus_test(srp_client_save_server_info "core;nexus") ot_nexus_test(srp_lease "core;nexus") ot_nexus_test(srp_many_services_mtu_check "core;nexus") +ot_nexus_test(srp_register_services_diff_lease "core;nexus") ot_nexus_test(srp_scale "core;nexus") ot_nexus_test(zero_len_external_route "core;nexus") diff --git a/tests/nexus/test_srp_register_services_diff_lease.cpp b/tests/nexus/test_srp_register_services_diff_lease.cpp new file mode 100644 index 000000000..f2b34b959 --- /dev/null +++ b/tests/nexus/test_srp_register_services_diff_lease.cpp @@ -0,0 +1,473 @@ +/* + * 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 +#include + +#include "common/string.hpp" +#include "platform/nexus_core.hpp" +#include "platform/nexus_node.hpp" + +#include + +namespace ot { +namespace Nexus { + +void TestSrpRegisterServicesDiffLease(void) +{ + Core nexus; + Node &server = nexus.CreateNode(); + Node &client = nexus.CreateNode(); + + server.SetName("SRP_SERVER"); + client.SetName("SRP_CLIENT"); + + SuccessOrQuit(Instance::SetGlobalLogLevel(kLogLevelNote)); + + server.Form(); + nexus.AdvanceTime(10000); + VerifyOrQuit(server.Get().IsLeader()); + + client.Join(server, Node::kAsFtd); + nexus.AdvanceTime(200000); + VerifyOrQuit(client.Get().IsRouter()); + + server.Get().SetEnabled(true); + client.Get().EnableAutoStartMode(nullptr, nullptr); + + nexus.AdvanceTime(15000); + + SuccessOrQuit(client.Get().SetHostName("host")); + SuccessOrQuit(client.Get().EnableAutoHostAddress()); + + // Add a service with specific lease and key lease + Srp::Client::Service ins1; + ClearAllBytes(ins1); + ins1.mName = "_test._udp"; + ins1.mInstanceName = "ins1"; + ins1.mPort = 1111; + ins1.mLease = 60; + ins1.mKeyLease = 800; + SuccessOrQuit(client.Get().AddService(ins1)); + + nexus.AdvanceTime(5000); + + // Check service on server + { + const Srp::Server::Host *host = server.Get().GetNextHost(nullptr); + const Srp::Server::Service *service = host->GetNextService(nullptr); + + VerifyOrQuit(StringMatch(service->GetInstanceName(), "ins1._test._udp.default.service.arpa.", + kStringCaseInsensitiveMatch)); + VerifyOrQuit(!service->IsDeleted()); + VerifyOrQuit(service->GetTtl() == 60); + + Srp::Server::LeaseInfo leaseInfo; + + service->GetLeaseInfo(leaseInfo); + VerifyOrQuit(leaseInfo.mLease == 60000); + VerifyOrQuit(leaseInfo.mKeyLease == 800000); + } + + // Register two more services with different lease intervals. + Srp::Client::Service ins2, ins3; + ClearAllBytes(ins2); + ins2.mName = "_test._udp"; + ins2.mInstanceName = "ins2"; + ins2.mPort = 2222; + ins2.mLease = 30; + ins2.mKeyLease = 200; + SuccessOrQuit(client.Get().AddService(ins2)); + + ClearAllBytes(ins3); + ins3.mName = "_test._udp"; + ins3.mInstanceName = "ins3"; + ins3.mPort = 3333; + ins3.mLease = 100; + ins3.mKeyLease = 1000; + SuccessOrQuit(client.Get().AddService(ins3)); + + nexus.AdvanceTime(10000); + + // Verify all 3 services on server + { + const Srp::Server::Host *host = server.Get().GetNextHost(nullptr); + const Srp::Server::Service *service = nullptr; + uint16_t count = 0; + + while ((service = host->GetNextService(service)) != nullptr) + { + count++; + Srp::Server::LeaseInfo leaseInfo; + service->GetLeaseInfo(leaseInfo); + if (StringMatch(service->GetInstanceName(), "ins1._test._udp.default.service.arpa.", + kStringCaseInsensitiveMatch)) + { + VerifyOrQuit(service->GetTtl() == 60); + VerifyOrQuit(leaseInfo.mLease == 60000); + VerifyOrQuit(leaseInfo.mKeyLease == 800000); + } + else if (StringMatch(service->GetInstanceName(), "ins2._test._udp.default.service.arpa.", + kStringCaseInsensitiveMatch)) + { + VerifyOrQuit(service->GetTtl() == 30); + VerifyOrQuit(leaseInfo.mLease == 30000); + VerifyOrQuit(leaseInfo.mKeyLease == 200000); + } + else if (StringMatch(service->GetInstanceName(), "ins3._test._udp.default.service.arpa.", + kStringCaseInsensitiveMatch)) + { + VerifyOrQuit(service->GetTtl() == 100); + VerifyOrQuit(leaseInfo.mLease == 100000); + VerifyOrQuit(leaseInfo.mKeyLease == 1000000); + } + else + { + VerifyOrQuit(false); + } + } + VerifyOrQuit(count == 3); + } + + // Wait for longest lease time to validate that all services renew their lease successfully. + nexus.AdvanceTime(105000); + { + const Srp::Server::Host *host = server.Get().GetNextHost(nullptr); + const Srp::Server::Service *service = nullptr; + uint16_t count = 0; + while ((service = host->GetNextService(service)) != nullptr) + { + count++; + VerifyOrQuit(!service->IsDeleted()); + } + VerifyOrQuit(count == 3); + } + + // Remove two services + SuccessOrQuit(client.Get().RemoveService(ins2)); + SuccessOrQuit(client.Get().RemoveService(ins3)); + + nexus.AdvanceTime(10000); + { + const Srp::Server::Host *host = server.Get().GetNextHost(nullptr); + const Srp::Server::Service *service = nullptr; + uint16_t count = 0; + while ((service = host->GetNextService(service)) != nullptr) + { + count++; + if (StringMatch(service->GetInstanceName(), "ins1._test._udp.default.service.arpa.", + kStringCaseInsensitiveMatch)) + { + VerifyOrQuit(!service->IsDeleted()); + } + else + { + VerifyOrQuit(service->IsDeleted()); + } + } + VerifyOrQuit(count == 3); + } + + // Wait for longer than key-lease of `ins2` service and check that it is removed on server. + nexus.AdvanceTime(201000); + { + const Srp::Server::Host *host = server.Get().GetNextHost(nullptr); + const Srp::Server::Service *service = nullptr; + uint16_t count = 0; + while ((service = host->GetNextService(service)) != nullptr) + { + count++; + if (StringMatch(service->GetInstanceName(), "ins1._test._udp.default.service.arpa.", + kStringCaseInsensitiveMatch)) + { + VerifyOrQuit(!service->IsDeleted()); + } + else if (StringMatch(service->GetInstanceName(), "ins3._test._udp.default.service.arpa.", + kStringCaseInsensitiveMatch)) + { + VerifyOrQuit(service->IsDeleted()); + } + else + { + VerifyOrQuit(false); + } + } + VerifyOrQuit(count == 2); + } + + // Add both services again now with same lease intervals. + ins2.mLease = 30; + ins2.mKeyLease = 100; + SuccessOrQuit(client.Get().AddService(ins2)); + ins3.mLease = 30; + ins3.mKeyLease = 100; + SuccessOrQuit(client.Get().AddService(ins3)); + + nexus.AdvanceTime(10000); + { + const Srp::Server::Host *host = server.Get().GetNextHost(nullptr); + const Srp::Server::Service *service = nullptr; + uint16_t count = 0; + while ((service = host->GetNextService(service)) != nullptr) + { + count++; + VerifyOrQuit(!service->IsDeleted()); + } + VerifyOrQuit(count == 3); + } + + // Remove `ins1` while adding a new service with same key-lease as `ins1` but different lease interval. + SuccessOrQuit(client.Get().RemoveService(ins1)); + Srp::Client::Service ins4; + ClearAllBytes(ins4); + ins4.mName = "_test._udp"; + ins4.mInstanceName = "ins4"; + ins4.mPort = 4444; + ins4.mLease = 90; + ins4.mKeyLease = 800; + SuccessOrQuit(client.Get().AddService(ins4)); + + nexus.AdvanceTime(5000); + { + const Srp::Server::Host *host = server.Get().GetNextHost(nullptr); + const Srp::Server::Service *service = nullptr; + uint16_t count = 0; + while ((service = host->GetNextService(service)) != nullptr) + { + count++; + if (StringMatch(service->GetInstanceName(), "ins4._test._udp.default.service.arpa.", + kStringCaseInsensitiveMatch)) + { + VerifyOrQuit(!service->IsDeleted()); + VerifyOrQuit(service->GetTtl() == 90); + } + else if (StringMatch(service->GetInstanceName(), "ins1._test._udp.default.service.arpa.", + kStringCaseInsensitiveMatch)) + { + VerifyOrQuit(service->IsDeleted()); + } + else + { + VerifyOrQuit(!service->IsDeleted()); + } + } + VerifyOrQuit(count == 4); + } + + // Remove `ins2` and `ins3`. + SuccessOrQuit(client.Get().RemoveService(ins2)); + SuccessOrQuit(client.Get().RemoveService(ins3)); + + nexus.AdvanceTime(10000); + { + const Srp::Server::Host *host = server.Get().GetNextHost(nullptr); + const Srp::Server::Service *service = nullptr; + uint16_t count = 0; + while ((service = host->GetNextService(service)) != nullptr) + { + count++; + if (StringMatch(service->GetInstanceName(), "ins4._test._udp.default.service.arpa.", + kStringCaseInsensitiveMatch)) + { + VerifyOrQuit(!service->IsDeleted()); + } + else + { + VerifyOrQuit(service->IsDeleted()); + } + } + VerifyOrQuit(count == 4); + } + + // Add `ins1` with key-lease smaller than lease and check that client handles this properly + ins1.mLease = 100; + ins1.mKeyLease = 90; + SuccessOrQuit(client.Get().AddService(ins1)); + + nexus.AdvanceTime(10000); + { + const Srp::Server::Host *host = server.Get().GetNextHost(nullptr); + const Srp::Server::Service *service = nullptr; + uint16_t count = 0; + + while ((service = host->GetNextService(service)) != nullptr) + { + count++; + if (StringMatch(service->GetInstanceName(), "ins1._test._udp.default.service.arpa.", + kStringCaseInsensitiveMatch)) + { + VerifyOrQuit(!service->IsDeleted()); + Srp::Server::LeaseInfo leaseInfo; + service->GetLeaseInfo(leaseInfo); + VerifyOrQuit(leaseInfo.mLease == 100000); + VerifyOrQuit(leaseInfo.mKeyLease == 100000); + } + } + VerifyOrQuit(count == 4); + } + + // Change default lease and key-lease intervals on client. + client.Get().SetLeaseInterval(40); + client.Get().SetKeyLeaseInterval(330); + + // Add `ins2` and `ins3`. `ins2` specifies the key-lease explicitly but leaves lease as default. `ins3` does the + // opposite. + ClearAllBytes(ins2); + ins2.mName = "_test._udp"; + ins2.mInstanceName = "ins2"; + ins2.mPort = 2222; + ins2.mKeyLease = 330; + SuccessOrQuit(client.Get().AddService(ins2)); + + ClearAllBytes(ins3); + ins3.mName = "_test._udp"; + ins3.mInstanceName = "ins3"; + ins3.mPort = 3333; + ins3.mLease = 40; + SuccessOrQuit(client.Get().AddService(ins3)); + + nexus.AdvanceTime(10000); + { + const Srp::Server::Host *host = server.Get().GetNextHost(nullptr); + const Srp::Server::Service *service = nullptr; + uint16_t count = 0; + + while ((service = host->GetNextService(service)) != nullptr) + { + count++; + Srp::Server::LeaseInfo leaseInfo; + service->GetLeaseInfo(leaseInfo); + if (StringMatch(service->GetInstanceName(), "ins2._test._udp.default.service.arpa.", + kStringCaseInsensitiveMatch) || + StringMatch(service->GetInstanceName(), "ins3._test._udp.default.service.arpa.", + kStringCaseInsensitiveMatch)) + { + VerifyOrQuit(leaseInfo.mLease == 40000); + VerifyOrQuit(leaseInfo.mKeyLease == 330000); + } + } + VerifyOrQuit(count == 4); + } + + // Change the default lease to 50 and wait for long enough for `ins2` and `ins3` to do lease refresh. Validate that + // `ins2` now requests new default lease of 50 while `ins3` should stay as before. + client.Get().SetLeaseInterval(50); + nexus.AdvanceTime(45000); + { + const Srp::Server::Host *host = server.Get().GetNextHost(nullptr); + const Srp::Server::Service *service = nullptr; + uint16_t count = 0; + + while ((service = host->GetNextService(service)) != nullptr) + { + count++; + Srp::Server::LeaseInfo leaseInfo; + service->GetLeaseInfo(leaseInfo); + if (StringMatch(service->GetInstanceName(), "ins2._test._udp.default.service.arpa.", + kStringCaseInsensitiveMatch)) + { + VerifyOrQuit(leaseInfo.mLease == 50000); + } + else if (StringMatch(service->GetInstanceName(), "ins3._test._udp.default.service.arpa.", + kStringCaseInsensitiveMatch)) + { + VerifyOrQuit(leaseInfo.mLease == 40000); + } + } + VerifyOrQuit(count == 4); + } + + // Change the default key lease to 35. `ins3` should adopt this but since it is shorter than its explicitly + // specified lease the client should use same value for both lease and key-lease. + client.Get().SetKeyLeaseInterval(35); + nexus.AdvanceTime(45000); + { + const Srp::Server::Host *host = server.Get().GetNextHost(nullptr); + const Srp::Server::Service *service = nullptr; + uint16_t count = 0; + + while ((service = host->GetNextService(service)) != nullptr) + { + count++; + Srp::Server::LeaseInfo leaseInfo; + service->GetLeaseInfo(leaseInfo); + if (StringMatch(service->GetInstanceName(), "ins3._test._udp.default.service.arpa.", + kStringCaseInsensitiveMatch)) + { + VerifyOrQuit(leaseInfo.mLease == 40000); + VerifyOrQuit(leaseInfo.mKeyLease == 40000); + } + } + VerifyOrQuit(count == 4); + } + + // Change the requested TTL. + client.Get().SetTtl(65); + nexus.AdvanceTime(110000); + { + const Srp::Server::Host *host = server.Get().GetNextHost(nullptr); + const Srp::Server::Service *service = nullptr; + uint16_t count = 0; + + while ((service = host->GetNextService(service)) != nullptr) + { + count++; + if (StringMatch(service->GetInstanceName(), "ins1._test._udp.default.service.arpa.", + kStringCaseInsensitiveMatch)) + { + VerifyOrQuit(service->GetTtl() == 65); + } + else if (StringMatch(service->GetInstanceName(), "ins2._test._udp.default.service.arpa.", + kStringCaseInsensitiveMatch)) + { + VerifyOrQuit(service->GetTtl() == 50); + } + else if (StringMatch(service->GetInstanceName(), "ins3._test._udp.default.service.arpa.", + kStringCaseInsensitiveMatch)) + { + VerifyOrQuit(service->GetTtl() == 40); + } + else if (StringMatch(service->GetInstanceName(), "ins4._test._udp.default.service.arpa.", + kStringCaseInsensitiveMatch)) + { + VerifyOrQuit(service->GetTtl() == 65); + } + } + VerifyOrQuit(count == 4); + } +} + +} // namespace Nexus +} // namespace ot + +int main(void) +{ + ot::Nexus::TestSrpRegisterServicesDiffLease(); + printf("All tests passed\n"); + return 0; +} diff --git a/tests/scripts/thread-cert/test_srp_register_services_diff_lease.py b/tests/scripts/thread-cert/test_srp_register_services_diff_lease.py deleted file mode 100755 index 3399dd310..000000000 --- a/tests/scripts/thread-cert/test_srp_register_services_diff_lease.py +++ /dev/null @@ -1,481 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2022, 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 ipaddress -import unittest - -import command -import config -import thread_cert - -# Test description: -# -# This test verifies the SRP client and server behavior when services -# with different lease (and/or key lease) intervals are registered. -# -# Topology: -# -# LEADER (SRP server) -# | -# | -# ROUTER (SRP client) -# - -SERVER = 1 -CLIENT = 2 - - -class SrpRegisterServicesDiffLease(thread_cert.TestCase): - USE_MESSAGE_FACTORY = False - SUPPORT_NCP = False - - TOPOLOGY = { - SERVER: { - 'name': 'SRP_SERVER', - 'mode': 'rdn', - }, - CLIENT: { - 'name': 'SRP_CLIENT', - 'mode': 'rdn', - }, - } - - def test(self): - server = self.nodes[SERVER] - client = self.nodes[CLIENT] - - #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Start the server and client. - - server.start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(server.get_state(), 'leader') - - client.start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(client.get_state(), 'router') - - server.srp_server_set_enabled(True) - client.srp_client_enable_auto_start_mode() - - self.simulator.go(15) - - client.srp_client_set_host_name('host') - client.srp_client_enable_auto_host_address() - - #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Add a service with specific lease and key lease and verify that - # it is successfully registered and seen with same lease/key-lease - # on server. - - client.srp_client_add_service('ins1', '_test._udp', 1111, lease=60, key_lease=800) - - self.simulator.go(5) - - self.check_services_on_client(client, 1) - services = server.srp_server_get_services() - self.assertEqual(len(services), 1) - service = services[0] - self.assertEqual(service['fullname'], 'ins1._test._udp.default.service.arpa.') - self.assertEqual(service['deleted'], 'false') - self.assertEqual(int(service['ttl']), 60) - self.assertEqual(int(service['lease']), 60) - self.assertEqual(int(service['key-lease']), 800) - - #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Register two more services with different lease intervals. - - client.srp_client_add_service('ins2', '_test._udp', 2222, lease=30, key_lease=200) - client.srp_client_add_service('ins3', '_test._udp', 3333, lease=100, key_lease=1000) - - self.simulator.go(10) - - self.check_services_on_client(client, 3) - server_services = server.srp_server_get_services() - self.assertEqual(len(server_services), 3) - for service in server_services: - if service['fullname'] == 'ins1._test._udp.default.service.arpa.': - self.assertEqual(service['deleted'], 'false') - self.assertEqual(int(service['ttl']), 60) - self.assertEqual(int(service['lease']), 60) - self.assertEqual(int(service['key-lease']), 800) - elif service['fullname'] == 'ins2._test._udp.default.service.arpa.': - self.assertEqual(service['deleted'], 'false') - self.assertEqual(int(service['ttl']), 30) - self.assertEqual(int(service['lease']), 30) - self.assertEqual(int(service['key-lease']), 200) - elif service['fullname'] == 'ins3._test._udp.default.service.arpa.': - self.assertEqual(service['deleted'], 'false') - self.assertEqual(int(service['ttl']), 100) - self.assertEqual(int(service['lease']), 100) - self.assertEqual(int(service['key-lease']), 1000) - else: - self.assertTrue(False) - - #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Wait for longest lease time to validate that all services renew their - # lease successfully. - - self.simulator.go(105) - - self.check_services_on_client(client, 3) - server_services = server.srp_server_get_services() - self.assertEqual(len(server_services), 3) - for service in server_services: - self.assertEqual(service['deleted'], 'false') - - #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Remove two services. - - client.srp_client_remove_service('ins2', '_test._udp') - client.srp_client_remove_service('ins3', '_test._udp') - - self.simulator.go(10) - - self.check_services_on_client(client, 1) - server_services = server.srp_server_get_services() - self.assertEqual(len(server_services), 3) - for service in server_services: - if service['fullname'] == 'ins1._test._udp.default.service.arpa.': - self.assertEqual(service['deleted'], 'false') - self.assertEqual(int(service['ttl']), 60) - self.assertEqual(int(service['lease']), 60) - self.assertEqual(int(service['key-lease']), 800) - elif service['fullname'] == 'ins2._test._udp.default.service.arpa.': - self.assertEqual(service['deleted'], 'true') - elif service['fullname'] == 'ins3._test._udp.default.service.arpa.': - self.assertEqual(service['deleted'], 'true') - else: - self.assertTrue(False) - - #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Wait for longer than key-lease of `ins2` service and check that it is - # removed on server. - - self.simulator.go(201) - - self.check_services_on_client(client, 1) - server_services = server.srp_server_get_services() - self.assertEqual(len(server_services), 2) - for service in server_services: - if service['fullname'] == 'ins1._test._udp.default.service.arpa.': - self.assertEqual(service['deleted'], 'false') - self.assertEqual(int(service['ttl']), 60) - self.assertEqual(int(service['lease']), 60) - self.assertEqual(int(service['key-lease']), 800) - elif service['fullname'] == 'ins3._test._udp.default.service.arpa.': - self.assertEqual(service['deleted'], 'true') - else: - self.assertTrue(False) - - #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Add both services again now with same lease intervals. - - client.srp_client_add_service('ins2', '_test._udp', 2222, lease=30, key_lease=100) - client.srp_client_add_service('ins3', '_test._udp', 3333, lease=30, key_lease=100) - - self.simulator.go(10) - - self.check_services_on_client(client, 3) - server_services = server.srp_server_get_services() - self.assertEqual(len(server_services), 3) - for service in server_services: - if service['fullname'] == 'ins1._test._udp.default.service.arpa.': - self.assertEqual(service['deleted'], 'false') - self.assertEqual(int(service['ttl']), 60) - self.assertEqual(int(service['lease']), 60) - self.assertEqual(int(service['key-lease']), 800) - elif service['fullname'] == 'ins2._test._udp.default.service.arpa.': - self.assertEqual(service['deleted'], 'false') - self.assertEqual(int(service['ttl']), 30) - self.assertEqual(int(service['lease']), 30) - self.assertEqual(int(service['key-lease']), 100) - elif service['fullname'] == 'ins3._test._udp.default.service.arpa.': - self.assertEqual(service['deleted'], 'false') - self.assertEqual(int(service['ttl']), 30) - self.assertEqual(int(service['lease']), 30) - self.assertEqual(int(service['key-lease']), 100) - else: - self.assertTrue(False) - - #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Remove `ins1` while adding a new service with same key-lease as - # `ins1` but different lease interval. - - client.srp_client_remove_service('ins1', '_test._udp') - client.srp_client_add_service('ins4', '_test._udp', 4444, lease=90, key_lease=800) - - self.simulator.go(5) - - self.check_services_on_client(client, 3) - server_services = server.srp_server_get_services() - self.assertEqual(len(server_services), 4) - for service in server_services: - if service['fullname'] == 'ins1._test._udp.default.service.arpa.': - self.assertEqual(service['deleted'], 'true') - elif service['fullname'] == 'ins2._test._udp.default.service.arpa.': - self.assertEqual(service['deleted'], 'false') - self.assertEqual(int(service['ttl']), 30) - self.assertEqual(int(service['lease']), 30) - self.assertEqual(int(service['key-lease']), 100) - elif service['fullname'] == 'ins3._test._udp.default.service.arpa.': - self.assertEqual(service['deleted'], 'false') - self.assertEqual(int(service['ttl']), 30) - self.assertEqual(int(service['lease']), 30) - self.assertEqual(int(service['key-lease']), 100) - elif service['fullname'] == 'ins4._test._udp.default.service.arpa.': - self.assertEqual(service['deleted'], 'false') - self.assertEqual(int(service['ttl']), 90) - self.assertEqual(int(service['lease']), 90) - self.assertEqual(int(service['key-lease']), 800) - else: - self.assertTrue(False) - - #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Remove two services `ins2` and `ins3` (they now have same key lease). - - client.srp_client_remove_service('ins2', '_test._udp') - client.srp_client_remove_service('ins3', '_test._udp') - - self.simulator.go(10) - - self.check_services_on_client(client, 1) - server_services = server.srp_server_get_services() - self.assertEqual(len(server_services), 4) - for service in server_services: - if service['fullname'] == 'ins1._test._udp.default.service.arpa.': - self.assertEqual(service['deleted'], 'true') - elif service['fullname'] == 'ins2._test._udp.default.service.arpa.': - self.assertEqual(service['deleted'], 'true') - elif service['fullname'] == 'ins3._test._udp.default.service.arpa.': - self.assertEqual(service['deleted'], 'true') - elif service['fullname'] == 'ins4._test._udp.default.service.arpa.': - self.assertEqual(service['deleted'], 'false') - self.assertEqual(int(service['ttl']), 90) - self.assertEqual(int(service['lease']), 90) - self.assertEqual(int(service['key-lease']), 800) - else: - self.assertTrue(False) - - #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Add `ins1` with key-lease smaller than lease and check that - # client handles this properly (uses the lease value for - # key-lease). - - client.srp_client_add_service('ins1', '_test._udp', 1111, lease=100, key_lease=90) - - self.simulator.go(10) - - self.check_services_on_client(client, 2) - server_services = server.srp_server_get_services() - self.assertEqual(len(server_services), 4) - for service in server_services: - if service['fullname'] == 'ins1._test._udp.default.service.arpa.': - self.assertEqual(service['deleted'], 'false') - self.assertEqual(int(service['ttl']), 100) - self.assertEqual(int(service['lease']), 100) - self.assertEqual(int(service['key-lease']), 100) - elif service['fullname'] == 'ins2._test._udp.default.service.arpa.': - self.assertEqual(service['deleted'], 'true') - elif service['fullname'] == 'ins3._test._udp.default.service.arpa.': - self.assertEqual(service['deleted'], 'true') - elif service['fullname'] == 'ins4._test._udp.default.service.arpa.': - self.assertEqual(service['deleted'], 'false') - self.assertEqual(int(service['ttl']), 90) - self.assertEqual(int(service['lease']), 90) - self.assertEqual(int(service['key-lease']), 800) - else: - self.assertTrue(False) - - #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Change default lease and key-lease intervals on client. - - client.srp_client_set_lease_interval(40) - self.assertEqual(client.srp_client_get_lease_interval(), 40) - - client.srp_client_set_key_lease_interval(330) - self.assertEqual(client.srp_client_get_key_lease_interval(), 330) - - #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Add `ins2` and `ins3`. `ins2` specifies the key-lease explicitly but - # leaves lease as default. `ins3` does the opposite. - - client.srp_client_add_service('ins2', '_test._udp', 2222, key_lease=330) - client.srp_client_add_service('ins3', '_test._udp', 3333, lease=40) - - self.simulator.go(10) - - self.check_services_on_client(client, 4) - server_services = server.srp_server_get_services() - self.assertEqual(len(server_services), 4) - for service in server_services: - if service['fullname'] == 'ins1._test._udp.default.service.arpa.': - self.assertEqual(service['deleted'], 'false') - self.assertEqual(int(service['ttl']), 100) - self.assertEqual(int(service['lease']), 100) - self.assertEqual(int(service['key-lease']), 100) - elif service['fullname'] == 'ins2._test._udp.default.service.arpa.': - self.assertEqual(service['deleted'], 'false') - self.assertEqual(int(service['ttl']), 40) - self.assertEqual(int(service['lease']), 40) - self.assertEqual(int(service['key-lease']), 330) - elif service['fullname'] == 'ins3._test._udp.default.service.arpa.': - self.assertEqual(service['deleted'], 'false') - self.assertEqual(int(service['ttl']), 40) - self.assertEqual(int(service['lease']), 40) - self.assertEqual(int(service['key-lease']), 330) - elif service['fullname'] == 'ins4._test._udp.default.service.arpa.': - self.assertEqual(service['deleted'], 'false') - self.assertEqual(int(service['ttl']), 90) - self.assertEqual(int(service['lease']), 90) - self.assertEqual(int(service['key-lease']), 800) - else: - self.assertTrue(False) - - #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Change the default lease to 50 and wait for long enough for `ins2` - # and `ins3` to do lease refresh. Validate that `ins2` now requests - # new default lease of 50 while `ins3` should stay as before. - - client.srp_client_set_lease_interval(50) - self.assertEqual(client.srp_client_get_lease_interval(), 50) - - self.simulator.go(45) - - self.check_services_on_client(client, 4) - server_services = server.srp_server_get_services() - self.assertEqual(len(server_services), 4) - for service in server_services: - if service['fullname'] == 'ins1._test._udp.default.service.arpa.': - self.assertEqual(service['deleted'], 'false') - self.assertEqual(int(service['ttl']), 100) - self.assertEqual(int(service['lease']), 100) - self.assertEqual(int(service['key-lease']), 100) - elif service['fullname'] == 'ins2._test._udp.default.service.arpa.': - self.assertEqual(service['deleted'], 'false') - self.assertEqual(int(service['ttl']), 50) - self.assertEqual(int(service['lease']), 50) - self.assertEqual(int(service['key-lease']), 330) - elif service['fullname'] == 'ins3._test._udp.default.service.arpa.': - self.assertEqual(service['deleted'], 'false') - self.assertEqual(int(service['ttl']), 40) - self.assertEqual(int(service['lease']), 40) - self.assertEqual(int(service['key-lease']), 330) - elif service['fullname'] == 'ins4._test._udp.default.service.arpa.': - self.assertEqual(service['deleted'], 'false') - self.assertEqual(int(service['ttl']), 90) - self.assertEqual(int(service['lease']), 90) - self.assertEqual(int(service['key-lease']), 800) - else: - self.assertTrue(False) - - #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Change the default key lease to 30. `ins3` should adopt this but - # since it is shorter than its explicitly specified lease the - # client should use same value for both lease and key-lease. - - client.srp_client_set_key_lease_interval(35) - self.assertEqual(client.srp_client_get_key_lease_interval(), 35) - - self.simulator.go(45) - - self.check_services_on_client(client, 4) - server_services = server.srp_server_get_services() - self.assertEqual(len(server_services), 4) - for service in server_services: - if service['fullname'] == 'ins1._test._udp.default.service.arpa.': - self.assertEqual(service['deleted'], 'false') - self.assertEqual(int(service['ttl']), 100) - self.assertEqual(int(service['lease']), 100) - self.assertEqual(int(service['key-lease']), 100) - elif service['fullname'] == 'ins2._test._udp.default.service.arpa.': - self.assertEqual(service['deleted'], 'false') - self.assertEqual(int(service['ttl']), 50) - self.assertEqual(int(service['lease']), 50) - self.assertEqual(int(service['key-lease']), 330) - elif service['fullname'] == 'ins3._test._udp.default.service.arpa.': - self.assertEqual(service['deleted'], 'false') - self.assertEqual(int(service['ttl']), 40) - self.assertEqual(int(service['lease']), 40) - self.assertEqual(int(service['key-lease']), 40) - elif service['fullname'] == 'ins4._test._udp.default.service.arpa.': - self.assertEqual(service['deleted'], 'false') - self.assertEqual(int(service['ttl']), 90) - self.assertEqual(int(service['lease']), 90) - self.assertEqual(int(service['key-lease']), 800) - else: - self.assertTrue(False) - - #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Change the requested TTL. Wait for long enough for all - # services to refresh and check that the new TTL is correctly - # requested by the client (when it is not larger than - # service lease). - - client.srp_client_set_ttl(65) - self.assertEqual(client.srp_client_get_ttl(), 65) - - self.simulator.go(110) - - self.check_services_on_client(client, 4) - server_services = server.srp_server_get_services() - self.assertEqual(len(server_services), 4) - for service in server_services: - if service['fullname'] == 'ins1._test._udp.default.service.arpa.': - self.assertEqual(service['deleted'], 'false') - self.assertEqual(int(service['ttl']), 65) - self.assertEqual(int(service['lease']), 100) - self.assertEqual(int(service['key-lease']), 100) - elif service['fullname'] == 'ins2._test._udp.default.service.arpa.': - self.assertEqual(service['deleted'], 'false') - self.assertEqual(int(service['ttl']), 50) - self.assertEqual(int(service['lease']), 50) - self.assertEqual(int(service['key-lease']), 330) - elif service['fullname'] == 'ins3._test._udp.default.service.arpa.': - self.assertEqual(service['deleted'], 'false') - self.assertEqual(int(service['ttl']), 40) - self.assertEqual(int(service['lease']), 40) - self.assertEqual(int(service['key-lease']), 40) - elif service['fullname'] == 'ins4._test._udp.default.service.arpa.': - self.assertEqual(service['deleted'], 'false') - self.assertEqual(int(service['ttl']), 65) - self.assertEqual(int(service['lease']), 90) - self.assertEqual(int(service['key-lease']), 800) - else: - self.assertTrue(False) - - def check_services_on_client(self, client, expected_num_services): - services = client.srp_client_get_services() - self.assertEqual(len(services), expected_num_services) - for service in client.srp_client_get_services(): - self.assertIn(service['state'], ['Registered', 'ToRefresh', 'Refreshing']) - - -if __name__ == '__main__': - unittest.main()