Skip to content

Commit acef228

Browse files
authored
[nexus] migrate test_srp_client_remove_host to Nexus (openthread#12946)
This commit migrates the SRP client host removal test from the thread-cert Python-based framework to the Nexus framework. The new C++ implementation in tests/nexus/test_srp_client_remove_host.cpp covers the same scenarios as the original Python script: - Successful registration of SRP host and services. - Verification that ClearHostAndServices() does not immediately remove server-side state. - Verification that RemoveHostAndServices(removeKey=False, sendUnregToServer=True) marks the host and services as deleted on the SRP server. - Verification that RemoveHostAndServices(removeKey=True, sendUnregToServer=True) fully removes the host and service entries from the SRP server. The original Python script test_srp_client_remove_host.py is removed as its functionality is now fully covered by the Nexus test.
1 parent 828ffef commit acef228

3 files changed

Lines changed: 179 additions & 176 deletions

File tree

tests/nexus/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,7 @@ ot_nexus_test(reed_address_solicit_rejected "core;nexus")
407407
ot_nexus_test(router_downgrade_on_sec_policy_change "core;nexus")
408408
ot_nexus_test(srp_auto_start "core;nexus")
409409
ot_nexus_test(srp_client_change_lease "core;nexus")
410+
ot_nexus_test(srp_client_remove_host "core;nexus")
410411
ot_nexus_test(srp_lease "core;nexus")
411412
ot_nexus_test(srp_many_services_mtu_check "core;nexus")
412413
ot_nexus_test(zero_len_external_route "core;nexus")
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
/*
2+
* Copyright (c) 2026, The OpenThread Authors.
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions are met:
7+
* 1. Redistributions of source code must retain the above copyright
8+
* notice, this list of conditions and the following disclaimer.
9+
* 2. Redistributions in binary form must reproduce the above copyright
10+
* notice, this list of conditions and the following disclaimer in the
11+
* documentation and/or other materials provided with the distribution.
12+
* 3. Neither the name of the copyright holder nor the
13+
* names of its contributors may be used to endorse or promote products
14+
* derived from this software without specific prior written permission.
15+
*
16+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26+
* POSSIBILITY OF SUCH DAMAGE.
27+
*/
28+
29+
#include <stdio.h>
30+
#include <string.h>
31+
32+
#include "platform/nexus_core.hpp"
33+
#include "platform/nexus_node.hpp"
34+
35+
namespace ot {
36+
namespace Nexus {
37+
38+
static const Srp::Server::Host *FindHost(Node &aServer, const char *aName)
39+
{
40+
static constexpr uint16_t kNameStringSize = 400;
41+
42+
const Srp::Server::Host *host = nullptr;
43+
String<kNameStringSize> fullName;
44+
45+
fullName.Append("%s.%s", aName, aServer.Get<Srp::Server>().GetDomain());
46+
47+
while (true)
48+
{
49+
host = aServer.Get<Srp::Server>().GetNextHost(host);
50+
51+
if (host == nullptr)
52+
{
53+
break;
54+
}
55+
56+
if (StringMatch(host->GetFullName(), fullName.AsCString()))
57+
{
58+
break;
59+
}
60+
}
61+
62+
return host;
63+
}
64+
65+
void TestSrpClientRemoveHost(void)
66+
{
67+
Core nexus;
68+
69+
Node &server = nexus.CreateNode();
70+
Node &client = nexus.CreateNode();
71+
72+
server.SetName("server");
73+
client.SetName("client");
74+
75+
Log("Step 0: Start the server and client devices.");
76+
77+
server.Form();
78+
nexus.AdvanceTime(13000);
79+
VerifyOrQuit(server.Get<Mle::Mle>().IsLeader());
80+
81+
client.Join(server);
82+
nexus.AdvanceTime(200000);
83+
VerifyOrQuit(client.Get<Mle::Mle>().IsRouter());
84+
85+
server.Get<Srp::Server>().SetEnabled(true);
86+
client.Get<Srp::Client>().EnableAutoStartMode(nullptr, nullptr);
87+
nexus.AdvanceTime(15000);
88+
89+
Log("Step 1: Register a single service and verify that it worked.");
90+
91+
SuccessOrQuit(client.Get<Srp::Client>().SetHostName("host"));
92+
93+
Ip6::Address address;
94+
Srp::Client::Service service;
95+
96+
SuccessOrQuit(address.FromString("2001::1"));
97+
SuccessOrQuit(client.Get<Srp::Client>().SetHostAddresses(&address, 1));
98+
99+
service.mName = "_srv._udp";
100+
service.mInstanceName = "ins";
101+
service.mSubTypeLabels = nullptr;
102+
service.mTxtEntries = nullptr;
103+
service.mNumTxtEntries = 0;
104+
service.mPort = 1977;
105+
service.mPriority = 0;
106+
service.mWeight = 0;
107+
service.mLease = 0;
108+
service.mKeyLease = 0;
109+
SuccessOrQuit(service.Init());
110+
SuccessOrQuit(client.Get<Srp::Client>().AddService(service));
111+
112+
nexus.AdvanceTime(2000);
113+
114+
VerifyOrQuit(client.Get<Srp::Client>().GetHostInfo().GetState() == Srp::Client::kRegistered);
115+
116+
const Srp::Server::Host *host = FindHost(server, "host");
117+
VerifyOrQuit(host != nullptr);
118+
VerifyOrQuit(!host->IsDeleted());
119+
120+
uint8_t numAddresses;
121+
const Ip6::Address *addresses = host->GetAddresses(numAddresses);
122+
VerifyOrQuit(numAddresses == 1);
123+
{
124+
Ip6::Address expectedAddress;
125+
SuccessOrQuit(expectedAddress.FromString("2001::1"));
126+
VerifyOrQuit(addresses[0] == expectedAddress);
127+
}
128+
129+
VerifyOrQuit(!host->GetServices().IsEmpty());
130+
const Srp::Server::Service *serverService = host->GetServices().GetHead();
131+
VerifyOrQuit(!serverService->IsDeleted());
132+
VerifyOrQuit(serverService->GetPort() == 1977);
133+
134+
Log("Step 2: Clear the info on client, and verify that it is still present on server.");
135+
136+
client.Get<Srp::Client>().ClearHostAndServices();
137+
nexus.AdvanceTime(2000);
138+
139+
VerifyOrQuit(client.Get<Srp::Client>().GetHostInfo().GetName() == nullptr);
140+
VerifyOrQuit(FindHost(server, "host") != nullptr);
141+
142+
Log("Step 3: Set host name and request 'host remove' requiring update to server.");
143+
144+
SuccessOrQuit(client.Get<Srp::Client>().SetHostName("host"));
145+
SuccessOrQuit(
146+
client.Get<Srp::Client>().RemoveHostAndServices(/* aRemoveKeyLease */ false, /* aSendUnregToServer */ true));
147+
nexus.AdvanceTime(2000);
148+
149+
VerifyOrQuit(client.Get<Srp::Client>().GetHostInfo().GetName() == nullptr);
150+
151+
host = FindHost(server, "host");
152+
VerifyOrQuit(host != nullptr);
153+
VerifyOrQuit(host->IsDeleted());
154+
VerifyOrQuit(!host->GetServices().IsEmpty());
155+
VerifyOrQuit(host->GetServices().GetHead()->IsDeleted());
156+
157+
Log("Step 4: Request 'host remove' with `remove_key`.");
158+
159+
SuccessOrQuit(client.Get<Srp::Client>().SetHostName("host"));
160+
SuccessOrQuit(
161+
client.Get<Srp::Client>().RemoveHostAndServices(/* aRemoveKeyLease */ true, /* aSendUnregToServer */ true));
162+
nexus.AdvanceTime(2000);
163+
164+
VerifyOrQuit(client.Get<Srp::Client>().GetHostInfo().GetName() == nullptr);
165+
VerifyOrQuit(FindHost(server, "host") == nullptr);
166+
167+
Log("Test passed successfully");
168+
}
169+
170+
} // namespace Nexus
171+
} // namespace ot
172+
173+
int main(void)
174+
{
175+
ot::Nexus::TestSrpClientRemoveHost();
176+
printf("All tests passed\n");
177+
return 0;
178+
}

tests/scripts/thread-cert/test_srp_client_remove_host.py

Lines changed: 0 additions & 176 deletions
This file was deleted.

0 commit comments

Comments
 (0)