Implement per-test timeout guard
Timeout value can be specified by test in suite.conf:
config:
suite:
<suite_name>:
<test_name>:
timeout: 2 # 2 seconds timeout
Change-Id: I522f51f77f8be64ebfdb5d5e07ba92baf82d7706
diff --git a/selftest/suite_test/suite_test.ok b/selftest/suite_test/suite_test.ok
index c7c76d7..58593fd 100644
--- a/selftest/suite_test/suite_test.ok
+++ b/selftest/suite_test/suite_test.ok
@@ -15,6 +15,11 @@
cnf [PATH]/selftest/suite_test/suitedirA/empty_dir/suite.conf: ERR: FileNotFoundError: [Errno 2] No such file or directory: '[PATH]/selftest/suite_test/suitedirA/empty_dir/suite.conf' [empty_dir↪[PATH]/selftest/suite_test/suitedirA/empty_dir/suite.conf]
- valid suite dir
cnf test_suite: DBG: reading suite.conf
+config:
+ suite:
+ test_suite:
+ test_timeout:
+ timeout: '1'
resources:
bts:
- label: sysmoCell 5000
@@ -28,7 +33,7 @@
- run hello world test
tst test_suite: DBG: {combining='config'}
-tst {combining_scenarios='config'}: DBG: {definition_conf={}} [test_suite↪{combining_scenarios='config'}]
+tst {combining_scenarios='config'}: DBG: {definition_conf={suite={test_suite={test_timeout={timeout='1'}}}}} [test_suite↪{combining_scenarios='config'}]
---------------------------------------------------------------------
trial test_suite
@@ -101,7 +106,7 @@
---------------------------------------------------------------------
trial test_suite PASS
---------------------------------------------------------------------
-PASS: test_suite (pass: 1, skip: 6)
+PASS: test_suite (pass: 1, skip: 7)
pass: hello_world.py (N.N sec)
skip: mo_mt_sms.py
skip: mo_sms.py
@@ -109,6 +114,7 @@
skip: test_fail.py
skip: test_fail_raise.py
skip: test_suite_params.py
+ skip: test_timeout.py
- a test with an error
@@ -125,7 +131,7 @@
---------------------------------------------------------------------
trial test_suite FAIL
---------------------------------------------------------------------
-FAIL: test_suite (fail: 1, skip: 6)
+FAIL: test_suite (fail: 1, skip: 7)
skip: hello_world.py (N.N sec)
skip: mo_mt_sms.py
skip: mo_sms.py
@@ -133,6 +139,7 @@
skip: test_fail.py
skip: test_fail_raise.py
skip: test_suite_params.py
+ skip: test_timeout.py
- a test with a failure
@@ -149,7 +156,7 @@
---------------------------------------------------------------------
trial test_suite FAIL
---------------------------------------------------------------------
-FAIL: test_suite (fail: 1, skip: 6)
+FAIL: test_suite (fail: 1, skip: 7)
skip: hello_world.py (N.N sec)
skip: mo_mt_sms.py
skip: mo_sms.py
@@ -157,6 +164,7 @@
FAIL: test_fail.py (N.N sec) EpicFail: This failure is expected
skip: test_fail_raise.py
skip: test_suite_params.py
+ skip: test_timeout.py
- a test with a raised failure
@@ -172,7 +180,7 @@
---------------------------------------------------------------------
trial test_suite FAIL
---------------------------------------------------------------------
-FAIL: test_suite (fail: 1, skip: 6)
+FAIL: test_suite (fail: 1, skip: 7)
skip: hello_world.py (N.N sec)
skip: mo_mt_sms.py
skip: mo_sms.py
@@ -180,9 +188,10 @@
skip: test_fail.py (N.N sec)
FAIL: test_fail_raise.py (N.N sec) ExpectedFail: This failure is expected
skip: test_suite_params.py
+ skip: test_timeout.py
- test with half empty scenario
tst test_suite: DBG: {combining='config'} [suite.py:[LINENR]]
-tst {combining_scenarios='config'}: DBG: {definition_conf={}} [test_suite↪{combining_scenarios='config'}] [suite.py:[LINENR]]
+tst {combining_scenarios='config'}: DBG: {definition_conf={suite={test_suite={test_timeout={timeout='1'}}}}} [test_suite↪{combining_scenarios='config'}] [suite.py:[LINENR]]
tst {combining_scenarios='config', scenario='foo'}: DBG: {conf={}, scenario='foo'} [test_suite↪{combining_scenarios='config', scenario='foo'}] [suite.py:[LINENR]]
---------------------------------------------------------------------
@@ -261,7 +270,7 @@
---------------------------------------------------------------------
trial test_suite PASS
---------------------------------------------------------------------
-PASS: test_suite (pass: 1, skip: 6)
+PASS: test_suite (pass: 1, skip: 7)
pass: hello_world.py (N.N sec)
skip: mo_mt_sms.py
skip: mo_sms.py
@@ -269,9 +278,10 @@
skip: test_fail.py
skip: test_fail_raise.py
skip: test_suite_params.py
+ skip: test_timeout.py
- test with scenario
tst test_suite: DBG: {combining='config'} [suite.py:[LINENR]]
-tst {combining_scenarios='config'}: DBG: {definition_conf={}} [test_suite↪{combining_scenarios='config'}] [suite.py:[LINENR]]
+tst {combining_scenarios='config'}: DBG: {definition_conf={suite={test_suite={test_timeout={timeout='1'}}}}} [test_suite↪{combining_scenarios='config'}] [suite.py:[LINENR]]
tst {combining_scenarios='config', scenario='foo'}: DBG: {conf={}, scenario='foo'} [test_suite↪{combining_scenarios='config', scenario='foo'}] [suite.py:[LINENR]]
---------------------------------------------------------------------
@@ -350,7 +360,7 @@
---------------------------------------------------------------------
trial test_suite PASS
---------------------------------------------------------------------
-PASS: test_suite (pass: 1, skip: 6)
+PASS: test_suite (pass: 1, skip: 7)
pass: hello_world.py (N.N sec)
skip: mo_mt_sms.py
skip: mo_sms.py
@@ -358,9 +368,10 @@
skip: test_fail.py
skip: test_fail_raise.py
skip: test_suite_params.py
+ skip: test_timeout.py
- test with scenario and modifiers
tst test_suite: DBG: {combining='config'} [suite.py:[LINENR]]
-tst {combining_scenarios='config'}: DBG: {definition_conf={}} [test_suite↪{combining_scenarios='config'}] [suite.py:[LINENR]]
+tst {combining_scenarios='config'}: DBG: {definition_conf={suite={test_suite={test_timeout={timeout='1'}}}}} [test_suite↪{combining_scenarios='config'}] [suite.py:[LINENR]]
tst {combining_scenarios='config', scenario='foo'}: DBG: {conf={}, scenario='foo'} [test_suite↪{combining_scenarios='config', scenario='foo'}] [suite.py:[LINENR]]
tst test_suite: reserving resources in [PATH]/selftest/suite_test/test_work/state_dir ... [suite.py:[LINENR]]
tst test_suite: DBG: {combining='resources'} [suite.py:[LINENR]]
@@ -485,7 +496,7 @@
---------------------------------------------------------------------
trial test_suite PASS
---------------------------------------------------------------------
-PASS: test_suite (pass: 1, skip: 6)
+PASS: test_suite (pass: 1, skip: 7)
pass: hello_world.py (N.N sec)
skip: mo_mt_sms.py
skip: mo_sms.py
@@ -493,9 +504,10 @@
skip: test_fail.py
skip: test_fail_raise.py
skip: test_suite_params.py
+ skip: test_timeout.py
- test with suite-specific config
tst test_suite: DBG: {combining='config'} [suite.py:[LINENR]]
-tst {combining_scenarios='config'}: DBG: {definition_conf={}} [test_suite↪{combining_scenarios='config'}] [suite.py:[LINENR]]
+tst {combining_scenarios='config'}: DBG: {definition_conf={suite={test_suite={test_timeout={timeout='1'}}}}} [test_suite↪{combining_scenarios='config'}] [suite.py:[LINENR]]
tst {combining_scenarios='config', scenario='foo'}: DBG: {conf={suite={test_suite={some_suite_global_param='heyho', test_suite_params={one_bool_parameter='true', second_list_parameter=['23', '45']}}}}, scenario='foo'} [test_suite↪{combining_scenarios='config', scenario='foo'}] [suite.py:[LINENR]]
tst test_suite: reserving resources in [PATH]/selftest/suite_test/test_work/state_dir ... [suite.py:[LINENR]]
tst test_suite: DBG: {combining='resources'} [suite.py:[LINENR]]
@@ -614,13 +626,21 @@
tst test_suite_params.py:[LINENR]: starting test [test_suite↪test_suite_params.py:[LINENR]] [test_suite_params.py:[LINENR]]
tst test_suite_params.py:[LINENR]: SPECIFIC SUITE CONFIG: {'some_suite_global_param': 'heyho', [test_suite↪test_suite_params.py:[LINENR]] [test_suite_params.py:[LINENR]]
tst test_suite_params.py:[LINENR]: 'test_suite_params': {'one_bool_parameter': 'true', [test_suite↪test_suite_params.py:[LINENR]] [test_suite_params.py:[LINENR]]
-tst test_suite_params.py:[LINENR]: 'second_list_parameter': ['23', '45']}} [test_suite↪test_suite_params.py:[LINENR]] [test_suite_params.py:[LINENR]]
+tst test_suite_params.py:[LINENR]: 'second_list_parameter': ['23', '45']}, [test_suite↪test_suite_params.py:[LINENR]] [test_suite_params.py:[LINENR]]
+tst test_suite_params.py:[LINENR]: 'test_timeout': {'timeout': '1'}} [test_suite↪test_suite_params.py:[LINENR]] [test_suite_params.py:[LINENR]]
tst test_suite_params.py:[LINENR]: SPECIFIC TEST CONFIG: {'one_bool_parameter': 'true', 'second_list_parameter': ['23', '45']} [test_suite↪test_suite_params.py:[LINENR]] [test_suite_params.py:[LINENR]]
tst test_suite_params.py:[LINENR] Test passed (N.N sec) [test_suite↪test_suite_params.py] [test.py:[LINENR]]
+
+----------------------------------------------
+trial test_suite test_timeout.py
+----------------------------------------------
+tst test_timeout.py:[LINENR]: starting test and waiting to receive Timeout after 1 seconds [test_suite↪test_timeout.py:[LINENR]] [test_timeout.py:[LINENR]]
+tst test_timeout.py:[LINENR]: ERR: Error: test_timeout.py:[LINENR] Test Timeout triggered: 1 seconds elapsed [test_suite↪test_timeout.py:[LINENR]↪test_timeout.py] [test_suite↪test_timeout.py:[LINENR]] [testenv.py:[LINENR]: raise log_module.Error('Test Timeout triggered: %d seconds elapsed' % self._test.elapsed_time())]
+tst test_timeout.py:[LINENR]: Test FAILED (N.N sec) [test_suite↪test_timeout.py:[LINENR]] [test.py:[LINENR]]
---------------------------------------------------------------------
-trial test_suite PASS
+trial test_suite FAIL
---------------------------------------------------------------------
-PASS: test_suite (pass: 1, skip: 6)
+FAIL: test_suite (fail: 1, pass: 1, skip: 6)
skip: hello_world.py
skip: mo_mt_sms.py
skip: mo_sms.py
@@ -628,6 +648,7 @@
skip: test_fail.py
skip: test_fail_raise.py
pass: test_suite_params.py (N.N sec)
+ FAIL: test_timeout.py (N.N sec) Error: test_timeout.py:[LINENR] Test Timeout triggered: 1 seconds elapsed [test_suite↪test_timeout.py:[LINENR]↪test_timeout.py]
- test with template overlay
cnf suiteC: DBG: reading suite.conf [suite.py:[LINENR]]
tst suiteC: DBG: {combining='config'} [suite.py:[LINENR]]
diff --git a/selftest/suite_test/suite_test.py b/selftest/suite_test/suite_test.py
index 260b9c4..9708037 100755
--- a/selftest/suite_test/suite_test.py
+++ b/selftest/suite_test/suite_test.py
@@ -102,7 +102,7 @@
s = suite.SuiteRun(trial, 'test_suite', s_def, [sc])
s.reserve_resources()
print(repr(s.reserved_resources))
-results = s.run_tests('test_suite_params.py')
+results = s.run_tests(['test_suite_params.py', 'test_timeout.py'])
print(report.suite_to_text(s))
print('- test with template overlay')
diff --git a/selftest/suite_test/suitedirA/test_suite/suite.conf b/selftest/suite_test/suitedirA/test_suite/suite.conf
index ff4899a..0426ea7 100644
--- a/selftest/suite_test/suitedirA/test_suite/suite.conf
+++ b/selftest/suite_test/suitedirA/test_suite/suite.conf
@@ -15,3 +15,9 @@
one_bool_parameter: 'bool_str'
second_list_parameter: ['uint']
+
+config:
+ suite:
+ test_suite:
+ test_timeout:
+ timeout: 1 # timeout in 1 second
diff --git a/selftest/suite_test/suitedirA/test_suite/test_timeout.py b/selftest/suite_test/suitedirA/test_suite/test_timeout.py
new file mode 100644
index 0000000..eeddb70
--- /dev/null
+++ b/selftest/suite_test/suitedirA/test_suite/test_timeout.py
@@ -0,0 +1,6 @@
+from osmo_gsm_tester.testenv import *
+
+timeout = int(tenv.config_test_specific()['timeout'])
+print('starting test and waiting to receive Timeout after %d seconds' % timeout)
+sleep(10)
+print('test failed, we expected timeout after %d seconds' % timeout)