1*9c5db199SXin Li# Copyright 2017 The Chromium OS Authors. All rights reserved. 2*9c5db199SXin Li# Use of this source code is governed by a BSD-style license that can be 3*9c5db199SXin Li# found in the LICENSE file. 4*9c5db199SXin Li 5*9c5db199SXin Liimport argparse 6*9c5db199SXin Liimport getpass 7*9c5db199SXin Liimport logging 8*9c5db199SXin Liimport sys 9*9c5db199SXin Li 10*9c5db199SXin Liimport common 11*9c5db199SXin Lifrom autotest_lib.client.common_lib import utils 12*9c5db199SXin Li 13*9c5db199SXin Li 14*9c5db199SXin Lidef setup_logging(log_level): 15*9c5db199SXin Li """Sets up direct logging to stdout for unittests. 16*9c5db199SXin Li 17*9c5db199SXin Li @param log_level: Level of logging to redirect to stdout, default to INFO. 18*9c5db199SXin Li """ 19*9c5db199SXin Li # Lifted from client.common_lib.logging_config. 20*9c5db199SXin Li FORMAT = ('%(asctime)s.%(msecs)03d %(levelname)-5.5s|%(module)18.18s:' 21*9c5db199SXin Li '%(lineno)4.4d| %(threadName)16.16s(%(thread)d)| %(message)s') 22*9c5db199SXin Li 23*9c5db199SXin Li logger = logging.getLogger() 24*9c5db199SXin Li logger.setLevel(log_level) 25*9c5db199SXin Li handler = logging.StreamHandler(sys.stdout) 26*9c5db199SXin Li handler.setLevel(log_level) 27*9c5db199SXin Li formatter = logging.Formatter(FORMAT) 28*9c5db199SXin Li handler.setFormatter(formatter) 29*9c5db199SXin Li logger.handlers = [] 30*9c5db199SXin Li logger.addHandler(handler) 31*9c5db199SXin Li 32*9c5db199SXin Li 33*9c5db199SXin Lidef verify_user(require_sudo=True): 34*9c5db199SXin Li """Checks that the current user is not root, but has sudo. 35*9c5db199SXin Li 36*9c5db199SXin Li Running unit tests as root can mask permissions problems, as not all the 37*9c5db199SXin Li code runs as root in production. 38*9c5db199SXin Li """ 39*9c5db199SXin Li # Ensure this process is not running as root. 40*9c5db199SXin Li if getpass.getuser() == 'root': 41*9c5db199SXin Li raise EnvironmentError('Unittests should not be run as root.') 42*9c5db199SXin Li 43*9c5db199SXin Li # However, most of the unit tests do require sudo. 44*9c5db199SXin Li # TODO(dshi): crbug.com/459344 Set remove this enforcement when test 45*9c5db199SXin Li # container can be unprivileged container. 46*9c5db199SXin Li if require_sudo and utils.sudo_require_password(): 47*9c5db199SXin Li logging.warning('SSP requires root privilege to run commands, please ' 48*9c5db199SXin Li 'grant root access to this process.') 49*9c5db199SXin Li utils.run('sudo true') 50*9c5db199SXin Li 51*9c5db199SXin Li 52*9c5db199SXin Liclass Config(object): 53*9c5db199SXin Li """A class for parsing and storing command line options. 54*9c5db199SXin Li 55*9c5db199SXin Li A convenience class for helping with unit test setup. A global instance of 56*9c5db199SXin Li this class is set up by the setup function. Clients can then check this 57*9c5db199SXin Li object for flags set on the command line. 58*9c5db199SXin Li """ 59*9c5db199SXin Li def parse_options(self): 60*9c5db199SXin Li """Parses command line flags for unittests.""" 61*9c5db199SXin Li parser = argparse.ArgumentParser() 62*9c5db199SXin Li parser.add_argument('-v', '--verbose', action='store_true', 63*9c5db199SXin Li default=False, 64*9c5db199SXin Li help='Print out ALL entries.') 65*9c5db199SXin Li parser.add_argument('-s', '--skip_cleanup', action='store_true', 66*9c5db199SXin Li default=False, 67*9c5db199SXin Li help='Skip deleting test containers.') 68*9c5db199SXin Li args, argv = parser.parse_known_args() 69*9c5db199SXin Li 70*9c5db199SXin Li for attr, value in vars(args).items(): 71*9c5db199SXin Li setattr(self, attr, value) 72*9c5db199SXin Li 73*9c5db199SXin Li # Hack: python unittest also processes args. Construct an argv to pass 74*9c5db199SXin Li # to it, that filters out the options it won't recognize. Then replace 75*9c5db199SXin Li # sys.argv with the constructed argv so that calling unittest.main "just 76*9c5db199SXin Li # works". 77*9c5db199SXin Li if args.verbose: 78*9c5db199SXin Li argv.insert(0, '-v') 79*9c5db199SXin Li argv.insert(0, sys.argv[0]) 80*9c5db199SXin Li sys.argv = argv 81*9c5db199SXin Li 82*9c5db199SXin Li 83*9c5db199SXin Li# Global namespace object for storing unittest options specified on the command 84*9c5db199SXin Li# line. 85*9c5db199SXin Liconfig = Config() 86*9c5db199SXin Li 87*9c5db199SXin Lidef setup(require_sudo=True): 88*9c5db199SXin Li """Performs global setup for unit-tests.""" 89*9c5db199SXin Li global setup_run 90*9c5db199SXin Li config.parse_options() 91*9c5db199SXin Li 92*9c5db199SXin Li verify_user(require_sudo) 93*9c5db199SXin Li 94*9c5db199SXin Li log_level = logging.DEBUG if config.verbose else logging.INFO 95*9c5db199SXin Li setup_logging(log_level) 96