xref: /spdk/test/iscsi_tgt/calsoft/calsoft.py (revision 7192849ed24874f3e9cc31e8a33a9b32c49b9506)
1#!/usr/bin/env python3
2
3import os
4import time
5import sys
6import subprocess
7import threading
8import json
9
10CALSOFT_BIN_PATH = "/usr/local/calsoft/iscsi-pcts-v1.5/bin"
11
12'''
1311/26/2015 disable tc_login_11_2 and tc_login_11_4
14RFC 7143 6.3
15Neither the initiator nor the target should attempt to declare or
16negotiate a parameter more than once during login, except for
17responses to specific keys that explicitly allow repeated key
18declarations (e.g., TargetAddress)
19
20The spec didn't make it clear what other keys could be re-declare
21Disscussed this with UNH and get the conclusion that TargetName/
22TargetAddress/MaxRecvDataSegmentLength could be re-declare.
23'''
24'''
2512/1/2015 add tc_login_2_2 to known_failed_cases
26RFC 7143 6.1
27A standard-label MUST begin with a capital letter and must not exceed
2863 characters.
29key name: A standard-label
30'''
31'''
3206/10/2020 add tc_login_29_1 to known_failed_cases
33RFC 3720 12.19. DataSequenceInOrder
34Irrelevant when: SessionType=Discovery
35'''
36
37known_failed_cases = ['tc_ffp_15_2', 'tc_ffp_29_2', 'tc_ffp_29_3', 'tc_ffp_29_4',
38                      'tc_err_1_1', 'tc_err_1_2', 'tc_err_2_8',
39                      'tc_err_3_1', 'tc_err_3_2', 'tc_err_3_3',
40                      'tc_err_3_4', 'tc_err_5_1', 'tc_login_3_1',
41                      'tc_login_11_2', 'tc_login_11_4', 'tc_login_2_2', 'tc_login_29_1']
42
43
44def run_case(case, result_list, log_dir_path):
45    try:
46        case_log = subprocess.check_output("{}/{}".format(CALSOFT_BIN_PATH, case), stderr=subprocess.STDOUT, shell=True).decode('utf-8')
47    except subprocess.CalledProcessError as e:
48        result_list.append({"Name": case, "Result": "FAIL"})
49        case_log = e.output.decode('utf-8')
50    else:
51        result_list.append({"Name": case, "Result": "PASS"})
52    with open(log_dir_path + case + '.txt', 'w') as f:
53        f.write(case_log)
54
55
56def main():
57    if not os.path.exists(CALSOFT_BIN_PATH):
58        print("The Calsoft test suite is not available on this machine.")
59        sys.exit(1)
60
61    output_dir = sys.argv[1]
62    if len(sys.argv) > 2:
63        output_file = sys.argv[2]
64    else:
65        output_file = "%s/calsoft.json" % (output_dir)
66
67    log_dir = "%s/calsoft/" % output_dir
68
69    all_cases = [x for x in os.listdir(CALSOFT_BIN_PATH) if x.startswith('tc')]
70    all_cases.sort()
71
72    case_result_list = []
73
74    result = {"Calsoft iSCSI tests": case_result_list}
75
76    if not os.path.exists(log_dir):
77        os.mkdir(log_dir)
78    for case in known_failed_cases:
79        print("Skipping %s. It is known to fail." % (case))
80        case_result_list.append({"Name": case, "Result": "SKIP"})
81
82    thread_objs = []
83    left_cases = list(set(all_cases) - set(known_failed_cases))
84    index = 0
85    max_thread_count = 32
86
87    while index < len(left_cases):
88        cur_thread_count = 0
89        for thread_obj in thread_objs:
90            if thread_obj.is_alive():
91                cur_thread_count += 1
92        while cur_thread_count < max_thread_count and index < len(left_cases):
93            thread_obj = threading.Thread(target=run_case, args=(left_cases[index], case_result_list, log_dir, ))
94            thread_obj.start()
95            time.sleep(0.02)
96            thread_objs.append(thread_obj)
97            index += 1
98            cur_thread_count += 1
99    end_time = time.time() + 30
100    while time.time() < end_time:
101        for thread_obj in thread_objs:
102            if thread_obj.is_alive():
103                break
104        else:
105            break
106    else:
107        print("Thread timeout")
108        exit(1)
109    with open(output_file, 'w') as f:
110        json.dump(obj=result, fp=f, indent=2)
111
112    failed = 0
113    for x in case_result_list:
114        if x["Result"] == "FAIL":
115            print("Test case %s failed." % (x["Name"]))
116            failed = 1
117    exit(failed)
118
119
120if __name__ == '__main__':
121    main()
122