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