[nexus] fix flaky BBR-TC-03 by filtering transient mDNS responses (#12736)

Nexus test 1_2_BBR_TC_3 occasionally fails during Step 6 after a
device reboot. The failure occurs because the Backbone Router (BBR)
is reported as active in the mDNS state bitmap ('sb' record), but
the mandatory 'omr' record is not yet present in the response.

This transient state happens because the BBR function is enabled
immediately upon attachment, whereas the Routing Manager requires
a brief period to establish and favor an OMR prefix.

This commit updates the Python verification script to filter for
mDNS responses that include the 'omr' record in Steps 6 and 13. This
allows the test to wait for the complete state to be published
naturally, rather than failing on the first transient packet
received.

Validated with 50 successful sequential executions of the test.
This commit is contained in:
Jonathan Hui
2026-03-22 23:34:11 -05:00
committed by GitHub
parent b70b3ccb6a
commit ea05e2fd0c
+20 -3
View File
@@ -108,6 +108,22 @@ def verify(pv):
entries[bytes(txt).decode()] = None
return entries
def get_bbr_txt_entries_if_complete(p):
"""Returns mDNS TXT entries if 'omr' and 'sb' records are present and have values, otherwise None."""
txt = get_txt_entries(p)
if txt and txt.get('omr') and txt.get('sb') is not None:
return txt
return None
def has_sb_bit(p, bit_pos):
"""Checks for a bit in the 'sb' record of a complete ('omr' and 'sb' present) mDNS response."""
txt = get_bbr_txt_entries_if_complete(p)
if not txt:
return False
# 'sb' is a 4-byte value.
sb_val = struct.unpack('>I', txt['sb'])[0]
return (sb_val >> bit_pos) & 1 == 1
def verify_mdns_response(p, expected_sb_bits, expected_omr_var):
# Verify Service Instance Name
names = []
@@ -263,6 +279,7 @@ def verify(pv):
filter_eth_src(BR_1_ETH).\
filter(is_mdns_response).\
filter(lambda p: p.number > q_number).\
filter(get_bbr_txt_entries_if_complete).\
must_next()
verify_mdns_response(p1, {
'ifstate': [1, 2],
@@ -320,7 +337,7 @@ def verify(pv):
filter_eth_src(BR_2_ETH).\
filter(is_mdns_response).\
filter(lambda p: p.number > q_number).\
filter(lambda p: (struct.unpack('>I', get_txt_entries(p)['sb'])[0] >> 8) & 1 == 1).\
filter(lambda p: has_sb_bit(p, 8)).\
must_next()
verify_mdns_response(p2, {'ifstate': 2, 'active': 1, 'primary': 1}, expected_omr_var='OMR_PREFIX_STEP_10')
@@ -342,7 +359,7 @@ def verify(pv):
filter_eth_src(BR_1_ETH).\
filter(is_mdns_response).\
filter(lambda p: p.number > q_number).\
filter(lambda p: (struct.unpack('>I', get_txt_entries(p)['sb'])[0] >> 7) & 1 == 1).\
filter(lambda p: has_sb_bit(p, 7)).\
must_next()
verify_mdns_response(p1, {'ifstate': 2, 'active': 1, 'primary': 0}, expected_omr_var='OMR_PREFIX_STEP_11')
@@ -351,7 +368,7 @@ def verify(pv):
filter_eth_src(BR_2_ETH).\
filter(is_mdns_response).\
filter(lambda p: p.number > q_number).\
filter(lambda p: (struct.unpack('>I', get_txt_entries(p)['sb'])[0] >> 8) & 1 == 1).\
filter(lambda p: has_sb_bit(p, 8)).\
must_next()
verify_mdns_response(p2, {'ifstate': 2, 'active': 1, 'primary': 1}, expected_omr_var='OMR_PREFIX_STEP_10')