Skip to content

Commit

Permalink
frr: T6746: add guard time after cli_commit() and before getFRRconfig()
Browse files Browse the repository at this point in the history
As vyos-configd will take care about the commit via FRRender class, and FRR
needs to internally process the configuration we might read it back via vtysh
"to fast". Add a 5 seconds guard timer after each cli_commit() and before
calling getFRRconfig().

Guard timer is reset every time, cli_commit() is called.
  • Loading branch information
c-po committed Dec 16, 2024
1 parent e803c5e commit 90e9aa9
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 22 deletions.
23 changes: 19 additions & 4 deletions smoketest/scripts/cli/base_vyostest_shim.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import pprint

from time import sleep
from time import time
from typing import Type

from vyos.configsession import ConfigSession
Expand All @@ -43,7 +44,7 @@ class TestCase(unittest.TestCase):
# trigger the certain failure condition.
# Use "self.debug = True" in derived classes setUp() method
debug = False

commit_guard = time()
@classmethod
def setUpClass(cls):
cls._session = ConfigSession(os.getpid())
Expand Down Expand Up @@ -87,6 +88,8 @@ def cli_commit(self):
# during a commit there is a process opening commit_lock, and run() returns 0
while run(f'sudo lsof -nP {commit_lock}') == 0:
sleep(0.250)
# reset getFRRconfig() guard timer
self.commit_guard = time()

def op_mode(self, path : list) -> None:
"""
Expand All @@ -101,17 +104,29 @@ def op_mode(self, path : list) -> None:
pprint.pprint(out)
return out

def getFRRconfig(self, string=None, end='$', endsection='^!', daemon=''):
def getFRRconfig(self, string=None, end='$', endsection='^!', daemon='', guard_time=10, empty_retry=0):
""" Retrieve current "running configuration" from FRR """
# Sometimes FRR needs some time after reloading the configuration to
# appear in vtysh. This is a workaround addiung a 2 seconds guard timer
sleep(2)
# appear in vtysh. This is a workaround addiung a 10 second guard timer
# between the last cli_commit() and the first read of FRR config via vtysh
while (time() - self.commit_guard) < guard_time:
sleep(0.250) # wait 250 milliseconds
command = f'vtysh -c "show run {daemon} no-header"'
if string: command += f' | sed -n "/^{string}{end}/,/{endsection}/p"'
out = cmd(command)
if self.debug:
print(f'\n\ncommand "{command}" returned:\n')
pprint.pprint(out)
if empty_retry:
retry_count = 0
while not out and retry_count < empty_retry:
if self.debug and retry_count % 10 == 0:
print(f"Attempt {retry_count}: FRR config is still empty. Retrying...")
retry_count += 1
sleep(1)
out = cmd(command)
if not out:
print(f'FRR configuration still empty after {empty_retry} retires!')
return out

@staticmethod
Expand Down
2 changes: 1 addition & 1 deletion smoketest/scripts/cli/test_protocols_babel.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ def test_babel_redistribute(self):

self.cli_commit()

frrconfig = self.getFRRconfig('router babel', endsection='^exit', daemon=babel_daemon)
frrconfig = self.getFRRconfig('router babel', endsection='^exit', daemon=babel_daemon, empty_retry=5)
for protocol in ipv4_protos:
self.assertIn(f' redistribute ipv4 {protocol}', frrconfig)
for protocol in ipv6_protos:
Expand Down
18 changes: 1 addition & 17 deletions smoketest/scripts/cli/test_protocols_ospf.py
Original file line number Diff line number Diff line change
Expand Up @@ -570,23 +570,7 @@ def test_ospf_17_duplicate_area_network(self):
self.cli_commit()

# Verify FRR ospfd configuration
frrconfig = self.getFRRconfig('router ospf', endsection='^exit', daemon=ospf_daemon)
# Required to prevent the race condition T6761
retry_count = 0
max_retries = 60

while not frrconfig and retry_count < max_retries:
# Log every 10 seconds
if retry_count % 10 == 0:
print(f"Attempt {retry_count}: FRR config is still empty. Retrying...")

retry_count += 1
sleep(1)
frrconfig = self.getFRRconfig('router ospf', endsection='^exit', daemon=ospf_daemon)

if not frrconfig:
print("Failed to retrieve FRR config after 60 seconds")

frrconfig = self.getFRRconfig('router ospf', endsection='^exit', daemon=ospf_daemon, empty_retry=60)
self.assertIn(f'router ospf', frrconfig)
self.assertIn(f' network {network} area {area1}', frrconfig)

Expand Down

0 comments on commit 90e9aa9

Please sign in to comment.