From efac5a99cbdd946a2f6e5ca7d02baccfc4c131d9 Mon Sep 17 00:00:00 2001 From: Greg Thompson Date: Wed, 6 Apr 2022 09:59:13 +0000 Subject: [PATCH] Revert "[code-health] Run mini_installer tests using python3" This reverts commit 30b9722ff42b244014adbb4fe5dd3028143fe824. Reason for revert: broke continuous builds. Original change's description: > [code-health] Run mini_installer tests using python3 > > Bug: 941669 > Cq-Include-Trybots: luci.chrome.try:win-chrome,win64-chrome > Change-Id: Ifcad5bb5a157c90c591fa77ed5260c7f91749ab0 > Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3561093 > Reviewed-by: Ben Pastene > Reviewed-by: Takuto Ikuta > Reviewed-by: Greg Thompson > Commit-Queue: Fabrice de Gans > Cr-Commit-Position: refs/heads/main@{#989048} Bug: 941669 Change-Id: Id0b280092c1979aa0eb71d228eed97c10af9549f Cq-Include-Trybots: luci.chrome.try:win-chrome,win64-chrome No-Presubmit: true No-Tree-Checks: true No-Try: true Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3574563 Auto-Submit: Greg Thompson Bot-Commit: Rubber Stamper Reviewed-by: Fabian Sommer Commit-Queue: Fabian Sommer Owners-Override: Fabian Sommer Cr-Commit-Position: refs/heads/main@{#989353} --- chrome/test/mini_installer/BUILD.gn | 1 + chrome/test/mini_installer/PRESUBMIT.py | 4 +- chrome/test/mini_installer/chrome_helper.py | 4 +- .../test/mini_installer/config/config.config | 32 ++++---- chrome/test/mini_installer/create_zip.py | 4 +- chrome/test/mini_installer/installer_test.py | 55 +++++++++----- chrome/test/mini_installer/launch_chrome.py | 1 - chrome/test/mini_installer/property_walker.py | 4 +- chrome/test/mini_installer/quit_chrome.py | 1 - .../mini_installer/registry_operations.py | 73 +++++++++---------- .../run_mini_installer_tests.py | 4 +- .../test_chrome_with_chromedriver.py | 20 ++++- .../test/mini_installer/uninstall_chrome.py | 23 +++--- chrome/test/mini_installer/update_lastrun.py | 16 ++-- .../test/mini_installer/variable_expander.py | 9 +-- testing/buildbot/gn_isolate_map.pyl | 1 + 16 files changed, 135 insertions(+), 117 deletions(-) mode change 100755 => 100644 chrome/test/mini_installer/launch_chrome.py mode change 100755 => 100644 chrome/test/mini_installer/quit_chrome.py mode change 100755 => 100644 chrome/test/mini_installer/test_chrome_with_chromedriver.py mode change 100755 => 100644 chrome/test/mini_installer/uninstall_chrome.py diff --git a/chrome/test/mini_installer/BUILD.gn b/chrome/test/mini_installer/BUILD.gn index a855ffaf8369d0..deffc22b8b43e9 100644 --- a/chrome/test/mini_installer/BUILD.gn +++ b/chrome/test/mini_installer/BUILD.gn @@ -65,6 +65,7 @@ if (is_win) { "//third_party/catapult/third_party/typ", ] data = [ + "//third_party/webdriver/pylib/", "//testing/scripts/", "//third_party/depot_tools/download_from_google_storage.py", "//third_party/depot_tools/gsutil.py", diff --git a/chrome/test/mini_installer/PRESUBMIT.py b/chrome/test/mini_installer/PRESUBMIT.py index 15a67fb365ae1f..8736749f166534 100644 --- a/chrome/test/mini_installer/PRESUBMIT.py +++ b/chrome/test/mini_installer/PRESUBMIT.py @@ -11,9 +11,7 @@ def CommonChecks(input_api, output_api): - return input_api.canned_checks.RunPylint(input_api, - output_api, - version='2.7') + return input_api.canned_checks.RunPylint(input_api, output_api) def CheckChangeOnUpload(input_api, output_api): diff --git a/chrome/test/mini_installer/chrome_helper.py b/chrome/test/mini_installer/chrome_helper.py index fd1f7c042d75a1..8549471c703fb3 100644 --- a/chrome/test/mini_installer/chrome_helper.py +++ b/chrome/test/mini_installer/chrome_helper.py @@ -99,7 +99,7 @@ def GetBrowserProcess(chrome_processes): |chrome_processes|. """ # Find the one whose parent isn't a chrome.exe process. - for process in chrome_processes.values(): + for process in chrome_processes.itervalues(): try: if get_process_ppid(process) not in chrome_processes: return process @@ -113,7 +113,7 @@ def GetBrowserProcess(chrome_processes): process = GetBrowserProcess(chrome_processes) if not process: # Pick any process to wait on if no top-level parent was found. - process = next(chrome_processes.values()) + process = next(chrome_processes.itervalues()) if process.is_running(): LOGGER.info('Waiting on %s for %s %s processes to exit' % (str(process), len(chrome_processes), diff --git a/chrome/test/mini_installer/config/config.config b/chrome/test/mini_installer/config/config.config index 680b787cb3ebf4..b0f97f1fd3e5ea 100644 --- a/chrome/test/mini_installer/config/config.config +++ b/chrome/test/mini_installer/config/config.config @@ -215,15 +215,15 @@ ], "actions": [ ["test_chrome_with_chromedriver_user", - "\"$PYTHON_INTERPRETER\" test_chrome_with_chromedriver.py --chromedriver-path=\"$CHROMEDRIVER_PATH\" $QUIET $OUTPUT_DIR \"$LOCAL_APPDATA\\$CHROME_DIR\\Application\\chrome.exe\""], + "python test_chrome_with_chromedriver.py --chromedriver-path=\"$CHROMEDRIVER_PATH\" $QUIET $OUTPUT_DIR \"$LOCAL_APPDATA\\$CHROME_DIR\\Application\\chrome.exe\""], ["test_chrome_with_chromedriver_system", - "\"$PYTHON_INTERPRETER\" test_chrome_with_chromedriver.py --chromedriver-path=\"$CHROMEDRIVER_PATH\" $QUIET $OUTPUT_DIR \"$PROGRAM_FILES\\$CHROME_DIR\\Application\\chrome.exe\""], + "python test_chrome_with_chromedriver.py --chromedriver-path=\"$CHROMEDRIVER_PATH\" $QUIET $OUTPUT_DIR \"$PROGRAM_FILES\\$CHROME_DIR\\Application\\chrome.exe\""], ["test_chrome_with_chromedriver_beta", - "\"$PYTHON_INTERPRETER\" test_chrome_with_chromedriver.py --chromedriver-path=\"$CHROMEDRIVER_PATH\" $QUIET $OUTPUT_DIR \"$LOCAL_APPDATA\\$CHROME_DIR_BETA\\Application\\chrome.exe\""], + "python test_chrome_with_chromedriver.py --chromedriver-path=\"$CHROMEDRIVER_PATH\" $QUIET $OUTPUT_DIR \"$LOCAL_APPDATA\\$CHROME_DIR_BETA\\Application\\chrome.exe\""], ["test_chrome_with_chromedriver_canary", - "\"$PYTHON_INTERPRETER\" test_chrome_with_chromedriver.py --chromedriver-path=\"$CHROMEDRIVER_PATH\" $QUIET $OUTPUT_DIR \"$LOCAL_APPDATA\\$CHROME_DIR_SXS\\Application\\chrome.exe\""], + "python test_chrome_with_chromedriver.py --chromedriver-path=\"$CHROMEDRIVER_PATH\" $QUIET $OUTPUT_DIR \"$LOCAL_APPDATA\\$CHROME_DIR_SXS\\Application\\chrome.exe\""], ["test_chrome_with_chromedriver_dev", - "\"$PYTHON_INTERPRETER\" test_chrome_with_chromedriver.py --chromedriver-path=\"$CHROMEDRIVER_PATH\" $QUIET $OUTPUT_DIR \"$LOCAL_APPDATA\\$CHROME_DIR_DEV\\Application\\chrome.exe\""], + "python test_chrome_with_chromedriver.py --chromedriver-path=\"$CHROMEDRIVER_PATH\" $QUIET $OUTPUT_DIR \"$LOCAL_APPDATA\\$CHROME_DIR_DEV\\Application\\chrome.exe\""], ["install_chrome_beta", "\"$MINI_INSTALLER\" --chrome-beta \"$LOG_FILE\" --verbose-logging --do-not-launch-chrome"], ["install_chrome_canary", @@ -245,27 +245,27 @@ ["kill_user_chrome", "reg.exe delete \"HKEY_CURRENT_USER\\$CHROME_UPDATE_REGISTRY_SUBKEY\" /v pv /f /reg:32"], ["launch_chrome_canary", - "\"$PYTHON_INTERPRETER\" launch_chrome.py \"$LOCAL_APPDATA\\$CHROME_DIR_SXS\\Application\\chrome.exe\""], + "python launch_chrome.py \"$LOCAL_APPDATA\\$CHROME_DIR_SXS\\Application\\chrome.exe\""], ["launch_chrome_system", - "\"$PYTHON_INTERPRETER\" launch_chrome.py \"$PROGRAM_FILES\\$CHROME_DIR\\Application\\chrome.exe\""], + "python launch_chrome.py \"$PROGRAM_FILES\\$CHROME_DIR\\Application\\chrome.exe\""], ["launch_chrome_user", - "\"$PYTHON_INTERPRETER\" launch_chrome.py \"$LOCAL_APPDATA\\$CHROME_DIR\\Application\\chrome.exe\""], + "python launch_chrome.py \"$LOCAL_APPDATA\\$CHROME_DIR\\Application\\chrome.exe\""], ["quit_chrome_canary", - "\"$PYTHON_INTERPRETER\" quit_chrome.py \"$LOCAL_APPDATA\\$CHROME_DIR_SXS\\Application\\chrome.exe\""], + "python quit_chrome.py \"$LOCAL_APPDATA\\$CHROME_DIR_SXS\\Application\\chrome.exe\""], ["quit_chrome_system", - "\"$PYTHON_INTERPRETER\" quit_chrome.py \"$PROGRAM_FILES\\$CHROME_DIR\\Application\\chrome.exe\""], + "python quit_chrome.py \"$PROGRAM_FILES\\$CHROME_DIR\\Application\\chrome.exe\""], ["quit_chrome_user", - "\"$PYTHON_INTERPRETER\" quit_chrome.py \"$LOCAL_APPDATA\\$CHROME_DIR\\Application\\chrome.exe\""], + "python quit_chrome.py \"$LOCAL_APPDATA\\$CHROME_DIR\\Application\\chrome.exe\""], ["uninstall_chrome_beta", - "\"$PYTHON_INTERPRETER\" uninstall_chrome.py \"$LOG_FILE\" --chrome-long-name=\"$CHROME_LONG_NAME_BETA\""], + "python uninstall_chrome.py \"$LOG_FILE\" --chrome-long-name=\"$CHROME_LONG_NAME_BETA\""], ["uninstall_chrome_canary", - "\"$PYTHON_INTERPRETER\" uninstall_chrome.py \"$LOG_FILE\" --chrome-long-name=\"$CHROME_LONG_NAME_SXS\""], + "python uninstall_chrome.py \"$LOG_FILE\" --chrome-long-name=\"$CHROME_LONG_NAME_SXS\""], ["uninstall_chrome_dev", - "\"$PYTHON_INTERPRETER\" uninstall_chrome.py \"$LOG_FILE\" --chrome-long-name=\"$CHROME_LONG_NAME_DEV\""], + "python uninstall_chrome.py \"$LOG_FILE\" --chrome-long-name=\"$CHROME_LONG_NAME_DEV\""], ["uninstall_chrome_system", - "\"$PYTHON_INTERPRETER\" uninstall_chrome.py \"$LOG_FILE\" --chrome-long-name=\"$CHROME_LONG_NAME\" --system-level"], + "python uninstall_chrome.py \"$LOG_FILE\" --chrome-long-name=\"$CHROME_LONG_NAME\" --system-level"], ["uninstall_chrome_user", - "\"$PYTHON_INTERPRETER\" uninstall_chrome.py \"$LOG_FILE\" --chrome-long-name=\"$CHROME_LONG_NAME\""], + "python uninstall_chrome.py \"$LOG_FILE\" --chrome-long-name=\"$CHROME_LONG_NAME\""], ["update_chrome_canary", "\"$MINI_INSTALLER\" --chrome-sxs \"$LOG_FILE\" --verbose-logging --do-not-launch-chrome"], ["update_chrome_system", diff --git a/chrome/test/mini_installer/create_zip.py b/chrome/test/mini_installer/create_zip.py index b49c85b59b5354..6ae5f43d999176 100644 --- a/chrome/test/mini_installer/create_zip.py +++ b/chrome/test/mini_installer/create_zip.py @@ -46,9 +46,9 @@ THIS_DIR = os.path.abspath(os.path.dirname(os.path.abspath(__file__))) SRC_DIR = os.path.join(THIS_DIR, '..', '..', '..') SELENIUM_PATH = os.path.abspath( - os.path.join(SRC_DIR, 'third_party', 'webdriver', 'pylib')) + os.path.join(SRC_DIR, r'third_party', 'webdriver', 'pylib')) TYP_PATH = os.path.abspath( - os.path.join(SRC_DIR, 'third_party', 'catapult', 'third_party', 'typ')) + os.path.join(SRC_DIR, r'third_party', 'catapult', 'third_party', 'typ')) BLOCKLIST = ['', '.pyc', '.gn', '.gni', '.txt', '.bat'] diff --git a/chrome/test/mini_installer/installer_test.py b/chrome/test/mini_installer/installer_test.py index a711929c26ecff..52f4d5593bf61c 100644 --- a/chrome/test/mini_installer/installer_test.py +++ b/chrome/test/mini_installer/installer_test.py @@ -9,6 +9,7 @@ driven by typ. """ +import argparse import contextlib import json import logging @@ -18,9 +19,10 @@ import sys import tempfile import traceback +import typ import unittest import win32api -from win32comext.shell import shell, shellcon +from win32com.shell import shell, shellcon from argument_parser import ArgumentParser import property_walker @@ -38,7 +40,7 @@ _force_clean = not RUNNING_LOCALLY -class Config: +class Config(object): """Describes the machine states, actions, and test cases. Attributes: @@ -71,7 +73,7 @@ def __init__(self, method_name): method_name: The name of this test. """ assert InstallerTest._config, 'module _initialize() not yet called' - super().__init__(method_name) + super(InstallerTest, self).__init__(method_name) self._name = method_name[5:] self._test = InstallerTest._config.traversals[self._name] self._clean_on_teardown = True @@ -164,7 +166,7 @@ def _VerifyState(self, state): except AssertionError as e: # If an AssertionError occurs, we intercept it and add the state # name to the error message so that we know where the test fails. - raise AssertionError("In state '%s', %s" % (state, str(e))) from e + raise AssertionError("In state '%s', %s" % (state, e)) def RunCommand(command, variable_expander): @@ -193,8 +195,6 @@ def RunCommand(command, variable_expander): proc = subprocess.Popen(expanded_command, shell=True, cwd=script_dir, - text=True, - encoding='utf-8', stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = proc.communicate() @@ -235,11 +235,10 @@ def RunCleanCommand(force_clean, clean_state, variable_expander): # Attempt to run each installed product's uninstaller. interactive_option = '--interactive' if not force_clean else '' for product_name, product_switch in data: - command = ( - '%s uninstall_chrome.py ' - '--chrome-long-name="%s" ' - '--no-error-if-absent %s %s' % - (sys.executable, product_name, product_switch, interactive_option)) + command = ('python uninstall_chrome.py ' + '--chrome-long-name="%s" ' + '--no-error-if-absent %s %s' % + (product_name, product_switch, interactive_option)) try: RunCommand(command, variable_expander) except: # pylint: disable=bare-except @@ -267,7 +266,7 @@ def MergePropertyDictionaries(current_property, new_property): current_property: The property dictionary to be modified. new_property: The new property dictionary. """ - for key, value in new_property.items(): + for key, value in new_property.iteritems(): if key not in current_property: current_property[key] = value else: @@ -275,7 +274,8 @@ def MergePropertyDictionaries(current_property, new_property): and isinstance(value, dict)) # This merges two dictionaries together. In case there are keys with # the same name, the latter will override the former. - current_property[key].update(value) + current_property[key] = dict(current_property[key].items() + + value.items()) def FilterConditionalElem(elem, condition_name, variable_expander): @@ -340,10 +340,9 @@ def ParseConfigFile(filename, variable_expander): config.tests = config_data['tests'] # Drop conditional tests that should not be run in the current # configuration. - config.tests = list( - filter( - lambda t: FilterConditionalElem(t, 'condition', variable_expander), - config.tests)) + config.tests = filter( + lambda t: FilterConditionalElem(t, 'condition', variable_expander), + config.tests) for state_name, state_property_filenames in config_data['states']: config.states[state_name] = ParsePropertyFiles( directory, state_property_filenames, variable_expander) @@ -454,15 +453,24 @@ def GetAbsoluteConfigPath(path): return os.path.abspath(path) +# Until we're using Python 3.8 or newer, we must use tearDownModule to restore +# the tmp dir. It would be cleaner to remove _temp_dir_manager and instead do +# something along the lines of this after __enter__(): +# unittest.addModuleCleanup(_temp_dir_manager.__exit__, None, None, None) +_temp_dir_manager = None + + def setUpModule(): # Make sure that TMP and Chrome's installation directory are on the same # drive to work around https://crbug.com/700809. (CSIDL_PROGRAM_FILESX86 is # valid for both 32 and 64-bit apps running on 32 or 64-bit Windows.) drive = os.path.splitdrive( shell.SHGetFolderPath(0, shellcon.CSIDL_PROGRAM_FILESX86, None, 0))[0] + global _temp_dir_manager _temp_dir_manager = ConfigureTempOnDrive(drive) - _temp_dir_manager.__enter__() # pylint: disable=no-member - unittest.addModuleCleanup(_temp_dir_manager.__exit__, None, None, None) # pylint: disable=no-member + _temp_dir_manager.__enter__() + # Switch to this once we're using Python 3.8 or newer: + # unittest.addModuleCleanup(_temp_dir_manager.__exit__, None, None, None) # The last state in any test's traversal is the "clean" state, so use it to # drive the initial cleanup operation. @@ -473,11 +481,18 @@ def setUpModule(): RunCleanCommand(_force_clean, clean_state, InstallerTest._variable_expander) except: - _temp_dir_manager.__exit__(None, None, None) # pylint: disable=no-member + _temp_dir_manager.__exit__(None, None, None) _temp_dir_manager = None raise +def tearDownModule(): + global _temp_dir_manager + if _temp_dir_manager: + _temp_dir_manager.__exit__(None, None, None) + _temp_dir_manager = None + + def _initialize(): """Initializes the InstallerTest class. diff --git a/chrome/test/mini_installer/launch_chrome.py b/chrome/test/mini_installer/launch_chrome.py old mode 100755 new mode 100644 index d54ed1f40f782a..d98437c045989f --- a/chrome/test/mini_installer/launch_chrome.py +++ b/chrome/test/mini_installer/launch_chrome.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 # Copyright 2013 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. diff --git a/chrome/test/mini_installer/property_walker.py b/chrome/test/mini_installer/property_walker.py index a87ee21ec788a5..96c97c2a339d5e 100644 --- a/chrome/test/mini_installer/property_walker.py +++ b/chrome/test/mini_installer/property_walker.py @@ -57,9 +57,9 @@ def _Walk(operations, continue_on_error, property_dict, variable_expander): property_dict: A property dictionary mapping type names to expectations. variable_expander: A VariableExpander. """ - for type_name, expectations in property_dict.items(): + for type_name, expectations in property_dict.iteritems(): operation = operations[type_name] - for expectation_name, expectation_dict in expectations.items(): + for expectation_name, expectation_dict in expectations.iteritems(): # Skip over expectations with conditions that aren't satisfied. if 'condition' in expectation_dict: condition = variable_expander.Expand( diff --git a/chrome/test/mini_installer/quit_chrome.py b/chrome/test/mini_installer/quit_chrome.py old mode 100755 new mode 100644 index 037d1f3e4fb55f..dbb32d931b0dd8 --- a/chrome/test/mini_installer/quit_chrome.py +++ b/chrome/test/mini_installer/quit_chrome.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 # Copyright 2013 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. diff --git a/chrome/test/mini_installer/registry_operations.py b/chrome/test/mini_installer/registry_operations.py index 9d9cf8e64bebde..2e637fa146f1b3 100644 --- a/chrome/test/mini_installer/registry_operations.py +++ b/chrome/test/mini_installer/registry_operations.py @@ -2,54 +2,53 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import logging -import winreg - import win32api import win32con +import logging import winerror +import _winreg LOGGER = logging.getLogger('installer_test') _REGISTRY_VIEW_MAPPING = { - 'KEY_WOW64_32KEY': winreg.KEY_WOW64_32KEY, - 'KEY_WOW64_64KEY': winreg.KEY_WOW64_64KEY, + 'KEY_WOW64_32KEY': _winreg.KEY_WOW64_32KEY, + 'KEY_WOW64_64KEY': _winreg.KEY_WOW64_64KEY, } _ROOT_KEY_MAPPING = { - 'HKEY_CLASSES_ROOT': winreg.HKEY_CLASSES_ROOT, - 'HKEY_CURRENT_USER': winreg.HKEY_CURRENT_USER, - 'HKEY_LOCAL_MACHINE': winreg.HKEY_LOCAL_MACHINE, - 'HKEY_USERS': winreg.HKEY_USERS, + 'HKEY_CLASSES_ROOT': _winreg.HKEY_CLASSES_ROOT, + 'HKEY_CURRENT_USER': _winreg.HKEY_CURRENT_USER, + 'HKEY_LOCAL_MACHINE': _winreg.HKEY_LOCAL_MACHINE, + 'HKEY_USERS': _winreg.HKEY_USERS, } def _RootKeyConstant(root_key): - """Converts a root registry key string into a winreg.HKEY_* constant.""" + """Converts a root registry key string into a _winreg.HKEY_* constant.""" if root_key not in _ROOT_KEY_MAPPING: raise KeyError("Unknown root registry key '%s'" % root_key) return _ROOT_KEY_MAPPING[root_key] def _RegistryViewConstant(registry_view): - """Converts a registry view string into a winreg.KEY_WOW64* constant.""" + """Converts a registry view string into a _winreg.KEY_WOW64* constant.""" if registry_view not in _REGISTRY_VIEW_MAPPING: raise KeyError("Unknown registry view '%s'" % registry_view) return _REGISTRY_VIEW_MAPPING[registry_view] def _ValueTypeConstant(value_type): - """Converts a registry value type string into a winreg.REG_* constant.""" + """Converts a registry value type string into a _winreg.REG_* constant.""" value_type_mapping = { - 'BINARY': winreg.REG_BINARY, - 'DWORD': winreg.REG_DWORD, - 'DWORD_LITTLE_ENDIAN': winreg.REG_DWORD_LITTLE_ENDIAN, - 'DWORD_BIG_ENDIAN': winreg.REG_DWORD_BIG_ENDIAN, - 'EXPAND_SZ': winreg.REG_EXPAND_SZ, - 'LINK': winreg.REG_LINK, - 'MULTI_SZ': winreg.REG_MULTI_SZ, - 'NONE': winreg.REG_NONE, - 'SZ': winreg.REG_SZ, + 'BINARY': _winreg.REG_BINARY, + 'DWORD': _winreg.REG_DWORD, + 'DWORD_LITTLE_ENDIAN': _winreg.REG_DWORD_LITTLE_ENDIAN, + 'DWORD_BIG_ENDIAN': _winreg.REG_DWORD_BIG_ENDIAN, + 'EXPAND_SZ': _winreg.REG_EXPAND_SZ, + 'LINK': _winreg.REG_LINK, + 'MULTI_SZ': _winreg.REG_MULTI_SZ, + 'NONE': _winreg.REG_NONE, + 'SZ': _winreg.REG_SZ, } if value_type not in value_type_mapping: raise KeyError("Unknown registry value type '%s'" % value_type) @@ -91,14 +90,14 @@ def VerifyRegistryEntryExpectation(expectation_name, expectation, try: # Query the Windows registry for the registry key. It will throw a # WindowsError if the key doesn't exist. - registry_view = winreg.KEY_WOW64_32KEY + registry_view = _winreg.KEY_WOW64_32KEY if 'wow_key' in expectation: registry_view = _RegistryViewConstant(expectation['wow_key']) elif variable_expander.Expand('$MINI_INSTALLER_BITNESS') == '64': - registry_view = winreg.KEY_WOW64_64KEY + registry_view = _winreg.KEY_WOW64_64KEY - key_handle = winreg.OpenKey(_RootKeyConstant(root_key), sub_key, 0, - winreg.KEY_QUERY_VALUE | registry_view) + key_handle = _winreg.OpenKey(_RootKeyConstant(root_key), sub_key, 0, + _winreg.KEY_QUERY_VALUE | registry_view) except WindowsError: # Key doesn't exist. See that it matches the expectation. assert expectation['exists'] != 'required', ('Registry key %s is ' @@ -112,12 +111,12 @@ def VerifyRegistryEntryExpectation(expectation_name, expectation, # Verify the expected values. if 'values' not in expectation: return - for value, value_expectation in expectation['values'].items(): + for value, value_expectation in expectation['values'].iteritems(): # Query the value. It will throw a WindowsError if the value doesn't # exist. value = variable_expander.Expand(value) try: - data, value_type = winreg.QueryValueEx(key_handle, value) + data, value_type = _winreg.QueryValueEx(key_handle, value) except WindowsError: # The value does not exist. See that this matches the expectation. assert 'type' not in value_expectation, ( @@ -140,7 +139,7 @@ def VerifyRegistryEntryExpectation(expectation_name, expectation, # Verify the associated data of the value. expected_data = value_expectation['data'] - if isinstance(expected_data, str): + if isinstance(expected_data, basestring): expected_data = variable_expander.Expand(expected_data) assert expected_data == data, \ ("Value '%s' of registry key %s has unexpected data.\n" @@ -173,17 +172,17 @@ def CleanRegistryEntry(expectation_name, expectation, variable_expander): 'property for key %s must not be \'required\'' % key) root_key, sub_key = key.split('\\', 1) - registry_view = winreg.KEY_WOW64_32KEY + registry_view = _winreg.KEY_WOW64_32KEY if 'wow_key' in expectation: registry_view = _RegistryViewConstant(expectation['wow_key']) elif variable_expander.Expand('$MINI_INSTALLER_BITNESS') == '64': - registry_view = winreg.KEY_WOW64_64KEY + registry_view = _winreg.KEY_WOW64_64KEY try: # Query the Windows registry for the registry key. It will throw a # WindowsError if the key doesn't exist. - key_handle = winreg.OpenKey(_RootKeyConstant(root_key), sub_key, 0, - (winreg.KEY_SET_VALUE | registry_view)) + key_handle = _winreg.OpenKey(_RootKeyConstant(root_key), sub_key, 0, + (_winreg.KEY_SET_VALUE | registry_view)) except WindowsError: # There is nothing to clean if the key doesn't exist. return @@ -194,10 +193,10 @@ def CleanRegistryEntry(expectation_name, expectation, variable_expander): # its values and subkeys. Open the root of the hive with the proper # permissions, then delete the key by name. key_handle = None - root_handle = winreg.OpenKey( + root_handle = _winreg.OpenKey( _RootKeyConstant(root_key), None, 0, - (win32con.DELETE | winreg.KEY_ENUMERATE_SUB_KEYS - | winreg.KEY_QUERY_VALUE | winreg.KEY_SET_VALUE + (win32con.DELETE | _winreg.KEY_ENUMERATE_SUB_KEYS + | _winreg.KEY_QUERY_VALUE | _winreg.KEY_SET_VALUE | registry_view)) win32api.RegDeleteTree(root_handle, sub_key) LOGGER.info('CleanRegistryEntry deleted key %s' % key) @@ -206,13 +205,13 @@ def CleanRegistryEntry(expectation_name, expectation, variable_expander): assert 'values' in expectation and expectation['values'], ( 'Invalid expectation for CleanRegistryEntry operation: a \'values\' ' + 'dictionary is required for optional key %s' % key) - for value, value_expectation in expectation['values'].items(): + for value, value_expectation in expectation['values'].iteritems(): value = variable_expander.Expand(value) assert 'type' not in value_expectation, ( 'Invalid expectation for CleanRegistryEntry operation: value ' + '%s\\%s must not specify a \'type\'' % (key, value)) try: - winreg.DeleteValue(key_handle, value) + _winreg.DeleteValue(key_handle, value) LOGGER.info('CleanRegistryEntry deleted value %s\\%s' % (key, value)) except WindowsError as e: diff --git a/chrome/test/mini_installer/run_mini_installer_tests.py b/chrome/test/mini_installer/run_mini_installer_tests.py index 0f24bf6ae984e2..4e717d62986692 100755 --- a/chrome/test/mini_installer/run_mini_installer_tests.py +++ b/chrome/test/mini_installer/run_mini_installer_tests.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python3 +#!/usr/bin/env python # Copyright 2021 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -77,7 +77,7 @@ def main(args): try: return runner.run()[0] except KeyboardInterrupt: - sys.stderr.write("interrupted, exiting") + self.print_("interrupted, exiting", stream=self.host.stderr) return 130 diff --git a/chrome/test/mini_installer/test_chrome_with_chromedriver.py b/chrome/test/mini_installer/test_chrome_with_chromedriver.py old mode 100755 new mode 100644 index 25610b0a3644d8..f214166e3192a6 --- a/chrome/test/mini_installer/test_chrome_with_chromedriver.py +++ b/chrome/test/mini_installer/test_chrome_with_chromedriver.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 # Copyright 2018 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -12,6 +11,7 @@ """ import argparse +import atexit import contextlib import logging import os @@ -20,13 +20,25 @@ import tempfile import time -from selenium import webdriver -from selenium.webdriver import ChromeOptions import chrome_helper THIS_DIR = os.path.dirname(os.path.abspath(__file__)) +SRC_DIR = os.path.join(THIS_DIR, '..', '..', '..') +WEBDRIVER_PATH = os.path.join(SRC_DIR, r'third_party', 'webdriver', 'pylib') TEST_HTML_FILE = 'file://' + os.path.join(THIS_DIR, 'test_page.html') +# Try and import webdriver +sys.path.insert(0, WEBDRIVER_PATH) +try: + from selenium import webdriver + from selenium.webdriver import ChromeOptions +except ImportError: + # If a system doesn't have the webdriver API this is a no-op phase + logging.info( + 'Chromedriver API (selenium.webdriver) is not installed available in ' + '%s. Exiting test_chrome_with_chromedriver.py' % WEBDRIVER_PATH) + sys.exit(0) + @contextlib.contextmanager def CreateChromedriver(args): @@ -36,7 +48,7 @@ def DeleteWithRetry(path, func): # There seems to be a race condition on the bots that causes the paths # to not delete because they are being used. This allows up to 4 seconds # to delete - for _ in range(8): + for _ in xrange(8): try: return func(path) except WindowsError: diff --git a/chrome/test/mini_installer/uninstall_chrome.py b/chrome/test/mini_installer/uninstall_chrome.py old mode 100755 new mode 100644 index ef2652c8597381..3f3cffa21c2b70 --- a/chrome/test/mini_installer/uninstall_chrome.py +++ b/chrome/test/mini_installer/uninstall_chrome.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 # Copyright 2013 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -8,11 +7,10 @@ the output status code. """ -import logging +import _winreg import optparse import subprocess import sys -import winreg def main(): @@ -47,31 +45,32 @@ def main(): # TODO(sukolsak): Add support for uninstalling MSI-based Chrome installs # when we support testing MSIs. if options.system_level: - root_key = winreg.HKEY_LOCAL_MACHINE + root_key = _winreg.HKEY_LOCAL_MACHINE else: - root_key = winreg.HKEY_CURRENT_USER + root_key = _winreg.HKEY_CURRENT_USER sub_key = ('SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\%s' % options.chrome_long_name) # Query the key. It will throw a WindowsError if the key doesn't exist. try: - key = winreg.OpenKey(root_key, sub_key, 0, - winreg.KEY_QUERY_VALUE | winreg.KEY_WOW64_32KEY) - except WindowsError as e: + key = _winreg.OpenKey( + root_key, sub_key, 0, + _winreg.KEY_QUERY_VALUE | _winreg.KEY_WOW64_32KEY) + except WindowsError: if options.no_error_if_absent: return 0 raise KeyError('Registry key %s\\%s is missing' % ('HKEY_LOCAL_MACHINE' if options.system_level else - 'HKEY_CURRENT_USER', sub_key)) from e + 'HKEY_CURRENT_USER', sub_key)) if options.interactive: prompt = ( 'Warning: This will uninstall %s at %s. Do you want to continue? ' '(y/N) ' % (options.chrome_long_name, 'system-level' if options.system_level else 'user-level')) - if input(prompt).strip() != 'y': - logging.error('User aborted') + if raw_input(prompt).strip() != 'y': + print >> sys.stderr, 'User aborted' return 1 - uninstall_string, _ = winreg.QueryValueEx(key, 'UninstallString') + uninstall_string, _ = _winreg.QueryValueEx(key, 'UninstallString') uninstall_string += ' --force-uninstall' if options.log_file: uninstall_string += (' --verbose-logging --log-file="%s"' % diff --git a/chrome/test/mini_installer/update_lastrun.py b/chrome/test/mini_installer/update_lastrun.py index 171bbdf7cd33d2..4a3441d09f08c3 100644 --- a/chrome/test/mini_installer/update_lastrun.py +++ b/chrome/test/mini_installer/update_lastrun.py @@ -3,10 +3,10 @@ # found in the LICENSE file. """Updates Chrome's "lastrun" value for the current user in HKCU.""" +import _winreg import optparse import sys import time -import winreg def UpdateLastrun(client_state_key_path): @@ -20,15 +20,15 @@ def UpdateLastrun(client_state_key_path): # since the Windows epoch. Adjust based on values inspired by # https://support.microsoft.com/en-us/kb/167296, which uses 100-nanosecond # ticks. - now_us = str(int(time.time() * 1000000 + 11644473600000000)) + now_us = str(int(time.time() * 1000000 + 11644473600000000L)) try: - with winreg.OpenKey(winreg.HKEY_CURRENT_USER, client_state_key_path, 0, - winreg.KEY_SET_VALUE - | winreg.KEY_WOW64_32KEY) as key: - winreg.SetValueEx(key, 'lastrun', 0, winreg.REG_SZ, now_us) - except WindowsError as e: + with _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, client_state_key_path, + 0, _winreg.KEY_SET_VALUE + | _winreg.KEY_WOW64_32KEY) as key: + _winreg.SetValueEx(key, 'lastrun', 0, _winreg.REG_SZ, now_us) + except WindowsError: raise KeyError('Failed opening registry key HKEY_CURRENT_USER\\%s' % - client_state_key_path) from e + client_state_key_path) return 0 diff --git a/chrome/test/mini_installer/variable_expander.py b/chrome/test/mini_installer/variable_expander.py index 8623f4b4f1927e..4fa4d5a4d8abff 100644 --- a/chrome/test/mini_installer/variable_expander.py +++ b/chrome/test/mini_installer/variable_expander.py @@ -6,7 +6,6 @@ import hashlib import os import string -import sys import win32api import win32file import win32com.client @@ -58,8 +57,8 @@ def _GetUserSpecificRegistrySuffix(): user_sid, _ = win32security.GetTokenInformation(token_handle, win32security.TokenUser) user_sid_string = win32security.ConvertSidToStringSid(user_sid) - md5_digest = hashlib.md5(user_sid_string.encode('utf-8')).digest() - return '.' + base64.b32encode(md5_digest).decode('utf-8').rstrip('=') + md5_digest = hashlib.md5(user_sid_string).digest() + return '.' + base64.b32encode(md5_digest).rstrip('=') class VariableExpander: @@ -112,8 +111,6 @@ def __init__(self, mini_installer_path, * $PREVIOUS_VERSION_MINI_INSTALLER_FILE_VERSION: the file version of $PREVIOUS_VERSION_MINI_INSTALLER. * $PROGRAM_FILES: the unquoted path to the Program Files folder. - * $PYTHON_INTERPRETER: the python interpreter. This is used to propagate - vpython VirtualEnv properly. * $USER_SPECIFIC_REGISTRY_SUFFIX: the output from the function _GetUserSpecificRegistrySuffix(). * $VERSION_[XP/SERVER_2003/VISTA/WIN7/WIN8/WIN8_1/WIN10]: a 2-tuple @@ -190,8 +187,6 @@ def __init__(self, mini_installer_path, 0, shellcon.CSIDL_PROGRAM_FILES if _GetFileBitness(mini_installer_abspath) == '64' else shellcon.CSIDL_PROGRAM_FILESX86, None, 0), - 'PYTHON_INTERPRETER': - sys.executable, 'USER_SPECIFIC_REGISTRY_SUFFIX': _GetUserSpecificRegistrySuffix(), 'VERSION_SERVER_2003': diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl index b9c13ec6b499a4..f4aac2f238cec2 100644 --- a/testing/buildbot/gn_isolate_map.pyl +++ b/testing/buildbot/gn_isolate_map.pyl @@ -1252,6 +1252,7 @@ "type": "additional_compile_target", }, "mini_installer_tests": { + "python3": False, "args": [ "../../chrome/test/mini_installer/run_mini_installer_tests.py", "--output-dir=${ISOLATED_OUTDIR}",