xref: /aosp_15_r20/external/autotest/server/autotest_unittest.py (revision 9c5db1993ded3edbeafc8092d69fe5de2ee02df7)
1*9c5db199SXin Li#!/usr/bin/python3
2*9c5db199SXin Li#pylint: disable-msg=C0111
3*9c5db199SXin Li__author__ = "[email protected] (Travis Miller)"
4*9c5db199SXin Li
5*9c5db199SXin Lifrom six.moves import StringIO
6*9c5db199SXin Liimport unittest, os, tempfile, logging
7*9c5db199SXin Li
8*9c5db199SXin Liimport common
9*9c5db199SXin Li
10*9c5db199SXin Lifrom autotest_lib.server import autotest, utils, hosts, server_job, profilers
11*9c5db199SXin Lifrom autotest_lib.client.bin import sysinfo
12*9c5db199SXin Lifrom autotest_lib.client.common_lib import packages
13*9c5db199SXin Lifrom autotest_lib.client.common_lib import error
14*9c5db199SXin Lifrom autotest_lib.client.common_lib.test_utils import mock
15*9c5db199SXin Li
16*9c5db199SXin Li
17*9c5db199SXin Liclass TestAutotest(unittest.TestCase):
18*9c5db199SXin Li    def setUp(self):
19*9c5db199SXin Li        # create god
20*9c5db199SXin Li        self.god = mock.mock_god()
21*9c5db199SXin Li
22*9c5db199SXin Li        # create mock host object
23*9c5db199SXin Li        self.host = self.god.create_mock_class(hosts.RemoteHost, "host")
24*9c5db199SXin Li        self.host.hostname = "hostname"
25*9c5db199SXin Li        self.host.job = self.god.create_mock_class(server_job.server_job,
26*9c5db199SXin Li                                                   "job")
27*9c5db199SXin Li        self.host.job.run_test_cleanup = True
28*9c5db199SXin Li        self.host.job.sysinfo = self.god.create_mock_class(
29*9c5db199SXin Li            sysinfo.sysinfo, "sysinfo")
30*9c5db199SXin Li        self.host.job.profilers = self.god.create_mock_class(
31*9c5db199SXin Li            profilers.profilers, "profilers")
32*9c5db199SXin Li        self.host.job.profilers.add_log = {}
33*9c5db199SXin Li        self.host.job.tmpdir = "/job/tmp"
34*9c5db199SXin Li        self.host.job.default_profile_only = False
35*9c5db199SXin Li        self.host.job.args = []
36*9c5db199SXin Li        self.host.job.record = lambda *args: None
37*9c5db199SXin Li        self.host.verify_job_repo_url = lambda *args: None
38*9c5db199SXin Li
39*9c5db199SXin Li        # stubs
40*9c5db199SXin Li        self.god.stub_function(utils, "get_server_dir")
41*9c5db199SXin Li        self.god.stub_function(utils, "run")
42*9c5db199SXin Li        self.god.stub_function(utils, "get")
43*9c5db199SXin Li        self.god.stub_function(utils, "read_keyval")
44*9c5db199SXin Li        self.god.stub_function(utils, "write_keyval")
45*9c5db199SXin Li        self.god.stub_function(utils, "system")
46*9c5db199SXin Li        self.god.stub_function(tempfile, "mkstemp")
47*9c5db199SXin Li        self.god.stub_function(tempfile, "mktemp")
48*9c5db199SXin Li        self.god.stub_function(os, "getcwd")
49*9c5db199SXin Li        self.god.stub_function(os, "system")
50*9c5db199SXin Li        self.god.stub_function(os, "chdir")
51*9c5db199SXin Li        self.god.stub_function(os, "makedirs")
52*9c5db199SXin Li        self.god.stub_function(os, "remove")
53*9c5db199SXin Li        self.god.stub_function(os, "fdopen")
54*9c5db199SXin Li        self.god.stub_function(os.path, "exists")
55*9c5db199SXin Li        self.god.stub_function(autotest, "open")
56*9c5db199SXin Li        self.god.stub_function(autotest.global_config.global_config,
57*9c5db199SXin Li                               "get_config_value")
58*9c5db199SXin Li        self.god.stub_function(logging, "exception")
59*9c5db199SXin Li        self.god.stub_class(autotest, "_Run")
60*9c5db199SXin Li        self.god.stub_class(autotest, "log_collector")
61*9c5db199SXin Li
62*9c5db199SXin Li
63*9c5db199SXin Li    def tearDown(self):
64*9c5db199SXin Li        self.god.unstub_all()
65*9c5db199SXin Li
66*9c5db199SXin Li
67*9c5db199SXin Li    def construct(self):
68*9c5db199SXin Li        # setup
69*9c5db199SXin Li        self.serverdir = "serverdir"
70*9c5db199SXin Li
71*9c5db199SXin Li        # record
72*9c5db199SXin Li        utils.get_server_dir.expect_call().and_return(self.serverdir)
73*9c5db199SXin Li
74*9c5db199SXin Li        # create the autotest object
75*9c5db199SXin Li        self.autotest = autotest.Autotest(self.host)
76*9c5db199SXin Li        self.autotest.job = self.host.job
77*9c5db199SXin Li        self.god.stub_function(self.autotest, "_install_using_send_file")
78*9c5db199SXin Li
79*9c5db199SXin Li        # stub out abspath
80*9c5db199SXin Li        self.god.stub_function(os.path, "abspath")
81*9c5db199SXin Li
82*9c5db199SXin Li        # check
83*9c5db199SXin Li        self.god.check_playback()
84*9c5db199SXin Li
85*9c5db199SXin Li
86*9c5db199SXin Li    def record_install_prologue(self):
87*9c5db199SXin Li        self.construct()
88*9c5db199SXin Li
89*9c5db199SXin Li        # setup
90*9c5db199SXin Li        self.god.stub_class(packages, "PackageManager")
91*9c5db199SXin Li        self.autotest.got = False
92*9c5db199SXin Li        location = os.path.join(self.serverdir, '../client')
93*9c5db199SXin Li        location = os.path.abspath.expect_call(location).and_return(location)
94*9c5db199SXin Li
95*9c5db199SXin Li        # record
96*9c5db199SXin Li        utils.get.expect_call(os.path.join(self.serverdir,
97*9c5db199SXin Li            '../client')).and_return('source_material')
98*9c5db199SXin Li
99*9c5db199SXin Li        self.host.wait_up.expect_call(timeout=30)
100*9c5db199SXin Li        self.host.setup.expect_call()
101*9c5db199SXin Li        self.host.get_autodir.expect_call().and_return("autodir")
102*9c5db199SXin Li        self.host.set_autodir.expect_call("autodir")
103*9c5db199SXin Li        self.host.run.expect_call('mkdir -p autodir')
104*9c5db199SXin Li        self.host.run.expect_call('rm -rf autodir/results/*',
105*9c5db199SXin Li                                  ignore_status=True)
106*9c5db199SXin Li
107*9c5db199SXin Li
108*9c5db199SXin Li    def test_constructor(self):
109*9c5db199SXin Li        self.construct()
110*9c5db199SXin Li
111*9c5db199SXin Li        # we should check the calls
112*9c5db199SXin Li        self.god.check_playback()
113*9c5db199SXin Li
114*9c5db199SXin Li
115*9c5db199SXin Li    def test_full_client_install(self):
116*9c5db199SXin Li        self.record_install_prologue()
117*9c5db199SXin Li
118*9c5db199SXin Li        self.host.run.expect_call('rm -f "autodir/packages.checksum"')
119*9c5db199SXin Li        c = autotest.global_config.global_config
120*9c5db199SXin Li        c.get_config_value.expect_call('PACKAGES',
121*9c5db199SXin Li                                       'serve_packages_from_autoserv',
122*9c5db199SXin Li                                       type=bool).and_return(False)
123*9c5db199SXin Li        self.host.send_file.expect_call('source_material', 'autodir',
124*9c5db199SXin Li                                        delete_dest=True)
125*9c5db199SXin Li        self.god.stub_function(autotest.Autotest, "_send_shadow_config")
126*9c5db199SXin Li        autotest.Autotest._send_shadow_config.expect_call()
127*9c5db199SXin Li        self.host.run.expect_call('autodir/bin/fs_sync.py', ignore_status=True)
128*9c5db199SXin Li
129*9c5db199SXin Li        # run and check
130*9c5db199SXin Li        self.autotest.install_full_client()
131*9c5db199SXin Li        self.god.check_playback()
132*9c5db199SXin Li
133*9c5db199SXin Li
134*9c5db199SXin Li    def test_autoserv_install(self):
135*9c5db199SXin Li        self.record_install_prologue()
136*9c5db199SXin Li
137*9c5db199SXin Li        c = autotest.global_config.global_config
138*9c5db199SXin Li        c.get_config_value.expect_call('PACKAGES',
139*9c5db199SXin Li            'fetch_location', type=list, default=[]).and_return([])
140*9c5db199SXin Li
141*9c5db199SXin Li        os.path.exists.expect_call('/etc/cros_chroot_version').and_return(True)
142*9c5db199SXin Li        c.get_config_value.expect_call('PACKAGES',
143*9c5db199SXin Li                                       'serve_packages_from_autoserv',
144*9c5db199SXin Li                                       type=bool).and_return(True)
145*9c5db199SXin Li        self.autotest._install_using_send_file.expect_call(self.host,
146*9c5db199SXin Li                                                           'autodir')
147*9c5db199SXin Li        self.god.stub_function(autotest.Autotest, "_send_shadow_config")
148*9c5db199SXin Li        autotest.Autotest._send_shadow_config.expect_call()
149*9c5db199SXin Li        self.host.run.expect_call('autodir/bin/fs_sync.py', ignore_status=True)
150*9c5db199SXin Li
151*9c5db199SXin Li        # run and check
152*9c5db199SXin Li        self.autotest.install()
153*9c5db199SXin Li        self.god.check_playback()
154*9c5db199SXin Li
155*9c5db199SXin Li
156*9c5db199SXin Li    def test_packaging_install(self):
157*9c5db199SXin Li        self.record_install_prologue()
158*9c5db199SXin Li
159*9c5db199SXin Li        c = autotest.global_config.global_config
160*9c5db199SXin Li        c.get_config_value.expect_call('PACKAGES',
161*9c5db199SXin Li            'fetch_location', type=list, default=[]).and_return(['repo'])
162*9c5db199SXin Li        os.path.exists.expect_call('/etc/cros_chroot_version').and_return(True)
163*9c5db199SXin Li        pkgmgr = packages.PackageManager.expect_new('autodir',
164*9c5db199SXin Li            repo_urls=['repo'], hostname='hostname', do_locking=False,
165*9c5db199SXin Li            run_function=self.host.run, run_function_dargs=dict(timeout=600))
166*9c5db199SXin Li        pkg_dir = os.path.join('autodir', 'packages')
167*9c5db199SXin Li        cmd = ('cd autodir && ls | grep -v "^packages$" | '
168*9c5db199SXin Li               'grep -v "^result_tools$" | '
169*9c5db199SXin Li               'xargs rm -rf && rm -rf .[!.]*')
170*9c5db199SXin Li        self.host.run.expect_call(cmd)
171*9c5db199SXin Li        pkgmgr.install_pkg.expect_call('autotest', 'client', pkg_dir,
172*9c5db199SXin Li                                       'autodir', preserve_install_dir=True)
173*9c5db199SXin Li
174*9c5db199SXin Li        # run and check
175*9c5db199SXin Li        self.autotest.install()
176*9c5db199SXin Li        self.god.check_playback()
177*9c5db199SXin Li
178*9c5db199SXin Li
179*9c5db199SXin Li    def test_run(self):
180*9c5db199SXin Li        self.construct()
181*9c5db199SXin Li
182*9c5db199SXin Li        # setup
183*9c5db199SXin Li        control = "control"
184*9c5db199SXin Li
185*9c5db199SXin Li        # stub out install
186*9c5db199SXin Li        self.god.stub_function(self.autotest, "install")
187*9c5db199SXin Li
188*9c5db199SXin Li        # record
189*9c5db199SXin Li        self.autotest.install.expect_call(self.host, use_packaging=True)
190*9c5db199SXin Li        self.host.wait_up.expect_call(timeout=30)
191*9c5db199SXin Li        os.path.abspath.expect_call('.').and_return('.')
192*9c5db199SXin Li        run_obj = autotest._Run.expect_new(self.host, '.', None, False, False)
193*9c5db199SXin Li        tag = None
194*9c5db199SXin Li        run_obj.manual_control_file = os.path.join('autodir',
195*9c5db199SXin Li                                                   'control.%s' % tag)
196*9c5db199SXin Li        run_obj.remote_control_file = os.path.join('autodir',
197*9c5db199SXin Li                                                   'control.%s.autoserv' % tag)
198*9c5db199SXin Li        run_obj.tag = tag
199*9c5db199SXin Li        run_obj.autodir = 'autodir'
200*9c5db199SXin Li        run_obj.verify_machine.expect_call()
201*9c5db199SXin Li        run_obj.background = False
202*9c5db199SXin Li        debug = os.path.join('.', 'debug')
203*9c5db199SXin Li        os.makedirs.expect_call(debug)
204*9c5db199SXin Li        delete_file_list = [run_obj.remote_control_file,
205*9c5db199SXin Li                            run_obj.remote_control_file + '.state',
206*9c5db199SXin Li                            run_obj.manual_control_file,
207*9c5db199SXin Li                            run_obj.manual_control_file + '.state']
208*9c5db199SXin Li        cmd = ';'.join('rm -f ' + control for control in delete_file_list)
209*9c5db199SXin Li        self.host.run.expect_call(cmd, ignore_status=True)
210*9c5db199SXin Li
211*9c5db199SXin Li        utils.get.expect_call(control, local_copy=True).and_return("temp")
212*9c5db199SXin Li
213*9c5db199SXin Li        c = autotest.global_config.global_config
214*9c5db199SXin Li        c.get_config_value.expect_call("PACKAGES",
215*9c5db199SXin Li            'fetch_location', type=list, default=[]).and_return(['repo'])
216*9c5db199SXin Li
217*9c5db199SXin Li        cfile = self.god.create_mock_class(StringIO, "StringIO")
218*9c5db199SXin Li        cfile_orig = "original control file"
219*9c5db199SXin Li        cfile_new = "args = []\njob.add_repository(['repo'])\n"
220*9c5db199SXin Li        cfile_new += cfile_orig
221*9c5db199SXin Li
222*9c5db199SXin Li        os.path.exists.expect_call('/etc/cros_chroot_version').and_return(True)
223*9c5db199SXin Li        autotest.open.expect_call("temp").and_return(cfile)
224*9c5db199SXin Li        cfile.read.expect_call().and_return(cfile_orig)
225*9c5db199SXin Li        autotest.open.expect_call("temp", 'w').and_return(cfile)
226*9c5db199SXin Li        cfile.write.expect_call(cfile_new)
227*9c5db199SXin Li
228*9c5db199SXin Li        self.host.job.preprocess_client_state.expect_call().and_return(
229*9c5db199SXin Li            '/job/tmp/file1')
230*9c5db199SXin Li        self.host.send_file.expect_call(
231*9c5db199SXin Li            "/job/tmp/file1", "autodir/control.None.autoserv.init.state")
232*9c5db199SXin Li        os.remove.expect_call("/job/tmp/file1")
233*9c5db199SXin Li
234*9c5db199SXin Li        self.host.send_file.expect_call("temp", run_obj.remote_control_file)
235*9c5db199SXin Li        os.path.abspath.expect_call('temp').and_return('control_file')
236*9c5db199SXin Li        os.path.abspath.expect_call('control').and_return('control')
237*9c5db199SXin Li        os.remove.expect_call("temp")
238*9c5db199SXin Li
239*9c5db199SXin Li        run_obj.execute_control.expect_call(timeout=30,
240*9c5db199SXin Li                                            client_disconnect_timeout=240)
241*9c5db199SXin Li
242*9c5db199SXin Li        # run and check output
243*9c5db199SXin Li        self.autotest.run(control, timeout=30)
244*9c5db199SXin Li        self.god.check_playback()
245*9c5db199SXin Li
246*9c5db199SXin Li
247*9c5db199SXin Li    def _stub_get_client_autodir_paths(self):
248*9c5db199SXin Li        def mock_get_client_autodir_paths(cls, host):
249*9c5db199SXin Li            return ['/some/path', '/another/path']
250*9c5db199SXin Li        self.god.stub_with(autotest.Autotest, 'get_client_autodir_paths',
251*9c5db199SXin Li                           classmethod(mock_get_client_autodir_paths))
252*9c5db199SXin Li
253*9c5db199SXin Li
254*9c5db199SXin Li    def _expect_failed_run(self, command):
255*9c5db199SXin Li        (self.host.run.expect_call(command).and_raises(
256*9c5db199SXin Li                error.AutoservRunError('placeholder', object())))
257*9c5db199SXin Li
258*9c5db199SXin Li
259*9c5db199SXin Li    def test_get_installed_autodir(self):
260*9c5db199SXin Li        self._stub_get_client_autodir_paths()
261*9c5db199SXin Li        self.host.get_autodir.expect_call().and_return(None)
262*9c5db199SXin Li        self._expect_failed_run('test -x /some/path/bin/autotest')
263*9c5db199SXin Li        self.host.run.expect_call('test -x /another/path/bin/autotest')
264*9c5db199SXin Li        self.host.run.expect_call('test -w /another/path')
265*9c5db199SXin Li
266*9c5db199SXin Li        autodir = autotest.Autotest.get_installed_autodir(self.host)
267*9c5db199SXin Li        self.assertEquals(autodir, '/another/path')
268*9c5db199SXin Li
269*9c5db199SXin Li
270*9c5db199SXin Li    def test_get_install_dir(self):
271*9c5db199SXin Li        self._stub_get_client_autodir_paths()
272*9c5db199SXin Li        self.host.get_autodir.expect_call().and_return(None)
273*9c5db199SXin Li        self._expect_failed_run('test -x /some/path/bin/autotest')
274*9c5db199SXin Li        self._expect_failed_run('test -x /another/path/bin/autotest')
275*9c5db199SXin Li        self._expect_failed_run('mkdir -p /some/path')
276*9c5db199SXin Li        self.host.run.expect_call('mkdir -p /another/path')
277*9c5db199SXin Li        self.host.run.expect_call('test -w /another/path')
278*9c5db199SXin Li
279*9c5db199SXin Li        install_dir = autotest.Autotest.get_install_dir(self.host)
280*9c5db199SXin Li        self.assertEquals(install_dir, '/another/path')
281*9c5db199SXin Li
282*9c5db199SXin Li
283*9c5db199SXin Li    def test_client_logger_process_line_log_copy_collection_failure(self):
284*9c5db199SXin Li        collector = autotest.log_collector.expect_new(self.host, '', '')
285*9c5db199SXin Li        logger = autotest.client_logger(self.host, '', '')
286*9c5db199SXin Li        collector.collect_client_job_results.expect_call().and_raises(
287*9c5db199SXin Li                Exception('log copy failure'))
288*9c5db199SXin Li        logging.exception.expect_call(mock.is_string_comparator())
289*9c5db199SXin Li        logger._process_line('AUTOTEST_TEST_COMPLETE:/autotest/fifo1')
290*9c5db199SXin Li
291*9c5db199SXin Li
292*9c5db199SXin Li    def test_client_logger_process_line_log_copy_fifo_failure(self):
293*9c5db199SXin Li        collector = autotest.log_collector.expect_new(self.host, '', '')
294*9c5db199SXin Li        logger = autotest.client_logger(self.host, '', '')
295*9c5db199SXin Li        collector.collect_client_job_results.expect_call()
296*9c5db199SXin Li        self.host.run.expect_call('echo A > /autotest/fifo2').and_raises(
297*9c5db199SXin Li                Exception('fifo failure'))
298*9c5db199SXin Li        logging.exception.expect_call(mock.is_string_comparator())
299*9c5db199SXin Li        logger._process_line('AUTOTEST_TEST_COMPLETE:/autotest/fifo2')
300*9c5db199SXin Li
301*9c5db199SXin Li
302*9c5db199SXin Li    def test_client_logger_process_line_package_install_fifo_failure(self):
303*9c5db199SXin Li        collector = autotest.log_collector.expect_new(self.host, '', '')
304*9c5db199SXin Li        logger = autotest.client_logger(self.host, '', '')
305*9c5db199SXin Li        self.god.stub_function(logger, '_send_tarball')
306*9c5db199SXin Li
307*9c5db199SXin Li        c = autotest.global_config.global_config
308*9c5db199SXin Li        c.get_config_value.expect_call('PACKAGES',
309*9c5db199SXin Li                                       'serve_packages_from_autoserv',
310*9c5db199SXin Li                                       type=bool).and_return(True)
311*9c5db199SXin Li        c.get_config_value.expect_call('PACKAGES',
312*9c5db199SXin Li                                       'serve_packages_from_autoserv',
313*9c5db199SXin Li                                       type=bool).and_return(True)
314*9c5db199SXin Li        logger._send_tarball.expect_call('pkgname.tar.bz2', '/autotest/dest/')
315*9c5db199SXin Li
316*9c5db199SXin Li        self.host.run.expect_call('echo B > /autotest/fifo3').and_raises(
317*9c5db199SXin Li                Exception('fifo failure'))
318*9c5db199SXin Li        logging.exception.expect_call(mock.is_string_comparator())
319*9c5db199SXin Li        logger._process_line('AUTOTEST_FETCH_PACKAGE:pkgname.tar.bz2:'
320*9c5db199SXin Li                             '/autotest/dest/:/autotest/fifo3')
321*9c5db199SXin Li
322*9c5db199SXin Li
323*9c5db199SXin Liif __name__ == "__main__":
324*9c5db199SXin Li    unittest.main()
325