xref: /XiangShan/debug/local_ci.py (revision 9473e04d5cab97eaf63add958b2392eec3d876a2)
1*9473e04dSbugGenerator
2*9473e04dSbugGeneratorimport sys
3*9473e04dSbugGeneratorimport argparse
4*9473e04dSbugGeneratorimport yaml
5*9473e04dSbugGeneratorimport os
6*9473e04dSbugGeneratorfrom datetime import date
7*9473e04dSbugGeneratorimport time
8*9473e04dSbugGenerator
9*9473e04dSbugGeneratorgithub_yaml = ""
10*9473e04dSbugGeneratorworkspace = ""
11*9473e04dSbugGeneratornemu_home = ""
12*9473e04dSbugGeneratoram_home = ""
13*9473e04dSbugGeneratorhead_sha = ""
14*9473e04dSbugGeneratorwave_home = ""
15*9473e04dSbugGeneratorperf_home = ""
16*9473e04dSbugGeneratorset_env = ""
17*9473e04dSbugGeneratorsh_path = ""
18*9473e04dSbugGenerator
19*9473e04dSbugGeneratordef remove_empty(list_str):
20*9473e04dSbugGenerator  list_new = []
21*9473e04dSbugGenerator  for s in list_str:
22*9473e04dSbugGenerator    if not (s == ""):
23*9473e04dSbugGenerator      list_new.append(s)
24*9473e04dSbugGenerator  return list_new
25*9473e04dSbugGenerator
26*9473e04dSbugGeneratordef split_cmd(cmd):
27*9473e04dSbugGenerator  c = cmd.replace("\\\n", " ")
28*9473e04dSbugGenerator  c = remove_empty(c.split("\n"))
29*9473e04dSbugGenerator  cs = []
30*9473e04dSbugGenerator  for ci in c:
31*9473e04dSbugGenerator    ci = ci.replace("\\\n", " ")
32*9473e04dSbugGenerator    ci = ci.replace("\n\n", "\n")
33*9473e04dSbugGenerator    ci = ci.replace("  ", " ")
34*9473e04dSbugGenerator    if ci[-1] == "\n":
35*9473e04dSbugGenerator      ci = ci[:-1]
36*9473e04dSbugGenerator    cs.append(ci)
37*9473e04dSbugGenerator  return cs
38*9473e04dSbugGenerator
39*9473e04dSbugGeneratordef parse_yaml(yaml_file):
40*9473e04dSbugGenerator  file_data = open(yaml_file, "r", encoding="utf-8").read()
41*9473e04dSbugGenerator  yaml_data = yaml.load(file_data, Loader=yaml.CLoader)
42*9473e04dSbugGenerator  return yaml_data
43*9473e04dSbugGenerator
44*9473e04dSbugGeneratordef show(test_info):
45*9473e04dSbugGenerator  name = test_info["name"]
46*9473e04dSbugGenerator  print(name)
47*9473e04dSbugGenerator
48*9473e04dSbugGeneratordef run_test(test_info, numa, run_mode):
49*9473e04dSbugGenerator  name = test_info["name"]
50*9473e04dSbugGenerator  coe_key = "continue-on-error"
51*9473e04dSbugGenerator  to_key = "timeout-minutes"
52*9473e04dSbugGenerator  s_key = "steps"
53*9473e04dSbugGenerator  continue_on_error = True if (coe_key not in test_info.keys()) else (False if (test_info[coe_key] == "false") else True)
54*9473e04dSbugGenerator  timeout_minutes = 9999 if (to_key not in test_info.keys()) else int(test_info[to_key])
55*9473e04dSbugGenerator  if s_key not in test_info.keys():
56*9473e04dSbugGenerator    print(name, " ", s_key, " not found in yaml, skip")
57*9473e04dSbugGenerator    sys.exit()
58*9473e04dSbugGenerator  steps_raw = test_info[s_key]
59*9473e04dSbugGenerator  # print("Steps")
60*9473e04dSbugGenerator  # print(steps)
61*9473e04dSbugGenerator  steps = {}
62*9473e04dSbugGenerator  for s in steps_raw:
63*9473e04dSbugGenerator    if "name" in s.keys():
64*9473e04dSbugGenerator      steps[s["name"]] = s["run"]
65*9473e04dSbugGenerator  # print(steps)
66*9473e04dSbugGenerator
67*9473e04dSbugGenerator  replace_list = [
68*9473e04dSbugGenerator    ["--numa", "--numa" if numa else ""],
69*9473e04dSbugGenerator    ["$GITHUB_WORKSPACE", f"{workspace}"],
70*9473e04dSbugGenerator    ["$HEAD_SHA", f"{head_sha}"],
71*9473e04dSbugGenerator    ["$PERF_HOME", f"{perf_home}"],
72*9473e04dSbugGenerator    ["$WAVE_HOME", f"{wave_home}"],
73*9473e04dSbugGenerator    ["$AM_HOME", f"{am_home}"]
74*9473e04dSbugGenerator  ]
75*9473e04dSbugGenerator
76*9473e04dSbugGenerator  steps.pop("set env")
77*9473e04dSbugGenerator
78*9473e04dSbugGenerator  for s in steps.keys():
79*9473e04dSbugGenerator    for r in replace_list:
80*9473e04dSbugGenerator      steps[s] = steps[s].replace(r[0], r[1])
81*9473e04dSbugGenerator
82*9473e04dSbugGenerator  cmd = []
83*9473e04dSbugGenerator  for s in steps.keys():
84*9473e04dSbugGenerator    cs = split_cmd(steps[s])
85*9473e04dSbugGenerator    cmd = cmd + cs
86*9473e04dSbugGenerator
87*9473e04dSbugGenerator  if run_mode:
88*9473e04dSbugGenerator    for c in cmd:
89*9473e04dSbugGenerator      f_c = set_env + " " + c
90*9473e04dSbugGenerator      print(f"[CMD] {f_c}", flush=True)
91*9473e04dSbugGenerator      os.system(f_c)
92*9473e04dSbugGenerator  else:
93*9473e04dSbugGenerator    if (sh_path is None):
94*9473e04dSbugGenerator      print("sh_path is None")
95*9473e04dSbugGenerator      sys.exit()
96*9473e04dSbugGenerator    elif (not os.path.exists(sh_path)):
97*9473e04dSbugGenerator      os.mkdir(sh_path)
98*9473e04dSbugGenerator
99*9473e04dSbugGenerator
100*9473e04dSbugGenerator    sh_file_name = os.path.join(sh_path, "_".join(name.strip().replace("-", "").split())+".sh")
101*9473e04dSbugGenerator    with open(sh_file_name, "w") as tmp_sh:
102*9473e04dSbugGenerator      tmp_sh.write(f"mkdir -p {wave_home}\n")
103*9473e04dSbugGenerator      tmp_sh.write(f"mkdir -p {perf_home}\n")
104*9473e04dSbugGenerator      for c in cmd:
105*9473e04dSbugGenerator        print(c)
106*9473e04dSbugGenerator        tmp_sh.write(c+"\n")
107*9473e04dSbugGenerator
108*9473e04dSbugGeneratorif __name__ == "__main__":
109*9473e04dSbugGenerator  # Usage:
110*9473e04dSbugGenerator  # 1. run ci test
111*9473e04dSbugGenerator  # python3 scripts/local_ci.py --xs-path $(pwd) --run
112*9473e04dSbugGenerator  # More Params:
113*9473e04dSbugGenerator  # --pick-test MC: only run 'EMU - MC'
114*9473e04dSbugGenerator
115*9473e04dSbugGenerator  # 2. print ci test name
116*9473e04dSbugGenerator  # python3 scripts/local_ci.py --xs-path $(pwd) --show-test
117*9473e04dSbugGenerator  # This can also use --pick-test
118*9473e04dSbugGenerator
119*9473e04dSbugGenerator  # 3. print ci test command into splited sh files. Run the sh manualy.
120*9473e04dSbugGenerator  # python3 scripts/local_ci.py --xs-path $(pwd) --sh-path /nfs/home/zhangzifei/work/xs-master/ci-sh
121*9473e04dSbugGenerator  # just remove --run
122*9473e04dSbugGenerator
123*9473e04dSbugGenerator  # Other Params:
124*9473e04dSbugGenerator  # --numa: use numa ctrl, require eypc
125*9473e04dSbugGenerator  # --head-sha: magic word, default is today's date
126*9473e04dSbugGenerator  # --nemu-home/--am-home: don't know if it is used
127*9473e04dSbugGenerator
128*9473e04dSbugGenerator  parser = argparse.ArgumentParser(description="run ci locally")
129*9473e04dSbugGenerator  parser.add_argument("--xs-path", type=str, help="XiangShan, NOOP_HOME")
130*9473e04dSbugGenerator  parser.add_argument("--nemu-home", type=str, help="NEMU_HOME")
131*9473e04dSbugGenerator  parser.add_argument("--am-home", type=str, help="AM_HOME")
132*9473e04dSbugGenerator  parser.add_argument("--sh-path", type=str, help="ci's sh file path")
133*9473e04dSbugGenerator  parser.add_argument("--head-sha", type=str, help="magic word")
134*9473e04dSbugGenerator  parser.add_argument("--run", action='store_true', help="run test, not gen sh")
135*9473e04dSbugGenerator  parser.add_argument("--numa", action='store_true', help="epyc numactl")
136*9473e04dSbugGenerator  parser.add_argument("--show-test", action="store_true", help="print test case")
137*9473e04dSbugGenerator  parser.add_argument("--pick-test", type=str, help="pick only one test")
138*9473e04dSbugGenerator
139*9473e04dSbugGenerator  args = parser.parse_args()
140*9473e04dSbugGenerator
141*9473e04dSbugGenerator  print(args)
142*9473e04dSbugGenerator
143*9473e04dSbugGenerator  workspace = os.getenv("NOOP_HOME") if (args.xs_path is None) else args.xs_path
144*9473e04dSbugGenerator  head_sha = date.today().strftime(r"%Y%m%d") if (args.head_sha is None) else args.head_sha
145*9473e04dSbugGenerator  wave_home = os.path.join(workspace, "wave", head_sha)
146*9473e04dSbugGenerator  perf_home = os.path.join(workspace, "perf", head_sha)
147*9473e04dSbugGenerator  github_yaml = os.path.join(workspace, ".github/workflows/emu.yml")
148*9473e04dSbugGenerator  nemu_home = os.getenv("NEMU_HOME") if (args.nemu_home is None) else args.nemu_home
149*9473e04dSbugGenerator  am_home = os.getenv("AM_HOME") if (args.am_home is None) else args.am_home
150*9473e04dSbugGenerator  set_env = f"NEMU_HOME={nemu_home}  NOOP_HOME={workspace}  WAVE_HOME={wave_home}  PERF_HOME={perf_home}  AM_HOME={am_home}"
151*9473e04dSbugGenerator  sh_path = f"{workspace}/ci-sh" if (args.sh_path is None) else args.sh_path
152*9473e04dSbugGenerator
153*9473e04dSbugGenerator  print("workspace(NOOP_HOME): ", workspace)
154*9473e04dSbugGenerator  print("head_sha: ", head_sha)
155*9473e04dSbugGenerator  print("wave_home: ", wave_home)
156*9473e04dSbugGenerator  print("perf_home: ", perf_home)
157*9473e04dSbugGenerator  print("github_yaml: ", github_yaml)
158*9473e04dSbugGenerator  print("nemu_home: ", nemu_home)
159*9473e04dSbugGenerator  print("am_home: ", am_home)
160*9473e04dSbugGenerator  print("set_env: ", set_env)
161*9473e04dSbugGenerator  print("sh_path", sh_path)
162*9473e04dSbugGenerator
163*9473e04dSbugGenerator  input("Press Enter to continue")
164*9473e04dSbugGenerator
165*9473e04dSbugGenerator  ci_tests = parse_yaml(github_yaml)["jobs"]
166*9473e04dSbugGenerator
167*9473e04dSbugGenerator  if (args.show_test):
168*9473e04dSbugGenerator    for test in ci_tests.keys():
169*9473e04dSbugGenerator      show(ci_tests[test])
170*9473e04dSbugGenerator  else:
171*9473e04dSbugGenerator    for test in ci_tests.keys():
172*9473e04dSbugGenerator      if args.pick_test is not None:
173*9473e04dSbugGenerator        if (args.pick_test in ci_tests[test]["name"]):
174*9473e04dSbugGenerator          run_test(ci_tests[test], args.numa, args.run)
175*9473e04dSbugGenerator      else:
176*9473e04dSbugGenerator        run_test(ci_tests[test], args.numa, args.run)