diff --git a/ci-scripts/cls_oaicitest.py b/ci-scripts/cls_oaicitest.py index 52cea6a3c4..ba322ca608 100644 --- a/ci-scripts/cls_oaicitest.py +++ b/ci-scripts/cls_oaicitest.py @@ -47,6 +47,7 @@ import constants as CONST import cls_module import cls_corenetwork import cls_cmd +from cls_ci_helper import archiveArtifact #----------------------------------------------------------- # Helper functions used here and in other classes @@ -256,7 +257,6 @@ class OaiCiTest(): self.ranAllowMerge = False self.ranTargetBranch = '' - self.testCase_id = '' self.testXMLfiles = [] self.ping_args = '' self.ping_packetloss_threshold = '' @@ -351,7 +351,7 @@ class OaiCiTest(): HTML.CreateHtmlTestRowQueue('NA', 'OK', messages) return True - def Ping_common(self, cn, ue, logPath): + def Ping_common(self, ctx, cn, ue): ping_status = 0 ueIP = ue.getIP() if not ueIP: @@ -359,13 +359,12 @@ class OaiCiTest(): svrIP = cn.getIP() if not svrIP: return (False, f"CN {cn.getName()} has no IP address") - ping_log_file = f'ping_{self.testCase_id}_{ue.getName()}.log' + ping_log_file = f'/tmp/ping_{ue.getName()}.log' ping_time = re.findall(r"-c *(\d+)",str(self.ping_args)) - local_ping_log_file = f'{logPath}/{ping_log_file}' if re.search('%cn_ip%', self.ping_args) or re.search(r'[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+', self.ping_args): raise Exception(f"ping_args should not have IP address: {self.ping_args}") interface = f'-I {ue.getIFName()}' if ue.getIFName() else '' - ping_cmd = f'{ue.getCmdPrefix()} ping {interface} {self.ping_args} {svrIP} 2>&1 | tee /tmp/{ping_log_file}' + ping_cmd = f'{ue.getCmdPrefix()} ping {interface} {self.ping_args} {svrIP} 2>&1 | tee {ping_log_file}' cmd = cls_cmd.getConnection(ue.getHost()) response = cmd.run(ping_cmd, timeout=int(ping_time[0])*1.5) ue_header = f'UE {ue.getName()} ({ueIP})' @@ -373,8 +372,7 @@ class OaiCiTest(): message = ue_header + ': ping crashed: TIMEOUT?' return (False, message) - #copy the ping log file to have it locally for analysis (ping stats) - cmd.copyin(src=f'/tmp/{ping_log_file}', tgt=local_ping_log_file) + local_ping_log_file = archiveArtifact(cmd, ctx, ping_log_file) cmd.close() with open(local_ping_log_file, 'r') as f: @@ -414,18 +412,13 @@ class OaiCiTest(): return (True, message) - def Ping(self, HTML, CONTAINERS, infra_file="ci_infra.yaml"): + def Ping(self, ctx, HTML, infra_file="ci_infra.yaml"): if self.ue_ids == [] or self.svr_id == None: raise Exception("no module names in self.ue_ids or/and self.svr_id provided") - # Creating destination log folder if needed on the python executor workspace - with cls_cmd.getConnection('localhost') as local: - ymlPath = CONTAINERS.yamlPath[0].split('/') - logPath = f'{os.getcwd()}/../cmake_targets/log/{ymlPath[-1]}' - local.run(f'mkdir -p {logPath}', silent=True) ues = [cls_module.Module_UE(ue_id, server_name, infra_file) for ue_id, server_name in zip(self.ue_ids, self.nodes)] cn = cls_corenetwork.CoreNetwork(self.svr_id, self.svr_node, filename=infra_file) with concurrent.futures.ThreadPoolExecutor(max_workers=64) as executor: - futures = [executor.submit(self.Ping_common, cn, ue, logPath) for ue in ues] + futures = [executor.submit(self.Ping_common, ctx, cn, ue) for ue in ues] results = [f.result() for f in futures] # each result in results is a tuple, first member goes to successes, second to messages successes, messages = map(list, zip(*results)) @@ -446,7 +439,7 @@ class OaiCiTest(): HTML.CreateHtmlTestRowQueue(self.ping_args, 'KO', messages) return success - def Iperf_Module(self, cn, ue, idx, ue_num, logPath): + def Iperf_Module(self, ctx, cn, ue, idx, ue_num): ueIP = ue.getIP() if not ueIP: return (False, f"UE {ue.getName()} has no IP address") @@ -459,7 +452,7 @@ class OaiCiTest(): serverReport = "" udpIperf = re.search('-u', iperf_opt) is not None bidirIperf = re.search('--bidir', iperf_opt) is not None - client_filename = f'iperf_client_{self.testCase_id}_{ue.getName()}.log' + client_filename = f'/tmp/iperf_client_{ue.getName()}.log' if udpIperf: target_bitrate, iperf_opt = Iperf_ComputeModifiedBW(idx, ue_num, self.iperf_profile, self.iperf_args) # note: for UDP testing we don't want to use json report - reports 0 Mbps received bitrate @@ -474,14 +467,11 @@ class OaiCiTest(): port = 5002 + idx # note: some core setups start an iperf3 server automatically, indicated in ci_infra by runIperf3Server: False` t = iperf_time * 2.5 - cmd_ue.run(f'rm /tmp/{client_filename}', reportNonZero=False, silent=True) + cmd_ue.run(f'rm {client_filename}', reportNonZero=False, silent=True) if cn.runIperf3Server(): cmd_svr.run(f'{cn.getCmdPrefix()} timeout -vk3 {t} iperf3 -s -B {svrIP} -p {port} -1 {jsonReport} >> /dev/null &', timeout=t) - cmd_ue.run(f'{ue.getCmdPrefix()} timeout -vk3 {t} {iperf_ue} -B {ueIP} -c {svrIP} -p {port} {iperf_opt} {jsonReport} {serverReport} -O 5 >> /tmp/{client_filename}', timeout=t) - # note: copy iperf3 log to the current directory for log analysis and log collection - dest_filename = f'{logPath}/{client_filename}' - cmd_ue.copyin(f'/tmp/{client_filename}', dest_filename) - cmd_ue.run(f'rm /tmp/{client_filename}', reportNonZero=False, silent=True) + cmd_ue.run(f'{ue.getCmdPrefix()} timeout -vk3 {t} {iperf_ue} -B {ueIP} -c {svrIP} -p {port} {iperf_opt} {jsonReport} {serverReport} -O 5 >> {client_filename}', timeout=t) + dest_filename = archiveArtifact(cmd_ue, ctx, client_filename) if udpIperf: status, msg = Iperf_analyzeV3UDP(dest_filename, self.iperf_bitrate_threshold, self.iperf_packetloss_threshold, target_bitrate) elif bidirIperf: @@ -491,20 +481,15 @@ class OaiCiTest(): return (status, f'{ue_header}\n{msg}') - def Iperf(self, HTML, CONTAINERS, infra_file="ci_infra.yaml"): + def Iperf(self, ctx, HTML, infra_file="ci_infra.yaml"): logging.debug(f'Iperf: iperf_args "{self.iperf_args}" iperf_packetloss_threshold "{self.iperf_packetloss_threshold}" iperf_bitrate_threshold "{self.iperf_bitrate_threshold}" iperf_profile "{self.iperf_profile}" iperf_options "{self.iperf_options}"') if self.ue_ids == [] or self.svr_id == None: raise Exception("no module names in self.ue_ids or/and self.svr_id provided") - # create log directory on executor node - with cls_cmd.getConnection('localhost') as local: - ymlPath = CONTAINERS.yamlPath[0].split('/') - logPath = f'{os.getcwd()}/../cmake_targets/log/{ymlPath[-1]}' - local.run(f'mkdir -p {logPath}', silent=True) ues = [cls_module.Module_UE(ue_id, server_name, infra_file) for ue_id, server_name in zip(self.ue_ids, self.nodes)] cn = cls_corenetwork.CoreNetwork(self.svr_id, self.svr_node, filename=infra_file) with concurrent.futures.ThreadPoolExecutor(max_workers=64) as executor: - futures = [executor.submit(self.Iperf_Module, cn, ue, i, len(ues), logPath) for i, ue in enumerate(ues)] + futures = [executor.submit(self.Iperf_Module, ctx, cn, ue, i, len(ues)) for i, ue in enumerate(ues)] results = [f.result() for f in futures] # each result in results is a tuple, first member goes to successes, second to messages successes, messages = map(list, zip(*results)) @@ -525,7 +510,7 @@ class OaiCiTest(): HTML.CreateHtmlTestRowQueue(self.iperf_args, 'KO', messages) return success - def Iperf2_Unidir(self, HTML, CONTAINERS, infra_file="ci_infra.yaml"): + def Iperf2_Unidir(self, ctx, HTML, infra_file="ci_infra.yaml"): if self.ue_ids == [] or self.svr_id == None or len(self.ue_ids) != 1: raise Exception("no module names in self.ue_ids or/and self.svr_id provided, multi UE scenario not supported") ue = cls_module.Module_UE(self.ue_ids[0].strip(),self.nodes[0].strip(), infra_file) @@ -536,23 +521,17 @@ class OaiCiTest(): svrIP = cn.getIP() if not svrIP: return False - server_filename = f'iperf_server_{self.testCase_id}_{ue.getName()}.log' - ymlPath = CONTAINERS.yamlPath[0].split('/') - logPath = f'{os.getcwd()}/../cmake_targets/log/{ymlPath[-1]}' + server_filename = f'/tmp/iperf_server_{ue.getName()}.log' iperf_time = Iperf_ComputeTime(self.iperf_args) target_bitrate, iperf_opt = Iperf_ComputeModifiedBW(0, 1, self.iperf_profile, self.iperf_args) t = iperf_time*2.5 - with cls_cmd.getConnection('localhost') as local: - local.run(f'mkdir -p {logPath}') with cls_cmd.getConnection(ue.getHost()) as cmd_ue, cls_cmd.getConnection(cn.getHost()) as cmd_svr: - cmd_ue.run(f'rm /tmp/{server_filename}', reportNonZero=False) - cmd_ue.run(f'{ue.getCmdPrefix()} timeout -vk3 {t} iperf -B {ueIP} -s -u -i1 >> /tmp/{server_filename} &', timeout=t) + cmd_ue.run(f'rm {server_filename}', reportNonZero=False) + cmd_ue.run(f'{ue.getCmdPrefix()} timeout -vk3 {t} iperf -B {ueIP} -s -u -i1 >> {server_filename} &', timeout=t) cmd_svr.run(f'{cn.getCmdPrefix()} timeout -vk3 {t} iperf -c {ueIP} -B {svrIP} {iperf_opt} -i1 >> /dev/null', timeout=t) localPath = f'{os.getcwd()}' - # note: copy iperf2 log to the directory for log collection - cmd_ue.copyin(f'/tmp/{server_filename}', f'{logPath}/{server_filename}') - cmd_ue.run(f'rm /tmp/{server_filename}', reportNonZero=False) - success, msg = Iperf_analyzeV2UDP(f'{logPath}/{server_filename}', self.iperf_bitrate_threshold, self.iperf_packetloss_threshold, target_bitrate) + local = archiveArtifact(cmd_ue, ctx, server_filename) + success, msg = Iperf_analyzeV2UDP(local, self.iperf_bitrate_threshold, self.iperf_packetloss_threshold, target_bitrate) ue_header = f'UE {ue.getName()} ({ueIP})' logging.info(f'\u001B[1;37;45m iperf result for {ue_header}\u001B[0m') for l in msg.split('\n'): diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 509cd19109..7ec30aa477 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -255,7 +255,7 @@ def ExecuteActionWithParam(action, ctx): else: CiTestObj.nodes = [None] * len(CiTestObj.ue_ids) ping_rttavg_threshold = test.findtext('ping_rttavg_threshold') or '' - success = CiTestObj.Ping(HTML, CONTAINERS) + success = CiTestObj.Ping(ctx, HTML) elif action == 'Iperf' or action == 'Iperf2_Unidir': CiTestObj.iperf_args = test.findtext('iperf_args') @@ -286,9 +286,9 @@ def ExecuteActionWithParam(action, ctx): logging.error('test-case has wrong option ' + CiTestObj.iperf_options) CiTestObj.iperf_options = 'check' if action == 'Iperf': - success = CiTestObj.Iperf(HTML, CONTAINERS) + success = CiTestObj.Iperf(ctx, HTML) elif action == 'Iperf2_Unidir': - success = CiTestObj.Iperf2_Unidir(HTML, CONTAINERS) + success = CiTestObj.Iperf2_Unidir(ctx, HTML) elif action == 'IdleSleep': st = test.findtext('idle_sleep_time_in_sec') or "5" diff --git a/ci-scripts/tests/ping-iperf.py b/ci-scripts/tests/ping-iperf.py index 225fe4e868..9d50567a07 100644 --- a/ci-scripts/tests/ping-iperf.py +++ b/ci-scripts/tests/ping-iperf.py @@ -9,11 +9,13 @@ import os os.system(f'rm -rf cmake_targets') os.system(f'mkdir -p cmake_targets/log') import unittest +import tempfile sys.path.append('./') # to find OAI imports below import cls_oai_html +from cls_ci_helper import TestCaseCtx import cls_oaicitest -import cls_containerize +import cls_cmd class TestPingIperf(unittest.TestCase): def setUp(self): @@ -22,7 +24,10 @@ class TestPingIperf(unittest.TestCase): self.ci = cls_oaicitest.OaiCiTest() self.ci.ue_ids = ["test"] self.ci.nodes = ["localhost"] - self.cont = cls_containerize.Containerize() + self.ctx = TestCaseCtx.Default(tempfile.mkdtemp()) + def tearDown(self): + with cls_cmd.LocalCmd() as c: + c.run(f'rm -rf {self.ctx.logPath}') def test_ping(self): self.ci.ping_args = "-c3" @@ -30,7 +35,7 @@ class TestPingIperf(unittest.TestCase): self.ci.svr_id = "test" infra_file = "tests/config/infra_ping_iperf.yaml" # TODO Should need nothing but options and UE(s) to use - success = self.ci.Ping(self.html, self.cont, infra_file=infra_file) + success = self.ci.Ping(self.ctx, self.html, infra_file=infra_file) self.assertTrue(success) def test_iperf(self): @@ -45,7 +50,7 @@ class TestPingIperf(unittest.TestCase): self.ci.iperf_profile = "balanced" infra_file = "tests/config/infra_ping_iperf.yaml" # TODO Should need nothing but options and UE(s) to use - success = self.ci.Iperf(self.html, self.cont, infra_file=infra_file) + success = self.ci.Iperf(self.ctx, self.html, infra_file=infra_file) self.assertTrue(success) def test_iperf2_unidir(self): @@ -57,7 +62,7 @@ class TestPingIperf(unittest.TestCase): self.ci.iperf_profile = "balanced" infra_file = "tests/config/infra_ping_iperf.yaml" # TODO Should need nothing but options and UE(s) to use - success = self.ci.Iperf2_Unidir(self.html, self.cont, infra_file=infra_file) + success = self.ci.Iperf2_Unidir(self.ctx, self.html, infra_file=infra_file) self.assertTrue(success) if __name__ == '__main__':