Skip to content

Commit 41c7b97

Browse files
ZhaohuiSmssonicbld
authored andcommitted
Exit pytest with error code 15 if duthosts fixture fails (sonic-net#10243)
What is the motivation for this PR? Sometimes, some cases may cause testbed unhealthy, such as previous case do some operations on DUT, it may cause DUT network unreachable, in this case, currently mechanism throw AnsibleConnectionFailure and still run the next test case, actually, all left cases can't be ran, the whole pytest needs to exit, fail pipeline, it saves time and let user know these is something wrong with this DUT now. How did you do it? Capture exception in duthosts fixture, when DUT becomes unreachable, this is the first failed fixture. set session.exitstatus to 15 and make run_test.sh aware of this failure and exit pipeline early. Signed-off-by: Zhaohui Sun <zhaohuisun@microsoft.com>
1 parent cc7feae commit 41c7b97

2 files changed

Lines changed: 22 additions & 1 deletion

File tree

tests/conftest.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
from tests.common.cache import FactsCache
4949
from tests.common.config_reload import config_reload
5050
from tests.common.connections.console_host import ConsoleHost
51+
from tests.common.helpers.assertions import pytest_assert as pt_assert
5152

5253
try:
5354
from tests.macsec import MacsecPlugin
@@ -63,6 +64,8 @@
6364
logger = logging.getLogger(__name__)
6465
cache = FactsCache()
6566

67+
DUTHOSTS_FIXTURE_FAILED_RC = 15
68+
6669
pytest_plugins = ('tests.common.plugins.ptfadapter',
6770
'tests.common.plugins.ansible_fixtures',
6871
'tests.common.plugins.dut_monitor',
@@ -314,6 +317,12 @@ def get_specified_duts(request):
314317
return duts
315318

316319

320+
def pytest_sessionfinish(session, exitstatus):
321+
if session.config.cache.get("duthosts_fixture_failed", None):
322+
session.config.cache.set("duthosts_fixture_failed", None)
323+
session.exitstatus = DUTHOSTS_FIXTURE_FAILED_RC
324+
325+
317326
@pytest.fixture(name="duthosts", scope="session")
318327
def fixture_duthosts(enhance_inventory, ansible_adhoc, tbinfo, request):
319328
"""
@@ -323,7 +332,14 @@ def fixture_duthosts(enhance_inventory, ansible_adhoc, tbinfo, request):
323332
mandatory argument for the class constructors.
324333
@param tbinfo: fixture provides information about testbed.
325334
"""
326-
return DutHosts(ansible_adhoc, tbinfo, get_specified_duts(request))
335+
try:
336+
host = DutHosts(ansible_adhoc, tbinfo, get_specified_duts(request))
337+
return host
338+
except BaseException as e:
339+
logger.error("Failed to initialize duthosts.")
340+
request.config.cache.set("duthosts_fixture_failed", True)
341+
pt_assert(False, "!!!!!!!!!!!!!!!! duthosts fixture failed !!!!!!!!!!!!!!!!"
342+
"Exception: {}".format(repr(e)))
327343

328344

329345
@pytest.fixture(scope="session")

tests/run_tests.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,11 @@ function run_individual_tests()
320320
echo "=== Sanity check failed for $test_script. Skip rest of the scripts if there is any. ==="
321321
return ${ret_code}
322322
fi
323+
# rc 15 means duthosts fixture failed
324+
if [ ${ret_code} -eq 15 ]; then
325+
echo "=== duthosts fixture failed for $test_script. Skip rest of the scripts if there is any. ==="
326+
return ${ret_code}
327+
fi
323328

324329
EXIT_CODE=1
325330
if [[ ${TEST_MAX_FAIL} != 0 ]]; then

0 commit comments

Comments
 (0)