xref: /aosp_15_r20/external/autotest/client/bin/setup_job_unittest.py (revision 9c5db1993ded3edbeafc8092d69fe5de2ee02df7)
1*9c5db199SXin Li#!/usr/bin/python3
2*9c5db199SXin Li#pylint: disable-msg=C0111
3*9c5db199SXin Liimport logging
4*9c5db199SXin Liimport os
5*9c5db199SXin Liimport shutil
6*9c5db199SXin Liimport six
7*9c5db199SXin Liimport sys
8*9c5db199SXin Liimport unittest
9*9c5db199SXin Li
10*9c5db199SXin Liimport common
11*9c5db199SXin Lifrom autotest_lib.client.bin import job, setup_job
12*9c5db199SXin Lifrom autotest_lib.client.bin import utils
13*9c5db199SXin Lifrom autotest_lib.client.common_lib import base_job
14*9c5db199SXin Lifrom autotest_lib.client.common_lib import logging_manager, logging_config
15*9c5db199SXin Lifrom autotest_lib.client.common_lib import base_job_unittest
16*9c5db199SXin Lifrom autotest_lib.client.common_lib.test_utils import mock
17*9c5db199SXin Li
18*9c5db199SXin Li
19*9c5db199SXin Liclass setup_job_test_case(unittest.TestCase):
20*9c5db199SXin Li    """Generic job TestCase class that defines a standard job setUp and
21*9c5db199SXin Li    tearDown, with some standard stubs."""
22*9c5db199SXin Li
23*9c5db199SXin Li    job_class = setup_job.setup_job
24*9c5db199SXin Li
25*9c5db199SXin Li    def setUp(self):
26*9c5db199SXin Li        self.god = mock.mock_god()
27*9c5db199SXin Li        self.god.stub_with(setup_job.setup_job, '_get_environ_autodir',
28*9c5db199SXin Li                           classmethod(lambda cls: '/adir'))
29*9c5db199SXin Li        self.job = self.job_class.__new__(self.job_class)
30*9c5db199SXin Li        self.job._job_directory = base_job_unittest.stub_job_directory
31*9c5db199SXin Li        self.job.args = []
32*9c5db199SXin Li
33*9c5db199SXin Li
34*9c5db199SXin Li    def tearDown(self):
35*9c5db199SXin Li        self.god.unstub_all()
36*9c5db199SXin Li
37*9c5db199SXin Li
38*9c5db199SXin Liclass test_find_base_directories(
39*9c5db199SXin Li        base_job_unittest.test_find_base_directories.generic_tests,
40*9c5db199SXin Li        setup_job_test_case):
41*9c5db199SXin Li
42*9c5db199SXin Li    def test_autodir_equals_clientdir(self):
43*9c5db199SXin Li        autodir, clientdir, _ = self.job._find_base_directories()
44*9c5db199SXin Li        self.assertEqual(autodir, '/adir')
45*9c5db199SXin Li        self.assertEqual(clientdir, '/adir')
46*9c5db199SXin Li
47*9c5db199SXin Li
48*9c5db199SXin Li    def test_serverdir_is_none(self):
49*9c5db199SXin Li        _, _, serverdir = self.job._find_base_directories()
50*9c5db199SXin Li        self.assertEqual(serverdir, None)
51*9c5db199SXin Li
52*9c5db199SXin Li
53*9c5db199SXin Liclass abstract_test_init(base_job_unittest.test_init.generic_tests):
54*9c5db199SXin Li    """Generic client job mixin used when defining variations on the
55*9c5db199SXin Li    job.__init__ generic tests."""
56*9c5db199SXin Li    PUBLIC_ATTRIBUTES = (
57*9c5db199SXin Li            base_job_unittest.test_init.generic_tests.PUBLIC_ATTRIBUTES - set([
58*9c5db199SXin Li                    'bootloader',
59*9c5db199SXin Li                    'control',
60*9c5db199SXin Li                    'drop_caches',
61*9c5db199SXin Li                    'drop_caches_between_iterations',
62*9c5db199SXin Li                    'force_full_log_collection',
63*9c5db199SXin Li                    'harness',
64*9c5db199SXin Li                    'hosts',
65*9c5db199SXin Li                    'logging',
66*9c5db199SXin Li                    'machines',
67*9c5db199SXin Li                    'num_tests_failed',
68*9c5db199SXin Li                    'num_tests_run',
69*9c5db199SXin Li                    'profilers',
70*9c5db199SXin Li                    'sysinfo',
71*9c5db199SXin Li                    'user',
72*9c5db199SXin Li                    'warning_loggers',
73*9c5db199SXin Li                    'warning_manager',
74*9c5db199SXin Li            ]))
75*9c5db199SXin Li
76*9c5db199SXin Li
77*9c5db199SXin Liclass test_init_minimal_options(abstract_test_init, setup_job_test_case):
78*9c5db199SXin Li    def call_init(self):
79*9c5db199SXin Li        # TODO(jadmanski): refactor more of the __init__ code to not need to
80*9c5db199SXin Li        # stub out countless random APIs
81*9c5db199SXin Li        self.god.stub_function_to_return(setup_job.os, 'mkdir', None)
82*9c5db199SXin Li        self.god.stub_function_to_return(setup_job.os.path, 'exists', True)
83*9c5db199SXin Li        self.god.stub_function_to_return(self.job, '_load_state', None)
84*9c5db199SXin Li        self.god.stub_function_to_return(setup_job.logging_manager,
85*9c5db199SXin Li                                         'configure_logging', None)
86*9c5db199SXin Li        class manager:
87*9c5db199SXin Li            def start_logging(self):
88*9c5db199SXin Li                return None
89*9c5db199SXin Li        self.god.stub_function_to_return(setup_job.logging_manager,
90*9c5db199SXin Li                                         'get_logging_manager', manager())
91*9c5db199SXin Li
92*9c5db199SXin Li        class options:
93*9c5db199SXin Li            tag = ''
94*9c5db199SXin Li            verbose = False
95*9c5db199SXin Li            cont = False
96*9c5db199SXin Li            harness = 'stub'
97*9c5db199SXin Li            hostname = None
98*9c5db199SXin Li            user = None
99*9c5db199SXin Li            log = False
100*9c5db199SXin Li            output_dir = False
101*9c5db199SXin Li
102*9c5db199SXin Li        self.job.__init__(options)
103*9c5db199SXin Li
104*9c5db199SXin Li
105*9c5db199SXin Liclass stub(object):
106*9c5db199SXin Li    """A simple placeholder for attributes"""
107*9c5db199SXin Li    pass
108*9c5db199SXin Li
109*9c5db199SXin Li
110*9c5db199SXin Liclass first_line_comparator(mock.argument_comparator):
111*9c5db199SXin Li    def __init__(self, first_line):
112*9c5db199SXin Li        self.first_line = first_line
113*9c5db199SXin Li
114*9c5db199SXin Li
115*9c5db199SXin Li    def is_satisfied_by(self, parameter):
116*9c5db199SXin Li        return self.first_line == parameter.splitlines()[0]
117*9c5db199SXin Li
118*9c5db199SXin Li
119*9c5db199SXin Liclass test_setup_job(unittest.TestCase):
120*9c5db199SXin Li    def setUp(self):
121*9c5db199SXin Li        # make god
122*9c5db199SXin Li        self.god = mock.mock_god()
123*9c5db199SXin Li
124*9c5db199SXin Li        # need to set some environ variables
125*9c5db199SXin Li        self.autodir = "autodir"
126*9c5db199SXin Li        os.environ['AUTODIR'] = self.autodir
127*9c5db199SXin Li
128*9c5db199SXin Li        # set up some variables
129*9c5db199SXin Li        self.jobtag = "jobtag"
130*9c5db199SXin Li
131*9c5db199SXin Li        # get rid of stdout and logging
132*9c5db199SXin Li        sys.stdout = six.StringIO()
133*9c5db199SXin Li        logging_manager.configure_logging(logging_config.TestingConfig())
134*9c5db199SXin Li        logging.disable(logging.CRITICAL)
135*9c5db199SXin Li        def stub_configure_logging(*args, **kwargs):
136*9c5db199SXin Li            pass
137*9c5db199SXin Li        self.god.stub_with(logging_manager, 'configure_logging',
138*9c5db199SXin Li                           stub_configure_logging)
139*9c5db199SXin Li        real_get_logging_manager = logging_manager.get_logging_manager
140*9c5db199SXin Li        def get_logging_manager_no_fds(manage_stdout_and_stderr=False,
141*9c5db199SXin Li                                       redirect_fds=False):
142*9c5db199SXin Li            return real_get_logging_manager(manage_stdout_and_stderr, False)
143*9c5db199SXin Li        self.god.stub_with(logging_manager, 'get_logging_manager',
144*9c5db199SXin Li                           get_logging_manager_no_fds)
145*9c5db199SXin Li
146*9c5db199SXin Li        # stub out some stuff
147*9c5db199SXin Li        self.god.stub_function(os.path, 'exists')
148*9c5db199SXin Li        self.god.stub_function(os.path, 'isdir')
149*9c5db199SXin Li        self.god.stub_function(os, 'makedirs')
150*9c5db199SXin Li        self.god.stub_function(os, 'mkdir')
151*9c5db199SXin Li        self.god.stub_function(os, 'remove')
152*9c5db199SXin Li        self.god.stub_function(shutil, 'rmtree')
153*9c5db199SXin Li        self.god.stub_function(shutil, 'copyfile')
154*9c5db199SXin Li        self.god.stub_function(setup_job, 'open')
155*9c5db199SXin Li        self.god.stub_function(utils, 'system')
156*9c5db199SXin Li
157*9c5db199SXin Li        self.god.stub_class_method(job.base_client_job,
158*9c5db199SXin Li                                   '_cleanup_debugdir_files')
159*9c5db199SXin Li        self.god.stub_class_method(job.base_client_job, '_cleanup_results_dir')
160*9c5db199SXin Li
161*9c5db199SXin Li        self.god.stub_with(base_job.job_directory, '_ensure_valid',
162*9c5db199SXin Li                           lambda *_: None)
163*9c5db199SXin Li
164*9c5db199SXin Li
165*9c5db199SXin Li    def tearDown(self):
166*9c5db199SXin Li        sys.stdout = sys.__stdout__
167*9c5db199SXin Li        self.god.unstub_all()
168*9c5db199SXin Li
169*9c5db199SXin Li
170*9c5db199SXin Li    def _setup_pre_record_init(self):
171*9c5db199SXin Li        resultdir = os.path.join(self.autodir, 'results', self.jobtag)
172*9c5db199SXin Li        tmpdir = os.path.join(self.autodir, 'tmp')
173*9c5db199SXin Li        job.base_client_job._cleanup_debugdir_files.expect_call()
174*9c5db199SXin Li        job.base_client_job._cleanup_results_dir.expect_call()
175*9c5db199SXin Li
176*9c5db199SXin Li        return resultdir
177*9c5db199SXin Li
178*9c5db199SXin Li    def construct_job(self):
179*9c5db199SXin Li        # will construct class instance using __new__
180*9c5db199SXin Li        self.job = setup_job.setup_job.__new__(setup_job.setup_job)
181*9c5db199SXin Li
182*9c5db199SXin Li        resultdir = self._setup_pre_record_init()
183*9c5db199SXin Li
184*9c5db199SXin Li        # finish constructor
185*9c5db199SXin Li        options = stub()
186*9c5db199SXin Li        options.tag = self.jobtag
187*9c5db199SXin Li        options.log = False
188*9c5db199SXin Li        options.verbose = False
189*9c5db199SXin Li        options.hostname = 'localhost'
190*9c5db199SXin Li        options.user = 'my_user'
191*9c5db199SXin Li        options.output_dir = False
192*9c5db199SXin Li        self.job.__init__(options)
193*9c5db199SXin Li
194*9c5db199SXin Li        # check
195*9c5db199SXin Li        self.god.check_playback()
196*9c5db199SXin Li
197*9c5db199SXin Li
198*9c5db199SXin Li    def get_partition_mock(self, devname):
199*9c5db199SXin Li        """
200*9c5db199SXin Li        Create a mock of a partition object and return it.
201*9c5db199SXin Li        """
202*9c5db199SXin Li        class mock(object):
203*9c5db199SXin Li            device = devname
204*9c5db199SXin Li            get_mountpoint = self.god.create_mock_function('get_mountpoint')
205*9c5db199SXin Li        return mock
206*9c5db199SXin Li
207*9c5db199SXin Li
208*9c5db199SXin Li    def test_constructor_first_run(self):
209*9c5db199SXin Li        self.construct_job()
210*9c5db199SXin Li
211*9c5db199SXin Li
212*9c5db199SXin Li    def test_constructor_continuation(self):
213*9c5db199SXin Li        self.construct_job()
214*9c5db199SXin Li
215*9c5db199SXin Li
216*9c5db199SXin Li    def test_setup_dirs_raise(self):
217*9c5db199SXin Li        self.construct_job()
218*9c5db199SXin Li
219*9c5db199SXin Li        # setup
220*9c5db199SXin Li        results_dir = 'foo'
221*9c5db199SXin Li        tmp_dir = 'bar'
222*9c5db199SXin Li
223*9c5db199SXin Li        # record
224*9c5db199SXin Li        os.path.exists.expect_call(tmp_dir).and_return(True)
225*9c5db199SXin Li        os.path.isdir.expect_call(tmp_dir).and_return(False)
226*9c5db199SXin Li
227*9c5db199SXin Li        # test
228*9c5db199SXin Li        self.assertRaises(ValueError, self.job.setup_dirs, results_dir, tmp_dir)
229*9c5db199SXin Li        self.god.check_playback()
230*9c5db199SXin Li
231*9c5db199SXin Li
232*9c5db199SXin Li    def test_setup_dirs(self):
233*9c5db199SXin Li        self.construct_job()
234*9c5db199SXin Li
235*9c5db199SXin Li        # setup
236*9c5db199SXin Li        results_dir1 = os.path.join(self.job.resultdir, 'build')
237*9c5db199SXin Li        results_dir2 = os.path.join(self.job.resultdir, 'build.2')
238*9c5db199SXin Li        results_dir3 = os.path.join(self.job.resultdir, 'build.3')
239*9c5db199SXin Li        tmp_dir = 'bar'
240*9c5db199SXin Li
241*9c5db199SXin Li        # record
242*9c5db199SXin Li        os.path.exists.expect_call(tmp_dir).and_return(False)
243*9c5db199SXin Li        os.mkdir.expect_call(tmp_dir)
244*9c5db199SXin Li        os.path.isdir.expect_call(tmp_dir).and_return(True)
245*9c5db199SXin Li        os.path.exists.expect_call(results_dir1).and_return(True)
246*9c5db199SXin Li        os.path.exists.expect_call(results_dir2).and_return(True)
247*9c5db199SXin Li        os.path.exists.expect_call(results_dir3).and_return(False)
248*9c5db199SXin Li        os.path.exists.expect_call(results_dir3).and_return(False)
249*9c5db199SXin Li        os.mkdir.expect_call(results_dir3)
250*9c5db199SXin Li
251*9c5db199SXin Li        # test
252*9c5db199SXin Li        self.assertEqual(self.job.setup_dirs(None, tmp_dir),
253*9c5db199SXin Li                         (results_dir3, tmp_dir))
254*9c5db199SXin Li        self.god.check_playback()
255*9c5db199SXin Li
256*9c5db199SXin Li
257*9c5db199SXin Liif __name__ == "__main__":
258*9c5db199SXin Li    unittest.main()
259