1#!/usr/bin/env python3
2#
3#  Copyright (c) 2022, 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# Verify router table entries.
38#
39#     r1 ------ r2 ---- r6
40#      \        /
41#       \      /
42#        \    /
43#          r3 ------ r4 ----- r5
44#
45#
46
47test_name = __file__[:-3] if __file__.endswith('.py') else __file__
48print('-' * 120)
49print('Starting \'{}\''.format(test_name))
50
51# -----------------------------------------------------------------------------------------------------------------------
52# Creating `cli.Nodes` instances
53
54speedup = 10
55cli.Node.set_time_speedup_factor(speedup)
56
57r1 = cli.Node()
58r2 = cli.Node()
59r3 = cli.Node()
60r4 = cli.Node()
61r5 = cli.Node()
62r6 = cli.Node()
63
64# -----------------------------------------------------------------------------------------------------------------------
65# Form topology
66
67r1.allowlist_node(r2)
68r1.allowlist_node(r3)
69
70r2.allowlist_node(r1)
71r2.allowlist_node(r3)
72r2.allowlist_node(r6)
73
74r3.allowlist_node(r1)
75r3.allowlist_node(r2)
76r3.allowlist_node(r4)
77
78r4.allowlist_node(r3)
79r4.allowlist_node(r5)
80
81r5.allowlist_node(r4)
82
83r6.allowlist_node(r2)
84
85r1.form("topo")
86for node in [r2, r3, r4, r5, r6]:
87    node.join(r1)
88
89verify(r1.get_state() == 'leader')
90for node in [r2, r3, r4, r5, r6]:
91    verify(node.get_state() == 'router')
92
93# -----------------------------------------------------------------------------------------------------------------------
94# Test Implementation
95
96r1_rloc16 = int(r1.get_rloc16(), 16)
97r2_rloc16 = int(r2.get_rloc16(), 16)
98r3_rloc16 = int(r3.get_rloc16(), 16)
99r4_rloc16 = int(r4.get_rloc16(), 16)
100r5_rloc16 = int(r5.get_rloc16(), 16)
101r6_rloc16 = int(r6.get_rloc16(), 16)
102
103r1_rid = r1_rloc16 / 1024
104r2_rid = r2_rloc16 / 1024
105r3_rid = r3_rloc16 / 1024
106r4_rid = r4_rloc16 / 1024
107r5_rid = r5_rloc16 / 1024
108r6_rid = r6_rloc16 / 1024
109
110# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
111
112
113def check_r1_router_table():
114    table = r1.get_router_table()
115    verify(len(table) == 6)
116    for entry in table:
117        rloc16 = int(entry['RLOC16'], 0)
118        link = int(entry['Link'])
119        nexthop = int(entry['Next Hop'])
120        cost = int(entry['Path Cost'])
121        if rloc16 == r1_rloc16:
122            verify(link == 0)
123        elif rloc16 == r2_rloc16:
124            verify(link == 1)
125            verify(nexthop == r3_rid)
126        elif rloc16 == r3_rloc16:
127            verify(link == 1)
128            verify(nexthop == r2_rid)
129        elif rloc16 == r4_rloc16:
130            verify(link == 0)
131            verify(nexthop == r3_rid)
132            verify(cost == 1)
133        elif rloc16 == r5_rloc16:
134            verify(link == 0)
135            verify(nexthop == r3_rid)
136            verify(cost == 2)
137        elif rloc16 == r6_rloc16:
138            verify(link == 0)
139            verify(nexthop == r2_rid)
140            verify(cost == 1)
141
142
143verify_within(check_r1_router_table, 160)
144
145# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
146
147
148def check_r2_router_table():
149    table = r2.get_router_table()
150    verify(len(table) == 6)
151    for entry in table:
152        rloc16 = int(entry['RLOC16'], 0)
153        link = int(entry['Link'])
154        nexthop = int(entry['Next Hop'])
155        cost = int(entry['Path Cost'])
156        if rloc16 == r1_rloc16:
157            verify(link == 1)
158            verify(nexthop == r3_rid)
159        elif rloc16 == r2_rloc16:
160            verify(link == 0)
161        elif rloc16 == r3_rloc16:
162            verify(link == 1)
163            verify(nexthop == r1_rid)
164        elif rloc16 == r4_rloc16:
165            verify(link == 0)
166            verify(nexthop == r3_rid)
167            verify(cost == 1)
168        elif rloc16 == r5_rloc16:
169            verify(link == 0)
170            verify(nexthop == r3_rid)
171            verify(cost == 2)
172        elif rloc16 == r6_rloc16:
173            verify(link == 1)
174
175
176verify_within(check_r2_router_table, 160)
177
178# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
179
180
181def check_r4_router_table():
182    table = r4.get_router_table()
183    verify(len(table) == 6)
184    for entry in table:
185        rloc16 = int(entry['RLOC16'], 0)
186        link = int(entry['Link'])
187        nexthop = int(entry['Next Hop'])
188        cost = int(entry['Path Cost'])
189        if rloc16 == r1_rloc16:
190            verify(link == 0)
191            verify(nexthop == r3_rid)
192            verify(cost == 1)
193        elif rloc16 == r2_rloc16:
194            verify(link == 0)
195            verify(nexthop == r3_rid)
196            verify(cost == 1)
197        elif rloc16 == r3_rloc16:
198            verify(link == 1)
199        elif rloc16 == r4_rloc16:
200            verify(link == 0)
201        elif rloc16 == r5_rloc16:
202            verify(link == 1)
203        elif rloc16 == r6_rloc16:
204            verify(link == 0)
205            verify(nexthop == r3_rid)
206            verify(cost == 2)
207
208
209verify_within(check_r4_router_table, 160)
210
211# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
212
213
214def check_r5_router_table():
215    table = r5.get_router_table()
216    verify(len(table) == 6)
217    for entry in table:
218        rloc16 = int(entry['RLOC16'], 0)
219        link = int(entry['Link'])
220        nexthop = int(entry['Next Hop'])
221        cost = int(entry['Path Cost'])
222        if rloc16 == r1_rloc16:
223            verify(link == 0)
224            verify(nexthop == r4_rid)
225            verify(cost == 2)
226        elif rloc16 == r2_rloc16:
227            verify(link == 0)
228            verify(nexthop == r4_rid)
229            verify(cost == 2)
230        elif rloc16 == r3_rloc16:
231            verify(link == 0)
232            verify(nexthop == r4_rid)
233            verify(cost == 1)
234        elif rloc16 == r4_rloc16:
235            verify(link == 1)
236        elif rloc16 == r5_rloc16:
237            verify(link == 0)
238        elif rloc16 == r6_rloc16:
239            verify(link == 0)
240            verify(nexthop == r4_rid)
241            verify(cost == 3)
242
243
244verify_within(check_r5_router_table, 160)
245
246# -----------------------------------------------------------------------------------------------------------------------
247# Test finished
248
249cli.Node.finalize_all_nodes()
250
251print('\'{}\' passed.'.format(test_name))
252