Skip to content

Commit

Permalink
Optimize the logic to compare the routing entries between ASIC_DB and…
Browse files Browse the repository at this point in the history
… the prefixes pushed to DUT (#5769)

- What is the motivation for this PR?
Optimize the logic to compare the routing entries between ASIC_DB and the prefixes pushed to DUT

- How did you do it?
The idea is to extract the prefixes from the output of the DUT and to avoid using json.load for each routing entry
to use set instead of list to check difference. O(n*n) => O(n*lg(n))
How did you verify/test it?
Run the test.

Signed-off-by: Stephen Sun <stephens@nvidia.com>
  • Loading branch information
stephenxs authored and wangxin committed Jun 21, 2022
1 parent 8cf81ab commit 36f8ba7
Showing 1 changed file with 25 additions and 16 deletions.
41 changes: 25 additions & 16 deletions tests/route/test_route_perf.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ def exec_routes(duthost, prefixes, str_intf_nexthop, op):

# Generate json file for routes
generate_route_file(duthost, prefixes, str_intf_nexthop, route_file_dir, op)
logger.info('Route file generated and copied')

# Check the number of routes in ASIC_DB
start_num_route = count_routes(duthost)
Expand All @@ -176,36 +177,44 @@ def exec_routes(duthost, prefixes, str_intf_nexthop, op):
pytest.fail('Operation {} not supported'.format(op))
start_time = datetime.now()

logger.info('Before pushing route to swssconfig')
# Apply routes with swssconfig
result = duthost.shell('docker exec -i swss swssconfig /dev/stdin < {}'.format(route_file_dir),
module_ignore_errors=True)
if result['rc'] != 0:
pytest.fail('Failed to apply route configuration file: {}'.format(result['stderr']))

# Wait until the routes set/del applys to ASIC_DB
def _check_num_routes(expected_num_routes):
# Check the number of routes in ASIC_DB
return count_routes(duthost) == expected_num_routes

if not wait_until(route_timeout, 0.5, 0, _check_num_routes, expected_num_routes):
pytest.fail('failed to add routes within time limit')
logger.info('All route entries have been pushed')

total_delay = 0
actual_num_routes = count_routes(duthost)
while actual_num_routes != expected_num_routes:
diff = abs(expected_num_routes - actual_num_routes)
delay = max(diff / 5000, 1)
now = datetime.now()
total_delay = (now - start_time).total_seconds()
logger.info('Current {} expected {} delayed {} will delay {}'.format(actual_num_routes, expected_num_routes, total_delay, delay))
time.sleep(delay)
actual_num_routes = count_routes(duthost)
if total_delay >= route_timeout:
break

# Record time when all routes show up in ASIC_DB
end_time = datetime.now()
logger.info('All route entries have been installed in ASIC_DB in {} seconds'.format((end_time - start_time).total_seconds()))

# Check route entries are correct
asic_route_keys = duthost.shell('sonic-db-cli ASIC_DB eval "return redis.call(\'keys\', \'{}*\')" 0'\
.format(ROUTE_TABLE_NAME), verbose=False)['stdout_lines']
asic_prefixes = []
for key in asic_route_keys:
json_obj = key[len(ROUTE_TABLE_NAME) + 1 : ]
asic_prefixes.append(json.loads(json_obj)['dest'])
table_name_length = len(ROUTE_TABLE_NAME)
asic_route_keys_set = set([re.search("\"dest\":\"([0-9a-f:/\.]*)\"", x[table_name_length:]).group(1) for x in asic_route_keys])
prefixes_set = set(prefixes)
diff = prefixes_set - asic_route_keys_set
if op == 'SET':
assert all(prefix in asic_prefixes for prefix in prefixes)
if diff:
pytest.fail("The following entries have not been installed into ASIC {}".format(diff))
elif op == 'DEL':
assert all(prefix not in asic_prefixes for prefix in prefixes)
else:
pytest.fail('Operation {} not supported'.format(op))
if diff != prefixes_set:
pytest.fail("The following entries have not been withdrawn from ASIC {}".format(prefixes_set - diff))

# Retuen time used for set/del routes
return (end_time - start_time).total_seconds()
Expand Down

0 comments on commit 36f8ba7

Please sign in to comment.