1*cfb92d14SAndroid Build Coastguard Worker#!/usr/bin/env python3 2*cfb92d14SAndroid Build Coastguard Worker# 3*cfb92d14SAndroid Build Coastguard Worker# Copyright (c) 2022, The OpenThread Authors. 4*cfb92d14SAndroid Build Coastguard Worker# All rights reserved. 5*cfb92d14SAndroid Build Coastguard Worker# 6*cfb92d14SAndroid Build Coastguard Worker# Redistribution and use in source and binary forms, with or without 7*cfb92d14SAndroid Build Coastguard Worker# modification, are permitted provided that the following conditions are met: 8*cfb92d14SAndroid Build Coastguard Worker# 1. Redistributions of source code must retain the above copyright 9*cfb92d14SAndroid Build Coastguard Worker# notice, this list of conditions and the following disclaimer. 10*cfb92d14SAndroid Build Coastguard Worker# 2. Redistributions in binary form must reproduce the above copyright 11*cfb92d14SAndroid Build Coastguard Worker# notice, this list of conditions and the following disclaimer in the 12*cfb92d14SAndroid Build Coastguard Worker# documentation and/or other materials provided with the distribution. 13*cfb92d14SAndroid Build Coastguard Worker# 3. Neither the name of the copyright holder nor the 14*cfb92d14SAndroid Build Coastguard Worker# names of its contributors may be used to endorse or promote products 15*cfb92d14SAndroid Build Coastguard Worker# derived from this software without specific prior written permission. 16*cfb92d14SAndroid Build Coastguard Worker# 17*cfb92d14SAndroid Build Coastguard Worker# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18*cfb92d14SAndroid Build Coastguard Worker# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19*cfb92d14SAndroid Build Coastguard Worker# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20*cfb92d14SAndroid Build Coastguard Worker# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21*cfb92d14SAndroid Build Coastguard Worker# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22*cfb92d14SAndroid Build Coastguard Worker# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23*cfb92d14SAndroid Build Coastguard Worker# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24*cfb92d14SAndroid Build Coastguard Worker# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25*cfb92d14SAndroid Build Coastguard Worker# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26*cfb92d14SAndroid Build Coastguard Worker# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27*cfb92d14SAndroid Build Coastguard Worker# POSSIBILITY OF SUCH DAMAGE. 28*cfb92d14SAndroid Build Coastguard Worker 29*cfb92d14SAndroid Build Coastguard Workerfrom cli import verify 30*cfb92d14SAndroid Build Coastguard Workerfrom cli import verify_within 31*cfb92d14SAndroid Build Coastguard Workerimport cli 32*cfb92d14SAndroid Build Coastguard Workerimport time 33*cfb92d14SAndroid Build Coastguard Worker 34*cfb92d14SAndroid Build Coastguard Worker# ----------------------------------------------------------------------------------------------------------------------- 35*cfb92d14SAndroid Build Coastguard Worker# Test description: Address Cache Table 36*cfb92d14SAndroid Build Coastguard Worker# 37*cfb92d14SAndroid Build Coastguard Worker# This test verifies the behavior of `AddressResolver` and how the cache 38*cfb92d14SAndroid Build Coastguard Worker# table is managed. In particular it verifies behavior query timeout and 39*cfb92d14SAndroid Build Coastguard Worker# query retry and snoop optimization. 40*cfb92d14SAndroid Build Coastguard Worker# 41*cfb92d14SAndroid Build Coastguard Worker# Build network topology 42*cfb92d14SAndroid Build Coastguard Worker# 43*cfb92d14SAndroid Build Coastguard Worker# r3 ---- r1 ---- r2 44*cfb92d14SAndroid Build Coastguard Worker# | | 45*cfb92d14SAndroid Build Coastguard Worker# | | 46*cfb92d14SAndroid Build Coastguard Worker# c3 c2 47*cfb92d14SAndroid Build Coastguard Worker# 48*cfb92d14SAndroid Build Coastguard Worker 49*cfb92d14SAndroid Build Coastguard Workertest_name = __file__[:-3] if __file__.endswith('.py') else __file__ 50*cfb92d14SAndroid Build Coastguard Workerprint('-' * 120) 51*cfb92d14SAndroid Build Coastguard Workerprint('Starting \'{}\''.format(test_name)) 52*cfb92d14SAndroid Build Coastguard Worker 53*cfb92d14SAndroid Build Coastguard Worker# ----------------------------------------------------------------------------------------------------------------------- 54*cfb92d14SAndroid Build Coastguard Worker# Creating `cli.Node` instances 55*cfb92d14SAndroid Build Coastguard Worker 56*cfb92d14SAndroid Build Coastguard Workerspeedup = 10 57*cfb92d14SAndroid Build Coastguard Workercli.Node.set_time_speedup_factor(speedup) 58*cfb92d14SAndroid Build Coastguard Worker 59*cfb92d14SAndroid Build Coastguard Workerr1 = cli.Node() 60*cfb92d14SAndroid Build Coastguard Workerr2 = cli.Node() 61*cfb92d14SAndroid Build Coastguard Workerr3 = cli.Node() 62*cfb92d14SAndroid Build Coastguard Workerc2 = cli.Node() 63*cfb92d14SAndroid Build Coastguard Workerc3 = cli.Node() 64*cfb92d14SAndroid Build Coastguard Worker 65*cfb92d14SAndroid Build Coastguard Worker# ----------------------------------------------------------------------------------------------------------------------- 66*cfb92d14SAndroid Build Coastguard Worker# Form topology 67*cfb92d14SAndroid Build Coastguard Worker 68*cfb92d14SAndroid Build Coastguard Workerr1.allowlist_node(r2) 69*cfb92d14SAndroid Build Coastguard Workerr1.allowlist_node(r3) 70*cfb92d14SAndroid Build Coastguard Worker 71*cfb92d14SAndroid Build Coastguard Workerr2.allowlist_node(r1) 72*cfb92d14SAndroid Build Coastguard Workerr2.allowlist_node(c2) 73*cfb92d14SAndroid Build Coastguard Worker 74*cfb92d14SAndroid Build Coastguard Workerr3.allowlist_node(r1) 75*cfb92d14SAndroid Build Coastguard Workerr3.allowlist_node(c3) 76*cfb92d14SAndroid Build Coastguard Worker 77*cfb92d14SAndroid Build Coastguard Workerc2.allowlist_node(r2) 78*cfb92d14SAndroid Build Coastguard Workerc3.allowlist_node(r3) 79*cfb92d14SAndroid Build Coastguard Worker 80*cfb92d14SAndroid Build Coastguard Workerr1.form('addrrslvr') 81*cfb92d14SAndroid Build Coastguard Worker 82*cfb92d14SAndroid Build Coastguard Workerprefix = 'fd00:abba::' 83*cfb92d14SAndroid Build Coastguard Workerr1.add_prefix(prefix + '/64', 'pos', 'med') 84*cfb92d14SAndroid Build Coastguard Workerr1.register_netdata() 85*cfb92d14SAndroid Build Coastguard Worker 86*cfb92d14SAndroid Build Coastguard Workerr2.join(r1) 87*cfb92d14SAndroid Build Coastguard Workerr3.join(r1) 88*cfb92d14SAndroid Build Coastguard Workerc2.join(r1, cli.JOIN_TYPE_END_DEVICE) 89*cfb92d14SAndroid Build Coastguard Workerc3.join(r1, cli.JOIN_TYPE_SLEEPY_END_DEVICE) 90*cfb92d14SAndroid Build Coastguard Workerc3.set_pollperiod(400) 91*cfb92d14SAndroid Build Coastguard Worker 92*cfb92d14SAndroid Build Coastguard Workerverify(r1.get_state() == 'leader') 93*cfb92d14SAndroid Build Coastguard Workerverify(r2.get_state() == 'router') 94*cfb92d14SAndroid Build Coastguard Workerverify(r3.get_state() == 'router') 95*cfb92d14SAndroid Build Coastguard Workerverify(c2.get_state() == 'child') 96*cfb92d14SAndroid Build Coastguard Workerverify(c3.get_state() == 'child') 97*cfb92d14SAndroid Build Coastguard Worker 98*cfb92d14SAndroid Build Coastguard Worker# ----------------------------------------------------------------------------------------------------------------------- 99*cfb92d14SAndroid Build Coastguard Worker# Test Implementation 100*cfb92d14SAndroid Build Coastguard Worker 101*cfb92d14SAndroid Build Coastguard Worker# Wait till first router has either established a link or 102*cfb92d14SAndroid Build Coastguard Worker# has a valid "next hop" towards all other routers. 103*cfb92d14SAndroid Build Coastguard Worker 104*cfb92d14SAndroid Build Coastguard Workerr1_rloc16 = int(r1.get_rloc16(), 16) 105*cfb92d14SAndroid Build Coastguard Worker 106*cfb92d14SAndroid Build Coastguard Worker 107*cfb92d14SAndroid Build Coastguard Workerdef check_r1_router_table(): 108*cfb92d14SAndroid Build Coastguard Worker table = r1.get_router_table() 109*cfb92d14SAndroid Build Coastguard Worker verify(len(table) == 3) 110*cfb92d14SAndroid Build Coastguard Worker for entry in table: 111*cfb92d14SAndroid Build Coastguard Worker verify(int(entry['RLOC16'], 0) == r1_rloc16 or int(entry['Link']) == 1 or int(entry['Next Hop']) != 63) 112*cfb92d14SAndroid Build Coastguard Worker 113*cfb92d14SAndroid Build Coastguard Worker 114*cfb92d14SAndroid Build Coastguard Workerverify_within(check_r1_router_table, 120) 115*cfb92d14SAndroid Build Coastguard Worker 116*cfb92d14SAndroid Build Coastguard Worker# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 117*cfb92d14SAndroid Build Coastguard Worker 118*cfb92d14SAndroid Build Coastguard Workerr1_rloc = int(r1.get_rloc16(), 16) 119*cfb92d14SAndroid Build Coastguard Workerr2_rloc = int(r2.get_rloc16(), 16) 120*cfb92d14SAndroid Build Coastguard Workerr3_rloc = int(r3.get_rloc16(), 16) 121*cfb92d14SAndroid Build Coastguard Workerc2_rloc = int(c2.get_rloc16(), 16) 122*cfb92d14SAndroid Build Coastguard Workerc3_rloc = int(c3.get_rloc16(), 16) 123*cfb92d14SAndroid Build Coastguard Worker 124*cfb92d14SAndroid Build Coastguard Worker# AddressResolver constants: 125*cfb92d14SAndroid Build Coastguard Worker 126*cfb92d14SAndroid Build Coastguard Workermax_cache_entries = 16 127*cfb92d14SAndroid Build Coastguard Workermax_snooped_non_evictable = 2 128*cfb92d14SAndroid Build Coastguard Worker 129*cfb92d14SAndroid Build Coastguard Worker# Add IPv6 addresses matching the on-mesh prefix on all nodes 130*cfb92d14SAndroid Build Coastguard Worker 131*cfb92d14SAndroid Build Coastguard Workerr1.add_ip_addr(prefix + '1') 132*cfb92d14SAndroid Build Coastguard Worker 133*cfb92d14SAndroid Build Coastguard Workernum_addresses = 4 # Number of addresses to add on r2, r3, c2, and c3 134*cfb92d14SAndroid Build Coastguard Worker 135*cfb92d14SAndroid Build Coastguard Workerfor num in range(num_addresses): 136*cfb92d14SAndroid Build Coastguard Worker r2.add_ip_addr(prefix + "2:" + str(num)) 137*cfb92d14SAndroid Build Coastguard Worker r3.add_ip_addr(prefix + "3:" + str(num)) 138*cfb92d14SAndroid Build Coastguard Worker c2.add_ip_addr(prefix + "c2:" + str(num)) 139*cfb92d14SAndroid Build Coastguard Worker c3.add_ip_addr(prefix + "c3:" + str(num)) 140*cfb92d14SAndroid Build Coastguard Worker 141*cfb92d14SAndroid Build Coastguard Worker# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 142*cfb92d14SAndroid Build Coastguard Worker 143*cfb92d14SAndroid Build Coastguard Worker# From r1 send msg to a group of addresses that are not provided by 144*cfb92d14SAndroid Build Coastguard Worker# any nodes in network. 145*cfb92d14SAndroid Build Coastguard Worker 146*cfb92d14SAndroid Build Coastguard Workernum_queries = 5 147*cfb92d14SAndroid Build Coastguard Workerstagger_interval = 1.2 148*cfb92d14SAndroid Build Coastguard Workerport = 1234 149*cfb92d14SAndroid Build Coastguard Workerinitial_retry_delay = 8 150*cfb92d14SAndroid Build Coastguard Worker 151*cfb92d14SAndroid Build Coastguard Workerr1.udp_open() 152*cfb92d14SAndroid Build Coastguard Worker 153*cfb92d14SAndroid Build Coastguard Workerfor num in range(num_queries): 154*cfb92d14SAndroid Build Coastguard Worker r1.udp_send(prefix + '800:' + str(num), port, 'hi_nobody') 155*cfb92d14SAndroid Build Coastguard Worker # Wait before next tx to stagger the address queries 156*cfb92d14SAndroid Build Coastguard Worker # request ensuring different timeouts 157*cfb92d14SAndroid Build Coastguard Worker time.sleep(stagger_interval / (num_queries * speedup)) 158*cfb92d14SAndroid Build Coastguard Worker 159*cfb92d14SAndroid Build Coastguard Worker# Verify that we do see entries in cache table for all the addresses 160*cfb92d14SAndroid Build Coastguard Worker# and all are in "query" state 161*cfb92d14SAndroid Build Coastguard Worker 162*cfb92d14SAndroid Build Coastguard Workercache_table = r1.get_eidcache() 163*cfb92d14SAndroid Build Coastguard Workerverify(len(cache_table) == num_queries) 164*cfb92d14SAndroid Build Coastguard Workerfor entry in cache_table: 165*cfb92d14SAndroid Build Coastguard Worker fields = entry.strip().split(' ') 166*cfb92d14SAndroid Build Coastguard Worker verify(fields[2] == 'query') 167*cfb92d14SAndroid Build Coastguard Worker verify(fields[3] == 'canEvict=0') 168*cfb92d14SAndroid Build Coastguard Worker verify(fields[4].startswith('timeout=')) 169*cfb92d14SAndroid Build Coastguard Worker verify(int(fields[4].split('=')[1]) > 0) 170*cfb92d14SAndroid Build Coastguard Worker 171*cfb92d14SAndroid Build Coastguard Worker# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 172*cfb92d14SAndroid Build Coastguard Worker# Check the retry-query behavior 173*cfb92d14SAndroid Build Coastguard Worker# 174*cfb92d14SAndroid Build Coastguard Worker# Wait till all the address queries time out and verify they 175*cfb92d14SAndroid Build Coastguard Worker# enter "retry-query" state. 176*cfb92d14SAndroid Build Coastguard Worker 177*cfb92d14SAndroid Build Coastguard Worker 178*cfb92d14SAndroid Build Coastguard Workerdef check_cache_entry_switch_to_retry_state(): 179*cfb92d14SAndroid Build Coastguard Worker cache_table = r1.get_eidcache() 180*cfb92d14SAndroid Build Coastguard Worker for entry in cache_table: 181*cfb92d14SAndroid Build Coastguard Worker fields = entry.strip().split(' ') 182*cfb92d14SAndroid Build Coastguard Worker verify(fields[2] == 'retry') 183*cfb92d14SAndroid Build Coastguard Worker verify(fields[3] == 'canEvict=1') 184*cfb92d14SAndroid Build Coastguard Worker verify(fields[4].startswith('timeout=')) 185*cfb92d14SAndroid Build Coastguard Worker verify(int(fields[4].split('=')[1]) >= 0) 186*cfb92d14SAndroid Build Coastguard Worker verify(fields[5].startswith('retryDelay=')) 187*cfb92d14SAndroid Build Coastguard Worker verify(int(fields[5].split('=')[1]) == initial_retry_delay) 188*cfb92d14SAndroid Build Coastguard Worker 189*cfb92d14SAndroid Build Coastguard Worker 190*cfb92d14SAndroid Build Coastguard Workerverify_within(check_cache_entry_switch_to_retry_state, 20) 191*cfb92d14SAndroid Build Coastguard Worker 192*cfb92d14SAndroid Build Coastguard Worker# Try sending again to same addresses which are all in "retry" state. 193*cfb92d14SAndroid Build Coastguard Worker 194*cfb92d14SAndroid Build Coastguard Workerfor num in range(num_queries): 195*cfb92d14SAndroid Build Coastguard Worker r1.udp_send(prefix + '800:' + str(num), port, 'hi_nobody') 196*cfb92d14SAndroid Build Coastguard Worker 197*cfb92d14SAndroid Build Coastguard Worker# Make sure the entries stayed in retry-query state as before. 198*cfb92d14SAndroid Build Coastguard Worker 199*cfb92d14SAndroid Build Coastguard Workerverify_within(check_cache_entry_switch_to_retry_state, 20) 200*cfb92d14SAndroid Build Coastguard Worker 201*cfb92d14SAndroid Build Coastguard Worker# Now wait for all entries to reach zero timeout. 202*cfb92d14SAndroid Build Coastguard Worker 203*cfb92d14SAndroid Build Coastguard Worker 204*cfb92d14SAndroid Build Coastguard Workerdef check_cache_entry_in_retry_state_to_enter_rampdown(): 205*cfb92d14SAndroid Build Coastguard Worker cache_table = r1.get_eidcache() 206*cfb92d14SAndroid Build Coastguard Worker for entry in cache_table: 207*cfb92d14SAndroid Build Coastguard Worker fields = entry.strip().split(' ') 208*cfb92d14SAndroid Build Coastguard Worker verify(fields[2] == 'retry') 209*cfb92d14SAndroid Build Coastguard Worker verify(fields[3] == 'canEvict=1') 210*cfb92d14SAndroid Build Coastguard Worker verify(fields[4].startswith('timeout=')) 211*cfb92d14SAndroid Build Coastguard Worker verify(fields[5].startswith('retryDelay=')) 212*cfb92d14SAndroid Build Coastguard Worker verify(fields[6] == 'rampDown=1') 213*cfb92d14SAndroid Build Coastguard Worker 214*cfb92d14SAndroid Build Coastguard Worker 215*cfb92d14SAndroid Build Coastguard Workerverify_within(check_cache_entry_in_retry_state_to_enter_rampdown, 20) 216*cfb92d14SAndroid Build Coastguard Worker 217*cfb92d14SAndroid Build Coastguard Worker# Now send again to the same addresses. 218*cfb92d14SAndroid Build Coastguard Worker 219*cfb92d14SAndroid Build Coastguard Workerfor num in range(num_queries): 220*cfb92d14SAndroid Build Coastguard Worker r1.udp_send(prefix + '800:' + str(num), port, 'hi_nobody') 221*cfb92d14SAndroid Build Coastguard Worker 222*cfb92d14SAndroid Build Coastguard Worker# We expect now after the delay to see retries for same addresses. 223*cfb92d14SAndroid Build Coastguard Worker 224*cfb92d14SAndroid Build Coastguard Worker 225*cfb92d14SAndroid Build Coastguard Workerdef check_cache_entry_switch_to_query_state(): 226*cfb92d14SAndroid Build Coastguard Worker cache_table = r1.get_eidcache() 227*cfb92d14SAndroid Build Coastguard Worker for entry in cache_table: 228*cfb92d14SAndroid Build Coastguard Worker fields = entry.strip().split(' ') 229*cfb92d14SAndroid Build Coastguard Worker verify(fields[2] == 'query') 230*cfb92d14SAndroid Build Coastguard Worker verify(fields[3] == 'canEvict=1') 231*cfb92d14SAndroid Build Coastguard Worker 232*cfb92d14SAndroid Build Coastguard Worker 233*cfb92d14SAndroid Build Coastguard Workerverify_within(check_cache_entry_switch_to_query_state, 20) 234*cfb92d14SAndroid Build Coastguard Worker 235*cfb92d14SAndroid Build Coastguard Worker 236*cfb92d14SAndroid Build Coastguard Workerdef check_cache_entry_switch_to_retry_state_with_double_retry_delay(): 237*cfb92d14SAndroid Build Coastguard Worker cache_table = r1.get_eidcache() 238*cfb92d14SAndroid Build Coastguard Worker for entry in cache_table: 239*cfb92d14SAndroid Build Coastguard Worker fields = entry.strip().split(' ') 240*cfb92d14SAndroid Build Coastguard Worker verify(fields[2] == 'retry') 241*cfb92d14SAndroid Build Coastguard Worker verify(fields[3] == 'canEvict=1') 242*cfb92d14SAndroid Build Coastguard Worker verify(fields[4].startswith('timeout=')) 243*cfb92d14SAndroid Build Coastguard Worker verify(fields[5].startswith('retryDelay=')) 244*cfb92d14SAndroid Build Coastguard Worker verify(int(fields[5].split('=')[1]) == 2 * initial_retry_delay) 245*cfb92d14SAndroid Build Coastguard Worker 246*cfb92d14SAndroid Build Coastguard Worker 247*cfb92d14SAndroid Build Coastguard Workerverify_within(check_cache_entry_switch_to_retry_state_with_double_retry_delay, 40) 248*cfb92d14SAndroid Build Coastguard Worker 249*cfb92d14SAndroid Build Coastguard Workerverify_within(check_cache_entry_in_retry_state_to_enter_rampdown, 40) 250*cfb92d14SAndroid Build Coastguard Worker 251*cfb92d14SAndroid Build Coastguard Worker 252*cfb92d14SAndroid Build Coastguard Workerdef check_cache_entry_ramp_down_to_initial_retry_delay(): 253*cfb92d14SAndroid Build Coastguard Worker cache_table = r1.get_eidcache() 254*cfb92d14SAndroid Build Coastguard Worker for entry in cache_table: 255*cfb92d14SAndroid Build Coastguard Worker fields = entry.strip().split(' ') 256*cfb92d14SAndroid Build Coastguard Worker verify(fields[2] == 'retry') 257*cfb92d14SAndroid Build Coastguard Worker verify(fields[3] == 'canEvict=1') 258*cfb92d14SAndroid Build Coastguard Worker verify(fields[4].startswith('timeout=')) 259*cfb92d14SAndroid Build Coastguard Worker verify(fields[5].startswith('retryDelay=')) 260*cfb92d14SAndroid Build Coastguard Worker verify(int(fields[5].split('=')[1]) == initial_retry_delay) 261*cfb92d14SAndroid Build Coastguard Worker verify(fields[6] == 'rampDown=1') 262*cfb92d14SAndroid Build Coastguard Worker 263*cfb92d14SAndroid Build Coastguard Worker 264*cfb92d14SAndroid Build Coastguard Workerverify_within(check_cache_entry_ramp_down_to_initial_retry_delay, 60) 265*cfb92d14SAndroid Build Coastguard Worker 266*cfb92d14SAndroid Build Coastguard Worker# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 267*cfb92d14SAndroid Build Coastguard Worker# Verify snoop optimization behavior. 268*cfb92d14SAndroid Build Coastguard Worker 269*cfb92d14SAndroid Build Coastguard Worker# Send to r1 from all addresses on r2. 270*cfb92d14SAndroid Build Coastguard Worker 271*cfb92d14SAndroid Build Coastguard Workerr2.udp_open() 272*cfb92d14SAndroid Build Coastguard Workerfor num in range(num_addresses): 273*cfb92d14SAndroid Build Coastguard Worker r2.udp_bind(prefix + '2:' + str(num), port) 274*cfb92d14SAndroid Build Coastguard Worker r2.udp_send(prefix + '1', port, 'hi_r1_from_r2_snoop_me') 275*cfb92d14SAndroid Build Coastguard Worker 276*cfb92d14SAndroid Build Coastguard Worker# Verify that we see all addresses from r2 as snooped in cache table. 277*cfb92d14SAndroid Build Coastguard Worker# At most two of them should be marked as non-evictable. 278*cfb92d14SAndroid Build Coastguard Worker 279*cfb92d14SAndroid Build Coastguard Worker 280*cfb92d14SAndroid Build Coastguard Workerdef check_cache_entry_contains_snooped_entries(): 281*cfb92d14SAndroid Build Coastguard Worker cache_table = r1.get_eidcache() 282*cfb92d14SAndroid Build Coastguard Worker verify(len(cache_table) >= num_addresses) 283*cfb92d14SAndroid Build Coastguard Worker snooped_count = 0 284*cfb92d14SAndroid Build Coastguard Worker snooped_non_evictable = 0 285*cfb92d14SAndroid Build Coastguard Worker for entry in cache_table: 286*cfb92d14SAndroid Build Coastguard Worker fields = entry.strip().split(' ') 287*cfb92d14SAndroid Build Coastguard Worker if fields[2] == 'snoop': 288*cfb92d14SAndroid Build Coastguard Worker verify(fields[0].startswith('fd00:abba:0:0:0:0:2:')) 289*cfb92d14SAndroid Build Coastguard Worker verify(int(fields[1], 16) == r2_rloc) 290*cfb92d14SAndroid Build Coastguard Worker snooped_count = snooped_count + 1 291*cfb92d14SAndroid Build Coastguard Worker if fields[3] == 'canEvict=0': 292*cfb92d14SAndroid Build Coastguard Worker snooped_non_evictable = snooped_non_evictable + 1 293*cfb92d14SAndroid Build Coastguard Worker verify(snooped_count == num_addresses) 294*cfb92d14SAndroid Build Coastguard Worker verify(snooped_non_evictable == max_snooped_non_evictable) 295*cfb92d14SAndroid Build Coastguard Worker 296*cfb92d14SAndroid Build Coastguard Worker 297*cfb92d14SAndroid Build Coastguard Workerverify_within(check_cache_entry_contains_snooped_entries, 20) 298*cfb92d14SAndroid Build Coastguard Worker 299*cfb92d14SAndroid Build Coastguard Worker# Now we use the snooped entries by sending from r1 to r2 using 300*cfb92d14SAndroid Build Coastguard Worker# all its addresses. 301*cfb92d14SAndroid Build Coastguard Worker 302*cfb92d14SAndroid Build Coastguard Workerfor num in range(num_addresses): 303*cfb92d14SAndroid Build Coastguard Worker r1.udp_send(prefix + '2:' + str(num), port, 'hi_back_r2_from_r1') 304*cfb92d14SAndroid Build Coastguard Worker 305*cfb92d14SAndroid Build Coastguard Workertime.sleep(0.1) 306*cfb92d14SAndroid Build Coastguard Worker 307*cfb92d14SAndroid Build Coastguard Worker# We expect to see the entries to be in "cached" state now. 308*cfb92d14SAndroid Build Coastguard Worker 309*cfb92d14SAndroid Build Coastguard Workercache_table = r1.get_eidcache() 310*cfb92d14SAndroid Build Coastguard Workerverify(len(cache_table) >= num_addresses) 311*cfb92d14SAndroid Build Coastguard Workermatch_count = 0 312*cfb92d14SAndroid Build Coastguard Workerfor entry in cache_table: 313*cfb92d14SAndroid Build Coastguard Worker fields = entry.strip().split(' ') 314*cfb92d14SAndroid Build Coastguard Worker if fields[0].startswith('fd00:abba:0:0:0:0:2:'): 315*cfb92d14SAndroid Build Coastguard Worker verify(fields[2] == 'cache') 316*cfb92d14SAndroid Build Coastguard Worker verify(fields[3] == 'canEvict=1') 317*cfb92d14SAndroid Build Coastguard Worker match_count = match_count + 1 318*cfb92d14SAndroid Build Coastguard Workerverify(match_count == num_addresses) 319*cfb92d14SAndroid Build Coastguard Worker 320*cfb92d14SAndroid Build Coastguard Worker# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 321*cfb92d14SAndroid Build Coastguard Worker# Check query requests and last transaction time 322*cfb92d14SAndroid Build Coastguard Worker 323*cfb92d14SAndroid Build Coastguard Worker# Send from r1 to all addresses on r3. Check entries 324*cfb92d14SAndroid Build Coastguard Worker# for r3 are at the top of cache table list. 325*cfb92d14SAndroid Build Coastguard Worker 326*cfb92d14SAndroid Build Coastguard Workerfor num in range(num_addresses): 327*cfb92d14SAndroid Build Coastguard Worker r1.udp_send(prefix + '3:' + str(num), port, 'hi_r3_from_r1') 328*cfb92d14SAndroid Build Coastguard Worker 329*cfb92d14SAndroid Build Coastguard Worker 330*cfb92d14SAndroid Build Coastguard Workerdef check_cache_entry_contains_r3_entries(): 331*cfb92d14SAndroid Build Coastguard Worker cache_table = r1.get_eidcache() 332*cfb92d14SAndroid Build Coastguard Worker for num in range(num_addresses): 333*cfb92d14SAndroid Build Coastguard Worker entry = cache_table[num] 334*cfb92d14SAndroid Build Coastguard Worker fields = entry.strip().split(' ') 335*cfb92d14SAndroid Build Coastguard Worker verify(fields[0].startswith('fd00:abba:0:0:0:0:3:')) 336*cfb92d14SAndroid Build Coastguard Worker verify(int(fields[1], 16) == r3_rloc) 337*cfb92d14SAndroid Build Coastguard Worker verify(fields[2] == 'cache') 338*cfb92d14SAndroid Build Coastguard Worker verify(fields[3] == 'canEvict=1') 339*cfb92d14SAndroid Build Coastguard Worker verify(fields[4] == 'transTime=0') 340*cfb92d14SAndroid Build Coastguard Worker 341*cfb92d14SAndroid Build Coastguard Worker 342*cfb92d14SAndroid Build Coastguard Workerverify_within(check_cache_entry_contains_r3_entries, 20) 343*cfb92d14SAndroid Build Coastguard Worker 344*cfb92d14SAndroid Build Coastguard Worker# Send from r1 to all addresses of c3 (sleepy child of r3) 345*cfb92d14SAndroid Build Coastguard Worker 346*cfb92d14SAndroid Build Coastguard Workerfor num in range(num_addresses): 347*cfb92d14SAndroid Build Coastguard Worker r1.udp_send(prefix + 'c3:' + str(num), port, 'hi_c3_from_r1') 348*cfb92d14SAndroid Build Coastguard Worker 349*cfb92d14SAndroid Build Coastguard Worker 350*cfb92d14SAndroid Build Coastguard Workerdef check_cache_entry_contains_c3_entries(): 351*cfb92d14SAndroid Build Coastguard Worker cache_table = r1.get_eidcache() 352*cfb92d14SAndroid Build Coastguard Worker for num in range(num_addresses): 353*cfb92d14SAndroid Build Coastguard Worker entry = cache_table[num] 354*cfb92d14SAndroid Build Coastguard Worker fields = entry.strip().split(' ') 355*cfb92d14SAndroid Build Coastguard Worker verify(fields[0].startswith('fd00:abba:0:0:0:0:c3:')) 356*cfb92d14SAndroid Build Coastguard Worker verify(int(fields[1], 16) == r3_rloc) 357*cfb92d14SAndroid Build Coastguard Worker verify(fields[2] == 'cache') 358*cfb92d14SAndroid Build Coastguard Worker verify(fields[3] == 'canEvict=1') 359*cfb92d14SAndroid Build Coastguard Worker verify(fields[4] == 'transTime=0') 360*cfb92d14SAndroid Build Coastguard Worker 361*cfb92d14SAndroid Build Coastguard Worker 362*cfb92d14SAndroid Build Coastguard Workerverify_within(check_cache_entry_contains_c3_entries, 20) 363*cfb92d14SAndroid Build Coastguard Worker 364*cfb92d14SAndroid Build Coastguard Worker# Send again to r2. This should cause the related cache entries to 365*cfb92d14SAndroid Build Coastguard Worker# be moved to top of the list. 366*cfb92d14SAndroid Build Coastguard Worker 367*cfb92d14SAndroid Build Coastguard Workerfor num in range(num_addresses): 368*cfb92d14SAndroid Build Coastguard Worker r1.udp_send(prefix + '2:' + str(num), port, 'hi_again_r2_from_r1') 369*cfb92d14SAndroid Build Coastguard Worker 370*cfb92d14SAndroid Build Coastguard Worker 371*cfb92d14SAndroid Build Coastguard Workerdef check_cache_entry_contains_r2_entries(): 372*cfb92d14SAndroid Build Coastguard Worker cache_table = r1.get_eidcache() 373*cfb92d14SAndroid Build Coastguard Worker for num in range(num_addresses): 374*cfb92d14SAndroid Build Coastguard Worker entry = cache_table[num] 375*cfb92d14SAndroid Build Coastguard Worker fields = entry.strip().split(' ') 376*cfb92d14SAndroid Build Coastguard Worker verify(fields[0].startswith('fd00:abba:0:0:0:0:2:')) 377*cfb92d14SAndroid Build Coastguard Worker verify(int(fields[1], 16) == r2_rloc) 378*cfb92d14SAndroid Build Coastguard Worker verify(fields[2] == 'cache') 379*cfb92d14SAndroid Build Coastguard Worker verify(fields[3] == 'canEvict=1') 380*cfb92d14SAndroid Build Coastguard Worker 381*cfb92d14SAndroid Build Coastguard Worker 382*cfb92d14SAndroid Build Coastguard Workerverify_within(check_cache_entry_contains_r2_entries, 20) 383*cfb92d14SAndroid Build Coastguard Worker 384*cfb92d14SAndroid Build Coastguard Worker# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 385*cfb92d14SAndroid Build Coastguard Worker# Check behavior when address cache table is full. 386*cfb92d14SAndroid Build Coastguard Worker 387*cfb92d14SAndroid Build Coastguard Workercache_table = r1.get_eidcache() 388*cfb92d14SAndroid Build Coastguard Workerverify(len(cache_table) == max_cache_entries) 389*cfb92d14SAndroid Build Coastguard Worker 390*cfb92d14SAndroid Build Coastguard Worker# From r1 send to non-existing addresses. 391*cfb92d14SAndroid Build Coastguard Worker 392*cfb92d14SAndroid Build Coastguard Workerfor num in range(num_queries): 393*cfb92d14SAndroid Build Coastguard Worker r1.udp_send(prefix + '900:' + str(num), port, 'hi_nobody!') 394*cfb92d14SAndroid Build Coastguard Worker 395*cfb92d14SAndroid Build Coastguard Workercache_table = r1.get_eidcache() 396*cfb92d14SAndroid Build Coastguard Workerverify(len(cache_table) == max_cache_entries) 397*cfb92d14SAndroid Build Coastguard Worker 398*cfb92d14SAndroid Build Coastguard Worker# Send from c2 to r1 and verify that snoop optimization uses at most 399*cfb92d14SAndroid Build Coastguard Worker# `max_snooped_non_evictable` entries 400*cfb92d14SAndroid Build Coastguard Worker 401*cfb92d14SAndroid Build Coastguard Workerc2.udp_open() 402*cfb92d14SAndroid Build Coastguard Worker 403*cfb92d14SAndroid Build Coastguard Workerfor num in range(num_addresses): 404*cfb92d14SAndroid Build Coastguard Worker c2.udp_bind(prefix + 'c2:' + str(num), port) 405*cfb92d14SAndroid Build Coastguard Worker c2.udp_send(prefix + '1', port, 'hi_r1_from_c2_snoop_me') 406*cfb92d14SAndroid Build Coastguard Worker 407*cfb92d14SAndroid Build Coastguard Worker 408*cfb92d14SAndroid Build Coastguard Workerdef check_cache_entry_contains_max_allowed_snopped(): 409*cfb92d14SAndroid Build Coastguard Worker cache_table = r1.get_eidcache() 410*cfb92d14SAndroid Build Coastguard Worker snooped_non_evictable = 0 411*cfb92d14SAndroid Build Coastguard Worker for entry in cache_table: 412*cfb92d14SAndroid Build Coastguard Worker fields = entry.strip().split(' ') 413*cfb92d14SAndroid Build Coastguard Worker if fields[2] == 'snoop': 414*cfb92d14SAndroid Build Coastguard Worker verify(fields[0].startswith('fd00:abba:0:0:0:0:c2:')) 415*cfb92d14SAndroid Build Coastguard Worker verify(fields[3] == 'canEvict=0') 416*cfb92d14SAndroid Build Coastguard Worker snooped_non_evictable = snooped_non_evictable + 1 417*cfb92d14SAndroid Build Coastguard Worker verify(snooped_non_evictable == max_snooped_non_evictable) 418*cfb92d14SAndroid Build Coastguard Worker 419*cfb92d14SAndroid Build Coastguard Worker 420*cfb92d14SAndroid Build Coastguard Workerverify_within(check_cache_entry_contains_max_allowed_snopped, 20) 421*cfb92d14SAndroid Build Coastguard Worker 422*cfb92d14SAndroid Build Coastguard Worker# Now send from r1 to c2, the snooped entries would be used 423*cfb92d14SAndroid Build Coastguard Worker# some other addresses will go through full address query. 424*cfb92d14SAndroid Build Coastguard Worker 425*cfb92d14SAndroid Build Coastguard Workerfor num in range(num_addresses): 426*cfb92d14SAndroid Build Coastguard Worker r1.udp_send(prefix + 'c2:' + str(num), port, 'hi_c2_from_r1') 427*cfb92d14SAndroid Build Coastguard Worker 428*cfb92d14SAndroid Build Coastguard Worker 429*cfb92d14SAndroid Build Coastguard Workerdef check_cache_entry_contains_c2_entries(): 430*cfb92d14SAndroid Build Coastguard Worker cache_table = r1.get_eidcache() 431*cfb92d14SAndroid Build Coastguard Worker for num in range(num_addresses): 432*cfb92d14SAndroid Build Coastguard Worker entry = cache_table[num] 433*cfb92d14SAndroid Build Coastguard Worker fields = entry.strip().split(' ') 434*cfb92d14SAndroid Build Coastguard Worker verify(fields[0].startswith('fd00:abba:0:0:0:0:c2:')) 435*cfb92d14SAndroid Build Coastguard Worker verify(int(fields[1], 16) == r2_rloc) 436*cfb92d14SAndroid Build Coastguard Worker verify(fields[2] == 'cache') 437*cfb92d14SAndroid Build Coastguard Worker verify(fields[3] == 'canEvict=1') 438*cfb92d14SAndroid Build Coastguard Worker 439*cfb92d14SAndroid Build Coastguard Worker 440*cfb92d14SAndroid Build Coastguard Workerverify_within(check_cache_entry_contains_c2_entries, 20) 441*cfb92d14SAndroid Build Coastguard Worker 442*cfb92d14SAndroid Build Coastguard Worker# ----------------------------------------------------------------------------------------------------------------------- 443*cfb92d14SAndroid Build Coastguard Worker# Test finished 444*cfb92d14SAndroid Build Coastguard Worker 445*cfb92d14SAndroid Build Coastguard Workercli.Node.finalize_all_nodes() 446*cfb92d14SAndroid Build Coastguard Worker 447*cfb92d14SAndroid Build Coastguard Workerprint('\'{}\' passed.'.format(test_name)) 448