X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=fhi_lib%2Ftest%2Fmaster.py;h=b5f0d550f2da5b38705d670121e617b6f564b967;hb=HEAD;hp=4ad8656be54c91b263233741e771372394f21d27;hpb=70d9d920dd4e575f085f1f1a9050fefd1c10e127;p=o-du%2Fphy.git diff --git a/fhi_lib/test/master.py b/fhi_lib/test/master.py index 4ad8656..b5f0d55 100755 --- a/fhi_lib/test/master.py +++ b/fhi_lib/test/master.py @@ -1,7 +1,7 @@ #!/usr/bin/python #****************************************************************************** # -# Copyright (c) 2019 Intel. +# Copyright (c) 2020 Intel. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -23,9 +23,11 @@ import logging import sys import argparse import re +import signal import subprocess import os import shutil +import copy from itertools import dropwhile from datetime import datetime from time import gmtime, strftime @@ -33,7 +35,7 @@ import json from threading import Timer import socket -timeout_sec = 60*3 #3 min max +timeout_sec = 60*5 #5 min max nLteNumRbsPerSymF1 = [ # 5MHz 10MHz 15MHz 20 MHz @@ -62,73 +64,263 @@ nRChBwOptions_keys_mu2and3 = ['50', '100', '200', '400'] nRChBwOptions_values_mu2and3 = [0,1,2,3] nRChBwOptions_mu2and3 = dict(zip(nRChBwOptions_keys_mu2and3, nRChBwOptions_values_mu2and3)) +vf_addr_o_xu=[] + # values for Jenkins server -eth_cp_dev = ["0000:19:02.1", "0000:19:0a.1"] -eth_up_dev = ["0000:19:02.0", "0000:19:0a.0"] +vf_addr_o_xu_jenkins = [ + #vf_addr_o_xu_a vf_addr_o_xu_b vf_addr_o_xu_c vf_addr_o_xu_d + ["0000:18:01.0,0000:18:01.1", "0000:18:09.0,0000:18:09.1", "0000:18:11.0,0000:18:11.1", "0000:18:19.0,0000:18:19.1" ], #O-DU + ["0000:af:01.0,0000:af:01.1", "0000:af:09.0,0000:af:09.1", "0000:af:11.0,0000:af:11.1", "0000:af:19.0,0000:af:19.1" ], #O-RU +] + +vf_addr_o_xu_sc12 = [ # 2x2x25G with loopback FVL0:port0 to FVL1:port 0 FVL0:port1 to FVL1:port 1 + #vf_addr_o_xu_a vf_addr_o_xu_b vf_addr_o_xu_c + ["0000:88:02.0,0000:88:0a.0", "0000:88:02.1,0000:88:0a.1", "0000:88:02.2,0000:88:0a.2", "0000:88:02.3,0000:88:0a.3" ], #O-DU + ["0000:86:02.0,0000:86:0a.0", "0000:86:02.1,0000:86:0a.1", "0000:86:02.2,0000:86:0a.2", "0000:86:02.3,0000:86:0a.3" ], #O-RU +] + +vf_addr_o_xu_sc12_cvl = [ + #vf_addr_o_xu_a vf_addr_o_xu_b vf_addr_o_xu_c + ["0000:af:01.0,0000:af:09.0", "0000:af:11.0,0000:af:19.0", "0000:1b:01.0,0000:1b:09.0", "0000:1b:11.0,0000:1b:19.0" ], #O-DU + ["0000:af:01.0,0000:af:09.0", "0000:af:11.0,0000:af:19.0", "0000:1a:01.0,0000:1a:09.0", "0000:1a:11.0,0000:1a:19.0" ], #O-RU +] + +vf_addr_o_xu_scs1_30 = [ + ["0000:65:01.0,0000:65:01.1,0000:65:01.2,0000:65:01.3", "0000:65:01.4,0000:65:01.5,0000:65:01.6,0000:65:01.7", "0000:65:02.0,0000:65:02.1,0000:65:02.2,0000:65:02.3", "0000:65:02.4,0000:65:02.5,0000:65:02.6,0000:65:02.7" ], #O-DU + ["0000:65:09.0,0000:65:09.1,0000:65:09.2,0000:65:09.3", "0000:65:09.4,0000:65:09.5,0000:65:09.6,0000:65:09.7", "0000:65:0a.0,0000:65:0a.1,0000:65:0a.2,0000:65:0a.3", "0000:65:0a.4,0000:65:0a.5,0000:65:0a.6,0000:65:0a.7" ], #O-RU +] + +vf_addr_o_xu_scs1_repo = [ + ["0000:18:01.0,0000:18:01.1,0000:18:01.2,0000:18:01.3", "0000:18:01.4,0000:18:01.5,0000:18:01.6,0000:18:01.7", "0000:18:02.0,0000:18:02.1,0000:18:02.2,0000:18:02.3", "0000:18:02.4,0000:18:02.5,0000:18:02.6,0000:18:02.7" ], #O-DU + ["0000:18:11.0,0000:18:11.1,0000:18:11.2,0000:18:11.3", "0000:18:11.4,0000:18:11.5,0000:18:11.6,0000:18:11.7", "0000:18:12.0,0000:18:12.1,0000:18:12.2,0000:18:12.3", "0000:18:12.4,0000:18:12.5,0000:18:12.6,0000:18:12.7" ], #O-RU +] + +vf_addr_o_xu_icelake_scs1_1 = [ + #vf_addr_o_xu_a vf_addr_o_xu_b vf_addr_o_xu_c vf_addr_o_xu_d + ["0000:51:01.0,0000:51:09.0", "0000:51:11.0,0000:51:19.0", "0000:18:01.0,0000:18:09.0", "0000:18:01.1,0000:18:09.1" ], #O-DU + ["0000:17:01.0,0000:17:09.0", "0000:17:11.0,0000:17:19.0", "0000:65:01.0,0000:65:09.0", "0000:65:01.1,0000:65:09.1" ], #O-RU +] + +vf_addr_o_xu_icx_npg_scs1_coyote4 = [ + #vf_addr_o_xu_a vf_addr_o_xu_b vf_addr_o_xu_c vf_addr_o_xu_d + ["0000:51:01.0,0000:51:09.0", "0000:51:11.0,0000:51:19.0", "0000:51:11.1,0000:51:19.1", "0000:51:01.1,0000:51:09.1" ], #O-DU + ["0000:17:01.0,0000:17:09.0", "0000:17:11.0,0000:17:19.0", "0000:17:11.1,0000:17:19.1", "0000:17:01.1,0000:17:09.1" ], #O-RU +] + +vf_addr_o_xu_scs1_35 = [ + ["0000:86:01.0,0000:86:01.1,0000:86:01.2,0000:86:01.3", "0000:86:01.4,0000:86:01.5,0000:86:01.6,0000:86:01.7", "0000:86:02.0,0000:86:02.1,0000:86:02.2,0000:86:02.3", "0000:86:02.4,0000:86:02.5,0000:86:02.6,0000:86:02.7" ], #O-DU + ["0000:86:11.0,0000:86:11.1,0000:86:11.2,0000:86:11.3", "0000:86:11.4,0000:86:11.5,0000:86:11.6,0000:86:11.7", "0000:86:12.0,0000:86:12.1,0000:86:12.2,0000:86:12.3", "0000:86:12.4,0000:86:12.5,0000:86:12.6,0000:86:12.7" ], #O-RU +] + +vf_addr_o_xu_csl_npg_scs1_33 = [ + #vf_addr_o_xu_a vf_addr_o_xu_b vf_addr_o_xu_c + ["0000:1a:01.0,0000:1a:01.1", "0000:1a:01.2,0000:1a:01.3", "0000:1a:01.4,0000:1a:01.5", "0000:1a:01.6,0000:1a:01.7" ], #O-DU + ["0000:1a:11.0,0000:1a:11.1", "0000:1a:11.2,0000:1a:11.3", "0000:1a:11.4,0000:1a:11.5", "0000:1a:11.6,0000:1a:11.7" ], #O-RU +] + +vf_addr_o_xu_skx_5gnr_sd6 = [ + #vf_addr_o_xu_a vf_addr_o_xu_b vf_addr_o_xu_c vf_addr_o_xu_d + ["0000:af:01.0,0000:af:09.0", "0000:af:11.0,0000:af:19.0", "0000:af:11.1,0000:af:19.1", "0000:af:01.1,0000:af:09.1"], #O-DU + ["0000:18:01.0,0000:18:09.0", "0000:18:11.0,0000:18:19.0", "0000:18:11.1,0000:18:19.1", "0000:18:01.1,0000:18:09.1"], #O-RU +] + # table of all test cases -# (ran, cat, mu, bw, test case) +# (ran, cat, mu, bw, test case, "test case description") #Cat A -NR_test_cases_A = [(0, 0, 0, 5, 0), - (0, 0, 0, 10, 0), - (0, 0, 0, 10, 12), - (0, 0, 0, 20, 0), - (0, 0, 0, 20, 12), - (0, 0, 1, 100, 0), - (0, 0, 3, 100, 0), +NR_test_cases_A = [(0, 0, 0, 5, 0, "NR_Sub6_Cat_A_5MHz_1_Cell_0"), + (0, 0, 0, 10, 12, "NR_Sub6_Cat_A_10MHz_12_Cell_12"), + (0, 0, 0, 20, 12, "NR_Sub6_Cat_A_20MHz_12_Cell_12"), + (0, 0, 0, 20, 20, "NR_Sub6_Cat_A_20MHz_1_Cell_owd_req_resp"), + (0, 0, 1, 100, 0, "NR_Sub6_Cat_A_100MHz_1_Cell_0"), + (0, 0, 3, 100, 7, "NR_mmWave_Cat_A_100MHz_1_Cell_0_sc"), +] + +NR_test_cases_A_ext = [(0, 0, 0, 5, 0, "NR_Sub6_Cat_A_5MHz_1_Cell_0"), + (0, 0, 0, 10, 0, "NR_Sub6_Cat_A_10MHz_1_Cell_0"), + (0, 0, 0, 10, 12, "NR_Sub6_Cat_A_10MHz_12_Cell_12"), + (0, 0, 0, 20, 0, "NR_Sub6_Cat_A_20MHz_1_Cell_0"), + (0, 0, 0, 20, 12, "NR_Sub6_Cat_A_20MHz_12_Cell_12"), + (0, 0, 0, 20, 20, "NR_Sub6_Cat_A_20MHz_1_Cell_owd_req_resp"), + (0, 0, 0, 20, 21, "NR_Sub6_Cat_A_20MHz_1_Cell_owd_rem_req"), + (0, 0, 0, 20, 22, "NR_Sub6_Cat_A_20MHz_1_Cell_owd_req_wfup"), + (0, 0, 0, 20, 23, "NR_Sub6_Cat_A_20MHz_1_Cell_owd_rem_req_wfup"), + (0, 0, 1, 100, 0, "NR_Sub6_Cat_A_100MHz_1_Cell_0"), + (0, 0, 3, 100, 0, "NR_mmWave_Cat_A_100MHz_1_Cell_0"), + (0, 0, 3, 100, 7, "NR_mmWave_Cat_A_100MHz_1_Cell_0_sc"), +] + +j_test_cases_A = [(0, 0, 1, 100, 204,"NR_Sub6_Cat_A_100MHz_4_O_RU_2Ant"), + (0, 0, 1, 100, 404,"NR_Sub6_Cat_A_100MHz_4_O_RU_4Ant") +] + +j_test_cases_A_ext = [(0, 0, 1, 100, 201,"NR_Sub6_Cat_A_100MHz_1_O_RU_2Ant"), + (0, 0, 1, 100, 202,"NR_Sub6_Cat_A_100MHz_2_O_RU_2Ant"), + (0, 0, 1, 100, 203,"NR_Sub6_Cat_A_100MHz_3_O_RU_2Ant"), + (0, 0, 1, 100, 204,"NR_Sub6_Cat_A_100MHz_4_O_RU_2Ant"), + (0, 0, 1, 100, 401,"NR_Sub6_Cat_A_100MHz_1_O_RU_4Ant"), + (0, 0, 1, 100, 402,"NR_Sub6_Cat_A_100MHz_2_O_RU_4Ant"), + (0, 0, 1, 100, 403,"NR_Sub6_Cat_A_100MHz_3_O_RU_4Ant"), + (0, 0, 1, 100, 404,"NR_Sub6_Cat_A_100MHz_4_O_RU_4Ant") +] + + +LTE_test_cases_A = [(1, 0, 0, 5, 0, "LTE_Cat_A_5Hz_1_Cell_0"), + (1, 0, 0, 10, 0, "LTE_Cat_A_10Hz_1_Cell_0"), + (1, 0, 0, 20, 0, "LTE_Cat_A_20Hz_1_Cell_0"), ] -LTE_test_cases_A = [(1, 0, 0, 5, 0), - (1, 0, 0, 10, 0), - (1, 0, 0, 20, 0), +DSS_test_cases_A = [(2, 0, 0, 20, 10, "DSS_Cat_A_20MHz_FDD_1_Cell"), + (2, 0, 0, 20, 11, "DSS_Cat_A_20MHz_TDD_1_Cell"), + (2, 0, 0, 20, 60, "DSS_Cat_A_20MHz_FDD_6_Cell"), + (2, 0, 0, 20, 61, "DSS_Cat_A_20MHz_TDD_6_Cell"), + (2, 0, 0, 10, 10, "DSS_Cat_A_10MHz_FDD_1_Cell"), + (2, 0, 0, 10, 11, "DSS_Cat_A_10MHz_TDD_1_Cell"), + (2, 0, 0, 10, 60, "DSS_Cat_A_10MHz_FDD_6_Cell"), + (2, 0, 0, 10, 61, "DSS_Cat_A_10MHz_TDD_6_Cell"), + (2, 0, 0, 5, 10, "DSS_Cat_A_5MHz_FDD_1_Cell"), + (2, 0, 0, 5, 11, "DSS_Cat_A_5MHz_TDD_1_Cell"), + (2, 0, 0, 5, 60, "DSS_Cat_A_5MHz_FDD_6_Cell"), + (2, 0, 0, 5, 61, "DSS_Cat_A_5MHz_TDD_6_Cell"), ] #Cat B -NR_test_cases_B = [(0, 1, 1, 100, 0), - (0, 1, 1, 100, 2), - (0, 1, 1, 100, 1), - (0, 1, 1, 100, 101), - (0, 1, 1, 100, 102), - (0, 1, 1, 100, 103), - (0, 1, 1, 100, 104), - (0, 1, 1, 100, 105), - #(0, 1, 1, 100, 106), 25G not enough - (0, 1, 1, 100, 107), - (0, 1, 1, 100, 108), - #(0, 1, 1, 100, 109), 25G not enough - (0, 1, 1, 100, 201), - #(0, 1, 1, 100, 202), 25G not enough - #(0, 1, 1, 100, 203), - (0, 1, 1, 100, 204), - (0, 1, 1, 100, 205), - (0, 1, 1, 100, 206), - (0, 1, 1, 100, 211), - #(0, 1, 1, 100, 212), 25G not enough - (0, 1, 1, 100, 213), - (0, 1, 1, 100, 214), - (0, 1, 1, 100, 215), - (0, 1, 1, 100, 216) -] - -LTE_test_cases_B = [(1, 1, 0, 5, 0), - (1, 1, 0, 10, 0), - (1, 1, 0, 20, 0), +NR_test_cases_B = [(0, 1, 1, 100, 0, "NR_Sub6_Cat_B_100MHz_1_Cell_0"), + (0, 1, 1, 100, 216, "NR_Sub6_Cat_B_100MHz_1_Cell_216"), +] + +NR_test_cases_B_ext = [(0, 1, 1, 100, 0, "NR_Sub6_Cat_B_100MHz_1_Cell_0"), + (0, 1, 1, 100, 1, "NR_Sub6_Cat_B_100MHz_1_Cell_1"), + (0, 1, 1, 100, 2, "NR_Sub6_Cat_B_100MHz_1_Cell_1_ext1"), + (0, 1, 1, 100, 101, "NR_Sub6_Cat_B_100MHz_1_Cell_101"), + (0, 1, 1, 100, 102, "NR_Sub6_Cat_B_100MHz_1_Cell_102"), + (0, 1, 1, 100, 103, "NR_Sub6_Cat_B_100MHz_1_Cell_103"), + (0, 1, 1, 100, 104, "NR_Sub6_Cat_B_100MHz_1_Cell_104"), + (0, 1, 1, 100, 105, "NR_Sub6_Cat_B_100MHz_1_Cell_105"), + (0, 1, 1, 100, 106, "NR_Sub6_Cat_B_100MHz_1_Cell_106"), + (0, 1, 1, 100, 107, "NR_Sub6_Cat_B_100MHz_1_Cell_107"), + (0, 1, 1, 100, 108, "NR_Sub6_Cat_B_100MHz_1_Cell_108"), + (0, 1, 1, 100, 109, "NR_Sub6_Cat_B_100MHz_1_Cell_109"), + (0, 1, 1, 100, 201, "NR_Sub6_Cat_B_100MHz_1_Cell_201"), + (0, 1, 1, 100, 202, "NR_Sub6_Cat_B_100MHz_1_Cell_202"), + (0, 1, 1, 100, 203, "NR_Sub6_Cat_B_100MHz_1_Cell_203"), + (0, 1, 1, 100, 204, "NR_Sub6_Cat_B_100MHz_1_Cell_204"), + (0, 1, 1, 100, 205, "NR_Sub6_Cat_B_100MHz_1_Cell_205"), + (0, 1, 1, 100, 206, "NR_Sub6_Cat_B_100MHz_1_Cell_206"), + (0, 1, 1, 100, 211, "NR_Sub6_Cat_B_100MHz_1_Cell_211"), + (0, 1, 1, 100, 212, "NR_Sub6_Cat_B_100MHz_1_Cell_212"), + (0, 1, 1, 100, 213, "NR_Sub6_Cat_B_100MHz_1_Cell_213"), + (0, 1, 1, 100, 214, "NR_Sub6_Cat_B_100MHz_1_Cell_214"), + (0, 1, 1, 100, 215, "NR_Sub6_Cat_B_100MHz_1_Cell_215"), + (0, 1, 1, 100, 216, "NR_Sub6_Cat_B_100MHz_1_Cell_216"), +] + +LTE_test_cases_B = [(1, 1, 0, 20, 0, "LTE_Cat_B_20MHz_1_Cell_0"), +] + +LTE_test_cases_B_ext = [(1, 1, 0, 5, 0, "LTE_Cat_B_5MHz_1_Cell_0"), + (1, 1, 0, 10, 0, "LTE_Cat_B_10MHz_1_Cell_0"), + (1, 1, 0, 20, 0, "LTE_Cat_B_20MHz_1_Cell_0"), + (1, 1, 0, 5, 1, "LTE_Cat_B_5Hz_1_Cell_0_sc"), + (1, 1, 0, 10, 1, "LTE_Cat_B_10Hz_1_Cell_0_sc"), + (1, 1, 0, 20, 1, "LTE_Cat_B_20Hz_1_Cell_0_sc"), + ] + V_test_cases_B = [ - # (0, 1, 1, 100, 301), 25G not enough - (0, 1, 1, 100, 302), - (0, 1, 1, 100, 303), - (0, 1, 1, 100, 304), - (0, 1, 1, 100, 305), - (0, 1, 1, 100, 306) + # (0, 1, 1, 100, 301, "NR_Sub6_Cat_B_100MHz_1_Cell_301"), + (0, 1, 1, 100, 602, "NR_Sub6_Cat_B_100MHz_1_Cell_602_sc"), +] + +V_test_cases_B_ext = [ + (0, 1, 1, 100, 301, "NR_Sub6_Cat_B_100MHz_1_Cell_301"), + (0, 1, 1, 100, 302, "NR_Sub6_Cat_B_100MHz_1_Cell_302"), + (0, 1, 1, 100, 303, "NR_Sub6_Cat_B_100MHz_1_Cell_303"), + (0, 1, 1, 100, 304, "NR_Sub6_Cat_B_100MHz_1_Cell_304"), + (0, 1, 1, 100, 305, "NR_Sub6_Cat_B_100MHz_1_Cell_305"), + (0, 1, 1, 100, 306, "NR_Sub6_Cat_B_100MHz_1_Cell_306"), + (0, 1, 1, 100, 602, "NR_Sub6_Cat_B_100MHz_1_Cell_602_sc"), +] + + +V_test_cases_B_2xUL = [ + # (0, 1, 1, 100, 311, "NR_Sub6_Cat_B_100MHz_1_Cell_311"), + (0, 1, 1, 100, 612, "NR_Sub6_Cat_B_100MHz_1_Cell_612_sc"), + +] + +V_test_cases_B_2xUL_ext = [ + (0, 1, 1, 100, 311, "NR_Sub6_Cat_B_100MHz_1_Cell_311"), + (0, 1, 1, 100, 312, "NR_Sub6_Cat_B_100MHz_1_Cell_312"), + (0, 1, 1, 100, 313, "NR_Sub6_Cat_B_100MHz_1_Cell_313"), + (0, 1, 1, 100, 314, "NR_Sub6_Cat_B_100MHz_1_Cell_314"), + (0, 1, 1, 100, 315, "NR_Sub6_Cat_B_100MHz_1_Cell_315"), + (0, 1, 1, 100, 316, "NR_Sub6_Cat_B_100MHz_1_Cell_316"), + (0, 1, 1, 100, 612, "NR_Sub6_Cat_B_100MHz_1_Cell_612_sc"), + +] + +V_test_cases_B_mtu_1500 = [ + (0, 1, 1, 100, 501, "NR_Sub6_Cat_B_100MHz_1_Cell_501"), + (0, 1, 1, 100, 502, "NR_Sub6_Cat_B_100MHz_1_Cell_502"), + (0, 1, 1, 100, 503, "NR_Sub6_Cat_B_100MHz_1_Cell_503"), + (0, 1, 1, 100, 504, "NR_Sub6_Cat_B_100MHz_1_Cell_504"), + (0, 1, 1, 100, 505, "NR_Sub6_Cat_B_100MHz_1_Cell_505"), + (0, 1, 1, 100, 506, "NR_Sub6_Cat_B_100MHz_1_Cell_506"), + (0, 1, 1, 100, 802, "NR_Sub6_Cat_B_100MHz_1_Cell_802_sc"), +] + +V_test_cases_B_mtu_1500_2xUL = [ + (0, 1, 1, 100, 511, "NR_Sub6_Cat_B_100MHz_1_Cell_511"), + (0, 1, 1, 100, 512, "NR_Sub6_Cat_B_100MHz_1_Cell_512"), + (0, 1, 1, 100, 513, "NR_Sub6_Cat_B_100MHz_1_Cell_513"), + (0, 1, 1, 100, 514, "NR_Sub6_Cat_B_100MHz_1_Cell_514"), + (0, 1, 1, 100, 515, "NR_Sub6_Cat_B_100MHz_1_Cell_515"), + (0, 1, 1, 100, 516, "NR_Sub6_Cat_B_100MHz_1_Cell_516"), + (0, 1, 1, 100, 812, "NR_Sub6_Cat_B_100MHz_1_Cell_812_sc"), +] + +V_test_cases_B_3Cells = [ + (0, 1, 1, 100, 3301, "NR_Sub6_Cat_B_100MHz_1_Cell_3301"), + (0, 1, 1, 100, 3311, "NR_Sub6_Cat_B_100MHz_1_Cell_3311") +] + +V_test_cases_B_3Cells_mtu_1500 = [ + (0, 1, 1, 100, 3501, "NR_Sub6_Cat_B_100MHz_1_Cell_3501"), + (0, 1, 1, 100, 3511, "NR_Sub6_Cat_B_100MHz_1_Cell_3511") ] -all_test_cases = NR_test_cases_A + LTE_test_cases_A + LTE_test_cases_B + NR_test_cases_B + V_test_cases_B + +J_test_cases_B_4Cells = [ + (0, 1, 1, 100, 1421, "NR_Sub6_Cat_B_100MHz_1_Cell_DL4UL2"), + (0, 1, 1, 100, 4424, "NR_Sub6_Cat_B_100MHz_4_Cell_DL4UL2") +] + +J_test_cases_B_4Cells_ext = [ + (0, 1, 1, 100, 1421, "NR_Sub6_Cat_B_100MHz_1_Cell_DL4UL2"), + (0, 1, 1, 100, 2422, "NR_Sub6_Cat_B_100MHz_2_Cell_DL4UL2"), + (0, 1, 1, 100, 3423, "NR_Sub6_Cat_B_100MHz_3_Cell_DL4UL2"), + (0, 1, 1, 100, 4424, "NR_Sub6_Cat_B_100MHz_4_Cell_DL4UL2") +] + +Ext1_test_cases_B_4Cells = [ + (0, 1, 1, 100, 142, "NR_Sub6_Cat_B_100MHz_ext1_1_Cell_DL4UL2"), + (0, 1, 1, 100, 242, "NR_Sub6_Cat_B_100MHz_ext1_2_Cell_DL4UL2"), + (0, 1, 1, 100, 342, "NR_Sub6_Cat_B_100MHz_ext1_3_Cell_DL4UL2"), + (0, 1, 1, 100, 442, "NR_Sub6_Cat_B_100MHz_ext1_4_Cell_DL4UL2") +] + +all_test_cases = [] + +#reduced duration test cycle +all_test_cases_short = NR_test_cases_A + LTE_test_cases_A + j_test_cases_A + LTE_test_cases_B + NR_test_cases_B + V_test_cases_B + V_test_cases_B_2xUL + J_test_cases_B_4Cells + +all_test_cases_long = NR_test_cases_A_ext + LTE_test_cases_A + j_test_cases_A_ext + DSS_test_cases_A + LTE_test_cases_B_ext + NR_test_cases_B_ext + V_test_cases_B_ext + V_test_cases_B_2xUL_ext + J_test_cases_B_4Cells_ext + Ext1_test_cases_B_4Cells dic_dir = dict({0:'DL', 1:'UL'}) dic_xu = dict({0:'o-du', 1:'o-ru'}) -dic_ran_tech = dict({0:'5g_nr', 1:'lte'}) +dic_ran_tech = dict({0:'5g_nr', 1:'lte', 2:'dss'}) def init_logger(console_level, logfile_level): """Initializes console and logfile logger with given logging levels""" @@ -150,18 +342,20 @@ def parse_args(args): # Parser configuration parser = argparse.ArgumentParser(description="Run test cases: category numerology bandwidth test_num") - parser.add_argument("--ran", type=int, default=0, help="Radio Access Tehcnology 0 (5G NR) or 1 (LTE)", metavar="ran", dest="rantech") + parser.add_argument("--rem_o_ru_host", type=str, default="", help="remote host to run O-RU", metavar="root@10.10.10.1", dest="rem_o_ru_host") + parser.add_argument("--ran", type=int, default=0, help="Radio Access Technology 0 (5G NR) , 1 (LTE) or 2 DSS (5G NR and LTE)", metavar="ran", dest="rantech") parser.add_argument("--cat", type=int, default=0, help="Category: 0 (A) or 1 (B)", metavar="cat", dest="category") parser.add_argument("--mu", type=int, default=0, help="numerology [0,1,3]", metavar="num", dest="numerology") parser.add_argument("--bw", type=int, default=20, help="bandwidth [5,10,20,100]", metavar="bw", dest="bandwidth") parser.add_argument("--testcase", type=int, default=0, help="test case number", metavar="testcase", dest="testcase") parser.add_argument("--verbose", type=int, default=0, help="enable verbose output", metavar="verbose", dest="verbose") + # Parse arguments options = parser.parse_args(args) #parser.print_help() - logging.debug("Options: ran=%d category=%d num=%d bw=%d testcase=%d", - options.rantech, options.category, options.numerology, options.bandwidth, options.testcase) + logging.info("Options: rem_o_ru_host=%s ran=%d category=%d num=%d bw=%d testcase=%d", + options.rem_o_ru_host, options.rantech, options.category, options.numerology, options.bandwidth, options.testcase) return options def is_comment(s): @@ -192,7 +386,7 @@ def get_re_map(nRB, direction): #print(PrbElemContent,"RBStart: ", xRBStart, "RBSize: ",xRBSize, list(range(xRBStart, xRBStart + xRBSize))) prb_map = prb_map + list(range(xRBStart*12, xRBStart*12 + xRBSize*12)) else: - nPrbElm = 0; + nPrbElm = 0 elif direction == 1: #UL @@ -208,17 +402,87 @@ def get_re_map(nRB, direction): #print(PrbElemContent,"RBStart: ", xRBStart, "RBSize: ",xRBSize, list(range(xRBStart, xRBStart + xRBSize))) prb_map = prb_map + list(range(xRBStart*12, xRBStart*12 + xRBSize*12)) else: - nPrbElm = 0; + nPrbElm = 0 + + elif direction == 2: + #UL + if 'nPrbElemSrs' in globals(): + nPrbElm = nPrbElemSrs + for i in range(0, nPrbElm): + elm = str('PrbElemSrs'+str(i)) + #print(elm) + if (elm in globals()): + PrbElemContent.insert(i,list(globals()[elm])) + xRBStart = PrbElemContent[i][0] + xRBSize = PrbElemContent[i][1] + #print(PrbElemContent,"RBStart: ", xRBStart, "RBSize: ",xRBSize, list(range(xRBStart, xRBStart + xRBSize))) + prb_map = prb_map + list(range(xRBStart*12, xRBStart*12 + xRBSize*12)) + else: + nPrbElm = 0 if nPrbElm == 0 : prb_map = list(range(0, nRB*12)) return prb_map -def compare_resuts(rantech, cat, mu, bw, tcase, xran_path, test_cfg, direction): +def get_bfw_map(direction): + bfw_map = [] + bfwElemContent = [] + if direction == 0: + #DL + if 'nPrbElemDl' in globals(): + nPrbElm = nPrbElemDl + numsetBFW_total = 0 + for i in range(0, nPrbElm): + elm = str('ExtBfwDl'+str(i)) + #print(elm) + if elm in globals(): + bfwElemContent.insert(i,list(globals()[elm])) + numBundPrb = bfwElemContent[i][0] + numsetBFW = bfwElemContent[i][1] + bfw_map = bfw_map + list(range(antElmTRx*numsetBFW_total, antElmTRx*numsetBFW_total + numsetBFW*antElmTRx)) + numsetBFW_total += numsetBFW + else: + nPrbElm = 0 + if nPrbElm == 0 : + bfw_map = list(range(0, (nPrbElm-1)*numsetBFW*antElmTRx)) + + return bfw_map, numsetBFW_total + +def check_for_string_present_in_file(file_name, search_string): + res = 1 + with open(file_name, 'r') as read_obj: + for line in read_obj: + if search_string in line: + read_obj.close() + res = 0 + return res + read_obj.close() + return res + +def check_owdm_test_results(xran_path, o_xu_id): + res = 0 + file_owd_oru = xran_path+"/app/logs/"+"o-ru"+str(o_xu_id)+"-owd_results.txt" + file_owd_odu = xran_path+"/app/logs/"+"o-du"+str(o_xu_id)+"-owd_results.txt" + print("file_owd_oru :", file_owd_oru) + print("file_owd_odu :", file_owd_odu) + res = check_for_string_present_in_file(file_owd_oru, 'passed') + res = res or check_for_string_present_in_file(file_owd_odu, 'passed') + + return res + +def compare_results(o_xu_id, rantech, cat, mu, bw, tcase, xran_path, test_cfg, direction): res = 0 re_map = [] - if rantech==1: + if rantech==2: + if mu == 0: + nDlRB = nLteNumRbsPerSymF1[mu][nRChBwOptions.get(str(nDLBandwidth))] + nUlRB = nLteNumRbsPerSymF1[mu][nRChBwOptions.get(str(nULBandwidth))] + else: + print("Incorrect arguments\n") + res = -1 + return res + elif rantech==1: if mu == 0: nDlRB = nLteNumRbsPerSymF1[mu][nRChBwOptions.get(str(nDLBandwidth))] nUlRB = nLteNumRbsPerSymF1[mu][nRChBwOptions.get(str(nULBandwidth))] @@ -244,15 +508,25 @@ def compare_resuts(rantech, cat, mu, bw, tcase, xran_path, test_cfg, direction): else: comp = 0 - if 'srsEanble' in globals(): - srs_enb = srsEanble + if 'srsEnable' in globals(): + srs_enb = srsEnable else: srs_enb = 0 - print("compare results: {} [compression {}]\n".format(dic_dir.get(direction), comp)) + if 'rachEnable' in globals(): + rach = rachEnable + else: + rach = 0 + + if 'extType' in globals(): + ext_type = extType + else: + ext_type = 0 + + print("O-RU {} compare results: {} [compression {}]\n".format(o_xu_id, dic_dir.get(direction), comp)) #if cat == 1: - # print("WARNING: Skip checking IQs and BF Weights for CAT B for now\n"); + # print("WARNING: Skip checking IQs and BF Weights for CAT B for now\n") # return res #get slot config @@ -282,6 +556,7 @@ def compare_resuts(rantech, cat, mu, bw, tcase, xran_path, test_cfg, direction): else : raise Exception('i should not exceed nTddPeriod %d. The value of i was: {}'.format(nTddPeriod, i)) #print(SlotConfig, type(sSlotConfig0)) + try: if (direction == 1) & (cat == 1): #UL @@ -303,13 +578,13 @@ def compare_resuts(rantech, cat, mu, bw, tcase, xran_path, test_cfg, direction): if direction == 0: # DL nRB = nDlRB - file_tst = xran_path+"/app/logs/"+"o-ru-rx_log_ant"+str(i)+".txt" - file_ref = xran_path+"/app/logs/"+"o-du-play_ant"+str(i)+".txt" + file_tst = xran_path+"/app/logs/"+"o-ru"+str(o_xu_id)+"-rx_log_ant"+str(i)+".txt" + file_ref = xran_path+"/app/logs/"+"o-du"+str(o_xu_id)+"-play_ant"+str(i)+".txt" elif direction == 1: # UL nRB = nUlRB - file_tst = xran_path+"/app/logs/"+"o-du-rx_log_ant"+str(i)+".txt" - file_ref = xran_path+"/app/logs/"+"o-ru-play_ant"+str(i)+".txt" + file_tst = xran_path+"/app/logs/"+"o-du"+str(o_xu_id)+"-rx_log_ant"+str(i)+".txt" + file_ref = xran_path+"/app/logs/"+"o-ru"+str(o_xu_id)+"-play_ant"+str(i)+".txt" else: raise Exception('Direction is not supported %d'.format(direction)) @@ -342,12 +617,13 @@ def compare_resuts(rantech, cat, mu, bw, tcase, xran_path, test_cfg, direction): print(len(tst)) print(len(ref)) - file_tst.close(); - file_ref.close(); + file_tst.close() + file_ref.close() print(numSlots) - for slot_idx in range(0, numSlots): + #skip last slot for UL as we stop on PPS boundary (OTA) and all symbols might not be received by O-DU + for slot_idx in range(0, numSlots - (1*direction)): for sym_idx in range(0, 14): if nFrameDuplexType==1: #skip sym if TDD @@ -400,14 +676,366 @@ def compare_resuts(rantech, cat, mu, bw, tcase, xran_path, test_cfg, direction): except GetOutOfLoops: return res - #if (direction == 0) | (cat == 0) | (srs_enb == 0): #DL or Cat A + if (direction == 1) & (rach == 1) & 0: #UL + print("O-RU {} compare results: {} [compression {}]\n".format(o_xu_id, 'PRACH', comp)) + + #rach + try: + if mu == 3: #FR2 + re_map = range(0, 144) + nRB = 12 + elif nFrameDuplexType==0: #FR1 FDD + if prachConfigIndex < 87: + re_map = range(0, 840) + nRB = 70 + else: + re_map = range(0, 144) + nRB = 12 + else: #FR1 TDD + if prachConfigIndex < 67: + re_map = range(0, 144) + nRB = 12 + else: + re_map = range(0, 840) + nRB = 70 + if cat == 1: + flowId = ccNum*antNumUL + else: + flowId = ccNum*antNum + + for i in range(0, flowId): + #read ref and test files + tst = [] + ref = [] + + file_tst = xran_path+"/app/logs/"+"o-du"+str(o_xu_id)+"-prach_log_ant"+str(i)+".txt" + file_ref = xran_path+"/app/logs/"+"o-ru"+str(o_xu_id)+"-play_prach_ant"+str(i)+".txt" + print("test result :", file_tst) + print("test reference:", file_ref) + if os.path.exists(file_tst): + try: + file_tst = open(file_tst, 'r') + except OSError: + print ("Could not open/read file:", file_tst) + sys.exit() + else: + print(file_tst, "doesn't exist") + res = -1 + return res + if os.path.exists(file_ref): + try: + file_ref = open(file_ref, 'r') + except OSError: + print ("Could not open/read file:", file_ref) + sys.exit() + else: + print(file_tst, "doesn't exist") + res = -1 + return res + + tst = file_tst.readlines() + ref = file_ref.readlines() + + print(len(tst)) + print(len(ref)) + + file_tst.close() + file_ref.close() + + print(numSlots) + + #skip last slot for UL as we stop on PPS boundary (OTA) and all symbols might not be received by O-DU + for slot_idx in range(0, numSlots - (1*direction)): + for sym_idx in range(0, 14): + if nFrameDuplexType==1: + #skip sym if TDD + if direction == 0: + #DL + sym_dir = SlotConfig[slot_idx%nTddPeriod][sym_idx] + if(sym_dir != 0): + continue + elif direction == 1: + #UL + sym_dir = SlotConfig[slot_idx%nTddPeriod][sym_idx] + if(sym_dir != 1): + continue + + #print("Check:","[",i,"]", slot_idx, sym_idx) + for line_idx in re_map: + offset = (slot_idx*nRB*12*14) + sym_idx*nRB*12 + line_idx + try: + line_tst = tst[offset].rstrip() + except IndexError: + res = -1 + print("FAIL:","IndexError on tst: ant:[",i,"]:",offset, slot_idx, sym_idx, line_idx, len(tst)) + raise GetOutOfLoops + try: + line_ref = ref[offset].rstrip() + except IndexError: + res = -1 + print("FAIL:","IndexError on ref: ant:[",i,"]:",offset, slot_idx, sym_idx, line_idx, len(ref)) + raise GetOutOfLoops + + if comp == 1: + # discard LSB bits as BFP compression is not "bit exact" + tst_i_value = int(line_tst.split(" ")[0]) & 0xFF80 + tst_q_value = int(line_tst.split(" ")[1]) & 0xFF80 + ref_i_value = int(line_ref.split(" ")[0]) & 0xFF80 + ref_q_value = int(line_ref.split(" ")[1]) & 0xFF80 + + #print("check:","ant:[",i,"]:",offset, slot_idx, sym_idx, line_idx,":","tst: ", tst_i_value, " ", tst_q_value, " " , "ref: ", ref_i_value, " ", ref_q_value, " ") + if (tst_i_value != ref_i_value) or (tst_q_value != ref_q_value) : + print("FAIL:","ant:[",i,"]:",offset, slot_idx, sym_idx, line_idx,":","tst: ", tst_i_value, " ", tst_q_value, " " , "ref: ", ref_i_value, " ", ref_q_value, " ") + res = -1 + raise GetOutOfLoops + else: + #if line_idx == 0: + #print("Check:", offset,"[",i,"]", slot_idx, sym_idx,":",line_tst, line_ref) + if line_ref != line_tst: + print("FAIL:","ant:[",i,"]:",offset, slot_idx, sym_idx, line_idx,":","tst:", line_tst, "ref:", line_ref) + res = -1 + raise GetOutOfLoops + except GetOutOfLoops: + return res + + if ((cat == 1) and (direction == 0) and (ext_type == 1)): #Cat B, DL and Extension type = 1 + try: + if (direction == 0) & (cat == 1): #DL + flowId = ccNum*antNum + if direction == 0: + bfw_map, numsetBFW_total = get_bfw_map(direction) + else: + raise Exception('Direction is not supported %d'.format(direction)) + + for i in range(0, flowId): + #read ref and test files + tst = [] + ref = [] + if direction == 0: + # DL + file_tst = xran_path+"/app/logs/"+"o-ru"+str(o_xu_id)+"-dl_bfw_log_ue"+str(i)+".txt" + file_ref = xran_path+"/app/logs/"+"o-du"+str(o_xu_id)+"-dl_bfw_ue"+str(i)+".txt" + else: + raise Exception('Direction is not supported %d'.format(direction)) + + print("test result :", file_tst) + print("test reference:", file_ref) + if os.path.exists(file_tst): + try: + file_tst = open(file_tst, 'r') + except OSError: + print ("Could not open/read file:", file_tst) + sys.exit() + else: + print(file_tst, "doesn't exist") + res = -1 + return res + if os.path.exists(file_ref): + try: + file_ref = open(file_ref, 'r') + except OSError: + print ("Could not open/read file:", file_ref) + sys.exit() + else: + print(file_tst, "doesn't exist") + res = -1 + return res + + tst = file_tst.readlines() + ref = file_ref.readlines() + + print(len(tst)) + print(len(ref)) + + file_tst.close() + file_ref.close() + + print(numSlots) + + for slot_idx in range(0, numSlots): + skip_tti = 1 + if nFrameDuplexType==1: + #skip tti if UL slot + if direction == 0: + #DL + for sym_idx in range(0,14): + sym_dir = SlotConfig[slot_idx%nTddPeriod][sym_idx] + if(sym_dir == 0): + skip_tti = 0 + break + if(skip_tti == 1): + continue + for line_idx in bfw_map: + offset = slot_idx * (nDlRB*antElmTRx) #(slot_idx*numsetBFW_total*antElmTRx) + line_idx + try: + line_tst = tst[offset].rstrip() + except IndexError: + res = -1 + print("FAIL:","IndexError on tst: ant:[",i,"]:",offset, slot_idx, line_idx, len(tst)) + raise GetOutOfLoops + try: + line_ref = ref[offset].rstrip() + except IndexError: + res = -1 + print("FAIL:","IndexError on ref: ant:[",i,"]:",offset, slot_idx, line_idx, len(ref)) + raise GetOutOfLoops + + if comp == 1: + # discard LSB bits as BFP compression is not "bit exact" + tst_i_value = int(line_tst.split(" ")[0]) & 0xFF80 + tst_q_value = int(line_tst.split(" ")[1]) & 0xFF80 + ref_i_value = int(line_ref.split(" ")[0]) & 0xFF80 + ref_q_value = int(line_ref.split(" ")[1]) & 0xFF80 + + tst_i_act = int(line_tst.split(" ")[0]) + tst_q_act = int(line_tst.split(" ")[1]) + ref_i_act = int(line_ref.split(" ")[0]) + ref_q_act = int(line_ref.split(" ")[1]) + + #print("check:","ant:[",i,"]:",offset, slot_idx, sym_idx, line_idx,":","tst: ", tst_i_value, " ", tst_q_value, " " , "ref: ", ref_i_value, " ", ref_q_value, " ") + if (tst_i_value != ref_i_value) or (tst_q_value != ref_q_value) : + print("868 Actual:","bfw:[",i,"]:",offset, slot_idx, line_idx,":","tst: ", tst_i_act, " ", tst_q_act, " " , "ref: ", ref_i_act, " ", ref_q_act, " ") + print("FAIL:","bfw:[",i,"]:",offset, slot_idx, line_idx,":","tst: ", tst_i_value, " ", tst_q_value, " " , "ref: ", ref_i_value, " ", ref_q_value, " ") + res = -1 + raise GetOutOfLoops + else: + #if line_idx == 0: + #print("Check:", offset,"[",i,"]", slot_idx, sym_idx,":",line_tst, line_ref) + if line_ref != line_tst: + print("876 Actual:","bfw:[",i,"]:",offset, slot_idx, line_idx,":","tst: ", tst_i_act, " ", tst_q_act, " " , "ref: ", ref_i_act, " ", ref_q_act, " ") + print("FAIL:","bfw:[",i,"]:",offset, slot_idx, line_idx,":","tst:", line_tst, "ref:", line_ref) + res = -1 + raise GetOutOfLoops + except GetOutOfLoops: + res = 0 # Not treating it as a test case fail criteria for now + # return res + + try: + if (direction == 0) & (cat == 1): #DL + flowId = ccNum*antNumUL + if direction == 0: + bfw_map, numsetBFW_total = get_bfw_map(direction) + else: + raise Exception('Direction is not supported %d'.format(direction)) + + for i in range(0, flowId): + #read ref and test files + tst = [] + ref = [] + if direction == 0: + # DL + file_tst = xran_path+"/app/logs/"+"o-ru"+str(o_xu_id)+"-ul_bfw_log_ue"+str(i)+".txt" + file_ref = xran_path+"/app/logs/"+"o-du"+str(o_xu_id)+"-ul_bfw_ue"+str(i)+".txt" + else: + raise Exception('Direction is not supported %d'.format(direction)) + + print("test result :", file_tst) + print("test reference:", file_ref) + if os.path.exists(file_tst): + try: + file_tst = open(file_tst, 'r') + except OSError: + print ("Could not open/read file:", file_tst) + sys.exit() + else: + print(file_tst, "doesn't exist") + res = -1 + return res + if os.path.exists(file_ref): + try: + file_ref = open(file_ref, 'r') + except OSError: + print ("Could not open/read file:", file_ref) + sys.exit() + else: + print(file_tst, "doesn't exist") + res = -1 + return res + + tst = file_tst.readlines() + ref = file_ref.readlines() + + print(len(tst)) + print(len(ref)) + + file_tst.close() + file_ref.close() + + print(numSlots) + + for slot_idx in range(0, numSlots): + skip_tti = 1 + if nFrameDuplexType==1: + #skip tti if UL slot + if direction == 0: + #DL + for sym_idx in range(0,14): + sym_dir = SlotConfig[slot_idx%nTddPeriod][sym_idx] + if(sym_dir == 1): + skip_tti = 0 + break + if(skip_tti == 1): + continue + for line_idx in bfw_map: + offset = slot_idx * (nUlRB*antElmTRx) #(slot_idx*numsetBFW_total*antElmTRx) + line_idx + try: + line_tst = tst[offset].rstrip() + except IndexError: + res = -1 + print("FAIL:","IndexError on tst: ant:[",i,"]:",offset, slot_idx, line_idx, len(tst)) + raise GetOutOfLoops + try: + line_ref = ref[offset].rstrip() + except IndexError: + res = -1 + print("FAIL:","IndexError on ref: ant:[",i,"]:",offset, slot_idx, line_idx, len(ref)) + raise GetOutOfLoops + + if comp == 1: + # discard LSB bits as BFP compression is not "bit exact" + tst_i_value = int(line_tst.split(" ")[0]) & 0xFF80 + tst_q_value = int(line_tst.split(" ")[1]) & 0xFF80 + ref_i_value = int(line_ref.split(" ")[0]) & 0xFF80 + ref_q_value = int(line_ref.split(" ")[1]) & 0xFF80 + + #print("check:","ant:[",i,"]:",offset, slot_idx, sym_idx, line_idx,":","tst: ", tst_i_value, " ", tst_q_value, " " , "ref: ", ref_i_value, " ", ref_q_value, " ") + if (tst_i_value != ref_i_value) or (tst_q_value != ref_q_value) : + print("FAIL:","bfw:[",i,"]:",offset, slot_idx, line_idx,":","tst: ", tst_i_value, " ", tst_q_value, " " , "ref: ", ref_i_value, " ", ref_q_value, " ") + res = -1 + raise GetOutOfLoops + else: + #if line_idx == 0: + #print("Check:", offset,"[",i,"]", slot_idx, sym_idx,":",line_tst, line_ref) + if line_ref != line_tst: + print("FAIL:","bfw:[",i,"]:",offset, slot_idx, line_idx,":","tst:", line_tst, "ref:", line_ref) + res = -1 + raise GetOutOfLoops + except GetOutOfLoops: + res = 0 # Not treating it as a test case fail criteria for now + # return res + + if (direction == 0) | (cat == 0) | (srs_enb == 0): #DL or Cat A #done return res - print("compare results: {} [compression {}]\n".format('SRS', comp)) + print("O-RU {} compare results: {} [compression {}]\n".format(o_xu_id, 'SRS', comp)) #srs - symbMask = srsSym + PrbElemContent = [] + if 'nPrbElemSrs' in globals(): + for i in range(0, nPrbElemSrs): + elm = str('PrbElemSrs'+str(i)) + #print(elm) + if (elm in globals()): + PrbElemContent.insert(i,list(globals()[elm])) + symbMask = 1 << PrbElemContent[i][2] # start symbol + print(symbMask) + #print(PrbElemContent,"RBStart: ", xRBStart, "RBSize: ",xRBSize, list(range(xRBStart, xRBStart + xRBSize))) + else: + print("Cannot find SRS PRB map!") + symbMask = 0 + + re_map = get_re_map(nUlRB, 2) try: flowId = ccNum*antElmTRx for i in range(0, flowId): @@ -418,8 +1046,8 @@ def compare_resuts(rantech, cat, mu, bw, tcase, xran_path, test_cfg, direction): if direction == 1: # UL nRB = nUlRB - file_tst = xran_path+"/app/logs/"+"o-du-srs_log_ant"+str(i)+".txt" - file_ref = xran_path+"/app/logs/"+"o-ru-play_srs_ant"+str(i)+".txt" + file_tst = xran_path+"/app/logs/"+"o-du"+str(o_xu_id)+"-srs_log_ant"+str(i)+".txt" + file_ref = xran_path+"/app/logs/"+"o-ru"+str(o_xu_id)+"-play_srs_ant"+str(i)+".txt" else: raise Exception('Direction is not supported %d'.format(direction)) @@ -452,15 +1080,15 @@ def compare_resuts(rantech, cat, mu, bw, tcase, xran_path, test_cfg, direction): print(len(tst)) print(len(ref)) - file_tst.close(); - file_ref.close(); + file_tst.close() + file_ref.close() print(numSlots) - for slot_idx in range(0, numSlots): + for slot_idx in range(0, numSlots - (1*direction)): for sym_idx in range(0, 14): - if symbMask & (1 << sym_idx): - print("SRS check sym ", sym_idx) + if symbMask & (1 << sym_idx) and slot_idx%nTddPeriod == srsSlot: + print("SRS check sym ", slot_idx, sym_idx) if nFrameDuplexType==1: #skip sym if TDD if direction == 0: @@ -471,11 +1099,12 @@ def compare_resuts(rantech, cat, mu, bw, tcase, xran_path, test_cfg, direction): elif direction == 1: #UL sym_dir = SlotConfig[slot_idx%nTddPeriod][sym_idx] - if(sym_dir != 1): - continue + # ignore if DL symbol for now + #if(sym_dir != 1): + # continue - #print("Check:","[",i,"]", slot_idx, sym_idx) - for line_idx in range(0, nRB*12): + print("Check:","[",i,"]", slot_idx, sym_idx) + for line_idx in re_map: offset = (slot_idx*nRB*12*14) + sym_idx*nRB*12 + line_idx try: line_tst = tst[offset].rstrip() @@ -489,15 +1118,15 @@ def compare_resuts(rantech, cat, mu, bw, tcase, xran_path, test_cfg, direction): res = -1 print("FAIL:","IndexError on ref: ant:[",i,"]:",offset, slot_idx, sym_idx, line_idx, len(ref)) raise GetOutOfLoops - if False : #SRS sent as not compressed - #comp == 1: - # discard LSB bits as BFP compression is not Bit Exact + + if comp == 1: + # discard LSB bits as BFP compression is not "bit exact" tst_i_value = int(line_tst.split(" ")[0]) & 0xFF80 tst_q_value = int(line_tst.split(" ")[1]) & 0xFF80 ref_i_value = int(line_ref.split(" ")[0]) & 0xFF80 ref_q_value = int(line_ref.split(" ")[1]) & 0xFF80 - print("check:","ant:[",i,"]:",offset, slot_idx, sym_idx, line_idx,":","tst: ", tst_i_value, " ", tst_q_value, " " , "ref: ", ref_i_value, " ", ref_q_value, " ") + #print("check:","ant:[",i,"]:",offset, slot_idx, sym_idx, line_idx,":","tst: ", tst_i_value, " ", tst_q_value, " " , "ref: ", ref_i_value, " ", ref_q_value, " ") if (tst_i_value != ref_i_value) or (tst_q_value != ref_q_value) : print("FAIL:","ant:[",i,"]:",offset, slot_idx, sym_idx, line_idx,":","tst: ", tst_i_value, " ", tst_q_value, " " , "ref: ", ref_i_value, " ", ref_q_value, " ") res = -1 @@ -510,15 +1139,52 @@ def compare_resuts(rantech, cat, mu, bw, tcase, xran_path, test_cfg, direction): res = -1 raise GetOutOfLoops except GetOutOfLoops: - pass + #don't threat SRS as error for now + res = 0 + return res return res +def parse_usecase_cfg(rantech, cat, mu, bw, tcase, xran_path, usecase_cfg): + #parse config files + logging.info("parse config files %s\n", usecase_cfg[0]) + lineList = list() + sep = '#' + with open(usecase_cfg[0],'r') as fh: + for curline in dropwhile(is_comment, fh): + my_line = curline.rstrip().split(sep, 1)[0].strip() + if my_line: + lineList.append(my_line) + + global_env = {} + local_env = {} + + for line in lineList: + exe_line = line.replace(":", ",0x") + if exe_line.find("../") > 0 : + exe_line = exe_line.replace('../', "'../") + exe_line = exe_line+"'" + elif exe_line.find("./") > 0 : + exe_line = exe_line.replace('./', "'./") + exe_line = exe_line+"'" + + code = compile(str(exe_line), '', 'exec') + exec (code, global_env, local_env) + + for k, v in local_env.items(): + globals()[k] = v + print(k, v) + + print("Number of O-RU:", oXuNum) + + return local_env + def parse_dat_file(rantech, cat, mu, bw, tcase, xran_path, test_cfg): #parse config files logging.info("parse config files %s\n", test_cfg[0]) lineList = list() + sep = '#' with open(test_cfg[0],'r') as fh: for curline in dropwhile(is_comment, fh): @@ -529,9 +1195,12 @@ def parse_dat_file(rantech, cat, mu, bw, tcase, xran_path, test_cfg): local_env = {} for line in lineList: - exe_line = line.replace(":", ",") - if exe_line.find("/") > 0 : - exe_line = exe_line.replace('./', "'") + exe_line = line.replace(":", ",0x") + if exe_line.find("../") > 0 : + exe_line = exe_line.replace('../', "'../") + exe_line = exe_line+"'" + elif exe_line.find("./") > 0 : + exe_line = exe_line.replace('./', "'./") exe_line = exe_line+"'" code = compile(str(exe_line), '', 'exec') @@ -553,20 +1222,20 @@ def del_dat_file_vars(local_env): def make_copy_mlog(rantech, cat, mu, bw, tcase, xran_path): res = 0 - src_bin = xran_path+"/app/mlog-o-du-c0.bin" - src_csv = xran_path+"/app/mlog-o-du-hist.csv" - dst_bin = xran_path+"/app/mlog-o-du-c0-ran"+str(rantech)+"-cat"+str(cat)+"-mu"+str(mu)+"-bw"+str(bw)+"-tcase"+str(tcase)+".bin" - dst_csv = xran_path+"/app/mlog-o-du-hist-ran"+str(rantech)+"-cat"+str(cat)+"-mu"+str(mu)+"-bw"+str(bw)+"-tcase"+str(tcase)+".csv" + src_bin = xran_path+"/app/mlog-o-du.bin" + src_csv = xran_path+"/app/mlog-o-du_hist.csv" + dst_bin = xran_path+"/app/mlog-o-du-ran"+str(rantech)+"-cat"+str(cat)+"-mu"+str(mu)+"-bw"+str(bw)+"-tcase"+str(tcase)+".bin" + dst_csv = xran_path+"/app/mlog-o-du_hist-ran"+str(rantech)+"-cat"+str(cat)+"-mu"+str(mu)+"-bw"+str(bw)+"-tcase"+str(tcase)+".csv" try: d_bin = shutil.copyfile(src_bin, dst_bin) d_csv = shutil.copyfile(src_csv, dst_csv) except IOError: - logging.info("MLog is not present\n") + logging.info("O-DU MLog is not present\n") res = 1 return res else: - logging.info("Mlog was copied\n") + logging.info("O-DU Mlog was copied\n") print("Destination path:", d_bin) @@ -575,10 +1244,10 @@ def make_copy_mlog(rantech, cat, mu, bw, tcase, xran_path): d_bin = shutil.copyfile(src_bin, dst_bin) d_csv = shutil.copyfile(src_csv, dst_csv) - src_bin = xran_path+"/app/mlog-o-ru-c0.bin" - src_csv = xran_path+"/app/mlog-o-ru-hist.csv" - dst_bin = xran_path+"/app/mlog-o-ru-c0-ran"+str(rantech)+"-cat"+str(cat)+"-mu"+str(mu)+"-bw"+str(bw)+"-tcase"+str(tcase)+".bin" - dst_csv = xran_path+"/app/mlog-o-ru-hist-ran"+str(rantech)+"-cat"+str(cat)+"-mu"+str(mu)+"-bw"+str(bw)+"-tcase"+str(tcase)+".csv" + src_bin = xran_path+"/app/mlog-o-ru.bin" + src_csv = xran_path+"/app/mlog-o-ru_hist.csv" + dst_bin = xran_path+"/app/mlog-o-ru-ran"+str(rantech)+"-cat"+str(cat)+"-mu"+str(mu)+"-bw"+str(bw)+"-tcase"+str(tcase)+".bin" + dst_csv = xran_path+"/app/mlog-o-ru_hist-ran"+str(rantech)+"-cat"+str(cat)+"-mu"+str(mu)+"-bw"+str(bw)+"-tcase"+str(tcase)+".csv" d_bin = shutil.copyfile(src_bin, dst_bin) d_csv = shutil.copyfile(src_csv, dst_csv) @@ -587,18 +1256,24 @@ def make_copy_mlog(rantech, cat, mu, bw, tcase, xran_path): d_bin = shutil.copyfile(src_bin, dst_bin) d_csv = shutil.copyfile(src_csv, dst_csv) except IOError: - logging.info("MLog is not present\n") + logging.info("O-RU MLog is not present\n") res = 1 return res else: - logging.info("Mlog was copied\n") + logging.info("O-RU Mlog was copied\n") return res -def run_tcase(rantech, cat, mu, bw, tcase, verbose, xran_path): +def run_tcase(rem_o_ru_host, rantech, cat, mu, bw, tcase, verbose, xran_path, vf_addr_o_xu): - if rantech == 1: #LTE + if rantech == 2: #LTE and #5G NR + if cat == 0: + test_config =xran_path+"/app/usecase/dss/mu{0:d}_{1:d}mhz".format(mu, bw) + else: + print("Incorrect cat argument\n") + return -1 + elif rantech == 1: #LTE if cat == 1: test_config =xran_path+"/app/usecase/lte_b/mu{0:d}_{1:d}mhz".format(mu, bw) elif cat == 0 : @@ -610,7 +1285,7 @@ def run_tcase(rantech, cat, mu, bw, tcase, verbose, xran_path): if cat == 1: test_config =xran_path+"/app/usecase/cat_b/mu{0:d}_{1:d}mhz".format(mu, bw) elif cat == 0 : - test_config =xran_path+"/app/usecase/mu{0:d}_{1:d}mhz".format(mu, bw) + test_config =xran_path+"/app/usecase/cat_a/mu{0:d}_{1:d}mhz".format(mu, bw) else: print("Incorrect cat argument\n") return -1 @@ -621,15 +1296,58 @@ def run_tcase(rantech, cat, mu, bw, tcase, verbose, xran_path): if(tcase > 0) : test_config = test_config+"/"+str(tcase) - app = xran_path+"/app/build/sample-app" + app = [xran_path+"/app/build/sample-app", xran_path+"/app/build-oru/sample-app-ru"] logging.debug("run: %s %s", app, test_config) logging.debug("Started script: master.py, XRAN path %s", xran_path) test_cfg = [] + global oXuOwdmEnabled + oXuOwdmEnabled = 0 #Default is owdm measurements are disabled + REM_O_RU_HOST=rem_o_ru_host + + if(os.system('lscpu | grep -q -i AVX512IFMA') == 0): + cpu = 'icx' + else: + cpu = 'csx' + + #O-DU + if REM_O_RU_HOST == "": + + if (cpu == 'icx'): + if ((os.path.isfile(test_config+"/usecase_du_icx.cfg")) & (os.path.isfile(test_config+"/usecase_ru_icx.cfg"))): + test_cfg.append(test_config+"/usecase_du_icx.cfg") + test_cfg.append(test_config+"/usecase_ru_icx.cfg") + else: + test_cfg.append(test_config+"/usecase_du.cfg") + test_cfg.append(test_config+"/usecase_ru.cfg") + else: #(csx_cpu) + if ((os.path.isfile(test_config+"/usecase_du_csx.cfg")) & (os.path.isfile(test_config+"/usecase_ru_csx.cfg"))): + test_cfg.append(test_config+"/usecase_du_csx.cfg") + test_cfg.append(test_config+"/usecase_ru_csx.cfg") + else: + test_cfg.append(test_config+"/usecase_du.cfg") + test_cfg.append(test_config+"/usecase_ru.cfg") + else: # O-RU remote always CSX-SP + if (cpu == 'icx'): + if (os.path.isfile(test_config+"/usecase_du_icx.cfg")): + test_cfg.append(test_config+"/usecase_du_icx.cfg") + else: + test_cfg.append(test_config+"/usecase_du.cfg") + if (os.path.isfile(test_config+"/usecase_ru_csx.cfg")): + test_cfg.append(test_config+"/usecase_ru_csx.cfg") + else: + test_cfg.append(test_config+"/usecase_ru.cfg") + else: #(csx_cpu) + if ((os.path.isfile(test_config+"/usecase_du_csx.cfg")) & (os.path.isfile(test_config+"/usecase_ru_csx.cfg"))): + test_cfg.append(test_config+"/usecase_du_csx.cfg") + test_cfg.append(test_config+"/usecase_ru_csx.cfg") + else: + test_cfg.append(test_config+"/usecase_du.cfg") + test_cfg.append(test_config+"/usecase_ru.cfg") - test_cfg.append(test_config+"/config_file_o_du.dat") - test_cfg.append(test_config+"/config_file_o_ru.dat") + usecase_dirname = os.path.dirname(os.path.realpath(test_cfg[0])) + print(usecase_dirname) wd = os.getcwd() os.chdir(xran_path+"/app/") @@ -640,17 +1358,36 @@ def run_tcase(rantech, cat, mu, bw, tcase, verbose, xran_path): timer = [] os.system('pkill -9 "sample-app"') + os.system('pkill -9 "sample-app-ru"') os.system('rm -rf ./logs') + usecase_cfg = parse_usecase_cfg(rantech, cat, mu, bw, tcase, xran_path, test_cfg) + + for i in range(2): + log_file_name.append("sampleapp_log_{}_{}_cat_{}_mu{}_{}mhz_tst_{}.log".format(dic_ran_tech.get(rantech), dic_xu.get(i),cat, mu, bw, tcase)) with open(log_file_name[i], "w") as f: - run_cmd = [app, "-c", test_cfg[i], "-p", "2", eth_up_dev[i], eth_cp_dev[i]] + run_cmd = [app[i], "--usecasefile", test_cfg[i], "--num_eth_vfs", "8", "--vf_addr_o_xu_a", vf_addr_o_xu[i][0], "--vf_addr_o_xu_b", vf_addr_o_xu[i][1],"--vf_addr_o_xu_c", vf_addr_o_xu[i][2],"--vf_addr_o_xu_d", vf_addr_o_xu[i][3]] #, stdout=f, stderr=f if (verbose==1): + if i == 0 or REM_O_RU_HOST == "": p = subprocess.Popen(run_cmd) else: + CMD = ' '.join([str(elem) for elem in run_cmd]) + ssh = ["ssh", "%s" % REM_O_RU_HOST, "cd " + xran_path + "/app"+"; hostname; pwd; pkill -9 sample-app; rm -rf ./logs; ulimit -c unlimited; echo 1 > /proc/sys/kernel/core_uses_pid; " + CMD] + print(ssh) + print("my_cmd: ", ' '.join([str(elem) for elem in ssh])) + p = subprocess.Popen(ssh, shell=False) + else: + if i == 0 or REM_O_RU_HOST == "": p = subprocess.Popen(run_cmd, stdout=f, stderr=f) + else : + CMD = ' '.join([str(elem) for elem in run_cmd]) + ssh = ["ssh", "%s" % REM_O_RU_HOST, "cd " + xran_path + "/app"+"; hostname; pwd; pkill -9 sample-app; rm -rf ./logs; ulimit -c unlimited; echo 1 > /proc/sys/kernel/core_uses_pid; " + CMD] + p = subprocess.Popen(ssh, shell=False, stdout=f, stderr=f) + #stdout=subprocess.PIPE, stderr=subprocess.PIPE) + t = Timer(timeout_sec, p.kill) t.start() timer.append(t) @@ -663,8 +1400,18 @@ def run_tcase(rantech, cat, mu, bw, tcase, verbose, xran_path): print(strftime("%a, %d %b %Y %H:%M:%S +0000", gmtime())) i = 0 for p, f in processes: + try: p.communicate()[0] p.wait() + except (KeyboardInterrupt, SystemExit): + for i in range(2): + timer[i].cancel() + timer[i].cancel() + for pp, ff in processes: + pp.send_signal(signal.SIGINT) + pp.wait() + raise + if p.returncode != 0: print("Application {} failed p.returncode:{}".format(dic_xu.get(i), p.returncode)) print("FAIL") @@ -675,42 +1422,79 @@ def run_tcase(rantech, cat, mu, bw, tcase, verbose, xran_path): f.close() for i in range(2): - timer[i].cancel(); - timer[i].cancel(); + timer[i].cancel() + timer[i].cancel() logging.info("O-DU and O-RU are done\n") - make_copy_mlog(rantech, cat, mu, bw, tcase, xran_path) - - usecase_cfg = parse_dat_file(rantech, cat, mu, bw, tcase, xran_path, test_cfg) + if REM_O_RU_HOST: + sys_cmd = "scp -r "+REM_O_RU_HOST+":"+ xran_path+"/app/logs/*.txt "+ xran_path+"/app/logs/" + print(sys_cmd) + os.system(sys_cmd) + sys_cmd = "scp -r "+REM_O_RU_HOST+":"+ xran_path+"/app/mlog-o-ru* "+ xran_path+"/app/" + print(sys_cmd) + os.system(sys_cmd) - res = compare_resuts(rantech, cat, mu, bw, tcase, xran_path, test_cfg, 0) + make_copy_mlog(rantech, cat, mu, bw, tcase, xran_path) + #oXuNum check only O-RU 0 for now + if 'oXuOwdmEnabled==1' in globals(): + OwdmTest=1 + else: + OwdmTest=0 + + for o_xu_id in range(0, oXuNum): + o_xu_test_cfg = [] + if o_xu_id == 0: + o_xu_test_cfg.append(usecase_dirname+"/"+oXuCfgFile0) + elif o_xu_id == 1: + o_xu_test_cfg.append(usecase_dirname+"/"+oXuCfgFile1) + elif o_xu_id == 2: + o_xu_test_cfg.append(usecase_dirname+"/"+oXuCfgFile2) + elif o_xu_id == 3: + o_xu_test_cfg.append(usecase_dirname+"/"+oXuCfgFile3) + + logging.info("O-RU %d parse config files %s\n", o_xu_id, o_xu_test_cfg) + + usecase_cfg_per_o_ru = parse_dat_file(rantech, cat, mu, bw, tcase, xran_path, o_xu_test_cfg) + + res = compare_results(o_xu_id,rantech, cat, mu, bw, tcase, xran_path, o_xu_test_cfg, 0) + if OwdmTest == 1: + # overwrite PASS/FAIL in res if the owd tests have failed + res1 = check_owdm_test_results(xran_path, o_xu_id) + print("res1 :", res1) + if res1 !=0 : + res = -1 if res != 0: os.chdir(wd) print("FAIL") + del_dat_file_vars(usecase_cfg_per_o_ru) return res - res = compare_resuts(rantech, cat, mu, bw, tcase, xran_path, test_cfg, 1) + res = compare_results(o_xu_id, rantech, cat, mu, bw, tcase, xran_path, o_xu_test_cfg, 1) if res != 0: os.chdir(wd) print("FAIL") + del_dat_file_vars(usecase_cfg_per_o_ru) return res os.chdir(wd) print("PASS") - del_dat_file_vars(usecase_cfg) + del_dat_file_vars(usecase_cfg_per_o_ru) return res def main(): test_results = [] - test_executed_total = 0 run_total = 0 + test_fail_cnt = 0 + test_pass_cnt = 0 cat = 0 mu = 0 bw = 0 tcase = 0 + tcase_description = "n/a" + """Processes input files to produce IACA files""" # Find path to XRAN if os.getenv("XRAN_DIR") is not None: @@ -724,20 +1508,42 @@ def main(): host_name = socket.gethostname() logging.info("host: %s Started script: master.py from XRAN path %s",host_name, xran_path) - #custom config for dev station + options = parse_args(sys.argv[1:]) + rem_o_ru_host = options.rem_o_ru_host + + all_test_cases = all_test_cases_long if host_name == "sc12-xran-sub6": - eth_cp_dev[0] = "0000:21:02.1" - eth_cp_dev[1] = "0000:21:0a.1" - eth_up_dev[0] = "0000:21:02.0" - eth_up_dev[1] = "0000:21:0a.0" + if rem_o_ru_host: + vf_addr_o_xu = vf_addr_o_xu_sc12_cvl + else: + vf_addr_o_xu = vf_addr_o_xu_sc12 + elif host_name == "csl-npg-scs1-30": + vf_addr_o_xu = vf_addr_o_xu_scs1_30 + elif host_name == "npg-scs1-repo.la.intel.com": + vf_addr_o_xu = vf_addr_o_xu_scs1_repo + elif host_name == "icelake-scs1-1": + vf_addr_o_xu = vf_addr_o_xu_icelake_scs1_1 + elif host_name == "icx-npg-scs1-coyote4": + vf_addr_o_xu = vf_addr_o_xu_icx_npg_scs1_coyote4 + elif host_name == "csl-npg-scs1-35": + vf_addr_o_xu = vf_addr_o_xu_scs1_35 + elif host_name == "csl-npg-scs1-33": + vf_addr_o_xu = vf_addr_o_xu_csl_npg_scs1_33 + elif host_name == "skx-5gnr-sd6": + vf_addr_o_xu = vf_addr_o_xu_skx_5gnr_sd6 + else: + vf_addr_o_xu = vf_addr_o_xu_jenkins + all_test_cases = all_test_cases_short + + print(vf_addr_o_xu[0][0],vf_addr_o_xu[0][1],vf_addr_o_xu[0][2],vf_addr_o_xu[0][3]) + print(vf_addr_o_xu[1][0],vf_addr_o_xu[1][1],vf_addr_o_xu[1][2],vf_addr_o_xu[1][3]) # Parse input arguments - if len(sys.argv) == 1 : + if len(sys.argv) == 1 or (len(sys.argv) == 3 and rem_o_ru_host): run_total = len(all_test_cases) print(run_total) print("Run All test cases {}\n".format(run_total)) else: - options = parse_args(sys.argv[1:]) rantech = options.rantech cat = options.category mu = options.numerology @@ -745,6 +1551,7 @@ def main(): tcase = options.testcase verbose = options.verbose + print(rem_o_ru_host) if (run_total): for test_run_ix in range(0, run_total): @@ -753,22 +1560,23 @@ def main(): mu = all_test_cases[test_run_ix][2] bw = all_test_cases[test_run_ix][3] tcase = all_test_cases[test_run_ix][4] + tcase_description = all_test_cases[test_run_ix][5] verbose = 0 - logging.info("Test# %d out of %d: ran %d cat %d mu %d bw %d test case %d\n",test_run_ix, run_total, rantech, cat, mu, bw, tcase) - res = run_tcase(rantech, cat, mu, bw, tcase, verbose, xran_path) + logging.info("Test# %d out of %d [PASS %d FAIL %d]: ran %d cat %d mu %d bw %d test case %d [%s]\n",test_run_ix, run_total, test_pass_cnt, test_fail_cnt, rantech, cat, mu, bw, tcase, tcase_description) + res = run_tcase(rem_o_ru_host, rantech, cat, mu, bw, tcase, verbose, xran_path, vf_addr_o_xu) if (res != 0): - test_results.append((rantech, cat, mu, bw, tcase,'FAIL')) + test_fail_cnt += 1 + test_results.append((rantech, cat, mu, bw, tcase,'FAIL', tcase_description)) continue - test_results.append((rantech, cat, mu, bw, tcase,'PASS')) - - with open('testresult.txt', 'w') as reshandle: - json.dump(test_results, reshandle) + test_pass_cnt += 1 + test_results.append((rantech, cat, mu, bw, tcase,'PASS', tcase_description)) else: - res = run_tcase(rantech, cat, mu, bw, tcase, verbose, xran_path) + res = run_tcase(rem_o_ru_host, rantech, cat, mu, bw, tcase, verbose, xran_path, vf_addr_o_xu) if (res != 0): test_results.append((rantech, cat, mu, bw, tcase,'FAIL')) + else: test_results.append((rantech, cat, mu, bw, tcase,'PASS')) with open('testresult.txt', 'w') as reshandle: @@ -777,6 +1585,12 @@ def main(): return res if __name__ == '__main__': + print("Python version") + print (sys.version) + print("Version info.") + print (sys.version_info) + if (sys.version_info[0] < 3): + raise Exception ("Must be Python 3") START_TIME = datetime.now() res = main() END_TIME = datetime.now()