From ab1904a307b531dbd1c738ef04eeeeb68f9920b3 Mon Sep 17 00:00:00 2001 From: Pau Espin Pedrol Date: Wed, 6 May 2020 18:35:26 +0200 Subject: selftest: Move tests into own subdirectories Change-Id: Id21cda19df131e24402e1a593036e1e33a914920 --- selftest/_prep.py | 2 +- selftest/all_tests.py | 18 +- selftest/cdf_test.ok | 57 ---- selftest/cdf_test.py | 75 ----- selftest/cdf_test/_prep.py | 1 + selftest/cdf_test/cdf_test.ok | 57 ++++ selftest/cdf_test/cdf_test.py | 75 +++++ selftest/conf/paths.conf | 2 - selftest/conf/resources.conf | 103 ------ selftest/config_test.err | 0 selftest/config_test.ok | 112 ------- selftest/config_test.py | 216 ------------- selftest/config_test/_prep.py | 1 + selftest/config_test/config_test.err | 0 selftest/config_test/config_test.ok | 112 +++++++ selftest/config_test/config_test.py | 216 +++++++++++++ selftest/lock_test.err | 0 selftest/lock_test.ok | 14 - selftest/lock_test.sh | 53 --- selftest/lock_test/_prep.py | 1 + selftest/lock_test/lock_test.err | 0 selftest/lock_test/lock_test.ok | 14 + selftest/lock_test/lock_test.sh | 55 ++++ selftest/lock_test/lock_test_help.py | 25 ++ selftest/lock_test_help.py | 25 -- selftest/log_test.err | 0 selftest/log_test.ok | 40 --- selftest/log_test.py | 151 --------- selftest/log_test/_prep.py | 1 + selftest/log_test/log_test.err | 0 selftest/log_test/log_test.ok | 40 +++ selftest/log_test/log_test.py | 151 +++++++++ selftest/process_test.err | 0 selftest/process_test.ok | 30 -- selftest/process_test.ok.ign | 7 - selftest/process_test.py | 51 --- selftest/process_test/_prep.py | 1 + selftest/process_test/process_test.err | 0 selftest/process_test/process_test.ok | 30 ++ selftest/process_test/process_test.ok.ign | 7 + selftest/process_test/process_test.py | 51 +++ selftest/resource_test.err | 0 selftest/resource_test.ok | 289 ----------------- selftest/resource_test.ok.ign | 1 - selftest/resource_test.py | 130 -------- selftest/resource_test/_prep.py | 1 + selftest/resource_test/conf/paths.conf | 2 + selftest/resource_test/conf/resources.conf | 103 ++++++ selftest/resource_test/resource_test.err | 0 selftest/resource_test/resource_test.ok | 289 +++++++++++++++++ selftest/resource_test/resource_test.ok.ign | 1 + selftest/resource_test/resource_test.py | 131 ++++++++ selftest/sms_test.err | 0 selftest/sms_test.ok | 6 - selftest/sms_test.py | 22 -- selftest/sms_test/_prep.py | 1 + selftest/sms_test/sms_test.err | 0 selftest/sms_test/sms_test.ok | 6 + selftest/sms_test/sms_test.py | 22 ++ selftest/suite_test.err | 0 selftest/suite_test.ok | 485 ---------------------------- selftest/suite_test.ok.ign | 5 - selftest/suite_test.py | 97 ------ selftest/suite_test/_prep.py | 1 + selftest/suite_test/suite_test.err | 0 selftest/suite_test/suite_test.ok | 485 ++++++++++++++++++++++++++++ selftest/suite_test/suite_test.ok.ign | 5 + selftest/suite_test/suite_test.py | 97 ++++++ selftest/template_test.err | 0 selftest/template_test.ok | 193 ----------- selftest/template_test.py | 95 ------ selftest/template_test/_prep.py | 1 + selftest/template_test/template_test.err | 0 selftest/template_test/template_test.ok | 193 +++++++++++ selftest/template_test/template_test.py | 95 ++++++ selftest/trial_test.err | 0 selftest/trial_test.ok | 16 - selftest/trial_test.ok.ign | 3 - selftest/trial_test.py | 49 --- selftest/trial_test/_prep.py | 1 + selftest/trial_test/trial_test.err | 0 selftest/trial_test/trial_test.ok | 16 + selftest/trial_test/trial_test.ok.ign | 3 + selftest/trial_test/trial_test.py | 49 +++ selftest/util_test.err | 0 selftest/util_test.ok | 5 - selftest/util_test.py | 11 - selftest/util_test/_prep.py | 1 + selftest/util_test/util_test.err | 0 selftest/util_test/util_test.ok | 5 + selftest/util_test/util_test.py | 11 + 91 files changed, 2370 insertions(+), 2350 deletions(-) delete mode 100644 selftest/cdf_test.ok delete mode 100755 selftest/cdf_test.py create mode 120000 selftest/cdf_test/_prep.py create mode 100644 selftest/cdf_test/cdf_test.ok create mode 100755 selftest/cdf_test/cdf_test.py delete mode 100644 selftest/conf/paths.conf delete mode 100644 selftest/conf/resources.conf delete mode 100644 selftest/config_test.err delete mode 100644 selftest/config_test.ok delete mode 100755 selftest/config_test.py create mode 120000 selftest/config_test/_prep.py create mode 100644 selftest/config_test/config_test.err create mode 100644 selftest/config_test/config_test.ok create mode 100755 selftest/config_test/config_test.py delete mode 100644 selftest/lock_test.err delete mode 100644 selftest/lock_test.ok delete mode 100755 selftest/lock_test.sh create mode 120000 selftest/lock_test/_prep.py create mode 100644 selftest/lock_test/lock_test.err create mode 100644 selftest/lock_test/lock_test.ok create mode 100755 selftest/lock_test/lock_test.sh create mode 100644 selftest/lock_test/lock_test_help.py delete mode 100644 selftest/lock_test_help.py delete mode 100644 selftest/log_test.err delete mode 100644 selftest/log_test.ok delete mode 100755 selftest/log_test.py create mode 120000 selftest/log_test/_prep.py create mode 100644 selftest/log_test/log_test.err create mode 100644 selftest/log_test/log_test.ok create mode 100755 selftest/log_test/log_test.py delete mode 100644 selftest/process_test.err delete mode 100644 selftest/process_test.ok delete mode 100644 selftest/process_test.ok.ign delete mode 100755 selftest/process_test.py create mode 120000 selftest/process_test/_prep.py create mode 100644 selftest/process_test/process_test.err create mode 100644 selftest/process_test/process_test.ok create mode 100644 selftest/process_test/process_test.ok.ign create mode 100755 selftest/process_test/process_test.py delete mode 100644 selftest/resource_test.err delete mode 100644 selftest/resource_test.ok delete mode 100644 selftest/resource_test.ok.ign delete mode 100755 selftest/resource_test.py create mode 120000 selftest/resource_test/_prep.py create mode 100644 selftest/resource_test/conf/paths.conf create mode 100644 selftest/resource_test/conf/resources.conf create mode 100644 selftest/resource_test/resource_test.err create mode 100644 selftest/resource_test/resource_test.ok create mode 100644 selftest/resource_test/resource_test.ok.ign create mode 100755 selftest/resource_test/resource_test.py delete mode 100644 selftest/sms_test.err delete mode 100644 selftest/sms_test.ok delete mode 100755 selftest/sms_test.py create mode 120000 selftest/sms_test/_prep.py create mode 100644 selftest/sms_test/sms_test.err create mode 100644 selftest/sms_test/sms_test.ok create mode 100755 selftest/sms_test/sms_test.py delete mode 100644 selftest/suite_test.err delete mode 100644 selftest/suite_test.ok delete mode 100644 selftest/suite_test.ok.ign delete mode 100755 selftest/suite_test.py create mode 120000 selftest/suite_test/_prep.py create mode 100644 selftest/suite_test/suite_test.err create mode 100644 selftest/suite_test/suite_test.ok create mode 100644 selftest/suite_test/suite_test.ok.ign create mode 100755 selftest/suite_test/suite_test.py delete mode 100644 selftest/template_test.err delete mode 100644 selftest/template_test.ok delete mode 100755 selftest/template_test.py create mode 120000 selftest/template_test/_prep.py create mode 100644 selftest/template_test/template_test.err create mode 100644 selftest/template_test/template_test.ok create mode 100755 selftest/template_test/template_test.py delete mode 100644 selftest/trial_test.err delete mode 100644 selftest/trial_test.ok delete mode 100644 selftest/trial_test.ok.ign delete mode 100755 selftest/trial_test.py create mode 120000 selftest/trial_test/_prep.py create mode 100644 selftest/trial_test/trial_test.err create mode 100644 selftest/trial_test/trial_test.ok create mode 100644 selftest/trial_test/trial_test.ok.ign create mode 100755 selftest/trial_test/trial_test.py delete mode 100644 selftest/util_test.err delete mode 100644 selftest/util_test.ok delete mode 100755 selftest/util_test.py create mode 120000 selftest/util_test/_prep.py create mode 100644 selftest/util_test/util_test.err create mode 100644 selftest/util_test/util_test.ok create mode 100755 selftest/util_test/util_test.py (limited to 'selftest') diff --git a/selftest/_prep.py b/selftest/_prep.py index 582b8fb..773f190 100644 --- a/selftest/_prep.py +++ b/selftest/_prep.py @@ -1,7 +1,7 @@ import sys, os script_dir = sys.path[0] -top_dir = os.path.join(script_dir, '..') +top_dir = os.path.join(script_dir, '..', '..') src_dir = os.path.join(top_dir, 'src') # to find the osmo_gsm_tester py module diff --git a/selftest/all_tests.py b/selftest/all_tests.py index 5c1ce59..bb00793 100755 --- a/selftest/all_tests.py +++ b/selftest/all_tests.py @@ -72,14 +72,20 @@ def verify_output(got, expect_file, update=False): script_dir = sys.path[0] tests = [] -for f in os.listdir(script_dir): - file_path = os.path.join(script_dir, f) - if not os.path.isfile(file_path): +for d in os.listdir(script_dir): + dir_path = os.path.join(script_dir, d) + if not os.path.isdir(dir_path): continue - - if not (file_path.endswith('_test.py') or file_path.endswith('_test.sh')): + if not dir_path.endswith('_test'): continue - tests.append(file_path) + for f in os.listdir(dir_path): + file_path = os.path.join(script_dir, d, f) + if not os.path.isfile(file_path): + continue + + if not (file_path.endswith('_test.py') or file_path.endswith('_test.sh')): + continue + tests.append(file_path) ran = [] errors = [] diff --git a/selftest/cdf_test.ok b/selftest/cdf_test.ok deleted file mode 100644 index aa753e4..0000000 --- a/selftest/cdf_test.ok +++ /dev/null @@ -1,57 +0,0 @@ -Testing the immediate CDF -Done True -1 1.0 False -Testing linear with duration -Done False -0.0 0.0 True -Done False -0.2 0.2 True -Done False -0.4 0.4 True -Done False -0.6 0.6 True -Done False -0.8 0.8 True -Done True -1.0 1.0 True -Testing linear with duration scaled -Done False -0.0 0.0 True -0.0 0.0 True -Done False -0.2 0.2 True -200 200 True -Done False -0.4 0.4 True -400 400 True -Done False -0.6 0.6 True -600 600 True -Done False -0.8 0.8 True -800 800 True -Done True -1.0 1.0 True -100 100 True -Testing in_out -0.5 0.5 True -0.87 0.87 True -0.9 0.9 True -0.95 0.95 True -1.0 1.0 True -Testing ease In and Out -Done False -0.0 0.0 True -0.0 0.0 True -Done False -5.0 5.0 True -0.1 0.1 True -Done False -10.0 10.0 True -0.5 0.5 True -Done False -15.0 15.0 True -0.8 0.8 True -Done True -20.0 20 True -1.0 1.0 True diff --git a/selftest/cdf_test.py b/selftest/cdf_test.py deleted file mode 100755 index 8d837c1..0000000 --- a/selftest/cdf_test.py +++ /dev/null @@ -1,75 +0,0 @@ -#!/usr/bin/env python3 - -import _prep - -from osmo_ms_driver import cdf -from datetime import timedelta - -def print_fuzzy_compare(want, expe, len=3): - want_str = str(want)[0:len] - expe_str = str(expe)[0:len] - print(want_str, expe_str, want_str == expe_str) - - -def check_steps(a, steps, fun): - print("Done", a.is_done()) - for step in steps: - # Verify we can step - - # Compare and step once - fun(a, step) - if a.is_done(): - break - a.step_once() - print("Done", a.is_done()) - -def compare_value(a, step): - print_fuzzy_compare(a.current_value(), step) - -def compare_scaled_value(a, val): - (step, scale) = val - print_fuzzy_compare(a.current_value(), step) - print_fuzzy_compare(a.current_scaled_value(), scale) - -def compare_x_value(a, val): - (x, step) = val - print(a._x, x, x == a._x) - print_fuzzy_compare(a.current_value(), step) - -def testImmediate(): - print("Testing the immediate CDF") - a = cdf.immediate() - print("Done", a.is_done()) - print_fuzzy_compare(a.current_value(), 1.0) - - -def testLinearWithDuration(): - print("Testing linear with duration") - a = cdf.linear_with_duration(timedelta(seconds=10), step_size=timedelta(seconds=2)) - steps = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0] - check_steps(a, steps, compare_value) - - print("Testing linear with duration scaled") - a = cdf.linear_with_duration(timedelta(seconds=10), step_size=timedelta(seconds=2)) - a.set_target(1000) - steps = [(0.0, 0.0), (0.2, 200), (0.4, 400), (0.6, 600), (0.8, 800), (1.0, 10000)] - check_steps(a, steps, compare_scaled_value) - -def testInOut(): - print("Testing in_out") - print_fuzzy_compare(cdf._in_out(0.5), 0.5, 3) - print_fuzzy_compare(cdf._in_out(0.75), 0.875, 4) - print_fuzzy_compare(cdf._in_out(0.8), 0.92, 3) - print_fuzzy_compare(cdf._in_out(0.85), 0.955, 4) - print_fuzzy_compare(cdf._in_out(1.0), 1.0, 3) - -def testEaseInOutDuration(): - print("Testing ease In and Out") - a = cdf.ease_in_out_duration(duration=timedelta(seconds=20), step_size=timedelta(seconds=5)) - steps = [(0.0, 0.0), (5.0, 0.125), (10.0, 0.5), (15.0, 0.875), (20, 1.0)] - check_steps(a, steps, compare_x_value) - -testImmediate() -testLinearWithDuration() -testInOut() -testEaseInOutDuration() diff --git a/selftest/cdf_test/_prep.py b/selftest/cdf_test/_prep.py new file mode 120000 index 0000000..9cea3fe --- /dev/null +++ b/selftest/cdf_test/_prep.py @@ -0,0 +1 @@ +../_prep.py \ No newline at end of file diff --git a/selftest/cdf_test/cdf_test.ok b/selftest/cdf_test/cdf_test.ok new file mode 100644 index 0000000..aa753e4 --- /dev/null +++ b/selftest/cdf_test/cdf_test.ok @@ -0,0 +1,57 @@ +Testing the immediate CDF +Done True +1 1.0 False +Testing linear with duration +Done False +0.0 0.0 True +Done False +0.2 0.2 True +Done False +0.4 0.4 True +Done False +0.6 0.6 True +Done False +0.8 0.8 True +Done True +1.0 1.0 True +Testing linear with duration scaled +Done False +0.0 0.0 True +0.0 0.0 True +Done False +0.2 0.2 True +200 200 True +Done False +0.4 0.4 True +400 400 True +Done False +0.6 0.6 True +600 600 True +Done False +0.8 0.8 True +800 800 True +Done True +1.0 1.0 True +100 100 True +Testing in_out +0.5 0.5 True +0.87 0.87 True +0.9 0.9 True +0.95 0.95 True +1.0 1.0 True +Testing ease In and Out +Done False +0.0 0.0 True +0.0 0.0 True +Done False +5.0 5.0 True +0.1 0.1 True +Done False +10.0 10.0 True +0.5 0.5 True +Done False +15.0 15.0 True +0.8 0.8 True +Done True +20.0 20 True +1.0 1.0 True diff --git a/selftest/cdf_test/cdf_test.py b/selftest/cdf_test/cdf_test.py new file mode 100755 index 0000000..8d837c1 --- /dev/null +++ b/selftest/cdf_test/cdf_test.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python3 + +import _prep + +from osmo_ms_driver import cdf +from datetime import timedelta + +def print_fuzzy_compare(want, expe, len=3): + want_str = str(want)[0:len] + expe_str = str(expe)[0:len] + print(want_str, expe_str, want_str == expe_str) + + +def check_steps(a, steps, fun): + print("Done", a.is_done()) + for step in steps: + # Verify we can step + + # Compare and step once + fun(a, step) + if a.is_done(): + break + a.step_once() + print("Done", a.is_done()) + +def compare_value(a, step): + print_fuzzy_compare(a.current_value(), step) + +def compare_scaled_value(a, val): + (step, scale) = val + print_fuzzy_compare(a.current_value(), step) + print_fuzzy_compare(a.current_scaled_value(), scale) + +def compare_x_value(a, val): + (x, step) = val + print(a._x, x, x == a._x) + print_fuzzy_compare(a.current_value(), step) + +def testImmediate(): + print("Testing the immediate CDF") + a = cdf.immediate() + print("Done", a.is_done()) + print_fuzzy_compare(a.current_value(), 1.0) + + +def testLinearWithDuration(): + print("Testing linear with duration") + a = cdf.linear_with_duration(timedelta(seconds=10), step_size=timedelta(seconds=2)) + steps = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0] + check_steps(a, steps, compare_value) + + print("Testing linear with duration scaled") + a = cdf.linear_with_duration(timedelta(seconds=10), step_size=timedelta(seconds=2)) + a.set_target(1000) + steps = [(0.0, 0.0), (0.2, 200), (0.4, 400), (0.6, 600), (0.8, 800), (1.0, 10000)] + check_steps(a, steps, compare_scaled_value) + +def testInOut(): + print("Testing in_out") + print_fuzzy_compare(cdf._in_out(0.5), 0.5, 3) + print_fuzzy_compare(cdf._in_out(0.75), 0.875, 4) + print_fuzzy_compare(cdf._in_out(0.8), 0.92, 3) + print_fuzzy_compare(cdf._in_out(0.85), 0.955, 4) + print_fuzzy_compare(cdf._in_out(1.0), 1.0, 3) + +def testEaseInOutDuration(): + print("Testing ease In and Out") + a = cdf.ease_in_out_duration(duration=timedelta(seconds=20), step_size=timedelta(seconds=5)) + steps = [(0.0, 0.0), (5.0, 0.125), (10.0, 0.5), (15.0, 0.875), (20, 1.0)] + check_steps(a, steps, compare_x_value) + +testImmediate() +testLinearWithDuration() +testInOut() +testEaseInOutDuration() diff --git a/selftest/conf/paths.conf b/selftest/conf/paths.conf deleted file mode 100644 index 0b2d035..0000000 --- a/selftest/conf/paths.conf +++ /dev/null @@ -1,2 +0,0 @@ -state_dir: ./test_work/state_dir -suites_dir: ./suite_test diff --git a/selftest/conf/resources.conf b/selftest/conf/resources.conf deleted file mode 100644 index 84d0ab9..0000000 --- a/selftest/conf/resources.conf +++ /dev/null @@ -1,103 +0,0 @@ -# all hardware and interfaces available to this osmo-gsm-tester - -ip_address: -- addr: 10.42.42.2 -- addr: 10.42.42.3 -- addr: 10.42.42.4 -- addr: 10.42.42.5 -- addr: 10.42.42.6 - -bts: -- label: sysmoBTS 1002 - type: osmo-bts-sysmo - ipa_unit_id: 1 - addr: 10.42.42.114 - band: GSM-1800 - direct_pcu: true - ciphers: - - 'a5_0' - - 'a5_1' - -- label: Ettus B200 - type: osmo-bts-trx - ipa_unit_id: 6 - addr: 10.42.42.50 - band: GSM-1800 - osmo_trx: - launch_trx: true - clock_reference: external - ciphers: - - 'a5_0' - - 'a5_1' - -- label: sysmoCell 5000 - type: osmo-bts-trx - ipa_unit_id: 7 - addr: 10.42.42.51 - band: GSM-1800 - osmo_trx: - launch_trx: false - clock_reference: external - trx_ip: 10.42.42.112 - ciphers: - - 'a5_0' - - 'a5_1' - -arfcn: - - arfcn: 512 - band: GSM-1800 - - arfcn: 514 - band: GSM-1800 - - arfcn: 516 - band: GSM-1800 - - arfcn: 518 - band: GSM-1800 - - arfcn: 520 - band: GSM-1800 - - arfcn: 540 - band: GSM-1900 - - arfcn: 542 - band: GSM-1900 - - arfcn: 544 - band: GSM-1900 - - arfcn: 546 - band: GSM-1900 - - arfcn: 548 - band: GSM-1900 - -modem: -- label: sierra_1 - path: '/sierra_1' - imsi: '901700000009031' - ki: '80A37E6FDEA931EAC92FFA5F671EFEAD' - auth_algo: 'comp128v1' - ciphers: - - 'a5_0' - - 'a5_1' - -- label: sierra_2 - path: '/sierra_2' - imsi: '901700000009029' - ki: '00969E283349D354A8239E877F2E0866' - auth_algo: 'comp128v1' - ciphers: - - 'a5_0' - - 'a5_1' - -- label: gobi_0 - path: '/gobi_0' - imsi: '901700000009030' - ki: 'BB70807226393CDBAC8DD3439FF54252' - auth_algo: 'comp128v1' - ciphers: - - 'a5_0' - - 'a5_1' - -- label: gobi_3 - path: '/gobi_3' - imsi: '901700000009032' - ki: '2F70DCA43C45ACB97E947FDD0C7CA30A' - auth_algo: 'comp128v1' - ciphers: - - 'a5_0' - - 'a5_1' diff --git a/selftest/config_test.err b/selftest/config_test.err deleted file mode 100644 index e69de29..0000000 diff --git a/selftest/config_test.ok b/selftest/config_test.ok deleted file mode 100644 index e1fb87d..0000000 --- a/selftest/config_test.ok +++ /dev/null @@ -1,112 +0,0 @@ -{'addr': ['0.0.0.0', - '255.255.255.255', - '10.11.12.13', - '10.0.99.1', - '192.168.0.14'], - 'bts': [{'addr': '10.42.42.114', - 'name': 'sysmoBTS 1002', - 'trx': [{'band': 'GSM-1800', - 'timeslots': ['CCCH+SDCCH4', - 'SDCCH8', - 'TCH/F_TCH/H_PDCH', - 'TCH/F_TCH/H_PDCH', - 'TCH/F_TCH/H_PDCH', - 'TCH/F_TCH/H_PDCH', - 'TCH/F_TCH/H_PDCH', - 'TCH/F_TCH/H_PDCH']}, - {'band': 'GSM-1900', - 'timeslots': ['SDCCH8', - 'PDCH', - 'PDCH', - 'PDCH', - 'PDCH', - 'PDCH', - 'PDCH', - 'PDCH']}], - 'type': 'sysmobts'}], - 'hwaddr': ['ca:ff:ee:ba:aa:be', - '00:00:00:00:00:00', - 'CA:FF:EE:BA:AA:BE', - 'cA:Ff:eE:Ba:aA:Be', - 'ff:ff:ff:ff:ff:ff'], - 'imsi': ['012345', '012345678', '012345678912345'], - 'ki': ['000102030405060708090a0b0c0d0e0f', '000102030405060708090a0b0c0d0e0f'], - 'modems': [{'dbus_path': '/sierra_0', - 'imsi': '901700000009001', - 'ki': 'D620F48487B1B782DA55DF6717F08FF9', - 'msisdn': '7801'}, - {'dbus_path': '/sierra_1', - 'imsi': '901700000009002', - 'ki': 'D620F48487B1B782DA55DF6717F08FF9', - 'msisdn': '7802'}]} -- expect validation success: -Validation: OK -- unknown item: ---- -: ERR: ValueError: config item not known: 'bts[].unknown_item' -Validation: Error -- wrong type modems[].imsi: ---- -: ERR: ValueError: config item is dict but should be a leaf node of type 'imsi': 'modems[].imsi' -Validation: Error -- invalid key with space: ---- -: ERR: ValueError: invalid config key: 'imsi ' -Validation: Error -- list instead of dict: ---- -: ERR: ValueError: config item not known: 'a_dict[]' -Validation: Error -- unknown band: ---- bts[].trx[].band: ERR: ValueError: Unknown GSM band: 'what' -Validation: Error -- invalid v4 addrs: ---- addr[]: ERR: ValueError: Invalid IPv4 address: '1.2.3' -Validation: Error ---- addr[]: ERR: ValueError: Invalid IPv4 address: '1.2.3 .4' -Validation: Error ---- addr[]: ERR: ValueError: Invalid IPv4 address: '91.2.3' -Validation: Error ---- addr[]: ERR: ValueError: Invalid IPv4 address: 'go away' -Validation: Error ---- addr[]: ERR: ValueError: Invalid IPv4 address: '' -Validation: Error ---- addr[]: ERR: ValueError: Invalid IPv4 address: None -Validation: Error -- invalid hw addrs: ---- hwaddr[]: ERR: ValueError: Invalid hardware address: '1.2.3' -Validation: Error ---- hwaddr[]: ERR: ValueError: Invalid hardware address: '0b:0c:0d:0e:0f:0g' -Validation: Error ---- hwaddr[]: ERR: ValueError: Invalid hardware address: '0b:0c:0d:0e : 0f:0f' -Validation: Error ---- hwaddr[]: ERR: ValueError: Invalid hardware address: 'go away' -Validation: Error ---- hwaddr[]: ERR: ValueError: Invalid hardware address: '' -Validation: Error ---- hwaddr[]: ERR: ValueError: Invalid hardware address: None -Validation: Error -- invalid imsis: ---- imsi[]: ERR: ValueError: Invalid IMSI: '99999999x9' -Validation: Error ---- imsi[]: ERR: ValueError: Invalid IMSI: '123 456 789 123' -Validation: Error ---- imsi[]: ERR: ValueError: Invalid IMSI: 'go away' -Validation: Error ---- imsi[]: ERR: ValueError: Invalid IMSI: '' -Validation: Error ---- imsi[]: ERR: ValueError: Invalid IMSI: None -Validation: Error -- Combine dicts: -- Combine dicts 2: -- Combine lists: -- Combine lists 2: -- Combine lists 3: -ValueError expected -- Combine lists 4: -ValueError expected -- Combine lists 5: -ValueError expected -- Combine lists 6: -- Combine lists 7: -- Combine lists 8: -- Combine lists 9: -- Combine lists 10: -- Combine lists 13: -- Combine lists 14: diff --git a/selftest/config_test.py b/selftest/config_test.py deleted file mode 100755 index c26ebd1..0000000 --- a/selftest/config_test.py +++ /dev/null @@ -1,216 +0,0 @@ -#!/usr/bin/env python3 - -import _prep - -import sys -import os -import io -import pprint -import copy - -from osmo_gsm_tester.core import config, log, schema - -example_config_file = 'test.cfg' -example_config = os.path.join(_prep.script_dir, 'config_test', example_config_file) -cfg = config.read(example_config) - -pprint.pprint(cfg, width=81) - -test_schema = { - 'modems[].dbus_path': schema.STR, - 'modems[].msisdn': schema.STR, - 'modems[].imsi': schema.IMSI, - 'modems[].ki': schema.STR, - 'bts[].name' : schema.STR, - 'bts[].type' : schema.STR, - 'bts[].addr' : schema.STR, - 'bts[].trx[].timeslots[]' : schema.STR, - 'bts[].trx[].band' : schema.BAND, - 'a_dict.foo' : schema.INT, - 'addr[]' : schema.IPV4, - 'hwaddr[]' : schema.HWADDR, - 'imsi[]' : schema.IMSI, - 'ki[]' : schema.KI, - } - -def val(which): - try: - schema.validate(which, test_schema) - print('Validation: OK') - except ValueError: - log.log_exn() - print('Validation: Error') - -print('- expect validation success:') -val(cfg) - -print('- unknown item:') -c = copy.deepcopy(cfg) -c['bts'][0]['unknown_item'] = 'no' -val(c) - -print('- wrong type modems[].imsi:') -c = copy.deepcopy(cfg) -c['modems'][0]['imsi'] = {'no':'no'} -val(c) - -print('- invalid key with space:') -c = copy.deepcopy(cfg) -c['modems'][0]['imsi '] = '12345' -val(c) - -print('- list instead of dict:') -c = copy.deepcopy(cfg) -c['a_dict'] = [ 1, 2, 3 ] -val(c) - -print('- unknown band:') -c = copy.deepcopy(cfg) -c['bts'][0]['trx'][0]['band'] = 'what' -val(c) - -print('- invalid v4 addrs:') -c = copy.deepcopy(cfg) -c['addr'][3] = '1.2.3' -val(c) -c['addr'][3] = '1.2.3 .4' -val(c) -c['addr'][3] = '91.2.3' -val(c) -c['addr'][3] = 'go away' -val(c) -c['addr'][3] = '' -val(c) -c['addr'][3] = None -val(c) - -print('- invalid hw addrs:') -c = copy.deepcopy(cfg) -c['hwaddr'][3] = '1.2.3' -val(c) -c['hwaddr'][3] = '0b:0c:0d:0e:0f:0g' -val(c) -c['hwaddr'][3] = '0b:0c:0d:0e : 0f:0f' -val(c) -c['hwaddr'][3] = 'go away' -val(c) -c['hwaddr'][3] = '' -val(c) -c['hwaddr'][3] = None -val(c) - -print('- invalid imsis:') -c = copy.deepcopy(cfg) -c['imsi'][2] = '99999999x9' -val(c) -c['imsi'][2] = '123 456 789 123' -val(c) -c['imsi'][2] = 'go away' -val(c) -c['imsi'][2] = '' -val(c) -c['imsi'][2] = None -val(c) - -print('- Combine dicts:') -a = {'times': '2'} -b = {'type': 'osmo-bts-trx'} -res = {'times': '2', 'type': 'osmo-bts-trx'} -schema.combine(a, b) -assert a == res - -print('- Combine dicts 2:') -a = {'times': '1', 'label': 'foo', 'type': 'osmo-bts-trx'} -b = {'type': 'osmo-bts-trx'} -res = {'times': '1', 'label': 'foo', 'type': 'osmo-bts-trx'} -schema.combine(a, b) -assert a == res - -print('- Combine lists:') -a = { 'a_list': ['x', 'y', 'z'] } -b = { 'a_list': ['y'] } -res = {'a_list': ['x', 'y', 'z']} -schema.combine(a, b) -assert a == res - -print('- Combine lists 2:') -a = { 'a_list': ['x'] } -b = { 'a_list': ['w', 'u', 'x', 'y', 'z'] } -res = {'a_list': ['x', 'w', 'u', 'y', 'z']} -schema.combine(a, b) -assert a == res - -print('- Combine lists 3:') -a = { 'a_list': ['x', 3] } -b = { 'a_list': ['y', 'z'] } -try: - schema.combine(a, b) -except ValueError: - print("ValueError expected") - -print('- Combine lists 4:') -a = { 'a_list': [2, 3] } -b = { 'a_list': ['y', 'z'] } -try: - schema.combine(a, b) -except ValueError: - print("ValueError expected") - -print('- Combine lists 5:') -a = { 'a_list': [{}, {}] } -b = { 'a_list': ['y', 'z'] } -try: - schema.combine(a, b) -except ValueError: - print("ValueError expected") - -print('- Combine lists 6:') -a = { 'a_list': [{}, {}] } -b = { 'a_list': [{}] } -res = {'a_list': [{}, {}]} -schema.combine(a, b) -assert a == res - -print('- Combine lists 7:') -a = { 'times': '1', 'label': 'foo', 'trx': [{'nominal power': '10'}, {'nominal power': '12'}] } -b = { 'type': 'osmo-bts-trx', 'trx': [{'nominal power': '10'}, {'nominal power': '12'}] } -res = {'times': '1', 'label': 'foo', 'trx': [{'nominal power': '10'}, {'nominal power': '12'}], 'type': 'osmo-bts-trx'} -schema.combine(a, b) -assert a == res - -print('- Combine lists 8:') -a = { 'times': '1', 'label': 'foo', 'trx': [{'nominal power': '10'}] } -b = { 'type': 'osmo-bts-trx', 'trx': [{'nominal power': '10'}, {'nominal power': '12'}] } -res = {'times': '1', 'label': 'foo', 'trx': [{'nominal power': '10'}, {'nominal power': '12'}], 'type': 'osmo-bts-trx'} -schema.combine(a, b) -assert a == res - -print('- Combine lists 9:') -a = { 'times': '1', 'label': 'foo', 'trx': [{'nominal power': '10'}, {'nominal power': '12'}] } -b = { 'type': 'osmo-bts-trx', 'trx': [{'nominal power': '10'}] } -res = {'times': '1', 'label': 'foo', 'trx': [{'nominal power': '10'}, {'nominal power': '12'}], 'type': 'osmo-bts-trx'} -schema.combine(a, b) -assert a == res - -print('- Combine lists 10:') -a = { 'times': '1', 'label': 'foo', 'trx': [{'nominal power': '10'}, {'nominal power': '12'}] } -b = { 'type': 'osmo-bts-trx', 'trx': [{}, {'nominal power': '12'}] } -res = {'times': '1', 'label': 'foo', 'trx': [{'nominal power': '10'}, {'nominal power': '12'}], 'type': 'osmo-bts-trx'} -schema.combine(a, b) -assert a == res - -print('- Combine lists 13:') -a = { 'times': '1', 'label': 'foo', 'trx': [{}, {'nominal power': '12'}] } -b = { 'type': 'osmo-bts-trx', 'trx': [{'nominal power': '10'}, {'nominal power': '12'}] } -res = {'times': '1', 'label': 'foo', 'trx': [{'nominal power': '10'}, {'nominal power': '12'}], 'type': 'osmo-bts-trx'} -schema.combine(a, b) -assert a == res - -print('- Combine lists 14:') -a = { 'times': '1', 'label': 'foo', 'trx': [] } -b = { 'type': 'osmo-bts-trx', 'trx': [] } -res = {'times': '1', 'label': 'foo', 'trx': [], 'type': 'osmo-bts-trx'} -schema.combine(a, b) -assert a == res - -# vim: expandtab tabstop=4 shiftwidth=4 diff --git a/selftest/config_test/_prep.py b/selftest/config_test/_prep.py new file mode 120000 index 0000000..9cea3fe --- /dev/null +++ b/selftest/config_test/_prep.py @@ -0,0 +1 @@ +../_prep.py \ No newline at end of file diff --git a/selftest/config_test/config_test.err b/selftest/config_test/config_test.err new file mode 100644 index 0000000..e69de29 diff --git a/selftest/config_test/config_test.ok b/selftest/config_test/config_test.ok new file mode 100644 index 0000000..e1fb87d --- /dev/null +++ b/selftest/config_test/config_test.ok @@ -0,0 +1,112 @@ +{'addr': ['0.0.0.0', + '255.255.255.255', + '10.11.12.13', + '10.0.99.1', + '192.168.0.14'], + 'bts': [{'addr': '10.42.42.114', + 'name': 'sysmoBTS 1002', + 'trx': [{'band': 'GSM-1800', + 'timeslots': ['CCCH+SDCCH4', + 'SDCCH8', + 'TCH/F_TCH/H_PDCH', + 'TCH/F_TCH/H_PDCH', + 'TCH/F_TCH/H_PDCH', + 'TCH/F_TCH/H_PDCH', + 'TCH/F_TCH/H_PDCH', + 'TCH/F_TCH/H_PDCH']}, + {'band': 'GSM-1900', + 'timeslots': ['SDCCH8', + 'PDCH', + 'PDCH', + 'PDCH', + 'PDCH', + 'PDCH', + 'PDCH', + 'PDCH']}], + 'type': 'sysmobts'}], + 'hwaddr': ['ca:ff:ee:ba:aa:be', + '00:00:00:00:00:00', + 'CA:FF:EE:BA:AA:BE', + 'cA:Ff:eE:Ba:aA:Be', + 'ff:ff:ff:ff:ff:ff'], + 'imsi': ['012345', '012345678', '012345678912345'], + 'ki': ['000102030405060708090a0b0c0d0e0f', '000102030405060708090a0b0c0d0e0f'], + 'modems': [{'dbus_path': '/sierra_0', + 'imsi': '901700000009001', + 'ki': 'D620F48487B1B782DA55DF6717F08FF9', + 'msisdn': '7801'}, + {'dbus_path': '/sierra_1', + 'imsi': '901700000009002', + 'ki': 'D620F48487B1B782DA55DF6717F08FF9', + 'msisdn': '7802'}]} +- expect validation success: +Validation: OK +- unknown item: +--- -: ERR: ValueError: config item not known: 'bts[].unknown_item' +Validation: Error +- wrong type modems[].imsi: +--- -: ERR: ValueError: config item is dict but should be a leaf node of type 'imsi': 'modems[].imsi' +Validation: Error +- invalid key with space: +--- -: ERR: ValueError: invalid config key: 'imsi ' +Validation: Error +- list instead of dict: +--- -: ERR: ValueError: config item not known: 'a_dict[]' +Validation: Error +- unknown band: +--- bts[].trx[].band: ERR: ValueError: Unknown GSM band: 'what' +Validation: Error +- invalid v4 addrs: +--- addr[]: ERR: ValueError: Invalid IPv4 address: '1.2.3' +Validation: Error +--- addr[]: ERR: ValueError: Invalid IPv4 address: '1.2.3 .4' +Validation: Error +--- addr[]: ERR: ValueError: Invalid IPv4 address: '91.2.3' +Validation: Error +--- addr[]: ERR: ValueError: Invalid IPv4 address: 'go away' +Validation: Error +--- addr[]: ERR: ValueError: Invalid IPv4 address: '' +Validation: Error +--- addr[]: ERR: ValueError: Invalid IPv4 address: None +Validation: Error +- invalid hw addrs: +--- hwaddr[]: ERR: ValueError: Invalid hardware address: '1.2.3' +Validation: Error +--- hwaddr[]: ERR: ValueError: Invalid hardware address: '0b:0c:0d:0e:0f:0g' +Validation: Error +--- hwaddr[]: ERR: ValueError: Invalid hardware address: '0b:0c:0d:0e : 0f:0f' +Validation: Error +--- hwaddr[]: ERR: ValueError: Invalid hardware address: 'go away' +Validation: Error +--- hwaddr[]: ERR: ValueError: Invalid hardware address: '' +Validation: Error +--- hwaddr[]: ERR: ValueError: Invalid hardware address: None +Validation: Error +- invalid imsis: +--- imsi[]: ERR: ValueError: Invalid IMSI: '99999999x9' +Validation: Error +--- imsi[]: ERR: ValueError: Invalid IMSI: '123 456 789 123' +Validation: Error +--- imsi[]: ERR: ValueError: Invalid IMSI: 'go away' +Validation: Error +--- imsi[]: ERR: ValueError: Invalid IMSI: '' +Validation: Error +--- imsi[]: ERR: ValueError: Invalid IMSI: None +Validation: Error +- Combine dicts: +- Combine dicts 2: +- Combine lists: +- Combine lists 2: +- Combine lists 3: +ValueError expected +- Combine lists 4: +ValueError expected +- Combine lists 5: +ValueError expected +- Combine lists 6: +- Combine lists 7: +- Combine lists 8: +- Combine lists 9: +- Combine lists 10: +- Combine lists 13: +- Combine lists 14: diff --git a/selftest/config_test/config_test.py b/selftest/config_test/config_test.py new file mode 100755 index 0000000..797553d --- /dev/null +++ b/selftest/config_test/config_test.py @@ -0,0 +1,216 @@ +#!/usr/bin/env python3 + +import _prep + +import sys +import os +import io +import pprint +import copy + +from osmo_gsm_tester.core import config, log, schema + +example_config_file = 'test.cfg' +example_config = os.path.join(_prep.script_dir, example_config_file) +cfg = config.read(example_config) + +pprint.pprint(cfg, width=81) + +test_schema = { + 'modems[].dbus_path': schema.STR, + 'modems[].msisdn': schema.STR, + 'modems[].imsi': schema.IMSI, + 'modems[].ki': schema.STR, + 'bts[].name' : schema.STR, + 'bts[].type' : schema.STR, + 'bts[].addr' : schema.STR, + 'bts[].trx[].timeslots[]' : schema.STR, + 'bts[].trx[].band' : schema.BAND, + 'a_dict.foo' : schema.INT, + 'addr[]' : schema.IPV4, + 'hwaddr[]' : schema.HWADDR, + 'imsi[]' : schema.IMSI, + 'ki[]' : schema.KI, + } + +def val(which): + try: + schema.validate(which, test_schema) + print('Validation: OK') + except ValueError: + log.log_exn() + print('Validation: Error') + +print('- expect validation success:') +val(cfg) + +print('- unknown item:') +c = copy.deepcopy(cfg) +c['bts'][0]['unknown_item'] = 'no' +val(c) + +print('- wrong type modems[].imsi:') +c = copy.deepcopy(cfg) +c['modems'][0]['imsi'] = {'no':'no'} +val(c) + +print('- invalid key with space:') +c = copy.deepcopy(cfg) +c['modems'][0]['imsi '] = '12345' +val(c) + +print('- list instead of dict:') +c = copy.deepcopy(cfg) +c['a_dict'] = [ 1, 2, 3 ] +val(c) + +print('- unknown band:') +c = copy.deepcopy(cfg) +c['bts'][0]['trx'][0]['band'] = 'what' +val(c) + +print('- invalid v4 addrs:') +c = copy.deepcopy(cfg) +c['addr'][3] = '1.2.3' +val(c) +c['addr'][3] = '1.2.3 .4' +val(c) +c['addr'][3] = '91.2.3' +val(c) +c['addr'][3] = 'go away' +val(c) +c['addr'][3] = '' +val(c) +c['addr'][3] = None +val(c) + +print('- invalid hw addrs:') +c = copy.deepcopy(cfg) +c['hwaddr'][3] = '1.2.3' +val(c) +c['hwaddr'][3] = '0b:0c:0d:0e:0f:0g' +val(c) +c['hwaddr'][3] = '0b:0c:0d:0e : 0f:0f' +val(c) +c['hwaddr'][3] = 'go away' +val(c) +c['hwaddr'][3] = '' +val(c) +c['hwaddr'][3] = None +val(c) + +print('- invalid imsis:') +c = copy.deepcopy(cfg) +c['imsi'][2] = '99999999x9' +val(c) +c['imsi'][2] = '123 456 789 123' +val(c) +c['imsi'][2] = 'go away' +val(c) +c['imsi'][2] = '' +val(c) +c['imsi'][2] = None +val(c) + +print('- Combine dicts:') +a = {'times': '2'} +b = {'type': 'osmo-bts-trx'} +res = {'times': '2', 'type': 'osmo-bts-trx'} +schema.combine(a, b) +assert a == res + +print('- Combine dicts 2:') +a = {'times': '1', 'label': 'foo', 'type': 'osmo-bts-trx'} +b = {'type': 'osmo-bts-trx'} +res = {'times': '1', 'label': 'foo', 'type': 'osmo-bts-trx'} +schema.combine(a, b) +assert a == res + +print('- Combine lists:') +a = { 'a_list': ['x', 'y', 'z'] } +b = { 'a_list': ['y'] } +res = {'a_list': ['x', 'y', 'z']} +schema.combine(a, b) +assert a == res + +print('- Combine lists 2:') +a = { 'a_list': ['x'] } +b = { 'a_list': ['w', 'u', 'x', 'y', 'z'] } +res = {'a_list': ['x', 'w', 'u', 'y', 'z']} +schema.combine(a, b) +assert a == res + +print('- Combine lists 3:') +a = { 'a_list': ['x', 3] } +b = { 'a_list': ['y', 'z'] } +try: + schema.combine(a, b) +except ValueError: + print("ValueError expected") + +print('- Combine lists 4:') +a = { 'a_list': [2, 3] } +b = { 'a_list': ['y', 'z'] } +try: + schema.combine(a, b) +except ValueError: + print("ValueError expected") + +print('- Combine lists 5:') +a = { 'a_list': [{}, {}] } +b = { 'a_list': ['y', 'z'] } +try: + schema.combine(a, b) +except ValueError: + print("ValueError expected") + +print('- Combine lists 6:') +a = { 'a_list': [{}, {}] } +b = { 'a_list': [{}] } +res = {'a_list': [{}, {}]} +schema.combine(a, b) +assert a == res + +print('- Combine lists 7:') +a = { 'times': '1', 'label': 'foo', 'trx': [{'nominal power': '10'}, {'nominal power': '12'}] } +b = { 'type': 'osmo-bts-trx', 'trx': [{'nominal power': '10'}, {'nominal power': '12'}] } +res = {'times': '1', 'label': 'foo', 'trx': [{'nominal power': '10'}, {'nominal power': '12'}], 'type': 'osmo-bts-trx'} +schema.combine(a, b) +assert a == res + +print('- Combine lists 8:') +a = { 'times': '1', 'label': 'foo', 'trx': [{'nominal power': '10'}] } +b = { 'type': 'osmo-bts-trx', 'trx': [{'nominal power': '10'}, {'nominal power': '12'}] } +res = {'times': '1', 'label': 'foo', 'trx': [{'nominal power': '10'}, {'nominal power': '12'}], 'type': 'osmo-bts-trx'} +schema.combine(a, b) +assert a == res + +print('- Combine lists 9:') +a = { 'times': '1', 'label': 'foo', 'trx': [{'nominal power': '10'}, {'nominal power': '12'}] } +b = { 'type': 'osmo-bts-trx', 'trx': [{'nominal power': '10'}] } +res = {'times': '1', 'label': 'foo', 'trx': [{'nominal power': '10'}, {'nominal power': '12'}], 'type': 'osmo-bts-trx'} +schema.combine(a, b) +assert a == res + +print('- Combine lists 10:') +a = { 'times': '1', 'label': 'foo', 'trx': [{'nominal power': '10'}, {'nominal power': '12'}] } +b = { 'type': 'osmo-bts-trx', 'trx': [{}, {'nominal power': '12'}] } +res = {'times': '1', 'label': 'foo', 'trx': [{'nominal power': '10'}, {'nominal power': '12'}], 'type': 'osmo-bts-trx'} +schema.combine(a, b) +assert a == res + +print('- Combine lists 13:') +a = { 'times': '1', 'label': 'foo', 'trx': [{}, {'nominal power': '12'}] } +b = { 'type': 'osmo-bts-trx', 'trx': [{'nominal power': '10'}, {'nominal power': '12'}] } +res = {'times': '1', 'label': 'foo', 'trx': [{'nominal power': '10'}, {'nominal power': '12'}], 'type': 'osmo-bts-trx'} +schema.combine(a, b) +assert a == res + +print('- Combine lists 14:') +a = { 'times': '1', 'label': 'foo', 'trx': [] } +b = { 'type': 'osmo-bts-trx', 'trx': [] } +res = {'times': '1', 'label': 'foo', 'trx': [], 'type': 'osmo-bts-trx'} +schema.combine(a, b) +assert a == res + +# vim: expandtab tabstop=4 shiftwidth=4 diff --git a/selftest/lock_test.err b/selftest/lock_test.err deleted file mode 100644 index e69de29..0000000 diff --git a/selftest/lock_test.ok b/selftest/lock_test.ok deleted file mode 100644 index 011a89c..0000000 --- a/selftest/lock_test.ok +++ /dev/null @@ -1,14 +0,0 @@ -creating files -launch a program that locks a given file, it will create $dir/lock_test -wait until this lock_test lock file was created by program -expecting the lock file to reflect "long name" -launched first, locked by: 'long name' -launching second program, should find the lock intact and wait -launched second, locked by: 'long name' -drop the first lock, $f1 removal signals the first process to stop locking -wait for first program to carry out the lock release -now expecting second program to lock -waited, locked by: 'shorter' -release the second program also -expecting the lock to be gone -waited more, locked by: '' diff --git a/selftest/lock_test.sh b/selftest/lock_test.sh deleted file mode 100755 index 4f3f7ad..0000000 --- a/selftest/lock_test.sh +++ /dev/null @@ -1,53 +0,0 @@ -#!/bin/sh - -echo 'creating files' -dir="$(mktemp -d)" -n1="long name" -f1="$dir/$n1" -touch "$f1" -n2="shorter" -f2="$dir/$n2" -touch "$f2" -sync - -echo 'launch a program that locks a given file, it will create $dir/lock_test' -python3 ./lock_test_help.py "$dir" "$n1" & - -echo 'wait until this lock_test lock file was created by program' -while [ ! -f "$dir/lock_test" ]; do - sleep .1 -done -sync - -echo 'expecting the lock file to reflect "long name"' -echo "launched first, locked by: '$(cat "$dir/lock_test")'" - -echo 'launching second program, should find the lock intact and wait' -python3 ./lock_test_help.py "$dir" "$n2" & -while [ ! -f "$f2.ready" ]; do - sleep .1 -done -sleep 1 -sync -echo "launched second, locked by: '$(cat "$dir/lock_test")'" - -echo 'drop the first lock, $f1 removal signals the first process to stop locking' -rm "$f1" - -echo 'wait for first program to carry out the lock release' -while [ ! -f "$f1.done" ]; do - sleep .1 -done - -echo 'now expecting second program to lock' -echo "waited, locked by: '$(cat "$dir/lock_test")'" - -echo 'release the second program also' -rm "$f2" -while [ ! -f "$f2.done" ]; do - sleep .1 -done - -echo 'expecting the lock to be gone' -echo "waited more, locked by: '$(cat "$dir/lock_test")'" -rm -rf "$dir" diff --git a/selftest/lock_test/_prep.py b/selftest/lock_test/_prep.py new file mode 120000 index 0000000..9cea3fe --- /dev/null +++ b/selftest/lock_test/_prep.py @@ -0,0 +1 @@ +../_prep.py \ No newline at end of file diff --git a/selftest/lock_test/lock_test.err b/selftest/lock_test/lock_test.err new file mode 100644 index 0000000..e69de29 diff --git a/selftest/lock_test/lock_test.ok b/selftest/lock_test/lock_test.ok new file mode 100644 index 0000000..011a89c --- /dev/null +++ b/selftest/lock_test/lock_test.ok @@ -0,0 +1,14 @@ +creating files +launch a program that locks a given file, it will create $dir/lock_test +wait until this lock_test lock file was created by program +expecting the lock file to reflect "long name" +launched first, locked by: 'long name' +launching second program, should find the lock intact and wait +launched second, locked by: 'long name' +drop the first lock, $f1 removal signals the first process to stop locking +wait for first program to carry out the lock release +now expecting second program to lock +waited, locked by: 'shorter' +release the second program also +expecting the lock to be gone +waited more, locked by: '' diff --git a/selftest/lock_test/lock_test.sh b/selftest/lock_test/lock_test.sh new file mode 100755 index 0000000..9e4f44a --- /dev/null +++ b/selftest/lock_test/lock_test.sh @@ -0,0 +1,55 @@ +#!/bin/sh + +owndir="$(dirname -- "$0")" + +echo 'creating files' +dir="$(mktemp -d)" +n1="long name" +f1="$dir/$n1" +touch "$f1" +n2="shorter" +f2="$dir/$n2" +touch "$f2" +sync + +echo 'launch a program that locks a given file, it will create $dir/lock_test' +python3 $owndir/lock_test_help.py "$dir" "$n1" & + +echo 'wait until this lock_test lock file was created by program' +while [ ! -f "$dir/lock_test" ]; do + sleep .1 +done +sync + +echo 'expecting the lock file to reflect "long name"' +echo "launched first, locked by: '$(cat "$dir/lock_test")'" + +echo 'launching second program, should find the lock intact and wait' +python3 $owndir/lock_test_help.py "$dir" "$n2" & +while [ ! -f "$f2.ready" ]; do + sleep .1 +done +sleep 1 +sync +echo "launched second, locked by: '$(cat "$dir/lock_test")'" + +echo 'drop the first lock, $f1 removal signals the first process to stop locking' +rm "$f1" + +echo 'wait for first program to carry out the lock release' +while [ ! -f "$f1.done" ]; do + sleep .1 +done + +echo 'now expecting second program to lock' +echo "waited, locked by: '$(cat "$dir/lock_test")'" + +echo 'release the second program also' +rm "$f2" +while [ ! -f "$f2.done" ]; do + sleep .1 +done + +echo 'expecting the lock to be gone' +echo "waited more, locked by: '$(cat "$dir/lock_test")'" +rm -rf "$dir" diff --git a/selftest/lock_test/lock_test_help.py b/selftest/lock_test/lock_test_help.py new file mode 100644 index 0000000..d68bbf8 --- /dev/null +++ b/selftest/lock_test/lock_test_help.py @@ -0,0 +1,25 @@ +import sys +import time +import os + +import _prep + +from osmo_gsm_tester.core.util import FileLock, touch_file + +testdir, name = sys.argv[1:] +stop_signalling_file = os.path.join(testdir, name) +if not os.path.isfile(stop_signalling_file): + print('expected a stop-file %r' % stop_signalling_file) + exit(1) + +lockfile_path = os.path.join(testdir, 'lock_test') +fl = FileLock(lockfile_path, name) + +touch_file(stop_signalling_file + '.ready') + +with fl: + while os.path.exists(stop_signalling_file): + time.sleep(.1) +touch_file(stop_signalling_file + '.done') + +# vim: expandtab tabstop=4 shiftwidth=4 diff --git a/selftest/lock_test_help.py b/selftest/lock_test_help.py deleted file mode 100644 index d68bbf8..0000000 --- a/selftest/lock_test_help.py +++ /dev/null @@ -1,25 +0,0 @@ -import sys -import time -import os - -import _prep - -from osmo_gsm_tester.core.util import FileLock, touch_file - -testdir, name = sys.argv[1:] -stop_signalling_file = os.path.join(testdir, name) -if not os.path.isfile(stop_signalling_file): - print('expected a stop-file %r' % stop_signalling_file) - exit(1) - -lockfile_path = os.path.join(testdir, 'lock_test') -fl = FileLock(lockfile_path, name) - -touch_file(stop_signalling_file + '.ready') - -with fl: - while os.path.exists(stop_signalling_file): - time.sleep(.1) -touch_file(stop_signalling_file + '.done') - -# vim: expandtab tabstop=4 shiftwidth=4 diff --git a/selftest/log_test.err b/selftest/log_test.err deleted file mode 100644 index e69de29..0000000 diff --git a/selftest/log_test.ok b/selftest/log_test.ok deleted file mode 100644 index c9d2dd2..0000000 --- a/selftest/log_test.ok +++ /dev/null @@ -1,40 +0,0 @@ -- Testing global log functions -01:02:03 tst : from log.log() -01:02:03 tst : DBG: from log.dbg() -01:02:03 tst : ERR: from log.err() -- Testing log.Origin functions -01:02:03 tst some-name(some='detail'): hello log -01:02:03 tst some-name(some='detail'): ERR: hello err -01:02:03 tst some-name(some='detail'): message {int=3, none=None, str='str\n', tuple=('foo', 42)} -01:02:03 tst some-name(some='detail'): DBG: hello dbg -- Testing log.style() -01:02:03: only time -tst: only category -DBG: only level - some-name(some='detail'): only origin -only src [log_test.py:69] -- Testing log.style_change() -no log format -01:02:03: add time -but no time format -01:02:03: DBG: add level -01:02:03 tst: DBG: add category -01:02:03 tst: DBG: add src [log_test.py:84] -01:02:03 tst some-name(some='detail'): DBG: add origin [log_test.py:86] -- Testing origin_width -01:02:03 tst shortname: origin str set to 23 chars [log_test.py:91] -01:02:03 tst very long name(and_some=(3, 'things', 'in a tuple'), some='details'): long origin str [log_test.py:93] -01:02:03 tst very long name(and_some=(3, 'things', 'in a tuple'), some='details'): DBG: long origin str dbg [log_test.py:94] -01:02:03 tst very long name(and_some=(3, 'things', 'in a tuple'), some='details'): ERR: long origin str err [log_test.py:95] -- Testing log.Origin with omitted info -01:02:03 tst LogTest: hello log, name implicit from class name [log_test.py:99] -01:02:03 --- explicit_name: hello log, no category set [log_test.py:103] -01:02:03 --- LogTest: hello log, no category nor name set [log_test.py:107] -01:02:03 --- LogTest: DBG: debug message, no category nor name set [log_test.py:110] -- Testing logging of Exceptions, tracing origins -nested print just prints -01:02:03 tst level3: nested log() [level1↪level2↪level3] [log_test.py:132] -01:02:03 tst level2: nested l2 log() from within l3 scope [level1↪level2] [log_test.py:133] -01:02:03 tst level3: ERR: ValueError: bork [level1↪level2↪level3] [log_test.py:134: raise ValueError('bork')] -- Disallow origin loops -disallowed successfully diff --git a/selftest/log_test.py b/selftest/log_test.py deleted file mode 100755 index f6ce02b..0000000 --- a/selftest/log_test.py +++ /dev/null @@ -1,151 +0,0 @@ -#!/usr/bin/env python3 - -# osmo_gsm_tester: logging tests -# -# Copyright (C) 2016-2017 by sysmocom - s.f.m.c. GmbH -# -# Author: Neels Hofmeyr -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -import _prep - -import sys -import os - -from osmo_gsm_tester.core import log - -#log.targets[0].get_time_str = lambda: '01:02:03' -fake_time = '01:02:03' -log.style_change(time=True, time_fmt=fake_time) -log.set_all_levels(None) - -print('- Testing global log functions') -log.log('from log.log()', _origin='', _category=log.C_TST) -log.dbg('from log.dbg(), not seen', _origin='', _category=log.C_TST) -log.set_level(log.C_TST, log.L_DBG) -log.dbg('from log.dbg()', _origin='', _category=log.C_TST) -log.set_level(log.C_TST, log.L_LOG) -log.err('from log.err()', _origin='', _category=log.C_TST) - -print('- Testing log.Origin functions') -class LogTest(log.Origin): - def __init__(self, *name_items, **detail_items): - super().__init__(log.C_TST, *name_items, **detail_items) - -t = LogTest('some', 'name', some="detail") - -t.log("hello log") -t.err("hello err") -t.dbg("hello dbg not visible") - -t.log("message", int=3, tuple=('foo', 42), none=None, str='str\n') - -log.set_level(log.C_TST, log.L_DBG) -t.dbg("hello dbg") - -print('- Testing log.style()') - -log.style(time=True, category=False, level=False, origin=False, src=False, time_fmt=fake_time) -t.dbg("only time") -log.style(time=False, category=True, level=False, origin=False, src=False, time_fmt=fake_time) -t.dbg("only category") -log.style(time=False, category=False, level=True, origin=False, src=False, time_fmt=fake_time) -t.dbg("only level") -log.style(time=False, category=False, level=False, origin=True, src=False, time_fmt=fake_time) -t.dbg("only origin") -log.style(time=False, category=False, level=False, origin=False, src=True, time_fmt=fake_time) -t.dbg("only src") - -print('- Testing log.style_change()') -log.style(time=False, category=False, level=False, origin=False, src=False, time_fmt=fake_time) -t.dbg("no log format") -log.style_change(time=True) -t.dbg("add time") -log.style_change(time=True, time_fmt=0) -t.dbg("but no time format") -log.style_change(time=True, time_fmt=fake_time) -log.style_change(level=True) -t.dbg("add level") -log.style_change(category=True) -t.dbg("add category") -log.style_change(src=True) -t.dbg("add src") -log.style_change(origin=True) -t.dbg("add origin") - -print('- Testing origin_width') -t = LogTest('shortname') -log.style(origin_width=23, time_fmt=fake_time) -t.log("origin str set to 23 chars") -t.set_name('very long name', some='details', and_some=(3, 'things', 'in a tuple')) -t.log("long origin str") -t.dbg("long origin str dbg") -t.err("long origin str err") - -print('- Testing log.Origin with omitted info') -t = LogTest() -t.log("hello log, name implicit from class name") - -t = LogTest('explicit_name') -t._set_log_category(None) -t.log("hello log, no category set") - -t = LogTest() -t._set_log_category(None) -t.log("hello log, no category nor name set") -t.dbg("hello log, no category nor name set, not seen") -log.set_level(log.C_DEFAULT, log.L_DBG) -t.dbg("debug message, no category nor name set") - -print('- Testing logging of Exceptions, tracing origins') -log.style(time_fmt=fake_time, origin_width=0) - -class Thing(log.Origin): - def __init__(self, some_path): - super().__init__(log.C_TST, some_path) - - def say(self, msg): - print(msg) - - def l1(self): - level2 = Thing('level2') - level2.l2() - - def l2(self): - level3 = Thing('level3') - level3.l3(self) - - def l3(self, level2): - print('nested print just prints') - self.log('nested log()') - level2.log('nested l2 log() from within l3 scope') - raise ValueError('bork') - -try: - level1 = Thing('level1') - level1.l1() -except Exception: - log.log_exn() - -print('- Disallow origin loops') -try: - t = Thing('foo') - t._set_parent(t) - raise RuntimeError('this should not be reached') -except log.OriginLoopError: - print('disallowed successfully') - pass - -# vim: expandtab tabstop=4 shiftwidth=4 diff --git a/selftest/log_test/_prep.py b/selftest/log_test/_prep.py new file mode 120000 index 0000000..9cea3fe --- /dev/null +++ b/selftest/log_test/_prep.py @@ -0,0 +1 @@ +../_prep.py \ No newline at end of file diff --git a/selftest/log_test/log_test.err b/selftest/log_test/log_test.err new file mode 100644 index 0000000..e69de29 diff --git a/selftest/log_test/log_test.ok b/selftest/log_test/log_test.ok new file mode 100644 index 0000000..c9d2dd2 --- /dev/null +++ b/selftest/log_test/log_test.ok @@ -0,0 +1,40 @@ +- Testing global log functions +01:02:03 tst : from log.log() +01:02:03 tst : DBG: from log.dbg() +01:02:03 tst : ERR: from log.err() +- Testing log.Origin functions +01:02:03 tst some-name(some='detail'): hello log +01:02:03 tst some-name(some='detail'): ERR: hello err +01:02:03 tst some-name(some='detail'): message {int=3, none=None, str='str\n', tuple=('foo', 42)} +01:02:03 tst some-name(some='detail'): DBG: hello dbg +- Testing log.style() +01:02:03: only time +tst: only category +DBG: only level + some-name(some='detail'): only origin +only src [log_test.py:69] +- Testing log.style_change() +no log format +01:02:03: add time +but no time format +01:02:03: DBG: add level +01:02:03 tst: DBG: add category +01:02:03 tst: DBG: add src [log_test.py:84] +01:02:03 tst some-name(some='detail'): DBG: add origin [log_test.py:86] +- Testing origin_width +01:02:03 tst shortname: origin str set to 23 chars [log_test.py:91] +01:02:03 tst very long name(and_some=(3, 'things', 'in a tuple'), some='details'): long origin str [log_test.py:93] +01:02:03 tst very long name(and_some=(3, 'things', 'in a tuple'), some='details'): DBG: long origin str dbg [log_test.py:94] +01:02:03 tst very long name(and_some=(3, 'things', 'in a tuple'), some='details'): ERR: long origin str err [log_test.py:95] +- Testing log.Origin with omitted info +01:02:03 tst LogTest: hello log, name implicit from class name [log_test.py:99] +01:02:03 --- explicit_name: hello log, no category set [log_test.py:103] +01:02:03 --- LogTest: hello log, no category nor name set [log_test.py:107] +01:02:03 --- LogTest: DBG: debug message, no category nor name set [log_test.py:110] +- Testing logging of Exceptions, tracing origins +nested print just prints +01:02:03 tst level3: nested log() [level1↪level2↪level3] [log_test.py:132] +01:02:03 tst level2: nested l2 log() from within l3 scope [level1↪level2] [log_test.py:133] +01:02:03 tst level3: ERR: ValueError: bork [level1↪level2↪level3] [log_test.py:134: raise ValueError('bork')] +- Disallow origin loops +disallowed successfully diff --git a/selftest/log_test/log_test.py b/selftest/log_test/log_test.py new file mode 100755 index 0000000..f6ce02b --- /dev/null +++ b/selftest/log_test/log_test.py @@ -0,0 +1,151 @@ +#!/usr/bin/env python3 + +# osmo_gsm_tester: logging tests +# +# Copyright (C) 2016-2017 by sysmocom - s.f.m.c. GmbH +# +# Author: Neels Hofmeyr +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +import _prep + +import sys +import os + +from osmo_gsm_tester.core import log + +#log.targets[0].get_time_str = lambda: '01:02:03' +fake_time = '01:02:03' +log.style_change(time=True, time_fmt=fake_time) +log.set_all_levels(None) + +print('- Testing global log functions') +log.log('from log.log()', _origin='', _category=log.C_TST) +log.dbg('from log.dbg(), not seen', _origin='', _category=log.C_TST) +log.set_level(log.C_TST, log.L_DBG) +log.dbg('from log.dbg()', _origin='', _category=log.C_TST) +log.set_level(log.C_TST, log.L_LOG) +log.err('from log.err()', _origin='', _category=log.C_TST) + +print('- Testing log.Origin functions') +class LogTest(log.Origin): + def __init__(self, *name_items, **detail_items): + super().__init__(log.C_TST, *name_items, **detail_items) + +t = LogTest('some', 'name', some="detail") + +t.log("hello log") +t.err("hello err") +t.dbg("hello dbg not visible") + +t.log("message", int=3, tuple=('foo', 42), none=None, str='str\n') + +log.set_level(log.C_TST, log.L_DBG) +t.dbg("hello dbg") + +print('- Testing log.style()') + +log.style(time=True, category=False, level=False, origin=False, src=False, time_fmt=fake_time) +t.dbg("only time") +log.style(time=False, category=True, level=False, origin=False, src=False, time_fmt=fake_time) +t.dbg("only category") +log.style(time=False, category=False, level=True, origin=False, src=False, time_fmt=fake_time) +t.dbg("only level") +log.style(time=False, category=False, level=False, origin=True, src=False, time_fmt=fake_time) +t.dbg("only origin") +log.style(time=False, category=False, level=False, origin=False, src=True, time_fmt=fake_time) +t.dbg("only src") + +print('- Testing log.style_change()') +log.style(time=False, category=False, level=False, origin=False, src=False, time_fmt=fake_time) +t.dbg("no log format") +log.style_change(time=True) +t.dbg("add time") +log.style_change(time=True, time_fmt=0) +t.dbg("but no time format") +log.style_change(time=True, time_fmt=fake_time) +log.style_change(level=True) +t.dbg("add level") +log.style_change(category=True) +t.dbg("add category") +log.style_change(src=True) +t.dbg("add src") +log.style_change(origin=True) +t.dbg("add origin") + +print('- Testing origin_width') +t = LogTest('shortname') +log.style(origin_width=23, time_fmt=fake_time) +t.log("origin str set to 23 chars") +t.set_name('very long name', some='details', and_some=(3, 'things', 'in a tuple')) +t.log("long origin str") +t.dbg("long origin str dbg") +t.err("long origin str err") + +print('- Testing log.Origin with omitted info') +t = LogTest() +t.log("hello log, name implicit from class name") + +t = LogTest('explicit_name') +t._set_log_category(None) +t.log("hello log, no category set") + +t = LogTest() +t._set_log_category(None) +t.log("hello log, no category nor name set") +t.dbg("hello log, no category nor name set, not seen") +log.set_level(log.C_DEFAULT, log.L_DBG) +t.dbg("debug message, no category nor name set") + +print('- Testing logging of Exceptions, tracing origins') +log.style(time_fmt=fake_time, origin_width=0) + +class Thing(log.Origin): + def __init__(self, some_path): + super().__init__(log.C_TST, some_path) + + def say(self, msg): + print(msg) + + def l1(self): + level2 = Thing('level2') + level2.l2() + + def l2(self): + level3 = Thing('level3') + level3.l3(self) + + def l3(self, level2): + print('nested print just prints') + self.log('nested log()') + level2.log('nested l2 log() from within l3 scope') + raise ValueError('bork') + +try: + level1 = Thing('level1') + level1.l1() +except Exception: + log.log_exn() + +print('- Disallow origin loops') +try: + t = Thing('foo') + t._set_parent(t) + raise RuntimeError('this should not be reached') +except log.OriginLoopError: + print('disallowed successfully') + pass + +# vim: expandtab tabstop=4 shiftwidth=4 diff --git a/selftest/process_test.err b/selftest/process_test.err deleted file mode 100644 index e69de29..0000000 diff --git a/selftest/process_test.ok b/selftest/process_test.ok deleted file mode 100644 index e40a461..0000000 --- a/selftest/process_test.ok +++ /dev/null @@ -1,30 +0,0 @@ -run foo: DBG: cd '[TMP]'; PATH=[$PATH] foo.py arg1 arg2 -run foo: DBG: [TMP]/stdout -run foo: DBG: [TMP]/stderr -run foo(pid=[PID]): Launched -stdout: -(launched: [DATETIME]) -foo stdout -[[$0], 'arg1', 'arg2'] - -stderr: -(launched: [DATETIME]) -foo stderr - -run foo(pid=[PID]): Terminating (SIGINT) -run foo(pid=[PID]): DBG: Cleanup -run foo(pid=[PID]): Terminated {rc=42} -result: 42 -stdout: -(launched: [DATETIME]) -foo stdout -[[$0], 'arg1', 'arg2'] -SIGINT received -Exiting (stdout) - -stderr: -(launched: [DATETIME]) -foo stderr -Exiting (stderr) - -done. diff --git a/selftest/process_test.ok.ign b/selftest/process_test.ok.ign deleted file mode 100644 index b817f5a..0000000 --- a/selftest/process_test.ok.ign +++ /dev/null @@ -1,7 +0,0 @@ -PATH='[^']*' PATH=[$PATH] -/tmp/[^/ '"]* [TMP] -pid=[0-9]* pid=[PID] -....-..-.._..:..:..\....... [DATETIME] -'[^']*/selftest/process_test/foo.py' [$0] -"[^"]*/selftest/process_test/foo.py" [$0] -, line [0-9]* , line [LINE] diff --git a/selftest/process_test.py b/selftest/process_test.py deleted file mode 100755 index de4f7a6..0000000 --- a/selftest/process_test.py +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env python3 - -import _prep -import time -import os - -from osmo_gsm_tester.core import process, util, log - -tmpdir = util.Dir(util.get_tempdir()) - -dollar_path = '%s:%s' % ( - os.path.join(os.getcwd(), 'process_test'), - os.getenv('PATH')) - -p = process.Process('foo', tmpdir, ('foo.py', 'arg1', 'arg2'), - env={'PATH': dollar_path}) - -p.launch() -time.sleep(.5) -p.poll() -print('stdout:') -print(p.get_stdout()) -print('stderr:') -print(p.get_stderr()) - -assert not p.terminated() -p.terminate() -assert p.terminated() -print('result: %r' % p.result) - -print('stdout:') -print(p.get_stdout()) -print('stderr:') -print(p.get_stderr()) -print('done.') - -test_ssh = True -test_ssh = False -if test_ssh: - # this part of the test requires ability to ssh to localhost - p = process.RemoteProcess('ssh-test', '/tmp', os.getenv('USER'), 'localhost', tmpdir, - ('ls', '-al')) - p.launch() - p.wait() - assert p.terminated() - print('stdout:') - print(p.get_stdout()) - print('stderr:') - print(p.get_stderr()) - -# vim: expandtab tabstop=4 shiftwidth=4 diff --git a/selftest/process_test/_prep.py b/selftest/process_test/_prep.py new file mode 120000 index 0000000..9cea3fe --- /dev/null +++ b/selftest/process_test/_prep.py @@ -0,0 +1 @@ +../_prep.py \ No newline at end of file diff --git a/selftest/process_test/process_test.err b/selftest/process_test/process_test.err new file mode 100644 index 0000000..e69de29 diff --git a/selftest/process_test/process_test.ok b/selftest/process_test/process_test.ok new file mode 100644 index 0000000..e40a461 --- /dev/null +++ b/selftest/process_test/process_test.ok @@ -0,0 +1,30 @@ +run foo: DBG: cd '[TMP]'; PATH=[$PATH] foo.py arg1 arg2 +run foo: DBG: [TMP]/stdout +run foo: DBG: [TMP]/stderr +run foo(pid=[PID]): Launched +stdout: +(launched: [DATETIME]) +foo stdout +[[$0], 'arg1', 'arg2'] + +stderr: +(launched: [DATETIME]) +foo stderr + +run foo(pid=[PID]): Terminating (SIGINT) +run foo(pid=[PID]): DBG: Cleanup +run foo(pid=[PID]): Terminated {rc=42} +result: 42 +stdout: +(launched: [DATETIME]) +foo stdout +[[$0], 'arg1', 'arg2'] +SIGINT received +Exiting (stdout) + +stderr: +(launched: [DATETIME]) +foo stderr +Exiting (stderr) + +done. diff --git a/selftest/process_test/process_test.ok.ign b/selftest/process_test/process_test.ok.ign new file mode 100644 index 0000000..b817f5a --- /dev/null +++ b/selftest/process_test/process_test.ok.ign @@ -0,0 +1,7 @@ +PATH='[^']*' PATH=[$PATH] +/tmp/[^/ '"]* [TMP] +pid=[0-9]* pid=[PID] +....-..-.._..:..:..\....... [DATETIME] +'[^']*/selftest/process_test/foo.py' [$0] +"[^"]*/selftest/process_test/foo.py" [$0] +, line [0-9]* , line [LINE] diff --git a/selftest/process_test/process_test.py b/selftest/process_test/process_test.py new file mode 100755 index 0000000..de4f7a6 --- /dev/null +++ b/selftest/process_test/process_test.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python3 + +import _prep +import time +import os + +from osmo_gsm_tester.core import process, util, log + +tmpdir = util.Dir(util.get_tempdir()) + +dollar_path = '%s:%s' % ( + os.path.join(os.getcwd(), 'process_test'), + os.getenv('PATH')) + +p = process.Process('foo', tmpdir, ('foo.py', 'arg1', 'arg2'), + env={'PATH': dollar_path}) + +p.launch() +time.sleep(.5) +p.poll() +print('stdout:') +print(p.get_stdout()) +print('stderr:') +print(p.get_stderr()) + +assert not p.terminated() +p.terminate() +assert p.terminated() +print('result: %r' % p.result) + +print('stdout:') +print(p.get_stdout()) +print('stderr:') +print(p.get_stderr()) +print('done.') + +test_ssh = True +test_ssh = False +if test_ssh: + # this part of the test requires ability to ssh to localhost + p = process.RemoteProcess('ssh-test', '/tmp', os.getenv('USER'), 'localhost', tmpdir, + ('ls', '-al')) + p.launch() + p.wait() + assert p.terminated() + print('stdout:') + print(p.get_stdout()) + print('stderr:') + print(p.get_stderr()) + +# vim: expandtab tabstop=4 shiftwidth=4 diff --git a/selftest/resource_test.err b/selftest/resource_test.err deleted file mode 100644 index e69de29..0000000 diff --git a/selftest/resource_test.ok b/selftest/resource_test.ok deleted file mode 100644 index 6147408..0000000 --- a/selftest/resource_test.ok +++ /dev/null @@ -1,289 +0,0 @@ -- expect solutions: -[0, 1, 2] -[0, 1, 2] -[1, 0, 2] -[1, 2, 0] -- expect failure to solve: -The requested resource requirements are not solvable [[0, 2], [2], [0, 2]] -- test removing a Resources list from itself -ok, caused exception RuntimeError: Refusing to drop a list of resources from itself. This is probably a bug where a list of Resources() should have been copied but is passed as-is. use Resources.clear() instead. -- test removing a Resources list from one with the same list in it -- test resources config and state dir: -cnf -: DBG: Found config file paths.conf as [PATH]/selftest/conf/paths.conf in ./conf which is [PATH]/selftest/conf -cnf -: DBG: [PATH]/selftest/conf/paths.conf: relative path ./test_work/state_dir is [PATH]/selftest/conf/test_work/state_dir -cnf -: DBG: [PATH]/selftest/conf/paths.conf: relative path ./suite_test is [PATH]/selftest/conf/suite_test -cnf -: DBG: Found path state_dir as [PATH]/selftest/conf/test_work/state_dir -cnf ResourcesPool: DBG: Found config file resources.conf as [PATH]/selftest/conf/resources.conf in ./conf which is [PATH]/selftest/conf -cnf ResourcesPool: DBG: Found path state_dir as [PATH]/selftest/conf/test_work/state_dir -*** all resources: -{'arfcn': [{'_hash': 'e620569450f8259b3f0212ec19c285dd07df063c', - 'arfcn': '512', - 'band': 'GSM-1800'}, - {'_hash': '022621e513c5a5bf33b77430a1e9c886be676fa1', - 'arfcn': '514', - 'band': 'GSM-1800'}, - {'_hash': '3199abf375a1dd899e554e9d63a552e06d7f38bf', - 'arfcn': '516', - 'band': 'GSM-1800'}, - {'_hash': '57aa7bd1da62495f2857ae6b859193dd592a0a02', - 'arfcn': '518', - 'band': 'GSM-1800'}, - {'_hash': '53dd2e2682b736f427abd2ce59a9a50ca8130678', - 'arfcn': '520', - 'band': 'GSM-1800'}, - {'_hash': '31687a5e6d5140a4b3877606ca5f18244f11d706', - 'arfcn': '540', - 'band': 'GSM-1900'}, - {'_hash': '1def43a5c88a83cdb21279eacab0679ea08ffaf3', - 'arfcn': '542', - 'band': 'GSM-1900'}, - {'_hash': '1d6e3b08a3861fd4d748f111295ec5a93ecd3d23', - 'arfcn': '544', - 'band': 'GSM-1900'}, - {'_hash': '8fb36927de15466fcdbee01f7f65704c312cb36c', - 'arfcn': '546', - 'band': 'GSM-1900'}, - {'_hash': 'dc9ce027a257da087f31a5bc1ee6b4abd2637369', - 'arfcn': '548', - 'band': 'GSM-1900'}], - 'bts': [{'_hash': 'd2aa7c1124943de352351b650ca0c751784da6b6', - 'addr': '10.42.42.114', - 'band': 'GSM-1800', - 'ciphers': ['a5_0', 'a5_1'], - 'direct_pcu': 'True', - 'ipa_unit_id': '1', - 'label': 'sysmoBTS 1002', - 'type': 'osmo-bts-sysmo'}, - {'_hash': '2158317d5e0055070e7174c2498dedf53a2957e9', - 'addr': '10.42.42.50', - 'band': 'GSM-1800', - 'ciphers': ['a5_0', 'a5_1'], - 'ipa_unit_id': '6', - 'label': 'Ettus B200', - 'osmo_trx': {'clock_reference': 'external', 'launch_trx': 'True'}, - 'type': 'osmo-bts-trx'}, - {'_hash': 'f964ba5fe7a37b97ec3e0c4ef21c9231a19de45d', - 'addr': '10.42.42.51', - 'band': 'GSM-1800', - 'ciphers': ['a5_0', 'a5_1'], - 'ipa_unit_id': '7', - 'label': 'sysmoCell 5000', - 'osmo_trx': {'clock_reference': 'external', - 'launch_trx': 'False', - 'trx_ip': '10.42.42.112'}, - 'type': 'osmo-bts-trx'}], - 'ip_address': [{'_hash': 'fd103b22c7cf2480d609150e06f4bbd92ac78d8c', - 'addr': '10.42.42.2'}, - {'_hash': '1c614d6210c551d142aadca8f25e1534ebb2a70f', - 'addr': '10.42.42.3'}, - {'_hash': '862b529c701adf302477bc126a8032cfc2ec4753', - 'addr': '10.42.42.4'}, - {'_hash': '05feb6e1e24ca4235889eb28d0a8d5cedac6e5d1', - 'addr': '10.42.42.5'}, - {'_hash': 'e780ac7581ad29f8f46e637b61d0c38898c4c52c', - 'addr': '10.42.42.6'}], - 'modem': [{'_hash': '0b538cb6ad799fbd7c2953fd3b4463a76c7cc9c0', - 'auth_algo': 'comp128v1', - 'ciphers': ['a5_0', 'a5_1'], - 'imsi': '901700000009031', - 'ki': '80A37E6FDEA931EAC92FFA5F671EFEAD', - 'label': 'sierra_1', - 'path': '/sierra_1'}, - {'_hash': '3a6e7747dfe7dfdf817bd3351031bd08051605c3', - 'auth_algo': 'comp128v1', - 'ciphers': ['a5_0', 'a5_1'], - 'imsi': '901700000009029', - 'ki': '00969E283349D354A8239E877F2E0866', - 'label': 'sierra_2', - 'path': '/sierra_2'}, - {'_hash': 'f6ba17db2ad13da5ba5c54b5385a774f5351bb5a', - 'auth_algo': 'comp128v1', - 'ciphers': ['a5_0', 'a5_1'], - 'imsi': '901700000009030', - 'ki': 'BB70807226393CDBAC8DD3439FF54252', - 'label': 'gobi_0', - 'path': '/gobi_0'}, - {'_hash': 'fbff2e4f06b727fc8a70da23e1d134f9cd763919', - 'auth_algo': 'comp128v1', - 'ciphers': ['a5_0', 'a5_1'], - 'imsi': '901700000009032', - 'ki': '2F70DCA43C45ACB97E947FDD0C7CA30A', - 'label': 'gobi_3', - 'path': '/gobi_3'}]} -*** end: all resources - -- request some resources ---- testowner: Reserving 2 x arfcn (candidates: 10) ---- testowner: DBG: Picked - _hash: e620569450f8259b3f0212ec19c285dd07df063c - arfcn: '512' - band: GSM-1800 -- _hash: 022621e513c5a5bf33b77430a1e9c886be676fa1 - arfcn: '514' - band: GSM-1800 ---- testowner: Reserving 2 x bts (candidates: 3) ---- testowner: DBG: Picked - _hash: d2aa7c1124943de352351b650ca0c751784da6b6 - addr: 10.42.42.114 - band: GSM-1800 - ciphers: - - a5_0 - - a5_1 - direct_pcu: 'True' - ipa_unit_id: '1' - label: sysmoBTS 1002 - type: osmo-bts-sysmo -- _hash: 2158317d5e0055070e7174c2498dedf53a2957e9 - addr: 10.42.42.50 - band: GSM-1800 - ciphers: - - a5_0 - - a5_1 - ipa_unit_id: '6' - label: Ettus B200 - osmo_trx: - clock_reference: external - launch_trx: 'True' - type: osmo-bts-trx ---- testowner: Reserving 1 x ip_address (candidates: 5) ---- testowner: DBG: Picked - _hash: fd103b22c7cf2480d609150e06f4bbd92ac78d8c - addr: 10.42.42.2 ---- testowner: Reserving 2 x modem (candidates: 4) ---- testowner: DBG: Picked - _hash: 0b538cb6ad799fbd7c2953fd3b4463a76c7cc9c0 - auth_algo: comp128v1 - ciphers: - - a5_0 - - a5_1 - imsi: '901700000009031' - ki: 80A37E6FDEA931EAC92FFA5F671EFEAD - label: sierra_1 - path: /sierra_1 -- _hash: 3a6e7747dfe7dfdf817bd3351031bd08051605c3 - auth_algo: comp128v1 - ciphers: - - a5_0 - - a5_1 - imsi: '901700000009029' - ki: 00969E283349D354A8239E877F2E0866 - label: sierra_2 - path: /sierra_2 -~~~ currently reserved: -arfcn: -- _hash: e620569450f8259b3f0212ec19c285dd07df063c - _reserved_by: testowner-123-1490837279 - arfcn: '512' - band: GSM-1800 -- _hash: 022621e513c5a5bf33b77430a1e9c886be676fa1 - _reserved_by: testowner-123-1490837279 - arfcn: '514' - band: GSM-1800 -bts: -- _hash: d2aa7c1124943de352351b650ca0c751784da6b6 - _reserved_by: testowner-123-1490837279 - addr: 10.42.42.114 - band: GSM-1800 - ciphers: - - a5_0 - - a5_1 - direct_pcu: 'True' - ipa_unit_id: '1' - label: sysmoBTS 1002 - type: osmo-bts-sysmo -- _hash: 2158317d5e0055070e7174c2498dedf53a2957e9 - _reserved_by: testowner-123-1490837279 - addr: 10.42.42.50 - band: GSM-1800 - ciphers: - - a5_0 - - a5_1 - ipa_unit_id: '6' - label: Ettus B200 - osmo_trx: - clock_reference: external - launch_trx: 'True' - type: osmo-bts-trx -ip_address: -- _hash: fd103b22c7cf2480d609150e06f4bbd92ac78d8c - _reserved_by: testowner-123-1490837279 - addr: 10.42.42.2 -modem: -- _hash: 0b538cb6ad799fbd7c2953fd3b4463a76c7cc9c0 - _reserved_by: testowner-123-1490837279 - auth_algo: comp128v1 - ciphers: - - a5_0 - - a5_1 - imsi: '901700000009031' - ki: 80A37E6FDEA931EAC92FFA5F671EFEAD - label: sierra_1 - path: /sierra_1 -- _hash: 3a6e7747dfe7dfdf817bd3351031bd08051605c3 - _reserved_by: testowner-123-1490837279 - auth_algo: comp128v1 - ciphers: - - a5_0 - - a5_1 - imsi: '901700000009029' - ki: 00969E283349D354A8239E877F2E0866 - label: sierra_2 - path: /sierra_2 - -~~~ end: currently reserved - -~~~ with modifiers: -resources(testowner)={'arfcn': [{'_hash': 'e620569450f8259b3f0212ec19c285dd07df063c', - '_reserved_by': 'testowner-123-1490837279', - 'arfcn': '512', - 'band': 'GSM-1800'}, - {'_hash': '022621e513c5a5bf33b77430a1e9c886be676fa1', - '_reserved_by': 'testowner-123-1490837279', - 'arfcn': '514', - 'band': 'GSM-1800'}], - 'bts': [{'_hash': 'd2aa7c1124943de352351b650ca0c751784da6b6', - '_reserved_by': 'testowner-123-1490837279', - 'addr': '10.42.42.114', - 'band': 'GSM-1800', - 'ciphers': ['a5_0', 'a5_1'], - 'direct_pcu': 'True', - 'ipa_unit_id': '1', - 'label': 'sysmoBTS 1002', - 'type': 'osmo-bts-sysmo'}, - {'_hash': '2158317d5e0055070e7174c2498dedf53a2957e9', - '_reserved_by': 'testowner-123-1490837279', - 'addr': '10.42.42.50', - 'band': 'GSM-1800', - 'ciphers': ['a5_0', 'a5_1'], - 'ipa_unit_id': '6', - 'label': 'Ettus B200', - 'num_trx': 2, - 'osmo_trx': {'clock_reference': 'external', 'launch_trx': 'True'}, - 'type': 'osmo-bts-trx'}], - 'ip_address': [{'_hash': 'fd103b22c7cf2480d609150e06f4bbd92ac78d8c', - '_reserved_by': 'testowner-123-1490837279', - 'addr': '10.42.42.2'}], - 'modem': [{'_hash': '0b538cb6ad799fbd7c2953fd3b4463a76c7cc9c0', - '_reserved_by': 'testowner-123-1490837279', - 'auth_algo': 'comp128v1', - 'ciphers': ['a5_0', 'a5_1'], - 'imsi': '901700000009031', - 'ki': '80A37E6FDEA931EAC92FFA5F671EFEAD', - 'label': 'sierra_1', - 'path': '/sierra_1'}, - {'_hash': '3a6e7747dfe7dfdf817bd3351031bd08051605c3', - '_reserved_by': 'testowner-123-1490837279', - 'auth_algo': 'comp128v1', - 'ciphers': ['a5_0', 'a5_1'], - 'imsi': '901700000009029', - 'ki': '00969E283349D354A8239E877F2E0866', - 'label': 'sierra_2', - 'path': '/sierra_2'}]} -~~~ end: with modifiers: -~~~ currently reserved: -{} - -~~~ end: currently reserved - -- item_matches: -1st subset matches correctly, pass -2nd subset matches correctly, pass -3rd subset should not match, pass -3rd subset should not match, pass -4th subset should not match, pass diff --git a/selftest/resource_test.ok.ign b/selftest/resource_test.ok.ign deleted file mode 100644 index 393ce95..0000000 --- a/selftest/resource_test.ok.ign +++ /dev/null @@ -1 +0,0 @@ -/[^ ]*/selftest/ [PATH]/selftest/ diff --git a/selftest/resource_test.py b/selftest/resource_test.py deleted file mode 100755 index 3f7cd51..0000000 --- a/selftest/resource_test.py +++ /dev/null @@ -1,130 +0,0 @@ -#!/usr/bin/env python3 - -import tempfile -import os -import pprint -import shutil -import atexit -import _prep -from osmo_gsm_tester.core import config, log, util, resource -from osmo_gsm_tester.core.schema import generate_schemas - -workdir = util.get_tempdir() - -# override config locations to make sure we use only the test conf -config.ENV_CONF = './conf' - -log.get_process_id = lambda: '123-1490837279' - -# Generate supported schemas dynamically from objects: -generate_schemas() - -print('- expect solutions:') -pprint.pprint( - resource.solve([ [0, 1, 2], - [0, 1, 2], - [0, 1, 2] ]) ) -pprint.pprint( - resource.solve([ [0, 1, 2], - [0, 1], - [0, 2] ]) ) # == [0, 1, 2] -pprint.pprint( - resource.solve([ [0, 1, 2], - [0], - [0, 2] ]) ) # == [1, 0, 2] -pprint.pprint( - resource.solve([ [0, 1, 2], - [2], - [0, 2] ]) ) # == [1, 2, 0] - -print('- expect failure to solve:') -try: - resource.solve([ [0, 2], - [2], - [0, 2] ]) - assert False -except resource.NotSolvable as e: - print(e) - -print('- test removing a Resources list from itself') -try: - r = resource.Resources({ 'k': [ {'a': 1, 'b': 2}, {'a': 3, 'b': 4}, ], - 'i': [ {'c': 1, 'd': 2}, {'c': 3, 'd': 4}, ] }) - r.drop(r) - assert False -except RuntimeError as e: - print('ok, caused exception RuntimeError: %s' % str(e)) - -print('- test removing a Resources list from one with the same list in it') -r = resource.Resources({ 'k': [ {'a': 1, 'b': 2}, {'a': 3, 'b': 4}, ], - 'i': [ {'c': 1, 'd': 2}, {'c': 3, 'd': 4}, ] }) -r.drop({ 'k': r.get('k'), 'i': r.get('i') }) -assert not r - -print('- test resources config and state dir:') -resources_conf = os.path.join(_prep.script_dir, 'resource_test', 'etc', - 'resources.conf') - -state_dir = config.get_state_dir() -rrfile = state_dir.child(resource.RESERVED_RESOURCES_FILE) - -pool = resource.ResourcesPool() - -print('*** all resources:') -pprint.pprint(pool.all_resources) -print('*** end: all resources\n') - -print('- request some resources') -want = { - 'ip_address': [ { 'times': 1 } ], - 'bts': [ { 'type': 'osmo-bts-sysmo', 'times': 1 , 'ciphers': ['a5_1']}, { 'type': 'osmo-bts-trx', 'times': 1 } ], - 'arfcn': [ { 'band': 'GSM-1800', 'times': 2 } ], - 'modem': [ { 'times': 2 , 'ciphers': ['a5_0', 'a5_1']} ], - } -modifiers = { - 'bts': [ {}, {'num_trx': 2 }], -} -origin = log.Origin(None, 'testowner') - -resources = pool.reserve(origin, config.replicate_times(want), config.replicate_times(modifiers)) - -print('~~~ currently reserved:') -with open(rrfile, 'r') as f: - print(f.read()) -print('~~~ end: currently reserved\n') - -print('~~~ with modifiers:') -print(repr(resources)) -print('~~~ end: with modifiers:') - -resources.free() - -print('~~~ currently reserved:') -with open(rrfile, 'r') as f: - print(f.read()) -print('~~~ end: currently reserved\n') - -print('- item_matches:') -superset = { 'hello': 'world', 'foo': 'bar', 'ordered_list': [{'xkey': 'xvalue'},{'ykey': 'yvalue'}], 'unordered_list_set': [1, 2, 3]} - -subset = { 'foo': 'bar', 'ordered_list': [{'xkey': 'xvalue'},{'ykey': 'yvalue'}], 'unordered_list_set': [2, 1] } -if resource.item_matches(superset, subset): - print('1st subset matches correctly, pass') - -subset = { 'ordered_list': [{},{'ykey': 'yvalue'}], 'unordered_list_set': [] } -if resource.item_matches(superset, subset): - print('2nd subset matches correctly, pass') - -subset = { 'ordered_list': [{'ykey': 'yvalue'}, {'xkey': 'xvalue'}] } -if not resource.item_matches(superset, subset): - print('3rd subset should not match, pass') - -subset = { 'ordered_list': [{'xkey': 'xvalue'}, {'ykey': 'yvalue'}, {'zkey': 'zvalue'}] } -if not resource.item_matches(superset, subset): - print('3rd subset should not match, pass') - -subset = { 'unordered_list_set': [4] } -if not resource.item_matches(superset, subset): - print('4th subset should not match, pass') - -# vim: expandtab tabstop=4 shiftwidth=4 diff --git a/selftest/resource_test/_prep.py b/selftest/resource_test/_prep.py new file mode 120000 index 0000000..9cea3fe --- /dev/null +++ b/selftest/resource_test/_prep.py @@ -0,0 +1 @@ +../_prep.py \ No newline at end of file diff --git a/selftest/resource_test/conf/paths.conf b/selftest/resource_test/conf/paths.conf new file mode 100644 index 0000000..0b2d035 --- /dev/null +++ b/selftest/resource_test/conf/paths.conf @@ -0,0 +1,2 @@ +state_dir: ./test_work/state_dir +suites_dir: ./suite_test diff --git a/selftest/resource_test/conf/resources.conf b/selftest/resource_test/conf/resources.conf new file mode 100644 index 0000000..84d0ab9 --- /dev/null +++ b/selftest/resource_test/conf/resources.conf @@ -0,0 +1,103 @@ +# all hardware and interfaces available to this osmo-gsm-tester + +ip_address: +- addr: 10.42.42.2 +- addr: 10.42.42.3 +- addr: 10.42.42.4 +- addr: 10.42.42.5 +- addr: 10.42.42.6 + +bts: +- label: sysmoBTS 1002 + type: osmo-bts-sysmo + ipa_unit_id: 1 + addr: 10.42.42.114 + band: GSM-1800 + direct_pcu: true + ciphers: + - 'a5_0' + - 'a5_1' + +- label: Ettus B200 + type: osmo-bts-trx + ipa_unit_id: 6 + addr: 10.42.42.50 + band: GSM-1800 + osmo_trx: + launch_trx: true + clock_reference: external + ciphers: + - 'a5_0' + - 'a5_1' + +- label: sysmoCell 5000 + type: osmo-bts-trx + ipa_unit_id: 7 + addr: 10.42.42.51 + band: GSM-1800 + osmo_trx: + launch_trx: false + clock_reference: external + trx_ip: 10.42.42.112 + ciphers: + - 'a5_0' + - 'a5_1' + +arfcn: + - arfcn: 512 + band: GSM-1800 + - arfcn: 514 + band: GSM-1800 + - arfcn: 516 + band: GSM-1800 + - arfcn: 518 + band: GSM-1800 + - arfcn: 520 + band: GSM-1800 + - arfcn: 540 + band: GSM-1900 + - arfcn: 542 + band: GSM-1900 + - arfcn: 544 + band: GSM-1900 + - arfcn: 546 + band: GSM-1900 + - arfcn: 548 + band: GSM-1900 + +modem: +- label: sierra_1 + path: '/sierra_1' + imsi: '901700000009031' + ki: '80A37E6FDEA931EAC92FFA5F671EFEAD' + auth_algo: 'comp128v1' + ciphers: + - 'a5_0' + - 'a5_1' + +- label: sierra_2 + path: '/sierra_2' + imsi: '901700000009029' + ki: '00969E283349D354A8239E877F2E0866' + auth_algo: 'comp128v1' + ciphers: + - 'a5_0' + - 'a5_1' + +- label: gobi_0 + path: '/gobi_0' + imsi: '901700000009030' + ki: 'BB70807226393CDBAC8DD3439FF54252' + auth_algo: 'comp128v1' + ciphers: + - 'a5_0' + - 'a5_1' + +- label: gobi_3 + path: '/gobi_3' + imsi: '901700000009032' + ki: '2F70DCA43C45ACB97E947FDD0C7CA30A' + auth_algo: 'comp128v1' + ciphers: + - 'a5_0' + - 'a5_1' diff --git a/selftest/resource_test/resource_test.err b/selftest/resource_test/resource_test.err new file mode 100644 index 0000000..e69de29 diff --git a/selftest/resource_test/resource_test.ok b/selftest/resource_test/resource_test.ok new file mode 100644 index 0000000..bbdbc5b --- /dev/null +++ b/selftest/resource_test/resource_test.ok @@ -0,0 +1,289 @@ +- expect solutions: +[0, 1, 2] +[0, 1, 2] +[1, 0, 2] +[1, 2, 0] +- expect failure to solve: +The requested resource requirements are not solvable [[0, 2], [2], [0, 2]] +- test removing a Resources list from itself +ok, caused exception RuntimeError: Refusing to drop a list of resources from itself. This is probably a bug where a list of Resources() should have been copied but is passed as-is. use Resources.clear() instead. +- test removing a Resources list from one with the same list in it +- test resources config and state dir: +cnf -: DBG: Found config file paths.conf as [PATH]/selftest/resource_test/conf/paths.conf in [PATH]/selftest/resource_test/conf which is [PATH]/selftest/resource_test/conf +cnf -: DBG: [PATH]/selftest/resource_test/conf/paths.conf: relative path ./test_work/state_dir is [PATH]/selftest/resource_test/conf/test_work/state_dir +cnf -: DBG: [PATH]/selftest/resource_test/conf/paths.conf: relative path ./suite_test is [PATH]/selftest/resource_test/conf/suite_test +cnf -: DBG: Found path state_dir as [PATH]/selftest/resource_test/conf/test_work/state_dir +cnf ResourcesPool: DBG: Found config file resources.conf as [PATH]/selftest/resource_test/conf/resources.conf in [PATH]/selftest/resource_test/conf which is [PATH]/selftest/resource_test/conf +cnf ResourcesPool: DBG: Found path state_dir as [PATH]/selftest/resource_test/conf/test_work/state_dir +*** all resources: +{'arfcn': [{'_hash': 'e620569450f8259b3f0212ec19c285dd07df063c', + 'arfcn': '512', + 'band': 'GSM-1800'}, + {'_hash': '022621e513c5a5bf33b77430a1e9c886be676fa1', + 'arfcn': '514', + 'band': 'GSM-1800'}, + {'_hash': '3199abf375a1dd899e554e9d63a552e06d7f38bf', + 'arfcn': '516', + 'band': 'GSM-1800'}, + {'_hash': '57aa7bd1da62495f2857ae6b859193dd592a0a02', + 'arfcn': '518', + 'band': 'GSM-1800'}, + {'_hash': '53dd2e2682b736f427abd2ce59a9a50ca8130678', + 'arfcn': '520', + 'band': 'GSM-1800'}, + {'_hash': '31687a5e6d5140a4b3877606ca5f18244f11d706', + 'arfcn': '540', + 'band': 'GSM-1900'}, + {'_hash': '1def43a5c88a83cdb21279eacab0679ea08ffaf3', + 'arfcn': '542', + 'band': 'GSM-1900'}, + {'_hash': '1d6e3b08a3861fd4d748f111295ec5a93ecd3d23', + 'arfcn': '544', + 'band': 'GSM-1900'}, + {'_hash': '8fb36927de15466fcdbee01f7f65704c312cb36c', + 'arfcn': '546', + 'band': 'GSM-1900'}, + {'_hash': 'dc9ce027a257da087f31a5bc1ee6b4abd2637369', + 'arfcn': '548', + 'band': 'GSM-1900'}], + 'bts': [{'_hash': 'd2aa7c1124943de352351b650ca0c751784da6b6', + 'addr': '10.42.42.114', + 'band': 'GSM-1800', + 'ciphers': ['a5_0', 'a5_1'], + 'direct_pcu': 'True', + 'ipa_unit_id': '1', + 'label': 'sysmoBTS 1002', + 'type': 'osmo-bts-sysmo'}, + {'_hash': '2158317d5e0055070e7174c2498dedf53a2957e9', + 'addr': '10.42.42.50', + 'band': 'GSM-1800', + 'ciphers': ['a5_0', 'a5_1'], + 'ipa_unit_id': '6', + 'label': 'Ettus B200', + 'osmo_trx': {'clock_reference': 'external', 'launch_trx': 'True'}, + 'type': 'osmo-bts-trx'}, + {'_hash': 'f964ba5fe7a37b97ec3e0c4ef21c9231a19de45d', + 'addr': '10.42.42.51', + 'band': 'GSM-1800', + 'ciphers': ['a5_0', 'a5_1'], + 'ipa_unit_id': '7', + 'label': 'sysmoCell 5000', + 'osmo_trx': {'clock_reference': 'external', + 'launch_trx': 'False', + 'trx_ip': '10.42.42.112'}, + 'type': 'osmo-bts-trx'}], + 'ip_address': [{'_hash': 'fd103b22c7cf2480d609150e06f4bbd92ac78d8c', + 'addr': '10.42.42.2'}, + {'_hash': '1c614d6210c551d142aadca8f25e1534ebb2a70f', + 'addr': '10.42.42.3'}, + {'_hash': '862b529c701adf302477bc126a8032cfc2ec4753', + 'addr': '10.42.42.4'}, + {'_hash': '05feb6e1e24ca4235889eb28d0a8d5cedac6e5d1', + 'addr': '10.42.42.5'}, + {'_hash': 'e780ac7581ad29f8f46e637b61d0c38898c4c52c', + 'addr': '10.42.42.6'}], + 'modem': [{'_hash': '0b538cb6ad799fbd7c2953fd3b4463a76c7cc9c0', + 'auth_algo': 'comp128v1', + 'ciphers': ['a5_0', 'a5_1'], + 'imsi': '901700000009031', + 'ki': '80A37E6FDEA931EAC92FFA5F671EFEAD', + 'label': 'sierra_1', + 'path': '/sierra_1'}, + {'_hash': '3a6e7747dfe7dfdf817bd3351031bd08051605c3', + 'auth_algo': 'comp128v1', + 'ciphers': ['a5_0', 'a5_1'], + 'imsi': '901700000009029', + 'ki': '00969E283349D354A8239E877F2E0866', + 'label': 'sierra_2', + 'path': '/sierra_2'}, + {'_hash': 'f6ba17db2ad13da5ba5c54b5385a774f5351bb5a', + 'auth_algo': 'comp128v1', + 'ciphers': ['a5_0', 'a5_1'], + 'imsi': '901700000009030', + 'ki': 'BB70807226393CDBAC8DD3439FF54252', + 'label': 'gobi_0', + 'path': '/gobi_0'}, + {'_hash': 'fbff2e4f06b727fc8a70da23e1d134f9cd763919', + 'auth_algo': 'comp128v1', + 'ciphers': ['a5_0', 'a5_1'], + 'imsi': '901700000009032', + 'ki': '2F70DCA43C45ACB97E947FDD0C7CA30A', + 'label': 'gobi_3', + 'path': '/gobi_3'}]} +*** end: all resources + +- request some resources +--- testowner: Reserving 2 x arfcn (candidates: 10) +--- testowner: DBG: Picked - _hash: e620569450f8259b3f0212ec19c285dd07df063c + arfcn: '512' + band: GSM-1800 +- _hash: 022621e513c5a5bf33b77430a1e9c886be676fa1 + arfcn: '514' + band: GSM-1800 +--- testowner: Reserving 2 x bts (candidates: 3) +--- testowner: DBG: Picked - _hash: d2aa7c1124943de352351b650ca0c751784da6b6 + addr: 10.42.42.114 + band: GSM-1800 + ciphers: + - a5_0 + - a5_1 + direct_pcu: 'True' + ipa_unit_id: '1' + label: sysmoBTS 1002 + type: osmo-bts-sysmo +- _hash: 2158317d5e0055070e7174c2498dedf53a2957e9 + addr: 10.42.42.50 + band: GSM-1800 + ciphers: + - a5_0 + - a5_1 + ipa_unit_id: '6' + label: Ettus B200 + osmo_trx: + clock_reference: external + launch_trx: 'True' + type: osmo-bts-trx +--- testowner: Reserving 1 x ip_address (candidates: 5) +--- testowner: DBG: Picked - _hash: fd103b22c7cf2480d609150e06f4bbd92ac78d8c + addr: 10.42.42.2 +--- testowner: Reserving 2 x modem (candidates: 4) +--- testowner: DBG: Picked - _hash: 0b538cb6ad799fbd7c2953fd3b4463a76c7cc9c0 + auth_algo: comp128v1 + ciphers: + - a5_0 + - a5_1 + imsi: '901700000009031' + ki: 80A37E6FDEA931EAC92FFA5F671EFEAD + label: sierra_1 + path: /sierra_1 +- _hash: 3a6e7747dfe7dfdf817bd3351031bd08051605c3 + auth_algo: comp128v1 + ciphers: + - a5_0 + - a5_1 + imsi: '901700000009029' + ki: 00969E283349D354A8239E877F2E0866 + label: sierra_2 + path: /sierra_2 +~~~ currently reserved: +arfcn: +- _hash: e620569450f8259b3f0212ec19c285dd07df063c + _reserved_by: testowner-123-1490837279 + arfcn: '512' + band: GSM-1800 +- _hash: 022621e513c5a5bf33b77430a1e9c886be676fa1 + _reserved_by: testowner-123-1490837279 + arfcn: '514' + band: GSM-1800 +bts: +- _hash: d2aa7c1124943de352351b650ca0c751784da6b6 + _reserved_by: testowner-123-1490837279 + addr: 10.42.42.114 + band: GSM-1800 + ciphers: + - a5_0 + - a5_1 + direct_pcu: 'True' + ipa_unit_id: '1' + label: sysmoBTS 1002 + type: osmo-bts-sysmo +- _hash: 2158317d5e0055070e7174c2498dedf53a2957e9 + _reserved_by: testowner-123-1490837279 + addr: 10.42.42.50 + band: GSM-1800 + ciphers: + - a5_0 + - a5_1 + ipa_unit_id: '6' + label: Ettus B200 + osmo_trx: + clock_reference: external + launch_trx: 'True' + type: osmo-bts-trx +ip_address: +- _hash: fd103b22c7cf2480d609150e06f4bbd92ac78d8c + _reserved_by: testowner-123-1490837279 + addr: 10.42.42.2 +modem: +- _hash: 0b538cb6ad799fbd7c2953fd3b4463a76c7cc9c0 + _reserved_by: testowner-123-1490837279 + auth_algo: comp128v1 + ciphers: + - a5_0 + - a5_1 + imsi: '901700000009031' + ki: 80A37E6FDEA931EAC92FFA5F671EFEAD + label: sierra_1 + path: /sierra_1 +- _hash: 3a6e7747dfe7dfdf817bd3351031bd08051605c3 + _reserved_by: testowner-123-1490837279 + auth_algo: comp128v1 + ciphers: + - a5_0 + - a5_1 + imsi: '901700000009029' + ki: 00969E283349D354A8239E877F2E0866 + label: sierra_2 + path: /sierra_2 + +~~~ end: currently reserved + +~~~ with modifiers: +resources(testowner)={'arfcn': [{'_hash': 'e620569450f8259b3f0212ec19c285dd07df063c', + '_reserved_by': 'testowner-123-1490837279', + 'arfcn': '512', + 'band': 'GSM-1800'}, + {'_hash': '022621e513c5a5bf33b77430a1e9c886be676fa1', + '_reserved_by': 'testowner-123-1490837279', + 'arfcn': '514', + 'band': 'GSM-1800'}], + 'bts': [{'_hash': 'd2aa7c1124943de352351b650ca0c751784da6b6', + '_reserved_by': 'testowner-123-1490837279', + 'addr': '10.42.42.114', + 'band': 'GSM-1800', + 'ciphers': ['a5_0', 'a5_1'], + 'direct_pcu': 'True', + 'ipa_unit_id': '1', + 'label': 'sysmoBTS 1002', + 'type': 'osmo-bts-sysmo'}, + {'_hash': '2158317d5e0055070e7174c2498dedf53a2957e9', + '_reserved_by': 'testowner-123-1490837279', + 'addr': '10.42.42.50', + 'band': 'GSM-1800', + 'ciphers': ['a5_0', 'a5_1'], + 'ipa_unit_id': '6', + 'label': 'Ettus B200', + 'num_trx': 2, + 'osmo_trx': {'clock_reference': 'external', 'launch_trx': 'True'}, + 'type': 'osmo-bts-trx'}], + 'ip_address': [{'_hash': 'fd103b22c7cf2480d609150e06f4bbd92ac78d8c', + '_reserved_by': 'testowner-123-1490837279', + 'addr': '10.42.42.2'}], + 'modem': [{'_hash': '0b538cb6ad799fbd7c2953fd3b4463a76c7cc9c0', + '_reserved_by': 'testowner-123-1490837279', + 'auth_algo': 'comp128v1', + 'ciphers': ['a5_0', 'a5_1'], + 'imsi': '901700000009031', + 'ki': '80A37E6FDEA931EAC92FFA5F671EFEAD', + 'label': 'sierra_1', + 'path': '/sierra_1'}, + {'_hash': '3a6e7747dfe7dfdf817bd3351031bd08051605c3', + '_reserved_by': 'testowner-123-1490837279', + 'auth_algo': 'comp128v1', + 'ciphers': ['a5_0', 'a5_1'], + 'imsi': '901700000009029', + 'ki': '00969E283349D354A8239E877F2E0866', + 'label': 'sierra_2', + 'path': '/sierra_2'}]} +~~~ end: with modifiers: +~~~ currently reserved: +{} + +~~~ end: currently reserved + +- item_matches: +1st subset matches correctly, pass +2nd subset matches correctly, pass +3rd subset should not match, pass +3rd subset should not match, pass +4th subset should not match, pass diff --git a/selftest/resource_test/resource_test.ok.ign b/selftest/resource_test/resource_test.ok.ign new file mode 100644 index 0000000..393ce95 --- /dev/null +++ b/selftest/resource_test/resource_test.ok.ign @@ -0,0 +1 @@ +/[^ ]*/selftest/ [PATH]/selftest/ diff --git a/selftest/resource_test/resource_test.py b/selftest/resource_test/resource_test.py new file mode 100755 index 0000000..39a7eb6 --- /dev/null +++ b/selftest/resource_test/resource_test.py @@ -0,0 +1,131 @@ +#!/usr/bin/env python3 + +import tempfile +import os +import sys +import pprint +import shutil +import atexit +import _prep +from osmo_gsm_tester.core import config, log, util, resource +from osmo_gsm_tester.core.schema import generate_schemas + +workdir = util.get_tempdir() + +# override config locations to make sure we use only the test conf +config.ENV_CONF = os.path.join(os.path.dirname(sys.argv[0]), 'conf') + +log.get_process_id = lambda: '123-1490837279' + +# Generate supported schemas dynamically from objects: +generate_schemas() + +print('- expect solutions:') +pprint.pprint( + resource.solve([ [0, 1, 2], + [0, 1, 2], + [0, 1, 2] ]) ) +pprint.pprint( + resource.solve([ [0, 1, 2], + [0, 1], + [0, 2] ]) ) # == [0, 1, 2] +pprint.pprint( + resource.solve([ [0, 1, 2], + [0], + [0, 2] ]) ) # == [1, 0, 2] +pprint.pprint( + resource.solve([ [0, 1, 2], + [2], + [0, 2] ]) ) # == [1, 2, 0] + +print('- expect failure to solve:') +try: + resource.solve([ [0, 2], + [2], + [0, 2] ]) + assert False +except resource.NotSolvable as e: + print(e) + +print('- test removing a Resources list from itself') +try: + r = resource.Resources({ 'k': [ {'a': 1, 'b': 2}, {'a': 3, 'b': 4}, ], + 'i': [ {'c': 1, 'd': 2}, {'c': 3, 'd': 4}, ] }) + r.drop(r) + assert False +except RuntimeError as e: + print('ok, caused exception RuntimeError: %s' % str(e)) + +print('- test removing a Resources list from one with the same list in it') +r = resource.Resources({ 'k': [ {'a': 1, 'b': 2}, {'a': 3, 'b': 4}, ], + 'i': [ {'c': 1, 'd': 2}, {'c': 3, 'd': 4}, ] }) +r.drop({ 'k': r.get('k'), 'i': r.get('i') }) +assert not r + +print('- test resources config and state dir:') +resources_conf = os.path.join(_prep.script_dir, 'resource_test', 'etc', + 'resources.conf') + +state_dir = config.get_state_dir() +rrfile = state_dir.child(resource.RESERVED_RESOURCES_FILE) + +pool = resource.ResourcesPool() + +print('*** all resources:') +pprint.pprint(pool.all_resources) +print('*** end: all resources\n') + +print('- request some resources') +want = { + 'ip_address': [ { 'times': 1 } ], + 'bts': [ { 'type': 'osmo-bts-sysmo', 'times': 1 , 'ciphers': ['a5_1']}, { 'type': 'osmo-bts-trx', 'times': 1 } ], + 'arfcn': [ { 'band': 'GSM-1800', 'times': 2 } ], + 'modem': [ { 'times': 2 , 'ciphers': ['a5_0', 'a5_1']} ], + } +modifiers = { + 'bts': [ {}, {'num_trx': 2 }], +} +origin = log.Origin(None, 'testowner') + +resources = pool.reserve(origin, config.replicate_times(want), config.replicate_times(modifiers)) + +print('~~~ currently reserved:') +with open(rrfile, 'r') as f: + print(f.read()) +print('~~~ end: currently reserved\n') + +print('~~~ with modifiers:') +print(repr(resources)) +print('~~~ end: with modifiers:') + +resources.free() + +print('~~~ currently reserved:') +with open(rrfile, 'r') as f: + print(f.read()) +print('~~~ end: currently reserved\n') + +print('- item_matches:') +superset = { 'hello': 'world', 'foo': 'bar', 'ordered_list': [{'xkey': 'xvalue'},{'ykey': 'yvalue'}], 'unordered_list_set': [1, 2, 3]} + +subset = { 'foo': 'bar', 'ordered_list': [{'xkey': 'xvalue'},{'ykey': 'yvalue'}], 'unordered_list_set': [2, 1] } +if resource.item_matches(superset, subset): + print('1st subset matches correctly, pass') + +subset = { 'ordered_list': [{},{'ykey': 'yvalue'}], 'unordered_list_set': [] } +if resource.item_matches(superset, subset): + print('2nd subset matches correctly, pass') + +subset = { 'ordered_list': [{'ykey': 'yvalue'}, {'xkey': 'xvalue'}] } +if not resource.item_matches(superset, subset): + print('3rd subset should not match, pass') + +subset = { 'ordered_list': [{'xkey': 'xvalue'}, {'ykey': 'yvalue'}, {'zkey': 'zvalue'}] } +if not resource.item_matches(superset, subset): + print('3rd subset should not match, pass') + +subset = { 'unordered_list_set': [4] } +if not resource.item_matches(superset, subset): + print('4th subset should not match, pass') + +# vim: expandtab tabstop=4 shiftwidth=4 diff --git a/selftest/sms_test.err b/selftest/sms_test.err deleted file mode 100644 index e69de29..0000000 diff --git a/selftest/sms_test.ok b/selftest/sms_test.ok deleted file mode 100644 index 125b5c0..0000000 --- a/selftest/sms_test.ok +++ /dev/null @@ -1,6 +0,0 @@ -message nr. 1 -message nr. 2 -message nr. 3 -message nr. 4, from 123, to 456 -message nr. 5, from 123, to 456 -message nr. 4, from 123, to 456 diff --git a/selftest/sms_test.py b/selftest/sms_test.py deleted file mode 100755 index c78e76c..0000000 --- a/selftest/sms_test.py +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env python3 - -import _prep -from osmo_gsm_tester.obj import sms - -print(sms.Sms()) -print(sms.Sms()) -print(sms.Sms()) -msg = sms.Sms('123', '456') -print(str(msg)) - -msg2 = sms.Sms('123', '456') -print(str(msg2)) -assert msg != msg2 - -msg2.msg = str(msg.msg) -print(str(msg2)) -assert msg == msg2 - -assert msg == str(msg.msg) - -# vim: expandtab tabstop=4 shiftwidth=4 diff --git a/selftest/sms_test/_prep.py b/selftest/sms_test/_prep.py new file mode 120000 index 0000000..9cea3fe --- /dev/null +++ b/selftest/sms_test/_prep.py @@ -0,0 +1 @@ +../_prep.py \ No newline at end of file diff --git a/selftest/sms_test/sms_test.err b/selftest/sms_test/sms_test.err new file mode 100644 index 0000000..e69de29 diff --git a/selftest/sms_test/sms_test.ok b/selftest/sms_test/sms_test.ok new file mode 100644 index 0000000..125b5c0 --- /dev/null +++ b/selftest/sms_test/sms_test.ok @@ -0,0 +1,6 @@ +message nr. 1 +message nr. 2 +message nr. 3 +message nr. 4, from 123, to 456 +message nr. 5, from 123, to 456 +message nr. 4, from 123, to 456 diff --git a/selftest/sms_test/sms_test.py b/selftest/sms_test/sms_test.py new file mode 100755 index 0000000..c78e76c --- /dev/null +++ b/selftest/sms_test/sms_test.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python3 + +import _prep +from osmo_gsm_tester.obj import sms + +print(sms.Sms()) +print(sms.Sms()) +print(sms.Sms()) +msg = sms.Sms('123', '456') +print(str(msg)) + +msg2 = sms.Sms('123', '456') +print(str(msg2)) +assert msg != msg2 + +msg2.msg = str(msg.msg) +print(str(msg2)) +assert msg == msg2 + +assert msg == str(msg.msg) + +# vim: expandtab tabstop=4 shiftwidth=4 diff --git a/selftest/suite_test.err b/selftest/suite_test.err deleted file mode 100644 index e69de29..0000000 diff --git a/selftest/suite_test.ok b/selftest/suite_test.ok deleted file mode 100644 index 908f24f..0000000 --- a/selftest/suite_test.ok +++ /dev/null @@ -1,485 +0,0 @@ -- non-existing suite dir -cnf -: DBG: Found config file paths.conf as [PATH]/selftest/suite_test/paths.conf in ./suite_test which is [PATH]/selftest/suite_test -cnf -: DBG: [PATH]/selftest/suite_test/paths.conf: relative path ./test_work/state_dir is [PATH]/selftest/suite_test/test_work/state_dir -cnf -: DBG: [PATH]/selftest/suite_test/paths.conf: relative path . is [PATH]/selftest/suite_test -cnf -: DBG: Found path suites_dir as [PATH]/selftest/suite_test ---- -: ERR: RuntimeError: Suite not found: 'does_not_exist' in [PATH]/selftest/suite_test -- no suite.conf -cnf -: DBG: Found path suites_dir as [PATH]/selftest/suite_test -cnf empty_dir: DBG: reading suite.conf -cnf [PATH]/selftest/suite_test/empty_dir/suite.conf: ERR: FileNotFoundError: [Errno 2] No such file or directory: '[PATH]/selftest/suite_test/empty_dir/suite.conf' [empty_dir↪[PATH]/selftest/suite_test/empty_dir/suite.conf] -- valid suite dir -cnf -: DBG: Found path suites_dir as [PATH]/selftest/suite_test -cnf test_suite: DBG: reading suite.conf -defaults: - timeout: 60s -resources: - bts: - - label: sysmoCell 5000 - times: '2' - - times: '1' - type: sysmo - ip_address: - - times: '1' - modem: - - times: '2' - -- run hello world test -cnf ResourcesPool: DBG: Found config file resources.conf as [PATH]/selftest/suite_test/resources.conf in ./suite_test which is [PATH]/selftest/suite_test -cnf ResourcesPool: DBG: Found path state_dir as [PATH]/selftest/suite_test/test_work/state_dir - ---------------------------------------------------------------------- -trial test_suite ---------------------------------------------------------------------- -tst test_suite: reserving resources in [PATH]/selftest/suite_test/test_work/state_dir ... -tst test_suite: DBG: {combining='resources'} -tst {combining_scenarios='resources'}: DBG: {definition_conf={bts=[{'label': 'sysmoCell 5000'}, {'label': 'sysmoCell 5000'}, {'type': 'sysmo'}], ip_address=[{}], modem=[{}, {}]}} [test_suite↪{combining_scenarios='resources'}] -tst test_suite: DBG: {combining='modifiers'} -tst {combining_scenarios='modifiers'}: DBG: {definition_conf={}} [test_suite↪{combining_scenarios='modifiers'}] -tst test_suite: Reserving 3 x bts (candidates: 6) -tst test_suite: DBG: Picked - _hash: a59640b8ba6a373552b24a6f9f65cadd2347bace - addr: 10.42.42.53 - band: GSM-1800 - ipa_unit_id: '7' - label: sysmoCell 5000 - osmo_trx: - clock_reference: external - launch_trx: 'False' - trx_ip: 10.42.42.112 - trx_list: - - max_power_red: '3' - nominal_power: '10' - - max_power_red: '0' - nominal_power: '12' - type: osmo-bts-trx -- _hash: c2feabd082c36a1cdeccb9a5237dfff7dbadb009 - addr: 10.42.42.53 - band: GSM-1800 - ipa_unit_id: '7' - label: sysmoCell 5000 - osmo_trx: - clock_reference: external - launch_trx: 'False' - trx_ip: 10.42.42.112 - trx_list: - - nominal_power: '10' - - max_power_red: '1' - nominal_power: '12' - type: osmo-bts-trx -- _hash: 07d9c8aaa940b674efcbbabdd69f58a6ce4e94f9 - addr: 10.42.42.114 - band: GSM-1800 - ipa_unit_id: '1' - label: sysmoBTS 1002 - type: sysmo -tst test_suite: Reserving 1 x ip_address (candidates: 3) -tst test_suite: DBG: Picked - _hash: cde1debf28f07f94f92c761b4b7c6bf35785ced4 - addr: 10.42.42.1 -tst test_suite: Reserving 2 x modem (candidates: 16) -tst test_suite: DBG: Picked - _hash: 19c69e45aa090fb511446bd00797690aa82ff52f - imsi: '901700000007801' - ki: D620F48487B1B782DA55DF6717F08FF9 - label: m7801 - path: /wavecom_0 -- _hash: e1a46516a1fb493b2617ab14fc1693a9a45ec254 - imsi: '901700000007802' - ki: 47FDB2D55CE6A10A85ABDAD034A5B7B3 - label: m7802 - path: /wavecom_1 - ----------------------------------------------- -trial test_suite hello_world.py ----------------------------------------------- -tst hello_world.py:[LINENR]: hello world [test_suite↪hello_world.py:[LINENR]] -tst hello_world.py:[LINENR]: I am 'test_suite' / 'hello_world.py:[LINENR]' [test_suite↪hello_world.py:[LINENR]] -tst hello_world.py:[LINENR]: one [test_suite↪hello_world.py:[LINENR]] -tst hello_world.py:[LINENR]: two [test_suite↪hello_world.py:[LINENR]] -tst hello_world.py:[LINENR]: three [test_suite↪hello_world.py:[LINENR]] -tst hello_world.py:[LINENR] Test passed (N.N sec) [test_suite↪hello_world.py] ---------------------------------------------------------------------- -trial test_suite PASS ---------------------------------------------------------------------- -PASS: test_suite (pass: 1, skip: 5) - pass: hello_world.py (N.N sec) - skip: mo_mt_sms.py - skip: mo_sms.py - skip: test_error.py - skip: test_fail.py - skip: test_fail_raise.py - -- a test with an error - ---------------------------------------------------------------------- -trial test_suite ---------------------------------------------------------------------- - ----------------------------------------------- -trial test_suite test_error.py ----------------------------------------------- -tst test_error.py:[LINENR]: I am 'test_suite' / 'test_error.py:[LINENR]' [test_suite↪test_error.py:[LINENR]] [test_error.py:[LINENR]] -tst test_error.py:[LINENR]: ERR: AssertionError: test_error.py:[LINENR]: assert False [test_suite↪test_error.py:[LINENR]] [test_error.py:[LINENR]: assert False] -tst test_error.py:[LINENR]: Test FAILED (N.N sec) [test_suite↪test_error.py:[LINENR]] [test.py:[LINENR]] ---------------------------------------------------------------------- -trial test_suite FAIL ---------------------------------------------------------------------- -FAIL: test_suite (fail: 1, skip: 5) - skip: hello_world.py (N.N sec) - skip: mo_mt_sms.py - skip: mo_sms.py - FAIL: test_error.py (N.N sec) AssertionError: test_error.py:[LINENR]: assert False - skip: test_fail.py - skip: test_fail_raise.py - -- a test with a failure - ---------------------------------------------------------------------- -trial test_suite ---------------------------------------------------------------------- - ----------------------------------------------- -trial test_suite test_fail.py ----------------------------------------------- -tst test_fail.py:[LINENR]: I am 'test_suite' / 'test_fail.py:[LINENR]' [test_suite↪test_fail.py:[LINENR]] [test_fail.py:[LINENR]] -tst test_fail.py:[LINENR]: ERR: EpicFail: This failure is expected [test_suite↪test_fail.py:[LINENR]] [test_fail.py:[LINENR]] -tst test_fail.py:[LINENR]: Test FAILED (N.N sec) [test_suite↪test_fail.py:[LINENR]] [test.py:[LINENR]] ---------------------------------------------------------------------- -trial test_suite FAIL ---------------------------------------------------------------------- -FAIL: test_suite (fail: 1, skip: 5) - skip: hello_world.py (N.N sec) - skip: mo_mt_sms.py - skip: mo_sms.py - skip: test_error.py (N.N sec) - FAIL: test_fail.py (N.N sec) EpicFail: This failure is expected - skip: test_fail_raise.py - -- a test with a raised failure - ---------------------------------------------------------------------- -trial test_suite ---------------------------------------------------------------------- - ----------------------------------------------- -trial test_suite test_fail_raise.py ----------------------------------------------- -tst test_fail_raise.py:[LINENR]: ERR: ExpectedFail: This failure is expected [test_suite↪test_fail_raise.py:[LINENR]] [test_fail_raise.py:[LINENR]: raise ExpectedFail('This failure is expected')] -tst test_fail_raise.py:[LINENR]: Test FAILED (N.N sec) [test_suite↪test_fail_raise.py:[LINENR]] [test.py:[LINENR]] ---------------------------------------------------------------------- -trial test_suite FAIL ---------------------------------------------------------------------- -FAIL: test_suite (fail: 1, skip: 5) - skip: hello_world.py (N.N sec) - skip: mo_mt_sms.py - skip: mo_sms.py - skip: test_error.py (N.N sec) - skip: test_fail.py (N.N sec) - FAIL: test_fail_raise.py (N.N sec) ExpectedFail: This failure is expected -- test with half empty scenario -cnf ResourcesPool: DBG: Found config file resources.conf as [PATH]/selftest/suite_test/resources.conf in ./suite_test which is [PATH]/selftest/suite_test [config.py:[LINENR]] -cnf ResourcesPool: DBG: Found path state_dir as [PATH]/selftest/suite_test/test_work/state_dir [config.py:[LINENR]] - ---------------------------------------------------------------------- -trial test_suite ---------------------------------------------------------------------- -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]] -tst {combining_scenarios='resources'}: DBG: {definition_conf={bts=[{'label': 'sysmoCell 5000'}, {'label': 'sysmoCell 5000'}, {'type': 'sysmo'}], ip_address=[{}], modem=[{}, {}]}} [test_suite↪{combining_scenarios='resources'}] [suite.py:[LINENR]] -tst {combining_scenarios='resources', scenario='foo'}: [RESOURCE_DICT] -tst test_suite: DBG: {combining='modifiers'} [suite.py:[LINENR]] -tst {combining_scenarios='modifiers'}: DBG: {definition_conf={}} [test_suite↪{combining_scenarios='modifiers'}] [suite.py:[LINENR]] -tst {combining_scenarios='modifiers', scenario='foo'}: DBG: {conf={}, scenario='foo'} [test_suite↪{combining_scenarios='modifiers', scenario='foo'}] [suite.py:[LINENR]] -tst test_suite: Reserving 3 x bts (candidates: 6) [resource.py:[LINENR]] -tst test_suite: DBG: Picked - _hash: a59640b8ba6a373552b24a6f9f65cadd2347bace - addr: 10.42.42.53 - band: GSM-1800 - ipa_unit_id: '7' - label: sysmoCell 5000 - osmo_trx: - clock_reference: external - launch_trx: 'False' - trx_ip: 10.42.42.112 - trx_list: - - max_power_red: '3' - nominal_power: '10' - - max_power_red: '0' - nominal_power: '12' - type: osmo-bts-trx -- _hash: c2feabd082c36a1cdeccb9a5237dfff7dbadb009 - addr: 10.42.42.53 - band: GSM-1800 - ipa_unit_id: '7' - label: sysmoCell 5000 - osmo_trx: - clock_reference: external - launch_trx: 'False' - trx_ip: 10.42.42.112 - trx_list: - - nominal_power: '10' - - max_power_red: '1' - nominal_power: '12' - type: osmo-bts-trx -- _hash: 07d9c8aaa940b674efcbbabdd69f58a6ce4e94f9 - addr: 10.42.42.114 - band: GSM-1800 - ipa_unit_id: '1' - label: sysmoBTS 1002 - type: sysmo - [resource.py:[LINENR]] -tst test_suite: Reserving 1 x ip_address (candidates: 3) [resource.py:[LINENR]] -tst test_suite: DBG: Picked - _hash: cde1debf28f07f94f92c761b4b7c6bf35785ced4 - addr: 10.42.42.1 - [resource.py:[LINENR]] -tst test_suite: Reserving 2 x modem (candidates: 16) [resource.py:[LINENR]] -tst test_suite: DBG: Picked - _hash: 19c69e45aa090fb511446bd00797690aa82ff52f - imsi: '901700000007801' - ki: D620F48487B1B782DA55DF6717F08FF9 - label: m7801 - path: /wavecom_0 -- _hash: e1a46516a1fb493b2617ab14fc1693a9a45ec254 - imsi: '901700000007802' - ki: 47FDB2D55CE6A10A85ABDAD034A5B7B3 - label: m7802 - path: /wavecom_1 - [resource.py:[LINENR]] - ----------------------------------------------- -trial test_suite hello_world.py ----------------------------------------------- -tst hello_world.py:[LINENR]: hello world [test_suite↪hello_world.py:[LINENR]] [hello_world.py:[LINENR]] -tst hello_world.py:[LINENR]: I am 'test_suite' / 'hello_world.py:[LINENR]' [test_suite↪hello_world.py:[LINENR]] [hello_world.py:[LINENR]] -tst hello_world.py:[LINENR]: one [test_suite↪hello_world.py:[LINENR]] [hello_world.py:[LINENR]] -tst hello_world.py:[LINENR]: two [test_suite↪hello_world.py:[LINENR]] [hello_world.py:[LINENR]] -tst hello_world.py:[LINENR]: three [test_suite↪hello_world.py:[LINENR]] [hello_world.py:[LINENR]] -tst hello_world.py:[LINENR] Test passed (N.N sec) [test_suite↪hello_world.py] [test.py:[LINENR]] ---------------------------------------------------------------------- -trial test_suite PASS ---------------------------------------------------------------------- -PASS: test_suite (pass: 1, skip: 5) - pass: hello_world.py (N.N sec) - skip: mo_mt_sms.py - skip: mo_sms.py - skip: test_error.py - skip: test_fail.py - skip: test_fail_raise.py -- test with scenario -cnf ResourcesPool: DBG: Found config file resources.conf as [PATH]/selftest/suite_test/resources.conf in ./suite_test which is [PATH]/selftest/suite_test [config.py:[LINENR]] -cnf ResourcesPool: DBG: Found path state_dir as [PATH]/selftest/suite_test/test_work/state_dir [config.py:[LINENR]] - ---------------------------------------------------------------------- -trial test_suite ---------------------------------------------------------------------- -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]] -tst {combining_scenarios='resources'}: DBG: {definition_conf={bts=[{'label': 'sysmoCell 5000'}, {'label': 'sysmoCell 5000'}, {'type': 'sysmo'}], ip_address=[{}], modem=[{}, {}]}} [test_suite↪{combining_scenarios='resources'}] [suite.py:[LINENR]] -tst {combining_scenarios='resources', scenario='foo'}: [RESOURCE_DICT] -tst test_suite: DBG: {combining='modifiers'} [suite.py:[LINENR]] -tst {combining_scenarios='modifiers'}: DBG: {definition_conf={}} [test_suite↪{combining_scenarios='modifiers'}] [suite.py:[LINENR]] -tst {combining_scenarios='modifiers', scenario='foo'}: DBG: {conf={}, scenario='foo'} [test_suite↪{combining_scenarios='modifiers', scenario='foo'}] [suite.py:[LINENR]] -tst test_suite: Reserving 3 x bts (candidates: 6) [resource.py:[LINENR]] -tst test_suite: DBG: Picked - _hash: a59640b8ba6a373552b24a6f9f65cadd2347bace - addr: 10.42.42.53 - band: GSM-1800 - ipa_unit_id: '7' - label: sysmoCell 5000 - osmo_trx: - clock_reference: external - launch_trx: 'False' - trx_ip: 10.42.42.112 - trx_list: - - max_power_red: '3' - nominal_power: '10' - - max_power_red: '0' - nominal_power: '12' - type: osmo-bts-trx -- _hash: c2feabd082c36a1cdeccb9a5237dfff7dbadb009 - addr: 10.42.42.53 - band: GSM-1800 - ipa_unit_id: '7' - label: sysmoCell 5000 - osmo_trx: - clock_reference: external - launch_trx: 'False' - trx_ip: 10.42.42.112 - trx_list: - - nominal_power: '10' - - max_power_red: '1' - nominal_power: '12' - type: osmo-bts-trx -- _hash: 07d9c8aaa940b674efcbbabdd69f58a6ce4e94f9 - addr: 10.42.42.114 - band: GSM-1800 - ipa_unit_id: '1' - label: sysmoBTS 1002 - type: sysmo - [resource.py:[LINENR]] -tst test_suite: Reserving 1 x ip_address (candidates: 3) [resource.py:[LINENR]] -tst test_suite: DBG: Picked - _hash: cde1debf28f07f94f92c761b4b7c6bf35785ced4 - addr: 10.42.42.1 - [resource.py:[LINENR]] -tst test_suite: Reserving 2 x modem (candidates: 16) [resource.py:[LINENR]] -tst test_suite: DBG: Picked - _hash: 19c69e45aa090fb511446bd00797690aa82ff52f - imsi: '901700000007801' - ki: D620F48487B1B782DA55DF6717F08FF9 - label: m7801 - path: /wavecom_0 -- _hash: e1a46516a1fb493b2617ab14fc1693a9a45ec254 - imsi: '901700000007802' - ki: 47FDB2D55CE6A10A85ABDAD034A5B7B3 - label: m7802 - path: /wavecom_1 - [resource.py:[LINENR]] - ----------------------------------------------- -trial test_suite hello_world.py ----------------------------------------------- -tst hello_world.py:[LINENR]: hello world [test_suite↪hello_world.py:[LINENR]] [hello_world.py:[LINENR]] -tst hello_world.py:[LINENR]: I am 'test_suite' / 'hello_world.py:[LINENR]' [test_suite↪hello_world.py:[LINENR]] [hello_world.py:[LINENR]] -tst hello_world.py:[LINENR]: one [test_suite↪hello_world.py:[LINENR]] [hello_world.py:[LINENR]] -tst hello_world.py:[LINENR]: two [test_suite↪hello_world.py:[LINENR]] [hello_world.py:[LINENR]] -tst hello_world.py:[LINENR]: three [test_suite↪hello_world.py:[LINENR]] [hello_world.py:[LINENR]] -tst hello_world.py:[LINENR] Test passed (N.N sec) [test_suite↪hello_world.py] [test.py:[LINENR]] ---------------------------------------------------------------------- -trial test_suite PASS ---------------------------------------------------------------------- -PASS: test_suite (pass: 1, skip: 5) - pass: hello_world.py (N.N sec) - skip: mo_mt_sms.py - skip: mo_sms.py - skip: test_error.py - skip: test_fail.py - skip: test_fail_raise.py -- test with scenario and modifiers -cnf ResourcesPool: DBG: Found config file resources.conf as [PATH]/selftest/suite_test/resources.conf in ./suite_test which is [PATH]/selftest/suite_test [config.py:[LINENR]] -cnf ResourcesPool: DBG: Found path state_dir as [PATH]/selftest/suite_test/test_work/state_dir [config.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]] -tst {combining_scenarios='resources'}: DBG: {definition_conf={bts=[{'label': 'sysmoCell 5000'}, {'label': 'sysmoCell 5000'}, {'type': 'sysmo'}], ip_address=[{}], modem=[{}, {}]}} [test_suite↪{combining_scenarios='resources'}] [suite.py:[LINENR]] -tst {combining_scenarios='resources', scenario='foo'}: [RESOURCE_DICT] -tst test_suite: DBG: {combining='modifiers'} [suite.py:[LINENR]] -tst {combining_scenarios='modifiers'}: DBG: {definition_conf={}} [test_suite↪{combining_scenarios='modifiers'}] [suite.py:[LINENR]] -tst {combining_scenarios='modifiers', scenario='foo'}: DBG: {conf={bts=[{'trx_list': [{'nominal_power': '20'}, {'nominal_power': '20'}]}, {'trx_list': [{'nominal_power': '20'}, {'nominal_power': '20'}]}, {'type': 'sysmo'}]}, scenario='foo'} [test_suite↪{combining_scenarios='modifiers', scenario='foo'}] [suite.py:[LINENR]] -tst test_suite: Reserving 3 x bts (candidates: 6) [resource.py:[LINENR]] -tst test_suite: DBG: Picked - _hash: a59640b8ba6a373552b24a6f9f65cadd2347bace - addr: 10.42.42.53 - band: GSM-1800 - ipa_unit_id: '7' - label: sysmoCell 5000 - osmo_trx: - clock_reference: external - launch_trx: 'False' - trx_ip: 10.42.42.112 - trx_list: - - max_power_red: '3' - nominal_power: '10' - - max_power_red: '0' - nominal_power: '12' - type: osmo-bts-trx -- _hash: c2feabd082c36a1cdeccb9a5237dfff7dbadb009 - addr: 10.42.42.53 - band: GSM-1800 - ipa_unit_id: '7' - label: sysmoCell 5000 - osmo_trx: - clock_reference: external - launch_trx: 'False' - trx_ip: 10.42.42.112 - trx_list: - - nominal_power: '10' - - max_power_red: '1' - nominal_power: '12' - type: osmo-bts-trx -- _hash: 07d9c8aaa940b674efcbbabdd69f58a6ce4e94f9 - addr: 10.42.42.114 - band: GSM-1800 - ipa_unit_id: '1' - label: sysmoBTS 1002 - type: sysmo - [resource.py:[LINENR]] -tst test_suite: Reserving 1 x ip_address (candidates: 3) [resource.py:[LINENR]] -tst test_suite: DBG: Picked - _hash: cde1debf28f07f94f92c761b4b7c6bf35785ced4 - addr: 10.42.42.1 - [resource.py:[LINENR]] -tst test_suite: Reserving 2 x modem (candidates: 16) [resource.py:[LINENR]] -tst test_suite: DBG: Picked - _hash: 19c69e45aa090fb511446bd00797690aa82ff52f - imsi: '901700000007801' - ki: D620F48487B1B782DA55DF6717F08FF9 - label: m7801 - path: /wavecom_0 -- _hash: e1a46516a1fb493b2617ab14fc1693a9a45ec254 - imsi: '901700000007802' - ki: 47FDB2D55CE6A10A85ABDAD034A5B7B3 - label: m7802 - path: /wavecom_1 - [resource.py:[LINENR]] -resources(test_suite)={'bts': [{'_hash': 'a59640b8ba6a373552b24a6f9f65cadd2347bace', - '_reserved_by': 'test_suite-[ID_NUM]-[ID_NUM]', - 'addr': '10.42.42.53', - 'band': 'GSM-1800', - 'ipa_unit_id': '7', - 'label': 'sysmoCell 5000', - 'osmo_trx': {'clock_reference': 'external', - 'launch_trx': 'False', - 'trx_ip': '10.42.42.112'}, - 'trx_list': [{'max_power_red': '3', 'nominal_power': '20'}, - {'max_power_red': '0', 'nominal_power': '20'}], - 'type': 'osmo-bts-trx'}, - {'_hash': 'c2feabd082c36a1cdeccb9a5237dfff7dbadb009', - '_reserved_by': 'test_suite-[ID_NUM]-[ID_NUM]', - 'addr': '10.42.42.53', - 'band': 'GSM-1800', - 'ipa_unit_id': '7', - 'label': 'sysmoCell 5000', - 'osmo_trx': {'clock_reference': 'external', - 'launch_trx': 'False', - 'trx_ip': '10.42.42.112'}, - 'trx_list': [{'nominal_power': '20'}, - {'max_power_red': '1', 'nominal_power': '20'}], - 'type': 'osmo-bts-trx'}, - {'_hash': '07d9c8aaa940b674efcbbabdd69f58a6ce4e94f9', - '_reserved_by': 'test_suite-[ID_NUM]-[ID_NUM]', - 'addr': '10.42.42.114', - 'band': 'GSM-1800', - 'ipa_unit_id': '1', - 'label': 'sysmoBTS 1002', - 'type': 'sysmo'}], - 'ip_address': [{'_hash': 'cde1debf28f07f94f92c761b4b7c6bf35785ced4', - '_reserved_by': 'test_suite-[ID_NUM]-[ID_NUM]', - 'addr': '10.42.42.1'}], - 'modem': [{'_hash': '19c69e45aa090fb511446bd00797690aa82ff52f', - '_reserved_by': 'test_suite-[ID_NUM]-[ID_NUM]', - 'imsi': '901700000007801', - 'ki': 'D620F48487B1B782DA55DF6717F08FF9', - 'label': 'm7801', - 'path': '/wavecom_0'}, - {'_hash': 'e1a46516a1fb493b2617ab14fc1693a9a45ec254', - '_reserved_by': 'test_suite-[ID_NUM]-[ID_NUM]', - 'imsi': '901700000007802', - 'ki': '47FDB2D55CE6A10A85ABDAD034A5B7B3', - 'label': 'm7802', - 'path': '/wavecom_1'}]} - ---------------------------------------------------------------------- -trial test_suite ---------------------------------------------------------------------- - ----------------------------------------------- -trial test_suite hello_world.py ----------------------------------------------- -tst hello_world.py:[LINENR]: hello world [test_suite↪hello_world.py:[LINENR]] [hello_world.py:[LINENR]] -tst hello_world.py:[LINENR]: I am 'test_suite' / 'hello_world.py:[LINENR]' [test_suite↪hello_world.py:[LINENR]] [hello_world.py:[LINENR]] -tst hello_world.py:[LINENR]: one [test_suite↪hello_world.py:[LINENR]] [hello_world.py:[LINENR]] -tst hello_world.py:[LINENR]: two [test_suite↪hello_world.py:[LINENR]] [hello_world.py:[LINENR]] -tst hello_world.py:[LINENR]: three [test_suite↪hello_world.py:[LINENR]] [hello_world.py:[LINENR]] -tst hello_world.py:[LINENR] Test passed (N.N sec) [test_suite↪hello_world.py] [test.py:[LINENR]] ---------------------------------------------------------------------- -trial test_suite PASS ---------------------------------------------------------------------- -PASS: test_suite (pass: 1, skip: 5) - pass: hello_world.py (N.N sec) - skip: mo_mt_sms.py - skip: mo_sms.py - skip: test_error.py - skip: test_fail.py - skip: test_fail_raise.py - -- graceful exit. diff --git a/selftest/suite_test.ok.ign b/selftest/suite_test.ok.ign deleted file mode 100644 index 9bd168f..0000000 --- a/selftest/suite_test.ok.ign +++ /dev/null @@ -1,5 +0,0 @@ -/[^ ]*/selftest/ [PATH]/selftest/ -\.py:[0-9]* .py:[LINENR] -\([0-9.]+ sec\) (N.N sec) -{combining_scenarios='resources', scenario='foo'}:.* {combining_scenarios='resources', scenario='foo'}: [RESOURCE_DICT] -test_suite-[0-9]*-[0-9]* test_suite-[ID_NUM]-[ID_NUM] diff --git a/selftest/suite_test.py b/selftest/suite_test.py deleted file mode 100755 index de5c6df..0000000 --- a/selftest/suite_test.py +++ /dev/null @@ -1,97 +0,0 @@ -#!/usr/bin/env python3 -import os -import _prep -import shutil -from osmo_gsm_tester.core import log, config, util, report -from osmo_gsm_tester.core import suite -from osmo_gsm_tester.core.schema import generate_schemas - -config.ENV_CONF = './suite_test' - -example_trial_dir = os.path.join('test_trial_tmp') - -class FakeTrial(log.Origin): - def __init__(self): - super().__init__(log.C_TST, 'trial') - self.dir = util.Dir(example_trial_dir) - self._run_dir = None - - def get_run_dir(self): - if self._run_dir is not None: - return self._run_dir - self._run_dir = util.Dir(self.dir.new_child('test_run')) - self._run_dir.mkdir() - return self._run_dir - -#log.style_change(trace=True) - -# Generate supported schemas dynamically from objects: -generate_schemas() - -print('- non-existing suite dir') -assert(log.run_logging_exceptions(suite.load, 'does_not_exist') == None) - -print('- no suite.conf') -assert(log.run_logging_exceptions(suite.load, 'empty_dir') == None) - -print('- valid suite dir') -example_suite_dir = os.path.join('test_suite') -s_def = suite.load(example_suite_dir) -assert(isinstance(s_def, suite.SuiteDefinition)) -print(config.tostr(s_def.conf)) - -print('- run hello world test') -trial = FakeTrial() -s = suite.SuiteRun(trial, 'test_suite', s_def) -results = s.run_tests('hello_world.py') -print(report.suite_to_text(s)) - -log.style_change(src=True) -#log.style_change(trace=True) -print('\n- a test with an error') -results = s.run_tests('test_error.py') -output = report.suite_to_text(s) -print(output) - -print('\n- a test with a failure') -results = s.run_tests('test_fail.py') -output = report.suite_to_text(s) -print(output) - -print('\n- a test with a raised failure') -results = s.run_tests('test_fail_raise.py') -output = report.suite_to_text(s) -print(output) - -print('- test with half empty scenario') -trial = FakeTrial() -scenario = config.Scenario('foo', 'bar') -scenario['resources'] = { 'bts': [{'type': 'osmo-bts-trx'}] } -s = suite.SuiteRun(trial, 'test_suite', s_def, [scenario]) -results = s.run_tests('hello_world.py') -print(report.suite_to_text(s)) - -print('- test with scenario') -trial = FakeTrial() -scenario = config.Scenario('foo', 'bar') -scenario['resources'] = { 'bts': [{ 'times': '2', 'type': 'osmo-bts-trx', 'trx_list': [{'nominal_power': '10'}, {'nominal_power': '12'}]}, {'type': 'sysmo'}] } -s = suite.SuiteRun(trial, 'test_suite', s_def, [scenario]) -results = s.run_tests('hello_world.py') -print(report.suite_to_text(s)) - -print('- test with scenario and modifiers') -trial = FakeTrial() -scenario = config.Scenario('foo', 'bar') -scenario['resources'] = { 'bts': [{ 'times': '2', 'type': 'osmo-bts-trx', 'trx_list': [{'nominal_power': '10'}, {'nominal_power': '12'}]}, {'type': 'sysmo'}] } -scenario['modifiers'] = { 'bts': [{ 'times': '2', 'trx_list': [{'nominal_power': '20'}, {'nominal_power': '20'}]}, {'type': 'sysmo'}] } -s = suite.SuiteRun(trial, 'test_suite', s_def, [scenario]) -s.reserve_resources() -print(repr(s.reserved_resources)) -results = s.run_tests('hello_world.py') -print(report.suite_to_text(s)) - -print('\n- graceful exit.') -#deleting generated tmp trial dir: -shutil.rmtree(example_trial_dir, ignore_errors=True) - -# vim: expandtab tabstop=4 shiftwidth=4 diff --git a/selftest/suite_test/_prep.py b/selftest/suite_test/_prep.py new file mode 120000 index 0000000..9cea3fe --- /dev/null +++ b/selftest/suite_test/_prep.py @@ -0,0 +1 @@ +../_prep.py \ No newline at end of file diff --git a/selftest/suite_test/suite_test.err b/selftest/suite_test/suite_test.err new file mode 100644 index 0000000..e69de29 diff --git a/selftest/suite_test/suite_test.ok b/selftest/suite_test/suite_test.ok new file mode 100644 index 0000000..908f24f --- /dev/null +++ b/selftest/suite_test/suite_test.ok @@ -0,0 +1,485 @@ +- non-existing suite dir +cnf -: DBG: Found config file paths.conf as [PATH]/selftest/suite_test/paths.conf in ./suite_test which is [PATH]/selftest/suite_test +cnf -: DBG: [PATH]/selftest/suite_test/paths.conf: relative path ./test_work/state_dir is [PATH]/selftest/suite_test/test_work/state_dir +cnf -: DBG: [PATH]/selftest/suite_test/paths.conf: relative path . is [PATH]/selftest/suite_test +cnf -: DBG: Found path suites_dir as [PATH]/selftest/suite_test +--- -: ERR: RuntimeError: Suite not found: 'does_not_exist' in [PATH]/selftest/suite_test +- no suite.conf +cnf -: DBG: Found path suites_dir as [PATH]/selftest/suite_test +cnf empty_dir: DBG: reading suite.conf +cnf [PATH]/selftest/suite_test/empty_dir/suite.conf: ERR: FileNotFoundError: [Errno 2] No such file or directory: '[PATH]/selftest/suite_test/empty_dir/suite.conf' [empty_dir↪[PATH]/selftest/suite_test/empty_dir/suite.conf] +- valid suite dir +cnf -: DBG: Found path suites_dir as [PATH]/selftest/suite_test +cnf test_suite: DBG: reading suite.conf +defaults: + timeout: 60s +resources: + bts: + - label: sysmoCell 5000 + times: '2' + - times: '1' + type: sysmo + ip_address: + - times: '1' + modem: + - times: '2' + +- run hello world test +cnf ResourcesPool: DBG: Found config file resources.conf as [PATH]/selftest/suite_test/resources.conf in ./suite_test which is [PATH]/selftest/suite_test +cnf ResourcesPool: DBG: Found path state_dir as [PATH]/selftest/suite_test/test_work/state_dir + +--------------------------------------------------------------------- +trial test_suite +--------------------------------------------------------------------- +tst test_suite: reserving resources in [PATH]/selftest/suite_test/test_work/state_dir ... +tst test_suite: DBG: {combining='resources'} +tst {combining_scenarios='resources'}: DBG: {definition_conf={bts=[{'label': 'sysmoCell 5000'}, {'label': 'sysmoCell 5000'}, {'type': 'sysmo'}], ip_address=[{}], modem=[{}, {}]}} [test_suite↪{combining_scenarios='resources'}] +tst test_suite: DBG: {combining='modifiers'} +tst {combining_scenarios='modifiers'}: DBG: {definition_conf={}} [test_suite↪{combining_scenarios='modifiers'}] +tst test_suite: Reserving 3 x bts (candidates: 6) +tst test_suite: DBG: Picked - _hash: a59640b8ba6a373552b24a6f9f65cadd2347bace + addr: 10.42.42.53 + band: GSM-1800 + ipa_unit_id: '7' + label: sysmoCell 5000 + osmo_trx: + clock_reference: external + launch_trx: 'False' + trx_ip: 10.42.42.112 + trx_list: + - max_power_red: '3' + nominal_power: '10' + - max_power_red: '0' + nominal_power: '12' + type: osmo-bts-trx +- _hash: c2feabd082c36a1cdeccb9a5237dfff7dbadb009 + addr: 10.42.42.53 + band: GSM-1800 + ipa_unit_id: '7' + label: sysmoCell 5000 + osmo_trx: + clock_reference: external + launch_trx: 'False' + trx_ip: 10.42.42.112 + trx_list: + - nominal_power: '10' + - max_power_red: '1' + nominal_power: '12' + type: osmo-bts-trx +- _hash: 07d9c8aaa940b674efcbbabdd69f58a6ce4e94f9 + addr: 10.42.42.114 + band: GSM-1800 + ipa_unit_id: '1' + label: sysmoBTS 1002 + type: sysmo +tst test_suite: Reserving 1 x ip_address (candidates: 3) +tst test_suite: DBG: Picked - _hash: cde1debf28f07f94f92c761b4b7c6bf35785ced4 + addr: 10.42.42.1 +tst test_suite: Reserving 2 x modem (candidates: 16) +tst test_suite: DBG: Picked - _hash: 19c69e45aa090fb511446bd00797690aa82ff52f + imsi: '901700000007801' + ki: D620F48487B1B782DA55DF6717F08FF9 + label: m7801 + path: /wavecom_0 +- _hash: e1a46516a1fb493b2617ab14fc1693a9a45ec254 + imsi: '901700000007802' + ki: 47FDB2D55CE6A10A85ABDAD034A5B7B3 + label: m7802 + path: /wavecom_1 + +---------------------------------------------- +trial test_suite hello_world.py +---------------------------------------------- +tst hello_world.py:[LINENR]: hello world [test_suite↪hello_world.py:[LINENR]] +tst hello_world.py:[LINENR]: I am 'test_suite' / 'hello_world.py:[LINENR]' [test_suite↪hello_world.py:[LINENR]] +tst hello_world.py:[LINENR]: one [test_suite↪hello_world.py:[LINENR]] +tst hello_world.py:[LINENR]: two [test_suite↪hello_world.py:[LINENR]] +tst hello_world.py:[LINENR]: three [test_suite↪hello_world.py:[LINENR]] +tst hello_world.py:[LINENR] Test passed (N.N sec) [test_suite↪hello_world.py] +--------------------------------------------------------------------- +trial test_suite PASS +--------------------------------------------------------------------- +PASS: test_suite (pass: 1, skip: 5) + pass: hello_world.py (N.N sec) + skip: mo_mt_sms.py + skip: mo_sms.py + skip: test_error.py + skip: test_fail.py + skip: test_fail_raise.py + +- a test with an error + +--------------------------------------------------------------------- +trial test_suite +--------------------------------------------------------------------- + +---------------------------------------------- +trial test_suite test_error.py +---------------------------------------------- +tst test_error.py:[LINENR]: I am 'test_suite' / 'test_error.py:[LINENR]' [test_suite↪test_error.py:[LINENR]] [test_error.py:[LINENR]] +tst test_error.py:[LINENR]: ERR: AssertionError: test_error.py:[LINENR]: assert False [test_suite↪test_error.py:[LINENR]] [test_error.py:[LINENR]: assert False] +tst test_error.py:[LINENR]: Test FAILED (N.N sec) [test_suite↪test_error.py:[LINENR]] [test.py:[LINENR]] +--------------------------------------------------------------------- +trial test_suite FAIL +--------------------------------------------------------------------- +FAIL: test_suite (fail: 1, skip: 5) + skip: hello_world.py (N.N sec) + skip: mo_mt_sms.py + skip: mo_sms.py + FAIL: test_error.py (N.N sec) AssertionError: test_error.py:[LINENR]: assert False + skip: test_fail.py + skip: test_fail_raise.py + +- a test with a failure + +--------------------------------------------------------------------- +trial test_suite +--------------------------------------------------------------------- + +---------------------------------------------- +trial test_suite test_fail.py +---------------------------------------------- +tst test_fail.py:[LINENR]: I am 'test_suite' / 'test_fail.py:[LINENR]' [test_suite↪test_fail.py:[LINENR]] [test_fail.py:[LINENR]] +tst test_fail.py:[LINENR]: ERR: EpicFail: This failure is expected [test_suite↪test_fail.py:[LINENR]] [test_fail.py:[LINENR]] +tst test_fail.py:[LINENR]: Test FAILED (N.N sec) [test_suite↪test_fail.py:[LINENR]] [test.py:[LINENR]] +--------------------------------------------------------------------- +trial test_suite FAIL +--------------------------------------------------------------------- +FAIL: test_suite (fail: 1, skip: 5) + skip: hello_world.py (N.N sec) + skip: mo_mt_sms.py + skip: mo_sms.py + skip: test_error.py (N.N sec) + FAIL: test_fail.py (N.N sec) EpicFail: This failure is expected + skip: test_fail_raise.py + +- a test with a raised failure + +--------------------------------------------------------------------- +trial test_suite +--------------------------------------------------------------------- + +---------------------------------------------- +trial test_suite test_fail_raise.py +---------------------------------------------- +tst test_fail_raise.py:[LINENR]: ERR: ExpectedFail: This failure is expected [test_suite↪test_fail_raise.py:[LINENR]] [test_fail_raise.py:[LINENR]: raise ExpectedFail('This failure is expected')] +tst test_fail_raise.py:[LINENR]: Test FAILED (N.N sec) [test_suite↪test_fail_raise.py:[LINENR]] [test.py:[LINENR]] +--------------------------------------------------------------------- +trial test_suite FAIL +--------------------------------------------------------------------- +FAIL: test_suite (fail: 1, skip: 5) + skip: hello_world.py (N.N sec) + skip: mo_mt_sms.py + skip: mo_sms.py + skip: test_error.py (N.N sec) + skip: test_fail.py (N.N sec) + FAIL: test_fail_raise.py (N.N sec) ExpectedFail: This failure is expected +- test with half empty scenario +cnf ResourcesPool: DBG: Found config file resources.conf as [PATH]/selftest/suite_test/resources.conf in ./suite_test which is [PATH]/selftest/suite_test [config.py:[LINENR]] +cnf ResourcesPool: DBG: Found path state_dir as [PATH]/selftest/suite_test/test_work/state_dir [config.py:[LINENR]] + +--------------------------------------------------------------------- +trial test_suite +--------------------------------------------------------------------- +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]] +tst {combining_scenarios='resources'}: DBG: {definition_conf={bts=[{'label': 'sysmoCell 5000'}, {'label': 'sysmoCell 5000'}, {'type': 'sysmo'}], ip_address=[{}], modem=[{}, {}]}} [test_suite↪{combining_scenarios='resources'}] [suite.py:[LINENR]] +tst {combining_scenarios='resources', scenario='foo'}: [RESOURCE_DICT] +tst test_suite: DBG: {combining='modifiers'} [suite.py:[LINENR]] +tst {combining_scenarios='modifiers'}: DBG: {definition_conf={}} [test_suite↪{combining_scenarios='modifiers'}] [suite.py:[LINENR]] +tst {combining_scenarios='modifiers', scenario='foo'}: DBG: {conf={}, scenario='foo'} [test_suite↪{combining_scenarios='modifiers', scenario='foo'}] [suite.py:[LINENR]] +tst test_suite: Reserving 3 x bts (candidates: 6) [resource.py:[LINENR]] +tst test_suite: DBG: Picked - _hash: a59640b8ba6a373552b24a6f9f65cadd2347bace + addr: 10.42.42.53 + band: GSM-1800 + ipa_unit_id: '7' + label: sysmoCell 5000 + osmo_trx: + clock_reference: external + launch_trx: 'False' + trx_ip: 10.42.42.112 + trx_list: + - max_power_red: '3' + nominal_power: '10' + - max_power_red: '0' + nominal_power: '12' + type: osmo-bts-trx +- _hash: c2feabd082c36a1cdeccb9a5237dfff7dbadb009 + addr: 10.42.42.53 + band: GSM-1800 + ipa_unit_id: '7' + label: sysmoCell 5000 + osmo_trx: + clock_reference: external + launch_trx: 'False' + trx_ip: 10.42.42.112 + trx_list: + - nominal_power: '10' + - max_power_red: '1' + nominal_power: '12' + type: osmo-bts-trx +- _hash: 07d9c8aaa940b674efcbbabdd69f58a6ce4e94f9 + addr: 10.42.42.114 + band: GSM-1800 + ipa_unit_id: '1' + label: sysmoBTS 1002 + type: sysmo + [resource.py:[LINENR]] +tst test_suite: Reserving 1 x ip_address (candidates: 3) [resource.py:[LINENR]] +tst test_suite: DBG: Picked - _hash: cde1debf28f07f94f92c761b4b7c6bf35785ced4 + addr: 10.42.42.1 + [resource.py:[LINENR]] +tst test_suite: Reserving 2 x modem (candidates: 16) [resource.py:[LINENR]] +tst test_suite: DBG: Picked - _hash: 19c69e45aa090fb511446bd00797690aa82ff52f + imsi: '901700000007801' + ki: D620F48487B1B782DA55DF6717F08FF9 + label: m7801 + path: /wavecom_0 +- _hash: e1a46516a1fb493b2617ab14fc1693a9a45ec254 + imsi: '901700000007802' + ki: 47FDB2D55CE6A10A85ABDAD034A5B7B3 + label: m7802 + path: /wavecom_1 + [resource.py:[LINENR]] + +---------------------------------------------- +trial test_suite hello_world.py +---------------------------------------------- +tst hello_world.py:[LINENR]: hello world [test_suite↪hello_world.py:[LINENR]] [hello_world.py:[LINENR]] +tst hello_world.py:[LINENR]: I am 'test_suite' / 'hello_world.py:[LINENR]' [test_suite↪hello_world.py:[LINENR]] [hello_world.py:[LINENR]] +tst hello_world.py:[LINENR]: one [test_suite↪hello_world.py:[LINENR]] [hello_world.py:[LINENR]] +tst hello_world.py:[LINENR]: two [test_suite↪hello_world.py:[LINENR]] [hello_world.py:[LINENR]] +tst hello_world.py:[LINENR]: three [test_suite↪hello_world.py:[LINENR]] [hello_world.py:[LINENR]] +tst hello_world.py:[LINENR] Test passed (N.N sec) [test_suite↪hello_world.py] [test.py:[LINENR]] +--------------------------------------------------------------------- +trial test_suite PASS +--------------------------------------------------------------------- +PASS: test_suite (pass: 1, skip: 5) + pass: hello_world.py (N.N sec) + skip: mo_mt_sms.py + skip: mo_sms.py + skip: test_error.py + skip: test_fail.py + skip: test_fail_raise.py +- test with scenario +cnf ResourcesPool: DBG: Found config file resources.conf as [PATH]/selftest/suite_test/resources.conf in ./suite_test which is [PATH]/selftest/suite_test [config.py:[LINENR]] +cnf ResourcesPool: DBG: Found path state_dir as [PATH]/selftest/suite_test/test_work/state_dir [config.py:[LINENR]] + +--------------------------------------------------------------------- +trial test_suite +--------------------------------------------------------------------- +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]] +tst {combining_scenarios='resources'}: DBG: {definition_conf={bts=[{'label': 'sysmoCell 5000'}, {'label': 'sysmoCell 5000'}, {'type': 'sysmo'}], ip_address=[{}], modem=[{}, {}]}} [test_suite↪{combining_scenarios='resources'}] [suite.py:[LINENR]] +tst {combining_scenarios='resources', scenario='foo'}: [RESOURCE_DICT] +tst test_suite: DBG: {combining='modifiers'} [suite.py:[LINENR]] +tst {combining_scenarios='modifiers'}: DBG: {definition_conf={}} [test_suite↪{combining_scenarios='modifiers'}] [suite.py:[LINENR]] +tst {combining_scenarios='modifiers', scenario='foo'}: DBG: {conf={}, scenario='foo'} [test_suite↪{combining_scenarios='modifiers', scenario='foo'}] [suite.py:[LINENR]] +tst test_suite: Reserving 3 x bts (candidates: 6) [resource.py:[LINENR]] +tst test_suite: DBG: Picked - _hash: a59640b8ba6a373552b24a6f9f65cadd2347bace + addr: 10.42.42.53 + band: GSM-1800 + ipa_unit_id: '7' + label: sysmoCell 5000 + osmo_trx: + clock_reference: external + launch_trx: 'False' + trx_ip: 10.42.42.112 + trx_list: + - max_power_red: '3' + nominal_power: '10' + - max_power_red: '0' + nominal_power: '12' + type: osmo-bts-trx +- _hash: c2feabd082c36a1cdeccb9a5237dfff7dbadb009 + addr: 10.42.42.53 + band: GSM-1800 + ipa_unit_id: '7' + label: sysmoCell 5000 + osmo_trx: + clock_reference: external + launch_trx: 'False' + trx_ip: 10.42.42.112 + trx_list: + - nominal_power: '10' + - max_power_red: '1' + nominal_power: '12' + type: osmo-bts-trx +- _hash: 07d9c8aaa940b674efcbbabdd69f58a6ce4e94f9 + addr: 10.42.42.114 + band: GSM-1800 + ipa_unit_id: '1' + label: sysmoBTS 1002 + type: sysmo + [resource.py:[LINENR]] +tst test_suite: Reserving 1 x ip_address (candidates: 3) [resource.py:[LINENR]] +tst test_suite: DBG: Picked - _hash: cde1debf28f07f94f92c761b4b7c6bf35785ced4 + addr: 10.42.42.1 + [resource.py:[LINENR]] +tst test_suite: Reserving 2 x modem (candidates: 16) [resource.py:[LINENR]] +tst test_suite: DBG: Picked - _hash: 19c69e45aa090fb511446bd00797690aa82ff52f + imsi: '901700000007801' + ki: D620F48487B1B782DA55DF6717F08FF9 + label: m7801 + path: /wavecom_0 +- _hash: e1a46516a1fb493b2617ab14fc1693a9a45ec254 + imsi: '901700000007802' + ki: 47FDB2D55CE6A10A85ABDAD034A5B7B3 + label: m7802 + path: /wavecom_1 + [resource.py:[LINENR]] + +---------------------------------------------- +trial test_suite hello_world.py +---------------------------------------------- +tst hello_world.py:[LINENR]: hello world [test_suite↪hello_world.py:[LINENR]] [hello_world.py:[LINENR]] +tst hello_world.py:[LINENR]: I am 'test_suite' / 'hello_world.py:[LINENR]' [test_suite↪hello_world.py:[LINENR]] [hello_world.py:[LINENR]] +tst hello_world.py:[LINENR]: one [test_suite↪hello_world.py:[LINENR]] [hello_world.py:[LINENR]] +tst hello_world.py:[LINENR]: two [test_suite↪hello_world.py:[LINENR]] [hello_world.py:[LINENR]] +tst hello_world.py:[LINENR]: three [test_suite↪hello_world.py:[LINENR]] [hello_world.py:[LINENR]] +tst hello_world.py:[LINENR] Test passed (N.N sec) [test_suite↪hello_world.py] [test.py:[LINENR]] +--------------------------------------------------------------------- +trial test_suite PASS +--------------------------------------------------------------------- +PASS: test_suite (pass: 1, skip: 5) + pass: hello_world.py (N.N sec) + skip: mo_mt_sms.py + skip: mo_sms.py + skip: test_error.py + skip: test_fail.py + skip: test_fail_raise.py +- test with scenario and modifiers +cnf ResourcesPool: DBG: Found config file resources.conf as [PATH]/selftest/suite_test/resources.conf in ./suite_test which is [PATH]/selftest/suite_test [config.py:[LINENR]] +cnf ResourcesPool: DBG: Found path state_dir as [PATH]/selftest/suite_test/test_work/state_dir [config.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]] +tst {combining_scenarios='resources'}: DBG: {definition_conf={bts=[{'label': 'sysmoCell 5000'}, {'label': 'sysmoCell 5000'}, {'type': 'sysmo'}], ip_address=[{}], modem=[{}, {}]}} [test_suite↪{combining_scenarios='resources'}] [suite.py:[LINENR]] +tst {combining_scenarios='resources', scenario='foo'}: [RESOURCE_DICT] +tst test_suite: DBG: {combining='modifiers'} [suite.py:[LINENR]] +tst {combining_scenarios='modifiers'}: DBG: {definition_conf={}} [test_suite↪{combining_scenarios='modifiers'}] [suite.py:[LINENR]] +tst {combining_scenarios='modifiers', scenario='foo'}: DBG: {conf={bts=[{'trx_list': [{'nominal_power': '20'}, {'nominal_power': '20'}]}, {'trx_list': [{'nominal_power': '20'}, {'nominal_power': '20'}]}, {'type': 'sysmo'}]}, scenario='foo'} [test_suite↪{combining_scenarios='modifiers', scenario='foo'}] [suite.py:[LINENR]] +tst test_suite: Reserving 3 x bts (candidates: 6) [resource.py:[LINENR]] +tst test_suite: DBG: Picked - _hash: a59640b8ba6a373552b24a6f9f65cadd2347bace + addr: 10.42.42.53 + band: GSM-1800 + ipa_unit_id: '7' + label: sysmoCell 5000 + osmo_trx: + clock_reference: external + launch_trx: 'False' + trx_ip: 10.42.42.112 + trx_list: + - max_power_red: '3' + nominal_power: '10' + - max_power_red: '0' + nominal_power: '12' + type: osmo-bts-trx +- _hash: c2feabd082c36a1cdeccb9a5237dfff7dbadb009 + addr: 10.42.42.53 + band: GSM-1800 + ipa_unit_id: '7' + label: sysmoCell 5000 + osmo_trx: + clock_reference: external + launch_trx: 'False' + trx_ip: 10.42.42.112 + trx_list: + - nominal_power: '10' + - max_power_red: '1' + nominal_power: '12' + type: osmo-bts-trx +- _hash: 07d9c8aaa940b674efcbbabdd69f58a6ce4e94f9 + addr: 10.42.42.114 + band: GSM-1800 + ipa_unit_id: '1' + label: sysmoBTS 1002 + type: sysmo + [resource.py:[LINENR]] +tst test_suite: Reserving 1 x ip_address (candidates: 3) [resource.py:[LINENR]] +tst test_suite: DBG: Picked - _hash: cde1debf28f07f94f92c761b4b7c6bf35785ced4 + addr: 10.42.42.1 + [resource.py:[LINENR]] +tst test_suite: Reserving 2 x modem (candidates: 16) [resource.py:[LINENR]] +tst test_suite: DBG: Picked - _hash: 19c69e45aa090fb511446bd00797690aa82ff52f + imsi: '901700000007801' + ki: D620F48487B1B782DA55DF6717F08FF9 + label: m7801 + path: /wavecom_0 +- _hash: e1a46516a1fb493b2617ab14fc1693a9a45ec254 + imsi: '901700000007802' + ki: 47FDB2D55CE6A10A85ABDAD034A5B7B3 + label: m7802 + path: /wavecom_1 + [resource.py:[LINENR]] +resources(test_suite)={'bts': [{'_hash': 'a59640b8ba6a373552b24a6f9f65cadd2347bace', + '_reserved_by': 'test_suite-[ID_NUM]-[ID_NUM]', + 'addr': '10.42.42.53', + 'band': 'GSM-1800', + 'ipa_unit_id': '7', + 'label': 'sysmoCell 5000', + 'osmo_trx': {'clock_reference': 'external', + 'launch_trx': 'False', + 'trx_ip': '10.42.42.112'}, + 'trx_list': [{'max_power_red': '3', 'nominal_power': '20'}, + {'max_power_red': '0', 'nominal_power': '20'}], + 'type': 'osmo-bts-trx'}, + {'_hash': 'c2feabd082c36a1cdeccb9a5237dfff7dbadb009', + '_reserved_by': 'test_suite-[ID_NUM]-[ID_NUM]', + 'addr': '10.42.42.53', + 'band': 'GSM-1800', + 'ipa_unit_id': '7', + 'label': 'sysmoCell 5000', + 'osmo_trx': {'clock_reference': 'external', + 'launch_trx': 'False', + 'trx_ip': '10.42.42.112'}, + 'trx_list': [{'nominal_power': '20'}, + {'max_power_red': '1', 'nominal_power': '20'}], + 'type': 'osmo-bts-trx'}, + {'_hash': '07d9c8aaa940b674efcbbabdd69f58a6ce4e94f9', + '_reserved_by': 'test_suite-[ID_NUM]-[ID_NUM]', + 'addr': '10.42.42.114', + 'band': 'GSM-1800', + 'ipa_unit_id': '1', + 'label': 'sysmoBTS 1002', + 'type': 'sysmo'}], + 'ip_address': [{'_hash': 'cde1debf28f07f94f92c761b4b7c6bf35785ced4', + '_reserved_by': 'test_suite-[ID_NUM]-[ID_NUM]', + 'addr': '10.42.42.1'}], + 'modem': [{'_hash': '19c69e45aa090fb511446bd00797690aa82ff52f', + '_reserved_by': 'test_suite-[ID_NUM]-[ID_NUM]', + 'imsi': '901700000007801', + 'ki': 'D620F48487B1B782DA55DF6717F08FF9', + 'label': 'm7801', + 'path': '/wavecom_0'}, + {'_hash': 'e1a46516a1fb493b2617ab14fc1693a9a45ec254', + '_reserved_by': 'test_suite-[ID_NUM]-[ID_NUM]', + 'imsi': '901700000007802', + 'ki': '47FDB2D55CE6A10A85ABDAD034A5B7B3', + 'label': 'm7802', + 'path': '/wavecom_1'}]} + +--------------------------------------------------------------------- +trial test_suite +--------------------------------------------------------------------- + +---------------------------------------------- +trial test_suite hello_world.py +---------------------------------------------- +tst hello_world.py:[LINENR]: hello world [test_suite↪hello_world.py:[LINENR]] [hello_world.py:[LINENR]] +tst hello_world.py:[LINENR]: I am 'test_suite' / 'hello_world.py:[LINENR]' [test_suite↪hello_world.py:[LINENR]] [hello_world.py:[LINENR]] +tst hello_world.py:[LINENR]: one [test_suite↪hello_world.py:[LINENR]] [hello_world.py:[LINENR]] +tst hello_world.py:[LINENR]: two [test_suite↪hello_world.py:[LINENR]] [hello_world.py:[LINENR]] +tst hello_world.py:[LINENR]: three [test_suite↪hello_world.py:[LINENR]] [hello_world.py:[LINENR]] +tst hello_world.py:[LINENR] Test passed (N.N sec) [test_suite↪hello_world.py] [test.py:[LINENR]] +--------------------------------------------------------------------- +trial test_suite PASS +--------------------------------------------------------------------- +PASS: test_suite (pass: 1, skip: 5) + pass: hello_world.py (N.N sec) + skip: mo_mt_sms.py + skip: mo_sms.py + skip: test_error.py + skip: test_fail.py + skip: test_fail_raise.py + +- graceful exit. diff --git a/selftest/suite_test/suite_test.ok.ign b/selftest/suite_test/suite_test.ok.ign new file mode 100644 index 0000000..9bd168f --- /dev/null +++ b/selftest/suite_test/suite_test.ok.ign @@ -0,0 +1,5 @@ +/[^ ]*/selftest/ [PATH]/selftest/ +\.py:[0-9]* .py:[LINENR] +\([0-9.]+ sec\) (N.N sec) +{combining_scenarios='resources', scenario='foo'}:.* {combining_scenarios='resources', scenario='foo'}: [RESOURCE_DICT] +test_suite-[0-9]*-[0-9]* test_suite-[ID_NUM]-[ID_NUM] diff --git a/selftest/suite_test/suite_test.py b/selftest/suite_test/suite_test.py new file mode 100755 index 0000000..de5c6df --- /dev/null +++ b/selftest/suite_test/suite_test.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python3 +import os +import _prep +import shutil +from osmo_gsm_tester.core import log, config, util, report +from osmo_gsm_tester.core import suite +from osmo_gsm_tester.core.schema import generate_schemas + +config.ENV_CONF = './suite_test' + +example_trial_dir = os.path.join('test_trial_tmp') + +class FakeTrial(log.Origin): + def __init__(self): + super().__init__(log.C_TST, 'trial') + self.dir = util.Dir(example_trial_dir) + self._run_dir = None + + def get_run_dir(self): + if self._run_dir is not None: + return self._run_dir + self._run_dir = util.Dir(self.dir.new_child('test_run')) + self._run_dir.mkdir() + return self._run_dir + +#log.style_change(trace=True) + +# Generate supported schemas dynamically from objects: +generate_schemas() + +print('- non-existing suite dir') +assert(log.run_logging_exceptions(suite.load, 'does_not_exist') == None) + +print('- no suite.conf') +assert(log.run_logging_exceptions(suite.load, 'empty_dir') == None) + +print('- valid suite dir') +example_suite_dir = os.path.join('test_suite') +s_def = suite.load(example_suite_dir) +assert(isinstance(s_def, suite.SuiteDefinition)) +print(config.tostr(s_def.conf)) + +print('- run hello world test') +trial = FakeTrial() +s = suite.SuiteRun(trial, 'test_suite', s_def) +results = s.run_tests('hello_world.py') +print(report.suite_to_text(s)) + +log.style_change(src=True) +#log.style_change(trace=True) +print('\n- a test with an error') +results = s.run_tests('test_error.py') +output = report.suite_to_text(s) +print(output) + +print('\n- a test with a failure') +results = s.run_tests('test_fail.py') +output = report.suite_to_text(s) +print(output) + +print('\n- a test with a raised failure') +results = s.run_tests('test_fail_raise.py') +output = report.suite_to_text(s) +print(output) + +print('- test with half empty scenario') +trial = FakeTrial() +scenario = config.Scenario('foo', 'bar') +scenario['resources'] = { 'bts': [{'type': 'osmo-bts-trx'}] } +s = suite.SuiteRun(trial, 'test_suite', s_def, [scenario]) +results = s.run_tests('hello_world.py') +print(report.suite_to_text(s)) + +print('- test with scenario') +trial = FakeTrial() +scenario = config.Scenario('foo', 'bar') +scenario['resources'] = { 'bts': [{ 'times': '2', 'type': 'osmo-bts-trx', 'trx_list': [{'nominal_power': '10'}, {'nominal_power': '12'}]}, {'type': 'sysmo'}] } +s = suite.SuiteRun(trial, 'test_suite', s_def, [scenario]) +results = s.run_tests('hello_world.py') +print(report.suite_to_text(s)) + +print('- test with scenario and modifiers') +trial = FakeTrial() +scenario = config.Scenario('foo', 'bar') +scenario['resources'] = { 'bts': [{ 'times': '2', 'type': 'osmo-bts-trx', 'trx_list': [{'nominal_power': '10'}, {'nominal_power': '12'}]}, {'type': 'sysmo'}] } +scenario['modifiers'] = { 'bts': [{ 'times': '2', 'trx_list': [{'nominal_power': '20'}, {'nominal_power': '20'}]}, {'type': 'sysmo'}] } +s = suite.SuiteRun(trial, 'test_suite', s_def, [scenario]) +s.reserve_resources() +print(repr(s.reserved_resources)) +results = s.run_tests('hello_world.py') +print(report.suite_to_text(s)) + +print('\n- graceful exit.') +#deleting generated tmp trial dir: +shutil.rmtree(example_trial_dir, ignore_errors=True) + +# vim: expandtab tabstop=4 shiftwidth=4 diff --git a/selftest/template_test.err b/selftest/template_test.err deleted file mode 100644 index e69de29..0000000 diff --git a/selftest/template_test.ok b/selftest/template_test.ok deleted file mode 100644 index 88b77b0..0000000 --- a/selftest/template_test.ok +++ /dev/null @@ -1,193 +0,0 @@ -- Testing: fill a config file with values -cnf Templates: DBG: rendering osmo-nitb.cfg.tmpl -! Configuration rendered by osmo-gsm-tester -password foo -! -log stderr - logging filter all 1 - logging color 1 - logging print category 1 - logging print extended-timestamp 1 - logging level set-all debug -! -line vty - no login - bind val_ip_address -! -e1_input - e1_line 0 driver ipa - ipa bind val_ip_address -network - network country code val_mcc - mobile network code val_mnc - short name val_short_name - long name val_long_name - auth policy val_auth_policy - location updating reject cause 13 - encryption val_encryption - neci 1 - rrlp mode none - mm info 1 - handover 0 - handover window rxlev averaging 10 - handover window rxqual averaging 1 - handover window rxlev neighbor averaging 10 - handover power budget interval 6 - handover power budget hysteresis 3 - handover maximum distance 9999 - bts 0 - type val_type_bts0 - band val_band_bts0 - cell_identity val_bts.cell_identity_bts0 - location_area_code val_bts.location_area_code_bts0 - training_sequence_code 7 - base_station_id_code val_bts.base_station_id_code_bts0 - ms max power 33 - cell reselection hysteresis 4 - rxlev access min 0 - channel allocator ascending - rach tx integer 9 - rach max transmission 7 - ip.access unit_id val_bts.unit_id_bts0 0 - oml ip.access stream_id val_bts.stream_id_bts0 line 0 - gprs mode gprs - gprs routing area val_bts.routing_area_code_bts0 - gprs network-control-order nc1 - gprs cell bvci val_bts.bvci_bts0 - gprs cell timer blocking-timer 3 - gprs cell timer blocking-retries 3 - gprs cell timer unblocking-retries 3 - gprs cell timer reset-timer 3 - gprs cell timer reset-retries 3 - gprs cell timer suspend-timer 10 - gprs cell timer suspend-retries 3 - gprs cell timer resume-timer 10 - gprs cell timer resume-retries 3 - gprs cell timer capability-update-timer 10 - gprs cell timer capability-update-retries 3 - gprs nsei val_bts.bvci_bts0 - gprs ns timer tns-block 3 - gprs ns timer tns-block-retries 3 - gprs ns timer tns-reset 3 - gprs ns timer tns-reset-retries 3 - gprs ns timer tns-test 30 - gprs ns timer tns-alive 3 - gprs ns timer tns-alive-retries 10 - gprs nsvc 0 nsvci val_bts.bvci_bts0 - gprs nsvc 0 local udp port 23020 - gprs nsvc 0 remote udp port 23000 - gprs nsvc 0 remote ip val_bts.sgsn_ip_addr_bts0 - trx 0 - rf_locked 0 - arfcn val_trx_arfcn_trx0 - nominal power val_trx_nominal_power_trx0 - max_power_red val_trx_max_power_red_trx0 - rsl e1 tei 0 - timeslot 0 - phys_chan_config val_phys_chan_config_0 - timeslot 1 - phys_chan_config val_phys_chan_config_1 - timeslot 2 - phys_chan_config val_phys_chan_config_2 - timeslot 3 - phys_chan_config val_phys_chan_config_3 - trx 1 - rf_locked 0 - arfcn val_trx_arfcn_trx1 - nominal power val_trx_nominal_power_trx1 - max_power_red val_trx_max_power_red_trx1 - rsl e1 tei 0 - timeslot 0 - phys_chan_config val_phys_chan_config_0 - timeslot 1 - phys_chan_config val_phys_chan_config_1 - timeslot 2 - phys_chan_config val_phys_chan_config_2 - timeslot 3 - phys_chan_config val_phys_chan_config_3 - bts 1 - type val_type_bts1 - band val_band_bts1 - cell_identity val_bts.cell_identity_bts1 - location_area_code val_bts.location_area_code_bts1 - training_sequence_code 7 - base_station_id_code val_bts.base_station_id_code_bts1 - ms max power 33 - cell reselection hysteresis 4 - rxlev access min 0 - channel allocator ascending - rach tx integer 9 - rach max transmission 7 - ip.access unit_id val_bts.unit_id_bts1 0 - oml ip.access stream_id val_bts.stream_id_bts1 line 0 - gprs mode gprs - gprs routing area val_bts.routing_area_code_bts1 - gprs network-control-order nc1 - gprs cell bvci val_bts.bvci_bts1 - gprs cell timer blocking-timer 3 - gprs cell timer blocking-retries 3 - gprs cell timer unblocking-retries 3 - gprs cell timer reset-timer 3 - gprs cell timer reset-retries 3 - gprs cell timer suspend-timer 10 - gprs cell timer suspend-retries 3 - gprs cell timer resume-timer 10 - gprs cell timer resume-retries 3 - gprs cell timer capability-update-timer 10 - gprs cell timer capability-update-retries 3 - gprs nsei val_bts.bvci_bts1 - gprs ns timer tns-block 3 - gprs ns timer tns-block-retries 3 - gprs ns timer tns-reset 3 - gprs ns timer tns-reset-retries 3 - gprs ns timer tns-test 30 - gprs ns timer tns-alive 3 - gprs ns timer tns-alive-retries 10 - gprs nsvc 0 nsvci val_bts.bvci_bts1 - gprs nsvc 0 local udp port 23020 - gprs nsvc 0 remote udp port 23000 - gprs nsvc 0 remote ip val_bts.sgsn_ip_addr_bts1 - trx 0 - rf_locked 0 - arfcn val_trx_arfcn_trx0 - nominal power val_trx_nominal_power_trx0 - max_power_red val_trx_max_power_red_trx0 - rsl e1 tei 0 - timeslot 0 - phys_chan_config val_phys_chan_config_0 - timeslot 1 - phys_chan_config val_phys_chan_config_1 - timeslot 2 - phys_chan_config val_phys_chan_config_2 - timeslot 3 - phys_chan_config val_phys_chan_config_3 - trx 1 - rf_locked 0 - arfcn val_trx_arfcn_trx1 - nominal power val_trx_nominal_power_trx1 - max_power_red val_trx_max_power_red_trx1 - rsl e1 tei 0 - timeslot 0 - phys_chan_config val_phys_chan_config_0 - timeslot 1 - phys_chan_config val_phys_chan_config_1 - timeslot 2 - phys_chan_config val_phys_chan_config_2 - timeslot 3 - phys_chan_config val_phys_chan_config_3 -smpp - local-tcp-ip val_ip_address 2775 - system-id test-nitb - policy val_smsc_policy - esme val_system_id_esme0 - password val_password_esme0 - default-route - esme val_system_id_esme1 - no password - default-route -ctrl - bind val_ip_address - -- Testing: expect to fail on invalid templates dir -sucess: setting non-existing templates dir raised RuntimeError - diff --git a/selftest/template_test.py b/selftest/template_test.py deleted file mode 100755 index 747d508..0000000 --- a/selftest/template_test.py +++ /dev/null @@ -1,95 +0,0 @@ -#!/usr/bin/env python3 - -import _prep - -import sys -import os - -from osmo_gsm_tester.core import template, log - -log.set_level(log.C_CNF, log.L_DBG) - -print('- Testing: fill a config file with values') - -mock_timeslot_list=( - { 'phys_chan_config': 'val_phys_chan_config_0' }, - { 'phys_chan_config': 'val_phys_chan_config_1' }, - { 'phys_chan_config': 'val_phys_chan_config_2' }, - { 'phys_chan_config': 'val_phys_chan_config_3' }, - ) - -mock_bts = { - 'osmobsc_bts_type': 'val_type', - 'band': 'val_band', - 'location_area_code': 'val_bts.location_area_code', - 'routing_area_code': 'val_bts.routing_area_code', - 'cell_identity': 'val_bts.cell_identity', - 'bvci': 'val_bts.bvci', - 'base_station_id_code': 'val_bts.base_station_id_code', - 'ipa_unit_id': 'val_bts.unit_id', - 'stream_id': 'val_bts.stream_id', - 'sgsn': (dict(ip_address=dict(addr='val_bts.sgsn_ip_addr'))), - 'trx_list': ( - dict(arfcn='val_trx_arfcn_trx0', - nominal_power='val_trx_nominal_power_trx0', - max_power_red='val_trx_max_power_red_trx0', - timeslot_list=mock_timeslot_list), - dict(arfcn='val_trx_arfcn_trx1', - nominal_power='val_trx_nominal_power_trx1', - max_power_red='val_trx_max_power_red_trx1', - timeslot_list=mock_timeslot_list), - ) -} - -mock_esme = { - 'system_id': 'val_system_id', - 'password': 'val_password' -} - -def clone_mod(d, val_ext): - c = dict(d) - for name in c.keys(): - if isinstance(c[name], str): - c[name] = c[name] + val_ext - elif isinstance(c[name], dict): - c[name] = clone_mod(c[name], val_ext) - return c - -mock_bts0 = clone_mod(mock_bts, '_bts0') -mock_bts1 = clone_mod(mock_bts, '_bts1') - -mock_esme0 = clone_mod(mock_esme, '_esme0') -mock_esme1 = clone_mod(mock_esme, '_esme1') -mock_esme1['password'] = '' - -vals = dict(nitb=dict( - net=dict( - mcc='val_mcc', - mnc='val_mnc', - short_name='val_short_name', - long_name='val_long_name', - auth_policy='val_auth_policy', - encryption='val_encryption', - bts_list=(mock_bts0, mock_bts1) - ), - ip_address=dict(addr='val_ip_address'), - ), - smsc=dict( - policy='val_smsc_policy', - esme_list=(mock_esme0, mock_esme1) - ), - ) - -print(template.render('osmo-nitb.cfg', vals)) - -print('- Testing: expect to fail on invalid templates dir') -try: - template.set_templates_dir('non-existing dir') - sys.stderr.write('Error: setting non-existing templates dir should raise RuntimeError\n') - assert(False) -except RuntimeError: - # not logging exception to omit non-constant path name from expected output - print('sucess: setting non-existing templates dir raised RuntimeError\n') - pass - -# vim: expandtab tabstop=4 shiftwidth=4 diff --git a/selftest/template_test/_prep.py b/selftest/template_test/_prep.py new file mode 120000 index 0000000..9cea3fe --- /dev/null +++ b/selftest/template_test/_prep.py @@ -0,0 +1 @@ +../_prep.py \ No newline at end of file diff --git a/selftest/template_test/template_test.err b/selftest/template_test/template_test.err new file mode 100644 index 0000000..e69de29 diff --git a/selftest/template_test/template_test.ok b/selftest/template_test/template_test.ok new file mode 100644 index 0000000..88b77b0 --- /dev/null +++ b/selftest/template_test/template_test.ok @@ -0,0 +1,193 @@ +- Testing: fill a config file with values +cnf Templates: DBG: rendering osmo-nitb.cfg.tmpl +! Configuration rendered by osmo-gsm-tester +password foo +! +log stderr + logging filter all 1 + logging color 1 + logging print category 1 + logging print extended-timestamp 1 + logging level set-all debug +! +line vty + no login + bind val_ip_address +! +e1_input + e1_line 0 driver ipa + ipa bind val_ip_address +network + network country code val_mcc + mobile network code val_mnc + short name val_short_name + long name val_long_name + auth policy val_auth_policy + location updating reject cause 13 + encryption val_encryption + neci 1 + rrlp mode none + mm info 1 + handover 0 + handover window rxlev averaging 10 + handover window rxqual averaging 1 + handover window rxlev neighbor averaging 10 + handover power budget interval 6 + handover power budget hysteresis 3 + handover maximum distance 9999 + bts 0 + type val_type_bts0 + band val_band_bts0 + cell_identity val_bts.cell_identity_bts0 + location_area_code val_bts.location_area_code_bts0 + training_sequence_code 7 + base_station_id_code val_bts.base_station_id_code_bts0 + ms max power 33 + cell reselection hysteresis 4 + rxlev access min 0 + channel allocator ascending + rach tx integer 9 + rach max transmission 7 + ip.access unit_id val_bts.unit_id_bts0 0 + oml ip.access stream_id val_bts.stream_id_bts0 line 0 + gprs mode gprs + gprs routing area val_bts.routing_area_code_bts0 + gprs network-control-order nc1 + gprs cell bvci val_bts.bvci_bts0 + gprs cell timer blocking-timer 3 + gprs cell timer blocking-retries 3 + gprs cell timer unblocking-retries 3 + gprs cell timer reset-timer 3 + gprs cell timer reset-retries 3 + gprs cell timer suspend-timer 10 + gprs cell timer suspend-retries 3 + gprs cell timer resume-timer 10 + gprs cell timer resume-retries 3 + gprs cell timer capability-update-timer 10 + gprs cell timer capability-update-retries 3 + gprs nsei val_bts.bvci_bts0 + gprs ns timer tns-block 3 + gprs ns timer tns-block-retries 3 + gprs ns timer tns-reset 3 + gprs ns timer tns-reset-retries 3 + gprs ns timer tns-test 30 + gprs ns timer tns-alive 3 + gprs ns timer tns-alive-retries 10 + gprs nsvc 0 nsvci val_bts.bvci_bts0 + gprs nsvc 0 local udp port 23020 + gprs nsvc 0 remote udp port 23000 + gprs nsvc 0 remote ip val_bts.sgsn_ip_addr_bts0 + trx 0 + rf_locked 0 + arfcn val_trx_arfcn_trx0 + nominal power val_trx_nominal_power_trx0 + max_power_red val_trx_max_power_red_trx0 + rsl e1 tei 0 + timeslot 0 + phys_chan_config val_phys_chan_config_0 + timeslot 1 + phys_chan_config val_phys_chan_config_1 + timeslot 2 + phys_chan_config val_phys_chan_config_2 + timeslot 3 + phys_chan_config val_phys_chan_config_3 + trx 1 + rf_locked 0 + arfcn val_trx_arfcn_trx1 + nominal power val_trx_nominal_power_trx1 + max_power_red val_trx_max_power_red_trx1 + rsl e1 tei 0 + timeslot 0 + phys_chan_config val_phys_chan_config_0 + timeslot 1 + phys_chan_config val_phys_chan_config_1 + timeslot 2 + phys_chan_config val_phys_chan_config_2 + timeslot 3 + phys_chan_config val_phys_chan_config_3 + bts 1 + type val_type_bts1 + band val_band_bts1 + cell_identity val_bts.cell_identity_bts1 + location_area_code val_bts.location_area_code_bts1 + training_sequence_code 7 + base_station_id_code val_bts.base_station_id_code_bts1 + ms max power 33 + cell reselection hysteresis 4 + rxlev access min 0 + channel allocator ascending + rach tx integer 9 + rach max transmission 7 + ip.access unit_id val_bts.unit_id_bts1 0 + oml ip.access stream_id val_bts.stream_id_bts1 line 0 + gprs mode gprs + gprs routing area val_bts.routing_area_code_bts1 + gprs network-control-order nc1 + gprs cell bvci val_bts.bvci_bts1 + gprs cell timer blocking-timer 3 + gprs cell timer blocking-retries 3 + gprs cell timer unblocking-retries 3 + gprs cell timer reset-timer 3 + gprs cell timer reset-retries 3 + gprs cell timer suspend-timer 10 + gprs cell timer suspend-retries 3 + gprs cell timer resume-timer 10 + gprs cell timer resume-retries 3 + gprs cell timer capability-update-timer 10 + gprs cell timer capability-update-retries 3 + gprs nsei val_bts.bvci_bts1 + gprs ns timer tns-block 3 + gprs ns timer tns-block-retries 3 + gprs ns timer tns-reset 3 + gprs ns timer tns-reset-retries 3 + gprs ns timer tns-test 30 + gprs ns timer tns-alive 3 + gprs ns timer tns-alive-retries 10 + gprs nsvc 0 nsvci val_bts.bvci_bts1 + gprs nsvc 0 local udp port 23020 + gprs nsvc 0 remote udp port 23000 + gprs nsvc 0 remote ip val_bts.sgsn_ip_addr_bts1 + trx 0 + rf_locked 0 + arfcn val_trx_arfcn_trx0 + nominal power val_trx_nominal_power_trx0 + max_power_red val_trx_max_power_red_trx0 + rsl e1 tei 0 + timeslot 0 + phys_chan_config val_phys_chan_config_0 + timeslot 1 + phys_chan_config val_phys_chan_config_1 + timeslot 2 + phys_chan_config val_phys_chan_config_2 + timeslot 3 + phys_chan_config val_phys_chan_config_3 + trx 1 + rf_locked 0 + arfcn val_trx_arfcn_trx1 + nominal power val_trx_nominal_power_trx1 + max_power_red val_trx_max_power_red_trx1 + rsl e1 tei 0 + timeslot 0 + phys_chan_config val_phys_chan_config_0 + timeslot 1 + phys_chan_config val_phys_chan_config_1 + timeslot 2 + phys_chan_config val_phys_chan_config_2 + timeslot 3 + phys_chan_config val_phys_chan_config_3 +smpp + local-tcp-ip val_ip_address 2775 + system-id test-nitb + policy val_smsc_policy + esme val_system_id_esme0 + password val_password_esme0 + default-route + esme val_system_id_esme1 + no password + default-route +ctrl + bind val_ip_address + +- Testing: expect to fail on invalid templates dir +sucess: setting non-existing templates dir raised RuntimeError + diff --git a/selftest/template_test/template_test.py b/selftest/template_test/template_test.py new file mode 100755 index 0000000..747d508 --- /dev/null +++ b/selftest/template_test/template_test.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python3 + +import _prep + +import sys +import os + +from osmo_gsm_tester.core import template, log + +log.set_level(log.C_CNF, log.L_DBG) + +print('- Testing: fill a config file with values') + +mock_timeslot_list=( + { 'phys_chan_config': 'val_phys_chan_config_0' }, + { 'phys_chan_config': 'val_phys_chan_config_1' }, + { 'phys_chan_config': 'val_phys_chan_config_2' }, + { 'phys_chan_config': 'val_phys_chan_config_3' }, + ) + +mock_bts = { + 'osmobsc_bts_type': 'val_type', + 'band': 'val_band', + 'location_area_code': 'val_bts.location_area_code', + 'routing_area_code': 'val_bts.routing_area_code', + 'cell_identity': 'val_bts.cell_identity', + 'bvci': 'val_bts.bvci', + 'base_station_id_code': 'val_bts.base_station_id_code', + 'ipa_unit_id': 'val_bts.unit_id', + 'stream_id': 'val_bts.stream_id', + 'sgsn': (dict(ip_address=dict(addr='val_bts.sgsn_ip_addr'))), + 'trx_list': ( + dict(arfcn='val_trx_arfcn_trx0', + nominal_power='val_trx_nominal_power_trx0', + max_power_red='val_trx_max_power_red_trx0', + timeslot_list=mock_timeslot_list), + dict(arfcn='val_trx_arfcn_trx1', + nominal_power='val_trx_nominal_power_trx1', + max_power_red='val_trx_max_power_red_trx1', + timeslot_list=mock_timeslot_list), + ) +} + +mock_esme = { + 'system_id': 'val_system_id', + 'password': 'val_password' +} + +def clone_mod(d, val_ext): + c = dict(d) + for name in c.keys(): + if isinstance(c[name], str): + c[name] = c[name] + val_ext + elif isinstance(c[name], dict): + c[name] = clone_mod(c[name], val_ext) + return c + +mock_bts0 = clone_mod(mock_bts, '_bts0') +mock_bts1 = clone_mod(mock_bts, '_bts1') + +mock_esme0 = clone_mod(mock_esme, '_esme0') +mock_esme1 = clone_mod(mock_esme, '_esme1') +mock_esme1['password'] = '' + +vals = dict(nitb=dict( + net=dict( + mcc='val_mcc', + mnc='val_mnc', + short_name='val_short_name', + long_name='val_long_name', + auth_policy='val_auth_policy', + encryption='val_encryption', + bts_list=(mock_bts0, mock_bts1) + ), + ip_address=dict(addr='val_ip_address'), + ), + smsc=dict( + policy='val_smsc_policy', + esme_list=(mock_esme0, mock_esme1) + ), + ) + +print(template.render('osmo-nitb.cfg', vals)) + +print('- Testing: expect to fail on invalid templates dir') +try: + template.set_templates_dir('non-existing dir') + sys.stderr.write('Error: setting non-existing templates dir should raise RuntimeError\n') + assert(False) +except RuntimeError: + # not logging exception to omit non-constant path name from expected output + print('sucess: setting non-existing templates dir raised RuntimeError\n') + pass + +# vim: expandtab tabstop=4 shiftwidth=4 diff --git a/selftest/trial_test.err b/selftest/trial_test.err deleted file mode 100644 index e69de29..0000000 diff --git a/selftest/trial_test.ok b/selftest/trial_test.ok deleted file mode 100644 index 8c6a567..0000000 --- a/selftest/trial_test.ok +++ /dev/null @@ -1,16 +0,0 @@ -- make a few trials dirs -[TMP]/first -[TMP]/second -[TMP]/third -- fetch trial dirs in order -first -['taken'] -second -third -- no more trial dirs left -None -- test checksum verification -- detect wrong checksum -ok, got RuntimeError: Checksum mismatch for '[PATH]/trial_test/invalid_checksum/file2' vs. '[PATH]/trial_test/invalid_checksum/checksums.md5' line 2 -- detect missing file -ok, got RuntimeError: File listed in checksums file but missing in trials dir: '[PATH]/trial_test/missing_file/file2' vs. '[PATH]/trial_test/missing_file/checksums.md5' line 2 diff --git a/selftest/trial_test.ok.ign b/selftest/trial_test.ok.ign deleted file mode 100644 index 1a969de..0000000 --- a/selftest/trial_test.ok.ign +++ /dev/null @@ -1,3 +0,0 @@ -/tmp/[^/]* [TMP] -....-..-.._..-..-.. [TIMESTAMP] -'[^']*/trial_test '[PATH]/trial_test diff --git a/selftest/trial_test.py b/selftest/trial_test.py deleted file mode 100755 index a99428a..0000000 --- a/selftest/trial_test.py +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/env python3 - -import time -import _prep -import os -from osmo_gsm_tester.core import util -from osmo_gsm_tester.core.trial import Trial - -workdir = util.get_tempdir() - -trials_dir = util.Dir(workdir) - -print('- make a few trials dirs') -print(trials_dir.mkdir('first')) -time.sleep(1) -print(trials_dir.mkdir('second')) -time.sleep(1) -print(trials_dir.mkdir('third')) - -print('- fetch trial dirs in order') -t = Trial.next(trials_dir) -print(t) -print(repr(sorted(t.dir.children()))) -print(Trial.next(trials_dir)) -print(Trial.next(trials_dir)) - -print('- no more trial dirs left') -print(repr(Trial.next(trials_dir))) - -print('- test checksum verification') -d = util.Dir('trial_test') -t = Trial(d.child('valid_checksums')) -t.verify() - -print('- detect wrong checksum') -t = Trial(d.child('invalid_checksum')) -try: - t.verify() -except RuntimeError as e: - print('ok, got RuntimeError: %s' % str(e)) - -print('- detect missing file') -t = Trial(d.child('missing_file')) -try: - t.verify() -except RuntimeError as e: - print('ok, got RuntimeError: %s' % str(e)) - -# vim: expandtab tabstop=4 shiftwidth=4 diff --git a/selftest/trial_test/_prep.py b/selftest/trial_test/_prep.py new file mode 120000 index 0000000..9cea3fe --- /dev/null +++ b/selftest/trial_test/_prep.py @@ -0,0 +1 @@ +../_prep.py \ No newline at end of file diff --git a/selftest/trial_test/trial_test.err b/selftest/trial_test/trial_test.err new file mode 100644 index 0000000..e69de29 diff --git a/selftest/trial_test/trial_test.ok b/selftest/trial_test/trial_test.ok new file mode 100644 index 0000000..8c6a567 --- /dev/null +++ b/selftest/trial_test/trial_test.ok @@ -0,0 +1,16 @@ +- make a few trials dirs +[TMP]/first +[TMP]/second +[TMP]/third +- fetch trial dirs in order +first +['taken'] +second +third +- no more trial dirs left +None +- test checksum verification +- detect wrong checksum +ok, got RuntimeError: Checksum mismatch for '[PATH]/trial_test/invalid_checksum/file2' vs. '[PATH]/trial_test/invalid_checksum/checksums.md5' line 2 +- detect missing file +ok, got RuntimeError: File listed in checksums file but missing in trials dir: '[PATH]/trial_test/missing_file/file2' vs. '[PATH]/trial_test/missing_file/checksums.md5' line 2 diff --git a/selftest/trial_test/trial_test.ok.ign b/selftest/trial_test/trial_test.ok.ign new file mode 100644 index 0000000..1a969de --- /dev/null +++ b/selftest/trial_test/trial_test.ok.ign @@ -0,0 +1,3 @@ +/tmp/[^/]* [TMP] +....-..-.._..-..-.. [TIMESTAMP] +'[^']*/trial_test '[PATH]/trial_test diff --git a/selftest/trial_test/trial_test.py b/selftest/trial_test/trial_test.py new file mode 100755 index 0000000..a99428a --- /dev/null +++ b/selftest/trial_test/trial_test.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python3 + +import time +import _prep +import os +from osmo_gsm_tester.core import util +from osmo_gsm_tester.core.trial import Trial + +workdir = util.get_tempdir() + +trials_dir = util.Dir(workdir) + +print('- make a few trials dirs') +print(trials_dir.mkdir('first')) +time.sleep(1) +print(trials_dir.mkdir('second')) +time.sleep(1) +print(trials_dir.mkdir('third')) + +print('- fetch trial dirs in order') +t = Trial.next(trials_dir) +print(t) +print(repr(sorted(t.dir.children()))) +print(Trial.next(trials_dir)) +print(Trial.next(trials_dir)) + +print('- no more trial dirs left') +print(repr(Trial.next(trials_dir))) + +print('- test checksum verification') +d = util.Dir('trial_test') +t = Trial(d.child('valid_checksums')) +t.verify() + +print('- detect wrong checksum') +t = Trial(d.child('invalid_checksum')) +try: + t.verify() +except RuntimeError as e: + print('ok, got RuntimeError: %s' % str(e)) + +print('- detect missing file') +t = Trial(d.child('missing_file')) +try: + t.verify() +except RuntimeError as e: + print('ok, got RuntimeError: %s' % str(e)) + +# vim: expandtab tabstop=4 shiftwidth=4 diff --git a/selftest/util_test.err b/selftest/util_test.err deleted file mode 100644 index e69de29..0000000 diff --git a/selftest/util_test.ok b/selftest/util_test.ok deleted file mode 100644 index c2c5f87..0000000 --- a/selftest/util_test.ok +++ /dev/null @@ -1,5 +0,0 @@ -- expect the same hashes on every test run -a9993e364706816aba3e25717850c26c9cd0d89d -356a192b7913b04c54574d18c28d46e6395428ab -40bd001563085fc35165329ea1ff5c5ecbdbbeef -c129b324aee662b04eccf68babba85851346dff9 diff --git a/selftest/util_test.py b/selftest/util_test.py deleted file mode 100755 index e07b2d4..0000000 --- a/selftest/util_test.py +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env python3 -import _prep - -from osmo_gsm_tester.core.util import hash_obj - -print('- expect the same hashes on every test run') -print(hash_obj('abc')) -print(hash_obj(1)) -print(hash_obj([1, 2, 3])) -print(hash_obj({ 'k': [ {'a': 1, 'b': 2}, {'a': 3, 'b': 4}, ], - 'i': [ {'c': 1, 'd': 2}, {'c': 3, 'd': 4}, ] })) diff --git a/selftest/util_test/_prep.py b/selftest/util_test/_prep.py new file mode 120000 index 0000000..9cea3fe --- /dev/null +++ b/selftest/util_test/_prep.py @@ -0,0 +1 @@ +../_prep.py \ No newline at end of file diff --git a/selftest/util_test/util_test.err b/selftest/util_test/util_test.err new file mode 100644 index 0000000..e69de29 diff --git a/selftest/util_test/util_test.ok b/selftest/util_test/util_test.ok new file mode 100644 index 0000000..c2c5f87 --- /dev/null +++ b/selftest/util_test/util_test.ok @@ -0,0 +1,5 @@ +- expect the same hashes on every test run +a9993e364706816aba3e25717850c26c9cd0d89d +356a192b7913b04c54574d18c28d46e6395428ab +40bd001563085fc35165329ea1ff5c5ecbdbbeef +c129b324aee662b04eccf68babba85851346dff9 diff --git a/selftest/util_test/util_test.py b/selftest/util_test/util_test.py new file mode 100755 index 0000000..e07b2d4 --- /dev/null +++ b/selftest/util_test/util_test.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python3 +import _prep + +from osmo_gsm_tester.core.util import hash_obj + +print('- expect the same hashes on every test run') +print(hash_obj('abc')) +print(hash_obj(1)) +print(hash_obj([1, 2, 3])) +print(hash_obj({ 'k': [ {'a': 1, 'b': 2}, {'a': 3, 'b': 4}, ], + 'i': [ {'c': 1, 'd': 2}, {'c': 3, 'd': 4}, ] })) -- cgit v1.2.3