114622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi#!/usr/bin/python
214622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi# Copyright 2015 The Chromium OS Authors. All rights reserved.
314622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi# Use of this source code is governed by a BSD-style license that can be
414622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi# found in the LICENSE file.
514622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi# pylint: disable-msg=C0111
614622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi
714622bb8249c2200e5258ea6d40b3362229e90a7Simran Basiimport os, unittest
814622bb8249c2200e5258ea6d40b3362229e90a7Simran Basiimport mox
914622bb8249c2200e5258ea6d40b3362229e90a7Simran Basiimport common
1014622bb8249c2200e5258ea6d40b3362229e90a7Simran Basiimport subprocess
1114622bb8249c2200e5258ea6d40b3362229e90a7Simran Basiimport types
1214622bb8249c2200e5258ea6d40b3362229e90a7Simran Basifrom autotest_lib.server import utils
1314622bb8249c2200e5258ea6d40b3362229e90a7Simran Basifrom autotest_lib.server.cros.dynamic_suite import constants
1414622bb8249c2200e5258ea6d40b3362229e90a7Simran Basifrom autotest_lib.site_utils import test_runner_utils
1514622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi
1614622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi
1714622bb8249c2200e5258ea6d40b3362229e90a7Simran Basiclass StartsWithList(mox.Comparator):
1814622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi    def __init__(self, start_of_list):
1914622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        """Mox comparator which returns True if the argument
2014622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        to the mocked function is a list that begins with the elements
2114622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        in start_of_list.
2214622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        """
2314622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        self._lhs = start_of_list
2414622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi
2514622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi    def equals(self, rhs):
2614622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        if len(rhs)<len(self._lhs):
2714622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi            return False
2814622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        for (x, y) in zip(self._lhs, rhs):
2914622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi            if x != y:
3014622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi                return False
3114622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        return True
3214622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi
3314622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi
3414622bb8249c2200e5258ea6d40b3362229e90a7Simran Basiclass ContainsSublist(mox.Comparator):
3514622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi    def __init__(self, sublist):
3614622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        """Mox comparator which returns True if the argument
3714622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        to the mocked function is a list that contains sublist
3814622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        as a sub-list.
3914622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        """
4014622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        self._sublist = sublist
4114622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi
4214622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi    def equals(self, rhs):
4314622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        n = len(self._sublist)
4414622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        if len(rhs)<n:
4514622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi            return False
4614622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        return any((self._sublist == rhs[i:i+n])
4714622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi                   for i in xrange(len(rhs) - n + 1))
4814622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi
4914622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi
5014622bb8249c2200e5258ea6d40b3362229e90a7Simran Basiclass TestRunnerUnittests(unittest.TestCase):
5114622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi
5214622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi    def test_fetch_local_suite(self):
5314622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        # Deferred until fetch_local_suite knows about non-local builds.
5414622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        pass
5514622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi
5614622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi    def test_get_predicate_for_test_arg(self):
5714622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        # Assert the type signature of get_predicate_for_test(...)
5814622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        # Because control.test_utils_wrapper calls this function,
5914622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        # it is imperative for backwards compatilbility that
6014622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        # the return type of the tested function does not change.
6114622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        tests = ['dummy_test', 'e:name_expression', 'f:expression',
6214622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi                 'suite:suitename']
6314622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        for test in tests:
6414622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi            pred, desc = test_runner_utils.get_predicate_for_test_arg(test)
6514622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi            self.assertTrue(isinstance(pred, types.FunctionType))
6614622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi            self.assertTrue(isinstance(desc, str))
6714622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi
6814622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi    def test_run_job(self):
6914622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        class Object():
7014622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi            pass
7114622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi
7214622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        autotest_path = 'htap_tsetotua'
7314622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        autoserv_command = os.path.join(autotest_path, 'server', 'autoserv')
7414622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        remote = 'etomer'
7514622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        results_dir = '/tmp/fakeresults'
7614622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        fast_mode = False
7714622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        job1_results_dir = '/tmp/fakeresults/results-1-gilbert'
7814622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        job2_results_dir = '/tmp/fakeresults/results-2-sullivan'
7914622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        args = 'matey'
8014622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        expected_args_sublist = ['--args', args]
8114622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        experimental_keyval = {constants.JOB_EXPERIMENTAL_KEY: False}
8214622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        self.mox = mox.Mox()
8314622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi
8414622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        # Create some dummy job objects.
8514622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        job1 = Object()
8614622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        job2 = Object()
8714622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        setattr(job1, 'control_type', 'cLiEnT')
8814622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        setattr(job1, 'control_file', 'c1')
8914622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        setattr(job1, 'id', 1)
9014622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        setattr(job1, 'name', 'gilbert')
9114622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        setattr(job1, 'keyvals', experimental_keyval)
9214622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi
9314622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        setattr(job2, 'control_type', 'Server')
9414622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        setattr(job2, 'control_file', 'c2')
9514622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        setattr(job2, 'id', 2)
9614622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        setattr(job2, 'name', 'sullivan')
9714622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        setattr(job2, 'keyvals', experimental_keyval)
9814622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi
9914622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        id_digits = 1
10014622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi
10114622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        # Stub out subprocess.Popen and wait calls.
10214622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        # Make them expect correct arguments.
10314622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        def fake_readline():
10414622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi            return b''
10514622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        mock_process_1 = self.mox.CreateMock(subprocess.Popen)
10614622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        mock_process_2 = self.mox.CreateMock(subprocess.Popen)
10714622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        fake_stdout = self.mox.CreateMock(file)
10814622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        fake_returncode = 0
10914622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        mock_process_1.stdout = fake_stdout
11014622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        mock_process_1.returncode = fake_returncode
11114622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        mock_process_2.stdout = fake_stdout
11214622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        mock_process_2.returncode = fake_returncode
11314622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi
11414622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        self.mox.StubOutWithMock(os, 'makedirs')
11514622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        self.mox.StubOutWithMock(utils, 'write_keyval')
11614622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        self.mox.StubOutWithMock(subprocess, 'Popen')
11714622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi
11814622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        os.makedirs(job1_results_dir)
11914622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        utils.write_keyval(job1_results_dir, experimental_keyval)
12014622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        arglist_1 = [autoserv_command, '-p', '-r', job1_results_dir,
12114622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi                     '-m', remote, '--no_console_prefix', '-l', 'gilbert',
12214622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi                     '-c']
12314622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        subprocess.Popen(mox.And(StartsWithList(arglist_1),
12414622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi                                 ContainsSublist(expected_args_sublist)),
12514622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi                         stdout=subprocess.PIPE,
12614622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi                         stderr=subprocess.STDOUT
12714622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi                        ).AndReturn(mock_process_1)
12814622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        mock_process_1.stdout.readline().AndReturn(b'')
12914622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        mock_process_1.wait().AndReturn(0)
13014622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi
13114622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        os.makedirs(job2_results_dir)
13214622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        utils.write_keyval(job2_results_dir, experimental_keyval)
13314622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        arglist_2 = [autoserv_command, '-p', '-r', job2_results_dir,
13414622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi                     '-m', remote,  '--no_console_prefix', '-l', 'sullivan',
13514622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi                     '-s']
13614622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        subprocess.Popen(mox.And(StartsWithList(arglist_2),
13714622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi                                 ContainsSublist(expected_args_sublist)),
13814622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi                         stdout=subprocess.PIPE,
13914622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi                         stderr=subprocess.STDOUT
14014622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi                        ).AndReturn(mock_process_2)
14114622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        mock_process_2.stdout.readline().AndReturn(b'')
14214622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        mock_process_2.wait().AndReturn(0)
14314622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi
14414622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        # Test run_job.
14514622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        self.mox.ReplayAll()
14614622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        code, job_res = test_runner_utils.run_job(
14714622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi                job1, remote, autotest_path,results_dir, fast_mode, id_digits,
14814622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi                0, None, args)
14914622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        self.assertEqual(job_res, job1_results_dir)
15014622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        self.assertEqual(code, 0)
15114622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        code, job_res = test_runner_utils.run_job(
15214622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi                job2, remote, autotest_path, results_dir, fast_mode, id_digits,
15314622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi                0, None, args)
15414622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi
15514622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        self.assertEqual(job_res, job2_results_dir)
15614622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        self.assertEqual(code, 0)
15714622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        self.mox.UnsetStubs()
15814622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        self.mox.VerifyAll()
15914622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        self.mox.ResetAll()
16014622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi
16114622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi    def test_perform_local_run(self):
16214622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        afe = test_runner_utils.setup_local_afe()
16314622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        autotest_path = 'ottotest_path'
16414622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        suite_name = 'sweet_name'
16514622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        test_arg = 'suite:' + suite_name
16614622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        remote = 'remoat'
16714622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        build = 'bild'
16814622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        board = 'bored'
16914622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        fast_mode = False
17014622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        suite_control_files = ['c1', 'c2', 'c3', 'c4']
17114622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        results_dir = '/tmp/test_that_results_fake'
17214622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        id_digits = 1
17314622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        ssh_verbosity = 2
17414622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        ssh_options = '-F /dev/null -i /dev/null'
17514622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        args = 'matey'
17614622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        ignore_deps = False
17714622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi
17814622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        # Fake suite objects that will be returned by fetch_local_suite
17914622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        class fake_suite(object):
18014622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi            def __init__(self, suite_control_files, hosts):
18114622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi                self._suite_control_files = suite_control_files
18214622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi                self._hosts = hosts
18314622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi
18414622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi            def schedule(self, *args, **kwargs):
18514622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi                for control_file in self._suite_control_files:
18614622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi                    afe.create_job(control_file, hosts=self._hosts)
18714622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi
18814622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        # Mock out scheduling of suite and running of jobs.
18914622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        self.mox = mox.Mox()
19014622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi
19114622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        self.mox.StubOutWithMock(test_runner_utils, 'fetch_local_suite')
19214622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        test_runner_utils.fetch_local_suite(autotest_path, mox.IgnoreArg(),
19314622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi                afe, test_arg=test_arg, remote=remote, build=build,
19414622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi                board=board, results_directory=results_dir,
19514622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi                no_experimental=False,
19614622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi                ignore_deps=ignore_deps
19714622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi                ).AndReturn(fake_suite(suite_control_files, [remote]))
19814622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        self.mox.StubOutWithMock(test_runner_utils, 'run_job')
19914622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        self.mox.StubOutWithMock(test_runner_utils, 'run_provisioning_job')
20014622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        self.mox.StubOutWithMock(test_runner_utils, '_auto_detect_labels')
20114622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi
20214622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        test_runner_utils._auto_detect_labels(afe, remote)
20314622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        # Test perform_local_run. Enforce that run_provisioning_job,
20414622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        # run_job and _auto_detect_labels are called correctly.
20514622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        test_runner_utils.run_provisioning_job(
20614622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi                'cros-version:' + build, remote, autotest_path,
20714622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi                 results_dir, fast_mode,
20814622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi                 ssh_verbosity, ssh_options,
20914622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi                 False, False)
21014622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi
21114622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        for control_file in suite_control_files:
21214622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi            test_runner_utils.run_job(
21314622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi                    mox.ContainsAttributeValue('control_file', control_file),
21414622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi                    remote, autotest_path, results_dir, fast_mode,id_digits,
21514622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi                    ssh_verbosity, ssh_options,args, False,
21614622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi                    False, {}).AndReturn((0, '/fake/dir'))
21714622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        self.mox.ReplayAll()
21814622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        test_runner_utils.perform_local_run(
21914622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi                afe, autotest_path, ['suite:'+suite_name], remote, fast_mode,
22014622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi                build=build, board=board, ignore_deps=False,
22114622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi                ssh_verbosity=ssh_verbosity, ssh_options=ssh_options,
22214622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi                args=args, results_directory=results_dir)
22314622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        self.mox.UnsetStubs()
22414622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi        self.mox.VerifyAll()
22514622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi
22614622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi
22714622bb8249c2200e5258ea6d40b3362229e90a7Simran Basiif __name__ == '__main__':
22814622bb8249c2200e5258ea6d40b3362229e90a7Simran Basi    unittest.main()
229