#!/usr/bin/python
# Copyright 2015 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# pylint: disable-msg=C0111

import os, unittest
import mox
import common
import subprocess
import shutil
import tempfile
import types
from autotest_lib.client.common_lib import control_data
from autotest_lib.server import utils
from autotest_lib.server.cros.dynamic_suite import constants
from autotest_lib.server.cros.dynamic_suite import control_file_getter
from autotest_lib.server.cros.dynamic_suite import suite as suite_module
from autotest_lib.site_utils import test_runner_utils


class StartsWithList(mox.Comparator):
    def __init__(self, start_of_list):
        """Mox comparator which returns True if the argument
        to the mocked function is a list that begins with the elements
        in start_of_list.
        """
        self._lhs = start_of_list

    def equals(self, rhs):
        if len(rhs)<len(self._lhs):
            return False
        for (x, y) in zip(self._lhs, rhs):
            if x != y:
                return False
        return True


class ContainsSublist(mox.Comparator):
    def __init__(self, sublist):
        """Mox comparator which returns True if the argument
        to the mocked function is a list that contains sublist
        as a sub-list.
        """
        self._sublist = sublist

    def equals(self, rhs):
        n = len(self._sublist)
        if len(rhs)<n:
            return False
        return any((self._sublist == rhs[i:i+n])
                   for i in xrange(len(rhs) - n + 1))

class DummyJob(object):
    def __init__(self, id=1):
        self.id = id

class TestRunnerUnittests(mox.MoxTestBase):

    def setUp(self):
        mox.MoxTestBase.setUp(self)


    def test_fetch_local_suite(self):
        # Deferred until fetch_local_suite knows about non-local builds.
        pass


    def test_handle_local_result_for_good_test(self):
        getter = self.mox.CreateMock(control_file_getter.DevServerGetter)
        getter.get_control_file_list(suite_name=mox.IgnoreArg()).AndReturn([])
        job = DummyJob()
        test = self.mox.CreateMock(control_data.ControlData)
        test.job_retries = 5
        self.mox.StubOutWithMock(test_runner_utils.LocalSuite,
                                 '_retry_local_result')
        self.mox.ReplayAll()
        suite = test_runner_utils.LocalSuite([], "tag", [], None, getter,
                                             job_retry=True)
        suite._retry_handler = suite_module.RetryHandler({job.id: test})
        #No calls, should not be retried
        directory = tempfile.mkdtemp()
        try:
            os.mkdir('%s/debug' % directory)
            with open("%s/status.log" % directory, mode='w+') as status:
                status.write("GOOD: nonexistent test completed successfully")
                status.flush()
                new_id = suite.handle_local_result(
                    job.id, directory,
                    lambda log_entry, log_in_subdir=False: None)
        finally:
            shutil.rmtree(directory)


    def test_handle_local_result_for_bad_test(self):
        getter = self.mox.CreateMock(control_file_getter.DevServerGetter)
        getter.get_control_file_list(suite_name=mox.IgnoreArg()).AndReturn([])
        job = DummyJob()
        test = self.mox.CreateMock(control_data.ControlData)
        test.job_retries = 5
        self.mox.StubOutWithMock(test_runner_utils.LocalSuite,
                                 '_retry_local_result')
        test_runner_utils.LocalSuite._retry_local_result(
            job.id, mox.IgnoreArg()).AndReturn(42)
        self.mox.ReplayAll()
        suite = test_runner_utils.LocalSuite([], "tag", [], None, getter,
                                             job_retry=True)
        suite._retry_handler = suite_module.RetryHandler({job.id: test})
        directory = tempfile.mkdtemp()
        try:
            os.mkdir('%s/debug' % directory)
            with open("%s/status.log" % directory, mode='w+') as status:
                status.write("FAIL")
                status.flush()
                new_id = suite.handle_local_result(
                    job.id, directory,
                    lambda log_entry, log_in_subdir=False: None)
                self.assertIsNotNone(new_id)
        finally:
            shutil.rmtree(directory)


    def test_get_predicate_for_test_arg(self):
        # Assert the type signature of get_predicate_for_test(...)
        # Because control.test_utils_wrapper calls this function,
        # it is imperative for backwards compatilbility that
        # the return type of the tested function does not change.
        tests = ['dummy_test', 'e:name_expression', 'f:expression',
                 'suite:suitename']
        for test in tests:
            pred, desc = test_runner_utils.get_predicate_for_test_arg(test)
            self.assertTrue(isinstance(pred, types.FunctionType))
            self.assertTrue(isinstance(desc, str))

    def test_run_job(self):
        class Object():
            pass

        autotest_path = 'htap_tsetotua'
        autoserv_command = os.path.join(autotest_path, 'server', 'autoserv')
        remote = 'etomer'
        results_dir = '/tmp/fakeresults'
        fast_mode = False
        job1_results_dir = '/tmp/fakeresults/results-1-gilbert'
        job2_results_dir = '/tmp/fakeresults/results-2-sullivan'
        args = 'matey'
        expected_args_sublist = ['--args', args]
        experimental_keyval = {constants.JOB_EXPERIMENTAL_KEY: False}

        # Create some dummy job objects.
        job1 = Object()
        job2 = Object()
        setattr(job1, 'control_type', 'cLiEnT')
        setattr(job1, 'control_file', 'c1')
        setattr(job1, 'id', 1)
        setattr(job1, 'name', 'gilbert')
        setattr(job1, 'keyvals', experimental_keyval)

        setattr(job2, 'control_type', 'Server')
        setattr(job2, 'control_file', 'c2')
        setattr(job2, 'id', 2)
        setattr(job2, 'name', 'sullivan')
        setattr(job2, 'keyvals', experimental_keyval)

        id_digits = 1

        # Stub out subprocess.Popen and wait calls.
        # Make them expect correct arguments.
        def fake_readline():
            return b''
        mock_process_1 = self.mox.CreateMock(subprocess.Popen)
        mock_process_2 = self.mox.CreateMock(subprocess.Popen)
        fake_stdout = self.mox.CreateMock(file)
        fake_returncode = 0
        mock_process_1.stdout = fake_stdout
        mock_process_1.returncode = fake_returncode
        mock_process_2.stdout = fake_stdout
        mock_process_2.returncode = fake_returncode

        self.mox.StubOutWithMock(os, 'makedirs')
        self.mox.StubOutWithMock(utils, 'write_keyval')
        self.mox.StubOutWithMock(subprocess, 'Popen')

        os.makedirs(job1_results_dir)
        utils.write_keyval(job1_results_dir, experimental_keyval)
        arglist_1 = [autoserv_command, '-p', '-r', job1_results_dir,
                     '-m', remote, '--no_console_prefix', '-l', 'gilbert',
                     '-c']
        subprocess.Popen(mox.And(StartsWithList(arglist_1),
                                 ContainsSublist(expected_args_sublist)),
                         stdout=subprocess.PIPE,
                         stderr=subprocess.STDOUT
                        ).AndReturn(mock_process_1)
        mock_process_1.stdout.readline().AndReturn(b'')
        mock_process_1.wait().AndReturn(0)

        os.makedirs(job2_results_dir)
        utils.write_keyval(job2_results_dir, experimental_keyval)
        arglist_2 = [autoserv_command, '-p', '-r', job2_results_dir,
                     '-m', remote,  '--no_console_prefix', '-l', 'sullivan',
                     '-s']
        subprocess.Popen(mox.And(StartsWithList(arglist_2),
                                 ContainsSublist(expected_args_sublist)),
                         stdout=subprocess.PIPE,
                         stderr=subprocess.STDOUT
                        ).AndReturn(mock_process_2)
        mock_process_2.stdout.readline().AndReturn(b'')
        mock_process_2.wait().AndReturn(0)

        # Test run_job.
        self.mox.ReplayAll()
        code, job_res = test_runner_utils.run_job(
                job1, remote, autotest_path,results_dir, fast_mode, id_digits,
                0, None, args)
        self.assertEqual(job_res, job1_results_dir)
        self.assertEqual(code, 0)
        code, job_res = test_runner_utils.run_job(
                job2, remote, autotest_path, results_dir, fast_mode, id_digits,
                0, None, args)

        self.assertEqual(job_res, job2_results_dir)
        self.assertEqual(code, 0)
        self.mox.ResetAll()

    def test_perform_local_run(self):
        afe = test_runner_utils.setup_local_afe()
        autotest_path = 'ottotest_path'
        suite_name = 'sweet_name'
        test_arg = 'suite:' + suite_name
        remote = 'remoat'
        build = 'bild'
        board = 'bored'
        fast_mode = False
        suite_control_files = ['c1', 'c2', 'c3', 'c4']
        results_dir = '/tmp/test_that_results_fake'
        id_digits = 1
        ssh_verbosity = 2
        ssh_options = '-F /dev/null -i /dev/null'
        args = 'matey'
        ignore_deps = False

        # Fake suite objects that will be returned by fetch_local_suite
        class fake_suite(object):
            def __init__(self, suite_control_files, hosts):
                self._suite_control_files = suite_control_files
                self._hosts = hosts
                self._jobs = []
                self._jobs_to_tests = {}
                self.retry_hack = True

            def schedule(self, *args, **kwargs):
                for control_file in self._suite_control_files:
                    job_id = afe.create_job(control_file, hosts=self._hosts)
                    self._jobs.append(job_id)
                    self._jobs_to_tests[job_id] = control_file

            def handle_local_result(self, job_id, results_dir, logger,
                                    **kwargs):
                if results_dir == "success_directory":
                    return None
                retries = True
                if 'retries' in kwargs:
                    retries = kwargs['retries']
                if retries and self.retry_hack:
                    self.retry_hack = False
                else:
                    return None
                control_file = self._jobs_to_tests.get(job_id)
                job_id = afe.create_job(control_file, hosts=self._hosts)
                self._jobs.append(job_id)
                self._jobs_to_tests[job_id] = control_file
                return job_id

            @property
            def jobs(self):
                return self._jobs

            def test_name_from_job(self, id):
                return ""

        # Mock out scheduling of suite and running of jobs.
        self.mox.StubOutWithMock(test_runner_utils, 'fetch_local_suite')
        test_runner_utils.fetch_local_suite(autotest_path, mox.IgnoreArg(),
                afe, test_arg=test_arg, remote=remote, build=build,
                board=board, results_directory=results_dir,
                no_experimental=False,
                ignore_deps=ignore_deps
                ).AndReturn(fake_suite(suite_control_files, [remote]))
        self.mox.StubOutWithMock(test_runner_utils, 'run_job')
        self.mox.StubOutWithMock(test_runner_utils, 'run_provisioning_job')
        self.mox.StubOutWithMock(test_runner_utils, '_auto_detect_labels')

        test_runner_utils._auto_detect_labels(afe, remote)
        # Test perform_local_run. Enforce that run_provisioning_job,
        # run_job and _auto_detect_labels are called correctly.
        test_runner_utils.run_provisioning_job(
                'cros-version:' + build, remote, autotest_path,
                 results_dir, fast_mode,
                 ssh_verbosity, ssh_options,
                 False, False)

        for control_file in suite_control_files:
            test_runner_utils.run_job(
                    mox.ContainsAttributeValue('control_file', control_file),
                    remote, autotest_path, results_dir, fast_mode,id_digits,
                    ssh_verbosity, ssh_options,args, False,
                    False, {}).AndReturn((0, '/fake/dir'))
        self.mox.ReplayAll()
        test_runner_utils.perform_local_run(
                afe, autotest_path, ['suite:'+suite_name], remote, fast_mode,
                build=build, board=board, ignore_deps=False,
                ssh_verbosity=ssh_verbosity, ssh_options=ssh_options,
                args=args, results_directory=results_dir)


if __name__ == '__main__':
    unittest.main()
