test_push.py revision ef1a5c0de1a2cfb039574f9d011d256114bda99a
17e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi#!/usr/bin/python 27e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi# 37e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi# Copyright (c) 2013 The Chromium OS Authors. All rights reserved. 47e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi# Use of this source code is governed by a BSD-style license that can be 57e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi# found in the LICENSE file. 67e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 77e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi"""Tool to validate code in prod branch before pushing to lab. 87e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 97e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan ShiThe script runs push_to_prod suite to verify code in prod branch is ready to be 107e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shipushed. Link to design document: 117e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shihttps://docs.google.com/a/google.com/document/d/1JMz0xS3fZRSHMpFkkKAL_rxsdbNZomhHbC3B8L71uuI/edit 127e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 137e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan ShiTo verify if prod branch can be pushed to lab, run following command in 147e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shichromeos-autotest.cbf server: 1552d9f1ff5cadba2828e64288afb5491122e3078dMichael Liang/usr/local/autotest/site_utils/test_push.py -e someone@company.com 167e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 177e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan ShiThe script uses latest stumpy canary build as test build by default. 187e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 197e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi""" 207e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 217e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shiimport argparse 227e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shiimport getpass 23ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shiimport multiprocessing 247e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shiimport os 257e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shiimport re 267e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shiimport subprocess 277e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shiimport sys 28ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shiimport time 29ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shiimport traceback 307e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shiimport urllib2 317e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 327e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shiimport common 33a8da7602ee0113004ef1b7213eab5599e3236ae7Dan Shitry: 34a8da7602ee0113004ef1b7213eab5599e3236ae7Dan Shi from autotest_lib.frontend import setup_django_environment 35a8da7602ee0113004ef1b7213eab5599e3236ae7Dan Shi from autotest_lib.frontend.afe import models 36a8da7602ee0113004ef1b7213eab5599e3236ae7Dan Shiexcept ImportError: 37a8da7602ee0113004ef1b7213eab5599e3236ae7Dan Shi # Unittest may not have Django database configured and will fail to import. 38a8da7602ee0113004ef1b7213eab5599e3236ae7Dan Shi pass 395fa602cbd7787ff604758f03b71da19b66263ca1Dan Shifrom autotest_lib.client.common_lib import global_config 407e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shifrom autotest_lib.server import site_utils 4147d3288e3ad2feba6c866ec369f2cfa8abb9346aDan Shifrom autotest_lib.server.cros import provision 427e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shifrom autotest_lib.server.cros.dynamic_suite import frontend_wrappers 437e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shifrom autotest_lib.server.cros.dynamic_suite import reporting 44a8da7602ee0113004ef1b7213eab5599e3236ae7Dan Shifrom autotest_lib.server.hosts import cros_host 455fa602cbd7787ff604758f03b71da19b66263ca1Dan Shifrom autotest_lib.site_utils import gmail_lib 4647d3288e3ad2feba6c866ec369f2cfa8abb9346aDan Shifrom autotest_lib.site_utils.suite_scheduler import constants 477e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 487e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan ShiCONFIG = global_config.global_config 497e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 507e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan ShiMAIL_FROM = 'chromeos-test@google.com' 515ba5d2e1433f180e2eaeac5721547e6f61ab30a7Dan ShiDEVSERVERS = CONFIG.get_config_value('CROS', 'dev_server', type=list, 525ba5d2e1433f180e2eaeac5721547e6f61ab30a7Dan Shi default=[]) 535ba5d2e1433f180e2eaeac5721547e6f61ab30a7Dan ShiBUILD_REGEX = '^R[\d]+-[\d]+\.[\d]+\.[\d]+$' 547e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan ShiRUN_SUITE_COMMAND = 'run_suite.py' 557e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan ShiPUSH_TO_PROD_SUITE = 'push_to_prod' 568f14391ed7dbbb0c8081d8e9a0ba60b7fa09ff4fJakob JuelichDUMMY_SUITE = 'dummy' 577e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan ShiAU_SUITE = 'paygen_au_canary' 587e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 596dddf60ffaf30337e17d393eb797f67f2419f02bFang DengSUITE_JOB_START_INFO_REGEX = ('^.*Created suite job:.*' 606dddf60ffaf30337e17d393eb797f67f2419f02bFang Deng 'tab_id=view_job&object_id=(\d+)$') 617e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 627e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi# Dictionary of test results keyed by test name regular expression. 637e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan ShiEXPECTED_TEST_RESULTS = {'^SERVER_JOB$': 'GOOD', 647e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi # This is related to dummy_Fail/control.dependency. 657e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 'dummy_Fail.dependency$': 'TEST_NA', 66dc9eb17ac97d5407a2ebce0510fe0311b3f18bfcDan Shi 'login_LoginSuccess.*': 'GOOD', 677e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 'platform_InstallTestImage_SERVER_JOB$': 'GOOD', 6847d3288e3ad2feba6c866ec369f2cfa8abb9346aDan Shi 'provision_AutoUpdate.double': 'GOOD', 697e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 'dummy_Pass.*': 'GOOD', 707e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 'dummy_Fail.Fail$': 'FAIL', 717e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 'dummy_Fail.RetryFail$': 'FAIL', 727e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 'dummy_Fail.RetrySuccess': 'GOOD', 737e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 'dummy_Fail.Error$': 'ERROR', 747e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 'dummy_Fail.Warn$': 'WARN', 757e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 'dummy_Fail.NAError$': 'TEST_NA', 767e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 'dummy_Fail.Crash$': 'GOOD', 777e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi } 787e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 798f14391ed7dbbb0c8081d8e9a0ba60b7fa09ff4fJakob JuelichEXPECTED_TEST_RESULTS_DUMMY = {'^SERVER_JOB$': 'GOOD', 808f14391ed7dbbb0c8081d8e9a0ba60b7fa09ff4fJakob Juelich 'dummy_Pass.*': 'GOOD', 818f14391ed7dbbb0c8081d8e9a0ba60b7fa09ff4fJakob Juelich 'dummy_Fail.Fail': 'FAIL', 828f14391ed7dbbb0c8081d8e9a0ba60b7fa09ff4fJakob Juelich 'dummy_Fail.Warn': 'WARN', 838f14391ed7dbbb0c8081d8e9a0ba60b7fa09ff4fJakob Juelich 'dummy_Fail.Crash': 'GOOD', 848f14391ed7dbbb0c8081d8e9a0ba60b7fa09ff4fJakob Juelich 'dummy_Fail.Error': 'ERROR', 858f14391ed7dbbb0c8081d8e9a0ba60b7fa09ff4fJakob Juelich 'dummy_Fail.NAError': 'TEST_NA',} 868f14391ed7dbbb0c8081d8e9a0ba60b7fa09ff4fJakob Juelich 877e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan ShiEXPECTED_TEST_RESULTS_AU = {'SERVER_JOB$': 'GOOD', 887e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 'autoupdate_EndToEndTest.paygen_au_canary_test_delta.*': 'GOOD', 897e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 'autoupdate_EndToEndTest.paygen_au_canary_test_full.*': 'GOOD', 907e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi } 917e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 927e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi# Anchor for the auto-filed bug for dummy_Fail tests. 937e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan ShiBUG_ANCHOR = 'TestFailure(push_to_prod,dummy_Fail.Fail,always fail)' 947e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 957e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan ShiURL_HOST = CONFIG.get_config_value('SERVER', 'hostname', type=str) 967e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan ShiURL_PATTERN = CONFIG.get_config_value('CROS', 'log_url_pattern', type=str) 977e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 98dc9eb17ac97d5407a2ebce0510fe0311b3f18bfcDan Shi# Some test could be missing from the test results for various reasons. Add 99dc9eb17ac97d5407a2ebce0510fe0311b3f18bfcDan Shi# such test in this list and explain the reason. 100dc9eb17ac97d5407a2ebce0510fe0311b3f18bfcDan ShiIGNORE_MISSING_TESTS = [ 101dc9eb17ac97d5407a2ebce0510fe0311b3f18bfcDan Shi # For latest build, npo_test_delta does not exist. 102dc9eb17ac97d5407a2ebce0510fe0311b3f18bfcDan Shi 'autoupdate_EndToEndTest.npo_test_delta.*', 103dc9eb17ac97d5407a2ebce0510fe0311b3f18bfcDan Shi # For trybot build, nmo_test_delta does not exist. 104dc9eb17ac97d5407a2ebce0510fe0311b3f18bfcDan Shi 'autoupdate_EndToEndTest.nmo_test_delta.*', 105dc9eb17ac97d5407a2ebce0510fe0311b3f18bfcDan Shi # Older build does not have login_LoginSuccess test in push_to_prod suite. 106dc9eb17ac97d5407a2ebce0510fe0311b3f18bfcDan Shi # TODO(dshi): Remove following lines after R41 is stable. 107dc9eb17ac97d5407a2ebce0510fe0311b3f18bfcDan Shi 'login_LoginSuccess'] 108dc9eb17ac97d5407a2ebce0510fe0311b3f18bfcDan Shi 1097e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi# Save all run_suite command output. 1107e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shirun_suite_output = [] 1117e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 1127e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shiclass TestPushException(Exception): 1137e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi """Exception to be raised when the test to push to prod failed.""" 1147e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi pass 1157e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 1165ba5d2e1433f180e2eaeac5721547e6f61ab30a7Dan Shi 1175ba5d2e1433f180e2eaeac5721547e6f61ab30a7Dan Shidef get_default_build(devserver=None, board='stumpy'): 1185ba5d2e1433f180e2eaeac5721547e6f61ab30a7Dan Shi """Get the default build to be used for test. 1195ba5d2e1433f180e2eaeac5721547e6f61ab30a7Dan Shi 1205ba5d2e1433f180e2eaeac5721547e6f61ab30a7Dan Shi @param devserver: devserver used to look for latest staged build. If value 1215ba5d2e1433f180e2eaeac5721547e6f61ab30a7Dan Shi is None, all devservers in config will be tried. 1225ba5d2e1433f180e2eaeac5721547e6f61ab30a7Dan Shi @param board: Name of board to be tested, default is stumpy. 1235ba5d2e1433f180e2eaeac5721547e6f61ab30a7Dan Shi @return: Build to be tested, e.g., stumpy-release/R36-5881.0.0 1245ba5d2e1433f180e2eaeac5721547e6f61ab30a7Dan Shi """ 1255ba5d2e1433f180e2eaeac5721547e6f61ab30a7Dan Shi LATEST_BUILD_URL_PATTERN = '%s/latestbuild?target=%s-release' 1265ba5d2e1433f180e2eaeac5721547e6f61ab30a7Dan Shi build = None 1275ba5d2e1433f180e2eaeac5721547e6f61ab30a7Dan Shi if not devserver: 1285ba5d2e1433f180e2eaeac5721547e6f61ab30a7Dan Shi for server in DEVSERVERS: 129ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi url = LATEST_BUILD_URL_PATTERN % (server, board) 130ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi build = urllib2.urlopen(url).read() 131ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi if build and re.match(BUILD_REGEX, build): 132ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi return '%s-release/%s' % (board, build) 1335ba5d2e1433f180e2eaeac5721547e6f61ab30a7Dan Shi 1345ba5d2e1433f180e2eaeac5721547e6f61ab30a7Dan Shi # If no devserver has any build staged for the given board, use the stable 1355ba5d2e1433f180e2eaeac5721547e6f61ab30a7Dan Shi # build in config. 1365ba5d2e1433f180e2eaeac5721547e6f61ab30a7Dan Shi build = CONFIG.get_config_value('CROS', 'stable_cros_version') 1375ba5d2e1433f180e2eaeac5721547e6f61ab30a7Dan Shi return '%s-release/%s' % (board, build) 1385ba5d2e1433f180e2eaeac5721547e6f61ab30a7Dan Shi 1395ba5d2e1433f180e2eaeac5721547e6f61ab30a7Dan Shi 1407e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shidef parse_arguments(): 1417e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi """Parse arguments for test_push tool. 1427e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 1437e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi @return: Parsed arguments. 1447e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 1457e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi """ 1467e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi parser = argparse.ArgumentParser() 1477e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi parser.add_argument('-b', '--board', dest='board', default='stumpy', 1487e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi help='Default is stumpy.') 1498f14391ed7dbbb0c8081d8e9a0ba60b7fa09ff4fJakob Juelich parser.add_argument('-sb', '--shard_board', dest='shard_board', 1508f14391ed7dbbb0c8081d8e9a0ba60b7fa09ff4fJakob Juelich default='quawks', 1518f14391ed7dbbb0c8081d8e9a0ba60b7fa09ff4fJakob Juelich help='Default is quawks.') 1527e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi parser.add_argument('-i', '--build', dest='build', default=None, 1537e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi help='Default is the latest canary build of given ' 1547e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 'board. Must be a canary build, otherwise AU test ' 1557e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 'will fail.') 1568f14391ed7dbbb0c8081d8e9a0ba60b7fa09ff4fJakob Juelich parser.add_argument('-si', '--shard_build', dest='shard_build', default=None, 1578f14391ed7dbbb0c8081d8e9a0ba60b7fa09ff4fJakob Juelich help='Default is the latest canary build of given ' 1588f14391ed7dbbb0c8081d8e9a0ba60b7fa09ff4fJakob Juelich 'board. Must be a canary build, otherwise AU test ' 1598f14391ed7dbbb0c8081d8e9a0ba60b7fa09ff4fJakob Juelich 'will fail.') 1607e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi parser.add_argument('-p', '--pool', dest='pool', default='bvt') 1617e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi parser.add_argument('-u', '--num', dest='num', type=int, default=3, 1627e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi help='Run on at most NUM machines.') 1637e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi parser.add_argument('-f', '--file_bugs', dest='file_bugs', default='True', 1647e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi help='File bugs on test failures. Must pass "True" or ' 1657e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi '"False" if used.') 1667e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi parser.add_argument('-e', '--email', dest='email', default=None, 1677e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi help='Email address for the notification to be sent to ' 1687e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 'after the script finished running.') 1697e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi parser.add_argument('-d', '--devserver', dest='devserver', 1705ba5d2e1433f180e2eaeac5721547e6f61ab30a7Dan Shi default=None, 1717e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi help='devserver to find what\'s the latest build.') 1727e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 1737e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi arguments = parser.parse_args(sys.argv[1:]) 1747e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 1757e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi # Get latest canary build as default build. 1767e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi if not arguments.build: 1775ba5d2e1433f180e2eaeac5721547e6f61ab30a7Dan Shi arguments.build = get_default_build(arguments.devserver, 1785ba5d2e1433f180e2eaeac5721547e6f61ab30a7Dan Shi arguments.board) 1798f14391ed7dbbb0c8081d8e9a0ba60b7fa09ff4fJakob Juelich if not arguments.shard_build: 1808f14391ed7dbbb0c8081d8e9a0ba60b7fa09ff4fJakob Juelich arguments.shard_build = get_default_build(arguments.devserver, 1818f14391ed7dbbb0c8081d8e9a0ba60b7fa09ff4fJakob Juelich arguments.shard_board) 1827e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 1837e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi return arguments 1847e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 1857e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 1868f14391ed7dbbb0c8081d8e9a0ba60b7fa09ff4fJakob Juelichdef do_run_suite(suite_name, arguments, use_shard=False): 1877e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi """Call run_suite to run a suite job, and return the suite job id. 1887e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 1897e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi The script waits the suite job to finish before returning the suite job id. 1907e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi Also it will echo the run_suite output to stdout. 1917e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 1927e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi @param suite_name: Name of a suite, e.g., dummy. 1937e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi @param arguments: Arguments for run_suite command. 1948f14391ed7dbbb0c8081d8e9a0ba60b7fa09ff4fJakob Juelich @param use_shard: If true, suite is scheduled for shard board. 1958f14391ed7dbbb0c8081d8e9a0ba60b7fa09ff4fJakob Juelich 1967e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi @return: Suite job ID. 1977e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 1987e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi """ 1998f14391ed7dbbb0c8081d8e9a0ba60b7fa09ff4fJakob Juelich if not use_shard: 2008f14391ed7dbbb0c8081d8e9a0ba60b7fa09ff4fJakob Juelich board = arguments.board 2018f14391ed7dbbb0c8081d8e9a0ba60b7fa09ff4fJakob Juelich build = arguments.build 2028f14391ed7dbbb0c8081d8e9a0ba60b7fa09ff4fJakob Juelich else: 2038f14391ed7dbbb0c8081d8e9a0ba60b7fa09ff4fJakob Juelich board = arguments.shard_board 2048f14391ed7dbbb0c8081d8e9a0ba60b7fa09ff4fJakob Juelich build = arguments.shard_build 2058f14391ed7dbbb0c8081d8e9a0ba60b7fa09ff4fJakob Juelich 20647d3288e3ad2feba6c866ec369f2cfa8abb9346aDan Shi # Remove cros-version label to force provision. 20747d3288e3ad2feba6c866ec369f2cfa8abb9346aDan Shi afe = frontend_wrappers.RetryingAFE(timeout_min=0.1, delay_sec=10) 20847d3288e3ad2feba6c866ec369f2cfa8abb9346aDan Shi hosts = afe.get_hosts(label=constants.Labels.BOARD_PREFIX+board) 20947d3288e3ad2feba6c866ec369f2cfa8abb9346aDan Shi for host in hosts: 21047d3288e3ad2feba6c866ec369f2cfa8abb9346aDan Shi for label in [l for l in host.labels 21147d3288e3ad2feba6c866ec369f2cfa8abb9346aDan Shi if l.startswith(provision.CROS_VERSION_PREFIX)]: 21247d3288e3ad2feba6c866ec369f2cfa8abb9346aDan Shi afe.run('host_remove_labels', id=host.id, labels=[label]) 21347d3288e3ad2feba6c866ec369f2cfa8abb9346aDan Shi 214ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi current_dir = os.path.dirname(os.path.realpath(__file__)) 215ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi cmd = [os.path.join(current_dir, RUN_SUITE_COMMAND), 2167e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi '-s', suite_name, 2178f14391ed7dbbb0c8081d8e9a0ba60b7fa09ff4fJakob Juelich '-b', board, 2188f14391ed7dbbb0c8081d8e9a0ba60b7fa09ff4fJakob Juelich '-i', build, 2197e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi '-p', arguments.pool, 2207e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi '-u', str(arguments.num), 2217e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi '-f', arguments.file_bugs] 2227e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 2237e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi suite_job_id = None 2247e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 2257e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, 2267e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi stderr=subprocess.STDOUT) 2277e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 2287e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi while True: 2297e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi line = proc.stdout.readline() 2307e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 2317e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi # Break when run_suite process completed. 2327e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi if not line and proc.poll() != None: 2337e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi break 2347e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi print line.rstrip() 2357e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi run_suite_output.append(line.rstrip()) 2367e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 2377e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi if not suite_job_id: 2387e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi m = re.match(SUITE_JOB_START_INFO_REGEX, line) 2397e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi if m and m.group(1): 2407e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi suite_job_id = int(m.group(1)) 2417e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 2427e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi if not suite_job_id: 2437e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi raise TestPushException('Failed to retrieve suite job ID.') 244a8da7602ee0113004ef1b7213eab5599e3236ae7Dan Shi 245a8da7602ee0113004ef1b7213eab5599e3236ae7Dan Shi print 'Suite job %s is completed.' % suite_job_id 2467e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi return suite_job_id 2477e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 2487e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 249a8da7602ee0113004ef1b7213eab5599e3236ae7Dan Shidef check_dut_image(build, suite_job_id): 250a8da7602ee0113004ef1b7213eab5599e3236ae7Dan Shi """Confirm all DUTs used for the suite are imaged to expected build. 251a8da7602ee0113004ef1b7213eab5599e3236ae7Dan Shi 252a8da7602ee0113004ef1b7213eab5599e3236ae7Dan Shi @param build: Expected build to be imaged. 253a8da7602ee0113004ef1b7213eab5599e3236ae7Dan Shi @param suite_job_id: job ID of the suite job. 254a8da7602ee0113004ef1b7213eab5599e3236ae7Dan Shi @raise TestPushException: If a DUT does not have expected build imaged. 255a8da7602ee0113004ef1b7213eab5599e3236ae7Dan Shi """ 256a8da7602ee0113004ef1b7213eab5599e3236ae7Dan Shi print 'Checking image installed in DUTs...' 257a8da7602ee0113004ef1b7213eab5599e3236ae7Dan Shi job_ids = [job.id for job in 258a8da7602ee0113004ef1b7213eab5599e3236ae7Dan Shi models.Job.objects.filter(parent_job_id=suite_job_id)] 259a8da7602ee0113004ef1b7213eab5599e3236ae7Dan Shi hqes = [models.HostQueueEntry.objects.filter(job_id=job_id)[0] 260a8da7602ee0113004ef1b7213eab5599e3236ae7Dan Shi for job_id in job_ids] 261a8da7602ee0113004ef1b7213eab5599e3236ae7Dan Shi hostnames = set([hqe.host.hostname for hqe in hqes]) 262a8da7602ee0113004ef1b7213eab5599e3236ae7Dan Shi for hostname in hostnames: 263a8da7602ee0113004ef1b7213eab5599e3236ae7Dan Shi host = cros_host.CrosHost(hostname) 264a8da7602ee0113004ef1b7213eab5599e3236ae7Dan Shi found_build = host.get_build() 265a8da7602ee0113004ef1b7213eab5599e3236ae7Dan Shi if found_build != build: 266a8da7602ee0113004ef1b7213eab5599e3236ae7Dan Shi raise TestPushException('DUT is not imaged properly. Host %s has ' 267a8da7602ee0113004ef1b7213eab5599e3236ae7Dan Shi 'build %s, while build %s is expected.' % 268a8da7602ee0113004ef1b7213eab5599e3236ae7Dan Shi (hostname, found_build, build)) 269a8da7602ee0113004ef1b7213eab5599e3236ae7Dan Shi 270a8da7602ee0113004ef1b7213eab5599e3236ae7Dan Shi 2718f14391ed7dbbb0c8081d8e9a0ba60b7fa09ff4fJakob Juelichdef test_suite(suite_name, expected_results, arguments, use_shard=False): 2727e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi """Call run_suite to start a suite job and verify results. 2737e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 2747e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi @param suite_name: Name of a suite, e.g., dummy 2757e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi @param expected_results: A dictionary of test name to test result. 2767e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi @param arguments: Arguments for run_suite command. 2778f14391ed7dbbb0c8081d8e9a0ba60b7fa09ff4fJakob Juelich @param use_shard: If true, suite is scheduled for shard board. 2787e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi """ 2798f14391ed7dbbb0c8081d8e9a0ba60b7fa09ff4fJakob Juelich suite_job_id = do_run_suite(suite_name, arguments, use_shard) 2807e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 281a8da7602ee0113004ef1b7213eab5599e3236ae7Dan Shi # Confirm all DUTs used for the suite are imaged to expected build. 2828f14391ed7dbbb0c8081d8e9a0ba60b7fa09ff4fJakob Juelich # hqe.host_id for jobs running in shard is not synced back to master db, 2838f14391ed7dbbb0c8081d8e9a0ba60b7fa09ff4fJakob Juelich # therefore, skip verifying dut build for jobs running in shard. 2848f14391ed7dbbb0c8081d8e9a0ba60b7fa09ff4fJakob Juelich if suite_name != AU_SUITE and not use_shard: 285a8da7602ee0113004ef1b7213eab5599e3236ae7Dan Shi check_dut_image(arguments.build, suite_job_id) 286a8da7602ee0113004ef1b7213eab5599e3236ae7Dan Shi 2877e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi # Find all tests and their status 288a8da7602ee0113004ef1b7213eab5599e3236ae7Dan Shi print 'Comparing test results...' 2897e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi TKO = frontend_wrappers.RetryingTKO(timeout_min=0.1, delay_sec=10) 2907e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi test_views = site_utils.get_test_views_from_tko(suite_job_id, TKO) 2917e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 2927e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi mismatch_errors = [] 2937e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi extra_test_errors = [] 2947e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 2957e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi found_keys = set() 2967e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi for test_name,test_status in test_views.items(): 2977e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi print "%s%s" % (test_name.ljust(30), test_status) 2987e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi test_found = False 2997e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi for key,val in expected_results.items(): 3007e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi if re.search(key, test_name): 3017e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi test_found = True 3027e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi found_keys.add(key) 3037e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi # TODO(dshi): result for this test is ignored until servo is 3047e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi # added to a host accessible by cbf server (crbug.com/277109). 3057e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi if key == 'platform_InstallTestImage_SERVER_JOB$': 3067e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi continue 3077e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi if val != test_status: 3087e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi error = ('%s Expected: [%s], Actual: [%s]' % 3097e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi (test_name, val, test_status)) 3107e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi mismatch_errors.append(error) 3117e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi if not test_found: 3127e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi extra_test_errors.append(test_name) 3137e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 3147e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi missing_test_errors = set(expected_results.keys()) - found_keys 315dc9eb17ac97d5407a2ebce0510fe0311b3f18bfcDan Shi for exception in IGNORE_MISSING_TESTS: 316dc9eb17ac97d5407a2ebce0510fe0311b3f18bfcDan Shi try: 317dc9eb17ac97d5407a2ebce0510fe0311b3f18bfcDan Shi missing_test_errors.remove(exception) 318dc9eb17ac97d5407a2ebce0510fe0311b3f18bfcDan Shi except KeyError: 319dc9eb17ac97d5407a2ebce0510fe0311b3f18bfcDan Shi pass 320dc9eb17ac97d5407a2ebce0510fe0311b3f18bfcDan Shi 3217e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi summary = [] 3227e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi if mismatch_errors: 3237e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi summary.append(('Results of %d test(s) do not match expected ' 3247e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 'values:') % len(mismatch_errors)) 3257e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi summary.extend(mismatch_errors) 3267e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi summary.append('\n') 3277e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 3287e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi if extra_test_errors: 3297e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi summary.append('%d test(s) are not expected to be run:' % 3307e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi len(extra_test_errors)) 3317e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi summary.extend(extra_test_errors) 3327e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi summary.append('\n') 3337e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 3347e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi if missing_test_errors: 3357e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi summary.append('%d test(s) are missing from the results:' % 3367e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi len(missing_test_errors)) 3377e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi summary.extend(missing_test_errors) 3387e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi summary.append('\n') 3397e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 3407e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi # Test link to log can be loaded. 3417e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi job_name = '%s-%s' % (suite_job_id, getpass.getuser()) 3427e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi log_link = URL_PATTERN % (URL_HOST, job_name) 3437e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi try: 3447e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi urllib2.urlopen(log_link).read() 3457e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi except urllib2.URLError: 3467e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi summary.append('Failed to load page for link to log: %s.' % log_link) 3477e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 3487e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi if summary: 3497e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi raise TestPushException('\n'.join(summary)) 3507e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 3517e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 352ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shidef test_suite_wrapper(queue, suite_name, expected_results, arguments, 353ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi use_shard=False): 354ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi """Wrapper to call test_suite. Handle exception and pipe it to parent 355ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi process. 356ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi 357ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi @param queue: Queue to save exception to be accessed by parent process. 358ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi @param suite_name: Name of a suite, e.g., dummy 359ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi @param expected_results: A dictionary of test name to test result. 360ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi @param arguments: Arguments for run_suite command. 361ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi @param use_shard: If true, suite is scheduled for shard board. 362ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi """ 363ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi try: 364ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi test_suite(suite_name, expected_results, arguments, use_shard) 365ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi except: 366ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi # Store the whole exc_info leads to a PicklingError. 367ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi except_type, except_value, tb = sys.exc_info() 368ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi queue.put((except_type, except_value, traceback.extract_tb(tb))) 369ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi 370ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi 3717e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shidef close_bug(): 3727e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi """Close all existing bugs filed for dummy_Fail. 3737e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 3747e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi @return: A list of issue ids to be used in check_bug_filed_and_deduped. 3757e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi """ 3767e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi old_issue_ids = [] 3777e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi reporter = reporting.Reporter() 3787e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi while True: 3797e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi issue = reporter.find_issue_by_marker(BUG_ANCHOR) 3807e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi if not issue: 3817e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi return old_issue_ids 3827e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi if issue.id in old_issue_ids: 3837e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi raise TestPushException('Failed to close issue %d' % issue.id) 3847e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi old_issue_ids.append(issue.id) 3857e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi reporter.modify_bug_report(issue.id, 3867e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi comment='Issue closed by test_push script.', 3877e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi label_update='', 3887e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi status='WontFix') 3897e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 3907e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 3917e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shidef check_bug_filed_and_deduped(old_issue_ids): 3927e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi """Confirm bug related to dummy_Fail was filed and deduped. 3937e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 3947e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi @param old_issue_ids: A list of issue ids that was closed earlier. id of the 3957e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi new issue must be not in this list. 3967e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi @raise TestPushException: If auto bug file failed to create a new issue or 3977e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi dedupe multiple failures. 3987e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi """ 3997e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi reporter = reporting.Reporter() 4007e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi issue = reporter.find_issue_by_marker(BUG_ANCHOR) 4017e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi if not issue: 4027e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi raise TestPushException('Auto bug file failed. Unable to locate bug ' 4037e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 'with marker %s' % BUG_ANCHOR) 4047e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi if old_issue_ids and issue.id in old_issue_ids: 4057e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi raise TestPushException('Auto bug file failed to create a new issue. ' 4067e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 'id of the old issue found is %d.' % issue.id) 4077e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi if not ('%s2' % reporter.AUTOFILED_COUNT) in issue.labels: 4087e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi raise TestPushException(('Auto bug file failed to dedupe for issue %d ' 4097e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 'with labels of %s.') % 4107e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi (issue.id, issue.labels)) 4117e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi # Close the bug, and do the search again, which should return None. 4127e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi reporter.modify_bug_report(issue.id, 4137e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi comment='Issue closed by test_push script.', 4147e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi label_update='', 4157e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi status='WontFix') 4167e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi second_issue = reporter.find_issue_by_marker(BUG_ANCHOR) 4177e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi if second_issue: 4187e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi ids = '%d, %d' % (issue.id, second_issue.id) 4197e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi raise TestPushException(('Auto bug file failed. Multiple issues (%s) ' 4207e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 'filed with marker %s') % (ids, BUG_ANCHOR)) 4217e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi print 'Issue %d was filed and deduped successfully.' % issue.id 4227e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 4237e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 424ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shidef check_queue(queue): 425ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi """Check the queue for any exception being raised. 426ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi 427ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi @param queue: Queue used to store exception for parent process to access. 428ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi @raise: Any exception found in the queue. 429ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi """ 430ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi if queue.empty(): 431ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi return 432ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi exc_info = queue.get() 433ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi # Raise the exception with original backtrace. 434ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi print 'Original stack trace of the exception:\n%s' % exc_info[2] 435ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi raise exc_info[0](exc_info[1]) 436ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi 437ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi 4387e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shidef main(): 4397e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi """Entry point for test_push script.""" 4407e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi arguments = parse_arguments() 4417e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 4427e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi try: 4437e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi # Close existing bugs. New bug should be filed in dummy_Fail test. 4447e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi old_issue_ids = close_bug() 4457e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 446ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi queue = multiprocessing.Queue() 447ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi 448ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi push_to_prod_suite = multiprocessing.Process( 449ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi target=test_suite_wrapper, 450ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi args=(queue, PUSH_TO_PROD_SUITE, EXPECTED_TEST_RESULTS, 451ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi arguments)) 452ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi push_to_prod_suite.start() 4538f14391ed7dbbb0c8081d8e9a0ba60b7fa09ff4fJakob Juelich 4547e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi # TODO(dshi): Remove following line after crbug.com/267644 is fixed. 4557e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi # Also, merge EXPECTED_TEST_RESULTS_AU to EXPECTED_TEST_RESULTS 456ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi au_suite = multiprocessing.Process( 457ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi target=test_suite_wrapper, 458ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi args=(queue, AU_SUITE, EXPECTED_TEST_RESULTS_AU, 459ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi arguments)) 460ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi au_suite.start() 461ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi 462ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi shard_suite = multiprocessing.Process( 463ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi target=test_suite_wrapper, 464ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi args=(queue, DUMMY_SUITE, EXPECTED_TEST_RESULTS_DUMMY, 465ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi arguments, True)) 466ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi shard_suite.start() 467ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi 468ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi bug_filing_checked = False 469ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi while (push_to_prod_suite.is_alive() or au_suite.is_alive() or 470ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi shard_suite.is_alive()): 471ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi check_queue(queue) 472ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi # Check bug filing results to fail early if bug filing failed. 473ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi if not bug_filing_checked and not push_to_prod_suite.is_alive(): 474ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi check_bug_filed_and_deduped(old_issue_ids) 475ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi bug_filing_checked = True 476ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi time.sleep(5) 477ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi 478ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi check_queue(queue) 479ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi 480ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi push_to_prod_suite.join() 481ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi au_suite.join() 482ef1a5c0de1a2cfb039574f9d011d256114bda99aDan Shi shard_suite.join() 4837e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi except Exception as e: 4847e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi print 'Test for pushing to prod failed:\n' 4857e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi print str(e) 4867e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi # Send out email about the test failure. 4877e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi if arguments.email: 4885fa602cbd7787ff604758f03b71da19b66263ca1Dan Shi gmail_lib.send_email( 4895fa602cbd7787ff604758f03b71da19b66263ca1Dan Shi arguments.email, 4905fa602cbd7787ff604758f03b71da19b66263ca1Dan Shi 'Test for pushing to prod failed. Do NOT push!', 4915fa602cbd7787ff604758f03b71da19b66263ca1Dan Shi ('Errors occurred during the test:\n\n%s\n\n' % str(e) + 4925fa602cbd7787ff604758f03b71da19b66263ca1Dan Shi 'run_suite output:\n\n%s' % '\n'.join(run_suite_output))) 4937e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi raise 4947e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 4957e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi message = ('\nAll tests are completed successfully, prod branch is ready to' 4967e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi ' be pushed.') 4977e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi print message 4987e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi # Send out email about test completed successfully. 4997e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi if arguments.email: 5005fa602cbd7787ff604758f03b71da19b66263ca1Dan Shi gmail_lib.send_email( 5015fa602cbd7787ff604758f03b71da19b66263ca1Dan Shi arguments.email, 5025fa602cbd7787ff604758f03b71da19b66263ca1Dan Shi 'Test for pushing to prod completed successfully', 5035fa602cbd7787ff604758f03b71da19b66263ca1Dan Shi message) 5047e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 5057e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi 5067e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shiif __name__ == '__main__': 5077e04fa8cf1f07512f52870cf4bffd9f8b0801088Dan Shi sys.exit(main()) 508