xref: /aosp_15_r20/external/openthread/tests/toranj/cli/test-401-srp-server-address-cache-snoop.py (revision cfb92d1480a9e65faed56933e9c12405f45898b4)
1#!/usr/bin/env python3
2#
3#  Copyright (c) 2024, The OpenThread Authors.
4#  All rights reserved.
5#
6#  Redistribution and use in source and binary forms, with or without
7#  modification, are permitted provided that the following conditions are met:
8#  1. Redistributions of source code must retain the above copyright
9#     notice, this list of conditions and the following disclaimer.
10#  2. Redistributions in binary form must reproduce the above copyright
11#     notice, this list of conditions and the following disclaimer in the
12#     documentation and/or other materials provided with the distribution.
13#  3. Neither the name of the copyright holder nor the
14#     names of its contributors may be used to endorse or promote products
15#     derived from this software without specific prior written permission.
16#
17#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27#  POSSIBILITY OF SUCH DAMAGE.
28
29from cli import verify
30from cli import verify_within
31import cli
32import time
33
34# -----------------------------------------------------------------------------------------------------------------------
35# Test description:
36#
37# Validate registered host addresses are properly added in address cache table
38# on SRP server.
39#
40#    r1 (leader) ----- r2 ------ r3
41#     /  |                        \
42#    /   |                         \
43#   fed1  sed1                     sed2
44#
45
46test_name = __file__[:-3] if __file__.endswith('.py') else __file__
47print('-' * 120)
48print('Starting \'{}\''.format(test_name))
49
50#-----------------------------------------------------------------------------------------------------------------------
51# Creating `cli.Nodes` instances
52
53speedup = 10
54cli.Node.set_time_speedup_factor(speedup)
55
56r1 = cli.Node()
57r2 = cli.Node()
58r3 = cli.Node()
59fed1 = cli.Node()
60sed1 = cli.Node()
61sed2 = cli.Node()
62
63WAIT_TIME = 5
64
65#-----------------------------------------------------------------------------------------------------------------------
66# Form topology
67
68r1.allowlist_node(r2)
69r1.allowlist_node(fed1)
70r1.allowlist_node(sed1)
71
72r2.allowlist_node(r1)
73r2.allowlist_node(r3)
74r2.allowlist_node(sed2)
75
76r3.allowlist_node(r2)
77r3.allowlist_node(sed2)
78
79fed1.allowlist_node(r1)
80sed1.allowlist_node(r1)
81
82sed2.allowlist_node(r3)
83
84r1.form('srp-snoop')
85r2.join(r1)
86r3.join(r2)
87fed1.join(r1, cli.JOIN_TYPE_REED)
88sed1.join(r1, cli.JOIN_TYPE_SLEEPY_END_DEVICE)
89sed2.join(r1, cli.JOIN_TYPE_SLEEPY_END_DEVICE)
90sed1.set_pollperiod(500)
91sed2.set_pollperiod(500)
92
93verify(r1.get_state() == 'leader')
94verify(r2.get_state() == 'router')
95verify(r2.get_state() == 'router')
96verify(sed1.get_state() == 'child')
97verify(sed2.get_state() == 'child')
98verify(fed1.get_state() == 'child')
99
100r2_rloc = int(r2.get_rloc16(), 16)
101r3_rloc = int(r3.get_rloc16(), 16)
102fed1_rloc = int(fed1.get_rloc16(), 16)
103
104# Start server and client and register single service
105r1.srp_server_enable()
106
107r2.srp_client_enable_auto_start_mode()
108r2.srp_client_set_host_name('r2')
109r2.srp_client_set_host_address('fd00::2')
110r2.srp_client_add_service('srv2', '_test._udp', 222, 0, 0)
111
112
113def check_server_has_host(num_hosts):
114    verify(len(r1.srp_server_get_hosts()) >= num_hosts)
115
116
117verify_within(check_server_has_host, WAIT_TIME, arg=1)
118
119cache_table = r1.get_eidcache()
120
121for entry in cache_table:
122    fields = entry.strip().split(' ')
123    if (fields[0] == 'fd00:0:0:0:0:0:0:2'):
124        verify(int(fields[1], 16) == r2_rloc)
125        verify(fields[2] == 'snoop')
126        break
127else:
128    verify(False)  # did not find cache entry
129
130# Register from r3 which one hop away from r1 server.
131
132r3.srp_client_enable_auto_start_mode()
133r3.srp_client_set_host_name('r3')
134r3.srp_client_set_host_address('fd00::3')
135r3.srp_client_add_service('srv3', '_test._udp', 333, 0, 0)
136
137verify_within(check_server_has_host, WAIT_TIME, arg=2)
138
139cache_table = r1.get_eidcache()
140
141for entry in cache_table:
142    fields = entry.strip().split(' ')
143    if (fields[0] == 'fd00:0:0:0:0:0:0:3'):
144        verify(int(fields[1], 16) == r3_rloc)
145        verify(fields[2] == 'snoop')
146        break
147else:
148    verify(False)  # did not find cache entry
149
150# Register from sed2 which child of r3. The cache table should
151# use the `r3` as the parent of sed2.
152
153sed2.srp_client_enable_auto_start_mode()
154sed2.srp_client_set_host_name('sed2')
155sed2.srp_client_set_host_address('fd00::1:3')
156sed2.srp_client_add_service('srv4', '_test._udp', 333, 0, 0)
157
158verify_within(check_server_has_host, WAIT_TIME, arg=3)
159
160cache_table = r1.get_eidcache()
161
162for entry in cache_table:
163    fields = entry.strip().split(' ')
164    if (fields[0] == 'fd00:0:0:0:0:0:1:3'):
165        verify(int(fields[1], 16) == r3_rloc)
166        verify(fields[2] == 'snoop')
167        break
168else:
169    verify(False)  # did not find cache entry
170
171# Register from fed1 which child of server (r1) itself. The cache table should
172# be properly updated
173
174fed1.srp_client_enable_auto_start_mode()
175fed1.srp_client_set_host_name('fed1')
176fed1.srp_client_set_host_address('fd00::2:3')
177fed1.srp_client_add_service('srv5', '_test._udp', 555, 0, 0)
178
179verify_within(check_server_has_host, WAIT_TIME, arg=4)
180
181cache_table = r1.get_eidcache()
182
183for entry in cache_table:
184    fields = entry.strip().split(' ')
185    if (fields[0] == 'fd00:0:0:0:0:0:2:3'):
186        verify(int(fields[1], 16) == fed1_rloc)
187        verify(fields[2] == 'snoop')
188        break
189else:
190    verify(False)  # did not find cache entry
191
192# Register from sed1 which is a sleepy child of server (r1).
193# The cache table should not be updated for sleepy child.
194
195sed1.srp_client_enable_auto_start_mode()
196sed1.srp_client_set_host_name('sed1')
197sed1.srp_client_set_host_address('fd00::3:4')
198sed1.srp_client_add_service('srv5', '_test._udp', 555, 0, 0)
199
200verify_within(check_server_has_host, WAIT_TIME, arg=4)
201
202cache_table = r1.get_eidcache()
203
204for entry in cache_table:
205    fields = entry.strip().split(' ')
206    verify(fields[0] != 'fd00:0:0:0:0:0:3:4')
207
208# -----------------------------------------------------------------------------------------------------------------------
209# Test finished
210
211cli.Node.finalize_all_nodes()
212
213print('\'{}\' passed.'.format(test_name))
214