blob: 5419834e37897ae27c04384fbbdf9095f4a6724d [file] [log] [blame]
George Keishinge7e91712021-09-03 11:28:44 -05001#!/usr/bin/env python3
manasarm5dedfaf2018-02-07 14:54:54 +05302
George Keishing9fbdf792016-10-18 06:16:09 -05003r"""
manasarm5dedfaf2018-02-07 14:54:54 +05304Use robot framework API to extract test result data from output.xml generated
5by robot tests. For more information on the Robot Framework API, see
Sridevi Rameshbe2b77d2025-03-17 00:50:40 -05006https://robot-framework.readthedocs.io/en/stable/autodoc/robot.result.html
George Keishing9fbdf792016-10-18 06:16:09 -05007"""
manasarm5dedfaf2018-02-07 14:54:54 +05308
George Keishinge635ddc2022-12-08 07:38:02 -06009import csv
Patrick Williams20f38712022-12-08 06:18:26 -060010import datetime
Patrick Williams20f38712022-12-08 06:18:26 -060011import os
Steven Sombar3e82e3b2019-03-21 10:33:52 -050012import stat
Patrick Williams20f38712022-12-08 06:18:26 -060013import sys
14from xml.etree import ElementTree
15
Patrick Williams20f38712022-12-08 06:18:26 -060016from robot.api import ExecutionResult
17from robot.result.visitor import ResultVisitor
manasarm5dedfaf2018-02-07 14:54:54 +053018
19# Remove the python library path to restore with local project path later.
George Keishingddfd7992023-02-16 03:39:47 -060020SAVE_PATH_0 = sys.path[0]
manasarm5dedfaf2018-02-07 14:54:54 +053021del sys.path[0]
George Keishingc2a6f092019-02-20 12:26:54 -060022sys.path.append(os.path.join(os.path.dirname(__file__), "../../lib"))
manasarm5dedfaf2018-02-07 14:54:54 +053023
Patrick Williams20f38712022-12-08 06:18:26 -060024from gen_arg import * # NOQA
George Keishing09679892022-12-08 08:21:52 -060025from gen_print import * # NOQA
26from gen_valid import * # NOQA
George Keishing37c58c82022-12-08 07:42:54 -060027
manasarm5dedfaf2018-02-07 14:54:54 +053028# Restore sys.path[0].
George Keishingddfd7992023-02-16 03:39:47 -060029sys.path.insert(0, SAVE_PATH_0)
manasarm5dedfaf2018-02-07 14:54:54 +053030
Steven Sombara5e32f22019-03-01 13:33:15 -060031
32this_program = sys.argv[0]
Patrick Williams20f38712022-12-08 06:18:26 -060033info = " For more information: " + this_program + " -h"
Steven Sombara5e32f22019-03-01 13:33:15 -060034if len(sys.argv) == 1:
George Keishingbfa859a2020-04-02 00:38:24 -050035 print(info)
Steven Sombara5e32f22019-03-01 13:33:15 -060036 sys.exit(1)
37
38
manasarm5dedfaf2018-02-07 14:54:54 +053039parser = argparse.ArgumentParser(
Steven Sombara5e32f22019-03-01 13:33:15 -060040 usage=info,
Patrick Williams20f38712022-12-08 06:18:26 -060041 description=(
42 "%(prog)s uses a robot framework API to extract test result data"
43 " from output.xml generated by robot tests. For more information on"
44 " the Robot Framework API, see "
Sridevi Rameshbe2b77d2025-03-17 00:50:40 -050045 " https://robot-framework.readthedocs.io/en/stable/autodoc/robot.result.html"
Patrick Williams20f38712022-12-08 06:18:26 -060046 ),
manasarm5dedfaf2018-02-07 14:54:54 +053047 formatter_class=argparse.ArgumentDefaultsHelpFormatter,
Patrick Williams20f38712022-12-08 06:18:26 -060048 prefix_chars="-+",
49)
manasarm5dedfaf2018-02-07 14:54:54 +053050
51parser.add_argument(
Patrick Williams20f38712022-12-08 06:18:26 -060052 "--source",
53 "-s",
54 help=(
Sridevi Rameshbe2b77d2025-03-17 00:50:40 -050055 "The output.xml robot test result file path. This parameter is "
Patrick Williams20f38712022-12-08 06:18:26 -060056 " required."
57 ),
58)
manasarm5dedfaf2018-02-07 14:54:54 +053059
60parser.add_argument(
Patrick Williams20f38712022-12-08 06:18:26 -060061 "--dest",
62 "-d",
63 help=(
Sridevi Rameshbe2b77d2025-03-17 00:50:40 -050064 "The directory path where the generated .csv files will go. This"
65 " parameter is required."
Patrick Williams20f38712022-12-08 06:18:26 -060066 ),
67)
manasarm5dedfaf2018-02-07 14:54:54 +053068
manasarme4f79c92018-02-22 13:02:46 +053069parser.add_argument(
Patrick Williams20f38712022-12-08 06:18:26 -060070 "--version_id",
71 help=(
Sridevi Rameshbe2b77d2025-03-17 00:50:40 -050072 "Driver version of openbmc firmware which was used during test,"
Patrick Williams20f38712022-12-08 06:18:26 -060073 ' e.g. "v2.1-215-g6e7eacb". This parameter is required.'
74 ),
75)
manasarme4f79c92018-02-22 13:02:46 +053076
77parser.add_argument(
Patrick Williams20f38712022-12-08 06:18:26 -060078 "--platform",
79 help=(
Sridevi Rameshbe2b77d2025-03-17 00:50:40 -050080 "OpenBMC platform which was used during test, e.g."
Patrick Williams20f38712022-12-08 06:18:26 -060081 ' "Witherspoon". This parameter is required.'
82 ),
83)
manasarme4f79c92018-02-22 13:02:46 +053084
George Keishing19533d52018-04-09 03:08:03 -050085parser.add_argument(
Patrick Williams20f38712022-12-08 06:18:26 -060086 "--level",
87 help=(
Sridevi Rameshbe2b77d2025-03-17 00:50:40 -050088 "OpenBMC release level which was used during test, e.g."
Patrick Williams20f38712022-12-08 06:18:26 -060089 ' "Master", "OBMC920". This parameter is required.'
90 ),
91)
Steven Sombara5e32f22019-03-01 13:33:15 -060092
93parser.add_argument(
Patrick Williams20f38712022-12-08 06:18:26 -060094 "--test_phase",
95 help=(
Sridevi Rameshbe2b77d2025-03-17 00:50:40 -050096 'Name of testing phase, e.g. "CI", "Regression", etc. This'
Patrick Williams20f38712022-12-08 06:18:26 -060097 " parameter is optional."
98 ),
99 default="FVT",
100)
Steven Sombara5e32f22019-03-01 13:33:15 -0600101
102parser.add_argument(
Patrick Williams20f38712022-12-08 06:18:26 -0600103 "--subsystem",
104 help=(
Sridevi Rameshbe2b77d2025-03-17 00:50:40 -0500105 'Name of the subsystem, e.g. "OPENBMC" etc. This parameter is'
Patrick Williams20f38712022-12-08 06:18:26 -0600106 " optional."
107 ),
108 default="OPENBMC",
109)
Vijaye3a98372019-10-30 02:04:22 -0500110
111parser.add_argument(
Patrick Williams20f38712022-12-08 06:18:26 -0600112 "--processor",
Sridevi Rameshbe2b77d2025-03-17 00:50:40 -0500113 help='Name of processor, e.g. "XY". This parameter is optional.',
Patrick Williams20f38712022-12-08 06:18:26 -0600114 default="OPENPOWER",
115)
Steven Sombara5e32f22019-03-01 13:33:15 -0600116
George Keishing19533d52018-04-09 03:08:03 -0500117
manasarm5dedfaf2018-02-07 14:54:54 +0530118# Populate stock_list with options we want.
119stock_list = [("test_mode", 0), ("quiet", 0), ("debug", 0)]
120
121
Sridevi Rameshbe2b77d2025-03-17 00:50:40 -0500122def exit_function(signal_number=0):
manasarm5dedfaf2018-02-07 14:54:54 +0530123 r"""
124 Execute whenever the program ends normally or with the signals that we
125 catch (i.e. TERM, INT).
126 """
127
128 dprint_executing()
129
130 dprint_var(signal_number)
131
132 qprint_pgm_footer()
133
134
Sridevi Rameshbe2b77d2025-03-17 00:50:40 -0500135def signal_handler():
manasarm5dedfaf2018-02-07 14:54:54 +0530136 r"""
137 Handle signals. Without a function to catch a SIGTERM or SIGINT, the
138 program would terminate immediately with return code 143 and without
139 calling the exit_function.
140 """
141
142 # Our convention is to set up exit_function with atexit.register() so
143 # there is no need to explicitly call exit_function from here.
144
145 dprint_executing()
146
147 # Calling exit prevents us from returning to the code that was running
148 # when the signal was received.
George Keishingddfd7992023-02-16 03:39:47 -0600149 sys.exit(0)
manasarm5dedfaf2018-02-07 14:54:54 +0530150
151
152def validate_parms():
manasarm5dedfaf2018-02-07 14:54:54 +0530153 r"""
154 Validate program parameters, etc. Return True or False (i.e. pass/fail)
155 accordingly.
156 """
157
158 if not valid_file_path(source):
159 return False
160
161 if not valid_dir_path(dest):
162 return False
163
164 gen_post_validation(exit_function, signal_handler)
165
166 return True
George Keishing9fbdf792016-10-18 06:16:09 -0500167
168
Patrick Williams20f38712022-12-08 06:18:26 -0600169def parse_output_xml(
170 xml_file_path,
171 csv_dir_path,
172 version_id,
173 platform,
174 level,
175 test_phase,
176 processor,
177):
manasarm5dedfaf2018-02-07 14:54:54 +0530178 r"""
179 Parse the robot-generated output.xml file and extract various test
180 output data. Put the extracted information into a csv file in the "dest"
181 folder.
182
183 Description of argument(s):
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -0500184 xml_file_path The path to a Robot-generated output.xml
185 file.
186 csv_dir_path The path to the directory that is to
187 contain the .csv files generated by
188 this function.
189 version_id Version of the openbmc firmware
190 (e.g. "v2.1-215-g6e7eacb").
191 platform Platform of the openbmc system.
192 level Release level of the OpenBMC system
George Keishing360db632018-09-06 12:01:28 -0500193 (e.g. "Master").
Sridevi Rameshbe2b77d2025-03-17 00:50:40 -0500194 test_phase Name of the test phase
195 e.g. "CI", "Regression", etc.
196 processor Name of processor, e.g. "XY".
manasarm5dedfaf2018-02-07 14:54:54 +0530197 """
198
Peter D Phan8e13ade2021-09-16 06:15:55 -0500199 # Initialize tallies
200 total_critical_tc = 0
201 total_critical_passed = 0
202 total_critical_failed = 0
203 total_non_critical_tc = 0
204 total_non_critical_passed = 0
205 total_non_critical_failed = 0
206
George Keishing74777bd2017-02-07 01:43:38 -0600207 result = ExecutionResult(xml_file_path)
Patrick Williams20f38712022-12-08 06:18:26 -0600208 result.configure(
209 stat_config={
210 "suite_stat_level": 2,
211 "tag_stat_combine": "tagANDanother",
212 }
213 )
George Keishing9fbdf792016-10-18 06:16:09 -0500214
215 stats = result.statistics
George Keishingf8a9ebe2018-08-06 12:49:11 -0500216 print("--------------------------------------")
Peter D Phan8e13ade2021-09-16 06:15:55 -0500217 try:
Patrick Williams20f38712022-12-08 06:18:26 -0600218 total_critical_tc = (
219 stats.total.critical.passed + stats.total.critical.failed
220 )
Peter D Phan8e13ade2021-09-16 06:15:55 -0500221 total_critical_passed = stats.total.critical.passed
222 total_critical_failed = stats.total.critical.failed
223 except AttributeError:
224 pass
225
226 try:
227 total_non_critical_tc = stats.total.passed + stats.total.failed
228 total_non_critical_passed = stats.total.passed
229 total_non_critical_failed = stats.total.failed
230 except AttributeError:
231 pass
232
Patrick Williams20f38712022-12-08 06:18:26 -0600233 print(
234 "Total Test Count:\t %d" % (total_non_critical_tc + total_critical_tc)
235 )
Peter D Phan8e13ade2021-09-16 06:15:55 -0500236
237 print("Total Critical Test Failed:\t %d" % total_critical_failed)
238 print("Total Critical Test Passed:\t %d" % total_critical_passed)
239 print("Total Non-Critical Test Failed:\t %d" % total_non_critical_failed)
240 print("Total Non-Critical Test Passed:\t %d" % total_non_critical_passed)
George Keishingf8a9ebe2018-08-06 12:49:11 -0500241 print("Test Start Time:\t %s" % result.suite.starttime)
242 print("Test End Time:\t\t %s" % result.suite.endtime)
243 print("--------------------------------------")
George Keishing9fbdf792016-10-18 06:16:09 -0500244
George Keishingddfd7992023-02-16 03:39:47 -0600245 # Use ResultVisitor object and save off the test data info.
George Keishing9fbdf792016-10-18 06:16:09 -0500246 class TestResult(ResultVisitor):
George Keishingddfd7992023-02-16 03:39:47 -0600247 r"""
248 Class methods to save off the test data information.
249 """
250
George Keishing9fbdf792016-10-18 06:16:09 -0500251 def __init__(self):
George Keishingddfd7992023-02-16 03:39:47 -0600252 self.test_data = []
George Keishing9fbdf792016-10-18 06:16:09 -0500253
254 def visit_test(self, test):
George Keishingddfd7992023-02-16 03:39:47 -0600255 self.test_data += [test]
George Keishing9fbdf792016-10-18 06:16:09 -0500256
George Keishingddfd7992023-02-16 03:39:47 -0600257 collect_data_obj = TestResult()
258 result.visit(collect_data_obj)
George Keishing9fbdf792016-10-18 06:16:09 -0500259
260 # Write the result statistics attributes to CSV file
261 l_csvlist = []
George Keishing74777bd2017-02-07 01:43:38 -0600262
263 # Default Test data
Steven Sombara5e32f22019-03-01 13:33:15 -0600264 l_test_type = test_phase
George Keishing19533d52018-04-09 03:08:03 -0500265
Patrick Williams20f38712022-12-08 06:18:26 -0600266 l_pse_rel = "Master"
George Keishing19533d52018-04-09 03:08:03 -0500267 if level:
268 l_pse_rel = level
269
Patrick Williams20f38712022-12-08 06:18:26 -0600270 l_env = "HW"
Steven Sombara5e32f22019-03-01 13:33:15 -0600271 l_proc = processor
George Keishing74777bd2017-02-07 01:43:38 -0600272 l_platform_type = ""
273 l_func_area = ""
274
Gunnar Mills096cd562018-03-26 10:19:12 -0500275 # System data from XML meta data
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -0500276 # l_system_info = get_system_details(xml_file_path)
manasarme4f79c92018-02-22 13:02:46 +0530277
278 # First let us try to collect information from keyboard input
279 # If keyboard input cannot give both information, then find from xml file.
280 if version_id and platform:
281 l_driver = version_id
282 l_platform_type = platform
George Keishingf8a9ebe2018-08-06 12:49:11 -0500283 print("BMC Version_id:%s" % version_id)
284 print("BMC Platform:%s" % platform)
George Keishing74777bd2017-02-07 01:43:38 -0600285 else:
manasarme4f79c92018-02-22 13:02:46 +0530286 # System data from XML meta data
287 l_system_info = get_system_details(xml_file_path)
288 l_driver = l_system_info[0]
289 l_platform_type = l_system_info[1]
290
291 # Driver version id and platform are mandatorily required for CSV file
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -0500292 # generation. If any one is not avaulable, exit CSV file generation
293 # process.
manasarme4f79c92018-02-22 13:02:46 +0530294 if l_driver and l_platform_type:
George Keishingf8a9ebe2018-08-06 12:49:11 -0500295 print("Driver and system info set.")
manasarme4f79c92018-02-22 13:02:46 +0530296 else:
Patrick Williams20f38712022-12-08 06:18:26 -0600297 print(
298 "Both driver and system info need to be set. CSV"
299 " file is not generated."
300 )
George Keishing74777bd2017-02-07 01:43:38 -0600301 sys.exit()
George Keishing9fbdf792016-10-18 06:16:09 -0500302
303 # Default header
Patrick Williams20f38712022-12-08 06:18:26 -0600304 l_header = [
305 "test_start",
306 "test_end",
307 "subsys",
308 "test_type",
309 "test_result",
310 "test_name",
311 "pse_rel",
312 "driver",
313 "env",
314 "proc",
315 "platform_type",
316 "test_func_area",
317 ]
George Keishing9fbdf792016-10-18 06:16:09 -0500318
319 l_csvlist.append(l_header)
320
321 # Generate CSV file onto the path with current time stamp
George Keishing74777bd2017-02-07 01:43:38 -0600322 l_base_dir = csv_dir_path
George Keishing937fe3c2019-10-29 11:20:34 -0500323 l_timestamp = datetime.datetime.utcnow().strftime("%Y-%m-%d-%H-%M-%S")
George Keishing74777bd2017-02-07 01:43:38 -0600324 # Example: 2017-02-20-08-47-22_Witherspoon.csv
325 l_csvfile = l_base_dir + l_timestamp + "_" + l_platform_type + ".csv"
George Keishing9fbdf792016-10-18 06:16:09 -0500326
George Keishingf8a9ebe2018-08-06 12:49:11 -0500327 print("Writing data into csv file:%s" % l_csvfile)
George Keishing9fbdf792016-10-18 06:16:09 -0500328
George Keishingddfd7992023-02-16 03:39:47 -0600329 for testcase in collect_data_obj.test_data:
George Keishing74777bd2017-02-07 01:43:38 -0600330 # Functional Area: Suite Name
331 # Test Name: Test Case Name
Patrick Williams20f38712022-12-08 06:18:26 -0600332 l_func_area = str(testcase.parent).split(" ", 1)[1]
George Keishing74777bd2017-02-07 01:43:38 -0600333 l_test_name = str(testcase)
George Keishing9fbdf792016-10-18 06:16:09 -0500334
335 # Test Result pass=0 fail=1
Patrick Williams20f38712022-12-08 06:18:26 -0600336 if testcase.status == "PASS":
George Keishing9fbdf792016-10-18 06:16:09 -0500337 l_test_result = 0
George Keishingc6f90c52023-02-16 03:09:25 -0600338 elif testcase.status == "SKIP":
339 # Skipped test result should not be mark pass or fail.
340 continue
George Keishing9fbdf792016-10-18 06:16:09 -0500341 else:
342 l_test_result = 1
343
George Keishing74777bd2017-02-07 01:43:38 -0600344 # Format datetime from robot output.xml to "%Y-%m-%d-%H-%M-%S"
345 l_stime = xml_to_csv_time(testcase.starttime)
346 l_etime = xml_to_csv_time(testcase.endtime)
George Keishing9fbdf792016-10-18 06:16:09 -0500347 # Data Sequence: test_start,test_end,subsys,test_type,
George Keishing74777bd2017-02-07 01:43:38 -0600348 # test_result,test_name,pse_rel,driver,
George Keishing360db632018-09-06 12:01:28 -0500349 # env,proc,platform_type,test_func_area,
Patrick Williams20f38712022-12-08 06:18:26 -0600350 l_data = [
351 l_stime,
352 l_etime,
353 subsystem,
354 l_test_type,
355 l_test_result,
356 l_test_name,
357 l_pse_rel,
358 l_driver,
359 l_env,
360 l_proc,
361 l_platform_type,
362 l_func_area,
363 ]
George Keishing9fbdf792016-10-18 06:16:09 -0500364 l_csvlist.append(l_data)
365
George Keishinga96e27c2016-12-04 23:05:04 -0600366 # Open the file and write to the CSV file
George Keishingddfd7992023-02-16 03:39:47 -0600367 with open(l_csvfile, "w", encoding="utf8") as l_file:
368 l_writer = csv.writer(l_file, lineterminator="\n")
369 l_writer.writerows(l_csvlist)
370 l_file.close()
371
Steven Sombar3e82e3b2019-03-21 10:33:52 -0500372 # Set file permissions 666.
Patrick Williams20f38712022-12-08 06:18:26 -0600373 perm = (
374 stat.S_IRUSR
375 + stat.S_IWUSR
376 + stat.S_IRGRP
377 + stat.S_IWGRP
378 + stat.S_IROTH
379 + stat.S_IWOTH
380 )
Steven Sombar3e82e3b2019-03-21 10:33:52 -0500381 os.chmod(l_csvfile, perm)
George Keishing9fbdf792016-10-18 06:16:09 -0500382
383
George Keishing74777bd2017-02-07 01:43:38 -0600384def xml_to_csv_time(xml_datetime):
385 r"""
386 Convert the time from %Y%m%d %H:%M:%S.%f format to %Y-%m-%d-%H-%M-%S format
387 and return it.
388
manasarm5dedfaf2018-02-07 14:54:54 +0530389 Description of argument(s):
Sridevi Rameshbe2b77d2025-03-17 00:50:40 -0500390 xml_datetime The date in the following format: %Y%m%d
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -0500391 %H:%M:%S.%f (This is the format
392 typically found in an XML file.)
George Keishing74777bd2017-02-07 01:43:38 -0600393
394 The date returned will be in the following format: %Y-%m-%d-%H-%M-%S
395 """
manasarm5dedfaf2018-02-07 14:54:54 +0530396
George Keishing74777bd2017-02-07 01:43:38 -0600397 # 20170206 05:05:19.342
George Keishing937fe3c2019-10-29 11:20:34 -0500398 l_str = datetime.datetime.strptime(xml_datetime, "%Y%m%d %H:%M:%S.%f")
George Keishing74777bd2017-02-07 01:43:38 -0600399 # 2017-02-06-05-05-19
400 l_str = l_str.strftime("%Y-%m-%d-%H-%M-%S")
401 return str(l_str)
402
403
404def get_system_details(xml_file_path):
405 r"""
406 Get the system data from output.xml generated by robot and return it.
Gunnar Mills28e403b2017-10-25 16:16:38 -0500407 The list returned will be in the following order: [driver,platform]
George Keishing74777bd2017-02-07 01:43:38 -0600408
manasarm5dedfaf2018-02-07 14:54:54 +0530409 Description of argument(s):
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -0500410 xml_file_path The relative or absolute path to the
411 output.xml file.
George Keishing74777bd2017-02-07 01:43:38 -0600412 """
manasarm5dedfaf2018-02-07 14:54:54 +0530413
manasarme4f79c92018-02-22 13:02:46 +0530414 bmc_version_id = ""
George Keishing74777bd2017-02-07 01:43:38 -0600415 bmc_platform = ""
George Keishingddfd7992023-02-16 03:39:47 -0600416 with open(xml_file_path, "rt", encoding="utf-8") as output:
George Keishing74777bd2017-02-07 01:43:38 -0600417 tree = ElementTree.parse(output)
418
Patrick Williams20f38712022-12-08 06:18:26 -0600419 for node in tree.iter("msg"):
George Keishing74777bd2017-02-07 01:43:38 -0600420 # /etc/os-release output is logged in the XML as msg
George Keishing360db632018-09-06 12:01:28 -0500421 # Example: ${output} = VERSION_ID="v1.99.2-71-gbc49f79"
Patrick Williams20f38712022-12-08 06:18:26 -0600422 if "${output} = VERSION_ID=" in node.text:
George Keishing360db632018-09-06 12:01:28 -0500423 # Get BMC version (e.g. v1.99.1-96-g2a46570)
manasarme4f79c92018-02-22 13:02:46 +0530424 bmc_version_id = str(node.text.split("VERSION_ID=")[1])[1:-1]
George Keishing74777bd2017-02-07 01:43:38 -0600425
426 # Platform is logged in the XML as msg.
427 # Example: ${bmc_model} = Witherspoon BMC
Patrick Williams20f38712022-12-08 06:18:26 -0600428 if "${bmc_model} = " in node.text:
George Keishing74777bd2017-02-07 01:43:38 -0600429 bmc_platform = node.text.split(" = ")[1]
430
manasarme4f79c92018-02-22 13:02:46 +0530431 print_vars(bmc_version_id, bmc_platform)
432 return [str(bmc_version_id), str(bmc_platform)]
George Keishing74777bd2017-02-07 01:43:38 -0600433
434
manasarm5dedfaf2018-02-07 14:54:54 +0530435def main():
George Keishingddfd7992023-02-16 03:39:47 -0600436 r"""
437 Main caller.
438 """
439
manasarm5dedfaf2018-02-07 14:54:54 +0530440 if not gen_get_options(parser, stock_list):
441 return False
George Keishing9fbdf792016-10-18 06:16:09 -0500442
manasarm5dedfaf2018-02-07 14:54:54 +0530443 if not validate_parms():
444 return False
George Keishing9fbdf792016-10-18 06:16:09 -0500445
manasarm5dedfaf2018-02-07 14:54:54 +0530446 qprint_pgm_header()
George Keishing9fbdf792016-10-18 06:16:09 -0500447
Patrick Williams20f38712022-12-08 06:18:26 -0600448 parse_output_xml(
449 source, dest, version_id, platform, level, test_phase, processor
450 )
George Keishing9fbdf792016-10-18 06:16:09 -0500451
manasarm5dedfaf2018-02-07 14:54:54 +0530452 return True
453
454
455# Main
456
457if not main():
George Keishingddfd7992023-02-16 03:39:47 -0600458 sys.exit(1)