blob: 7e59e837f55e46795e0bcde5fa8b49d29b63e23b [file] [log] [blame]
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright 2017 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""This script uploads CTS Verifier results to CTS and APFE gs:// buckets."""
from lib.upload_utils import UploadUtils
from xml.dom import minidom
import argparse
import getopt
import os.path
import sys
class UploadCtsVerifier(UploadUtils):
"""Helps upload CTS-V results to gs:// buckets.
Prints CTS-V test results with their pass/fail status to terminal.
Prints gsutil links to the terminal to upload CTS-V results to gs:// buckets
to get the results in the tooling.
Attributes:
build_mismatch_exist: A boolean indicating if build mismatch exists.
failed_tests_exist: A boolean indicating if failed tests exist.
valid_files_exist: A boolean indicating if any valid file with the
correct build version exists.
untested_tests_exist: A boolean indicating if untested tests exist.
test_board_name_list: List of test board names.
"""
def __init__(self):
super(UploadCtsVerifier, self).__init__()
self.build_mismatch_exist = False
self.failed_tests_exist = False
self.valid_files_exist = False
self.untested_tests_exist = False
self.test_board_name_list = []
def PrintBuildInfoList(self):
"""Sorts build information by build board and prints to the terminal."""
self.build_info_list.sort(key=lambda x: x[1])
for item in self.build_info_list:
if item[1] not in self.test_board_name_list:
title_msg = 'List of files for %s' % item[1]
table_column_header = self.TABLE_HEADER_CTSV
print(self.BOLD +
self.C_PURPLE +
title_msg +
self.BOLD +
self.C_END)
print(self.BOLD +
self.C_BLACK +
table_column_header +
self.BOLD +
self.C_END)
self.test_board_name_list.append(item[1])
self.PrintFormattedDataCtsv(item)
print('\n')
def PrintGsutilLinks(self, dir_path):
"""Prints gsutil links to upload results to CTS dashboard and APFE buckets.
CTS-V APFE :board.board for non-unibuild.
CTS-V APFE :model.board for unibuild.
Appended veyron_ and auron_ to model name for veyron and auron boards.
Sample:auron_yuna.auron_yuna-release,veyron_mighty.veyron_mighty-release
Args:
dir_path: Results directory path.
"""
for item in self.build_info_list:
if item[1].startswith('veyron') or item[1].startswith('auron'):
gsutil_msg_apfe = ('gsutil cp -r {0}/{1}.{2}-release/ '
'gs://chromeos-ctsverifier-results/'
.format(dir_path, item[1], item[1]))
else:
gsutil_msg_apfe = ('gsutil cp -r {0}/{1}.{2}-release/ '
'gs://chromeos-ctsverifier-results/'
.format(dir_path, item[2], item[1]))
gsutil_msg_cts = ('gsutil cp -r {0}/{1}_{2}/ '
'gs://chromeos-cts-results/ctsVerifier'
.format(dir_path, item[3], item[1]))
print(self.BOLD +
self.C_PURPLE +
gsutil_msg_cts +
self.BOLD +
self.C_END)
print(self.BOLD +
self.C_PURPLE +
gsutil_msg_apfe +
self.BOLD +
self.C_END)
def PrintIfAllTestsPassed(self):
"""Print message to terminal if all tests have passed."""
if not self.failed_tests_exist and self.build_mismatch_file_count == 0:
print('All Cts Verifier Tests passed!')
def PrintFailedTestResults(self, tests):
"""Prints failed results if any to the terminal.
Args:
tests: CTS Verifier Test Results.
"""
test_title = ' '
result = ' '
for test in tests:
test_title = test.getAttribute('name')
result = test.getAttribute('result')
if result == 'fail' or result == 'not-executed':
self.failed_tests_exist = True
print('Test Title:%s, Result:%s' % (test_title, result))
print('\n')
def ParseXmlFile(self, abs_input_file_path, dir_path):
"""Gets build information from CTS Verifier xml file.
Parses the CTS Verifier Xml File to obtain Build Information such as
basename, build_board, build_id, suite_version.
Args:
abs_input_file_path: Absolute Input file path.
Eg: ~/Downloads/ctsv/2017.09.21_17.13.04-
CTS_VERIFIER-google-relm-relm_cheets-R62-9901.20.0
dir_path: Results directory path.
Eg: ~/Downloads/Manual
Returns:
tests: CTS Verifier Test Results.
"""
test_result_filename_n_build = 'test_result.xml'
tag_list = self.GetXmlTagNamesCtsv()
build_version = tag_list[0]
result = tag_list[1]
suite_version = tag_list[2]
build_board = tag_list[3]
build_model = tag_list[4]
build_id_n = tag_list[5]
test = tag_list[6]
split_file_list = self.SplitFileName(abs_input_file_path)
basename = split_file_list[1]
full_base_name = os.path.join(dir_path, basename)
basename_xml_file = split_file_list[2]
absolute_base_xml_file = os.path.join(dir_path, basename_xml_file)
self.CopyFileToDestination(full_base_name,
test_result_filename_n_build,
dir_path,
basename_xml_file)
xml_doc = minidom.parse(absolute_base_xml_file)
build = xml_doc.getElementsByTagName(build_version)
verifier_info = xml_doc.getElementsByTagName(result)
suite_version = verifier_info[0].attributes[suite_version].value
build_board = build[0].attributes[build_board].value
build_model = build[0].attributes[build_model].value
build_id = build[0].attributes[build_id_n].value
tests = xml_doc.getElementsByTagName(test)
self.UpdateBuildInfoList(
[basename, build_board, build_model, build_id, suite_version])
return tests
def ProcessFilesToUpload(self, input_build_id, dir_path):
"""Process Files to Upload to CTS Verifier Bucket.
Parses the test_result.xml file to obtain build information.
Pushes valid files to appropriate folders to upload to CTS-V bucket.
Pushes invalid files to Obsolete Folder.
Print Build results to terminal.
Args:
input_build_id: Build ID for which results are to be uploaded.
dir_path: Results directory path.
"""
build_id = ' '
item = ' '
for the_file in os.listdir(dir_path):
if the_file.endswith('.zip'):
full_file = os.path.join(dir_path, the_file)
self.ExtractZipFile(full_file, dir_path)
tests = self.ParseXmlFile(the_file, dir_path)
for item in self.build_info_list:
build_id = item[3]
if build_id == input_build_id:
self.valid_files_exist = True
self.failed_tests_exist = False
self.CreateCtsvApfeFolder(full_file, dir_path)
self.CreateCtsFolder(full_file, dir_path)
self.PrintBuildInfoList()
self.PrintFailedTestResults(tests)
self.PrintIfAllTestsPassed()
else:
self.build_mismatch_exist = True
self.build_info_list.remove(item)
self.CreateObsoleteFolder(full_file, dir_path)
def main(argv):
"""Processes result files and prints gsutil links to upload CTS-V results.
Displays help message when script is called without expected arguments.
Displays Usage: upload_cts_verifier.py <build_id> <results_dir_path>
"""
parser = argparse.ArgumentParser()
parser.add_argument('build_id',
help='Usage: upload_cts_verifier.py'
'<build_id>'
'<results_dir_path>')
parser.add_argument('dir_path',
help='Usage: upload_cts_verifier.py'
'<build_id>'
'<results_dir_path>')
args = parser.parse_args()
input_build_id = args.build_id
dir_path = args.dir_path
if len(sys.argv) == 1:
parser.print_help()
sys.exit(1)
parser.parse_args()
try:
opts, args = getopt.getopt(argv, 'hb:', ['buildID='])
except getopt.GetoptError:
print('upload_cts_verifier.py <build_id> <results_dir_path>')
sys.exit(2)
ctsv = UploadCtsVerifier()
for opt in opts:
if opt == '-h':
ctsv.usage()
sys.exit()
ctsv.ProcessFilesToUpload(input_build_id, dir_path)
if ctsv.valid_files_exist is True:
ctsv.PrintGsutilLinks(dir_path)
if ctsv.build_mismatch_exist is True:
ctsv.PrintObsoleteFolderCount()
if __name__ == '__main__':
main(sys.argv[1:])