# Copyright 2017 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Unit tests for tast_test_stages."""

import json
import os
import sys

from chromite.cbuildbot import cbuildbot_unittest
from chromite.cbuildbot import commands
from chromite.cbuildbot.stages import generic_stages_unittest
from chromite.cbuildbot.stages import tast_test_stages
from chromite.lib import cgroups
from chromite.lib import config_lib
from chromite.lib import constants
from chromite.lib import cros_build_lib
from chromite.lib import cros_test_lib
from chromite.lib import failures_lib
from chromite.lib import osutils
from chromite.lib import results_lib
from chromite.lib.buildstore import FakeBuildStore


class TastVMTestStageTest(
    generic_stages_unittest.AbstractStageTestCase,
    cbuildbot_unittest.SimpleBuilderTestCase,
):
    """Tests for tast_test_stages.TastVMTestStage."""

    BOT_ID = "amd64-generic-full"
    RELEASE_TAG = ""

    # Directory relative to the chroot containing per-suite results dir.
    RESULTS_CHROOT_PATH = "/tmp/tast_vm_results"

    # Results file and content to write within per-suite results dir.
    RESULTS_OUT_BASENAME = "results.txt"
    RESULTS_OUT_DATA = "example output"

    # Canned test results for the results.json file.
    PASSED_TEST = {
        "name": "example.Pass",
        "start": "2019-05-03T16:28:31-07:00",
        "end": "2019-05-03T16:28:36-07:00",
        "errors": None,
    }
    FAILED_TEST = {
        "name": "example.Fail",
        "start": "2019-05-03T16:28:31-07:00",
        "end": "2019-05-03T16:28:36-07:00",
        "errors": [{"reason": "Failed!"}],
    }
    INCOMPLETE_TEST = {
        "name": "example.Fail",
        "start": "2019-05-03T16:28:31-07:00",
        "end": tast_test_stages.ZERO_TIME,
        "errors": None,
    }

    def setUp(self):
        # TastVMTestStage being tested.
        self._stage = None

        # String test suite set in the TastVMTestConfig.
        self._exp_test_suite = None

        # List of string test expressions expected to be passed to the tast command.
        self._exp_test_exprs = []

        # Array of dicts to be written to tast_test_stages.RESULTS_FILENAME as test
        # results. Not written if None. If a string is specified, it will be written
        # directly.
        self._test_results_data = []

        # Integer exit code to be returned by _FakeRunCommand.
        self._run_command_exit_code = 0

        # Optional exception to be raised by UploadArtifact.
        self._artifact_exception = None

        # Note that autospec=True instructs the mock library to verify that methods
        # that are called on the mock object actually exist and are passed valid
        # args. Without autospec=True, calls like mocked_object.nonexistent_method()
        # will succeed and return new mock objects.
        self._test_root = os.path.join(
            self.build_root,
            constants.DEFAULT_CHROOT_DIR,
            TastVMTestStageTest.RESULTS_CHROOT_PATH.lstrip("/"),
        )
        os.makedirs(self._test_root)
        self._mock_create_test_root = self.PatchObject(
            commands, "CreateTestRoot", autospec=True
        )
        self._mock_create_test_root.return_value = (
            TastVMTestStageTest.RESULTS_CHROOT_PATH
        )

        self._mock_run_command = self.PatchObject(
            cros_build_lib, "run", autospec=True
        )
        self._mock_run_command.side_effect = self._FakeRunCommand

        # Mock out functions that make calls to cros_build_lib.run that we
        # don't want to see.
        self.PatchObject(osutils, "RmDir", autospec=True)
        self.PatchObject(cgroups, "SimpleContainChildren", autospec=True)

        # Define mocked functions that can only be created once we've created the
        # stage in ConstructStage.
        self._mock_upload_artifact = None
        self._mock_print_download_link = None

        self._Prepare()

    def ConstructStage(self):
        # pylint: disable=protected-access
        self._run.GetArchive().SetupArchivePath()
        bs = FakeBuildStore()
        self._stage = tast_test_stages.TastVMTestStage(
            self._run, bs, self._current_board
        )
        self._stage._attempt = 1
        image_dir = self._stage.GetImageDirSymlink()
        osutils.Touch(
            os.path.join(image_dir, constants.TEST_KEY_PRIVATE), makedirs=True
        )

        # Mock out some of the methods that TastVMTestStage inherits from
        # generic_stages. This is gross, but slightly less gross than mocking out
        # everything called by generic_stages.
        self._mock_upload_artifact = self.PatchObject(
            self._stage, "UploadArtifact", autospec=True
        )
        self._mock_upload_artifact.side_effect = self._artifact_exception
        self._mock_print_download_link = self.PatchObject(
            self._stage, "PrintDownloadLink", autospec=True
        )

        return self._stage

    def _FakeRunCommand(self, cmd, **kwargs):
        """Fake implemenation of cros_build_lib.run."""
        # pylint: disable=unused-argument
        # Just check positional args and tricky flags. Checking all args is an
        # exercise in verifying that we're capable of typing the same thing twice.
        self.assertEqual(cmd[0], "./cros_run_test")

        # test_exprs are at the end, if they exist.
        num_test_exprs = len(self._exp_test_exprs)
        if num_test_exprs:
            self.assertEqual(cmd[-num_test_exprs:], self._exp_test_exprs)

        # The passed results dir should be relative to the chroot and should contain
        # the test suite.
        results_dir = os.path.join(self._test_root, self._exp_test_suite)
        self.assertIn("--results-dir=" + results_dir, cmd)

        # Should have tast.
        self.assertIn("--tast", cmd)

        if self._test_results_data is not None:
            self._WriteResultsFile(self._test_results_data)
        return cros_build_lib.CompletedProcess(
            returncode=self._run_command_exit_code
        )

    def _GetResultsFilePath(self):
        """Returns the path to the results file."""
        results_dir = os.path.join(self._test_root, self._exp_test_suite)
        if not os.path.isdir(results_dir):
            os.makedirs(results_dir)
        return os.path.join(results_dir, tast_test_stages.RESULTS_FILENAME)

    def _WriteResultsFile(self, data):
        """Writes a results file within the suite's results dir."""
        with open(self._GetResultsFilePath(), "w") as f:
            if isinstance(data, str):
                f.write(data)
            else:
                json.dump(data, f)

    def _SetSuite(self, suite_name, test_exprs):
        """Configures the test framework to run a given suite."""
        self._exp_test_suite = suite_name
        self._exp_test_exprs = test_exprs
        self._run.config["tast_vm_tests"] = [
            config_lib.TastVMTestConfig(suite_name, list(test_exprs)),
        ]

    def _VerifyArtifacts(self):
        """Verifies that results were archived and queued to be uploaded."""
        # pylint: disable=protected-access
        archive_dir = constants.TAST_VM_TEST_RESULTS % {
            "attempt": self._stage._attempt,
        }
        self.assertEqual(os.listdir(self._stage.archive_path), [archive_dir])
        archived_results_path = os.path.join(
            self._stage.archive_path,
            archive_dir,
            self._exp_test_suite,
            tast_test_stages.RESULTS_FILENAME,
        )
        self.assertTrue(os.path.isfile(archived_results_path))
        self._mock_upload_artifact.assert_called_once_with(
            archive_dir, archive=False, strict=False
        )

        # There should be a download link for results and for each failed test.
        self._mock_print_download_link.assert_any_call(
            archive_dir, tast_test_stages.RESULTS_LINK_PREFIX
        )
        num_failed_tests = 0
        with open(archived_results_path, "r") as f:
            for test in json.load(f):
                if (
                    test[tast_test_stages.RESULTS_ERRORS_KEY]
                    or test[tast_test_stages.RESULTS_END_KEY]
                    == tast_test_stages.ZERO_TIME
                ):
                    num_failed_tests += 1
                    informational = (
                        tast_test_stages.RESULTS_INFORMATIONAL_ATTR
                        in test.get(tast_test_stages.RESULTS_ATTR_KEY, [])
                    )

                    name = test[tast_test_stages.RESULTS_NAME_KEY]
                    test_url = os.path.join(
                        archive_dir,
                        self._exp_test_suite,
                        tast_test_stages.RESULTS_TESTS_DIR,
                        name,
                    )
                    desc = (
                        tast_test_stages.INFORMATIONAL_PREFIX + name
                        if informational
                        else name
                    )
                    self._mock_print_download_link.assert_any_call(
                        test_url, text_to_display=desc
                    )
        self.assertEqual(
            self._mock_print_download_link.call_count, num_failed_tests + 1
        )

    def _VerifyStageResult(self, result, description):
        """Verifies that the stage reported the expected result.

        Args:
          result: Either a string result constant from results_lib.Results
                  (e.g. SUCCESS, FORGIVEN, SKIPPED) or (in the case of a failure)
                  the exception class thrown by the test (e.g.
                  failures_lib.TestFailure).
          description: String exactly matching description in results_lib.Results().
        """
        self.assertEqual(
            [
                (
                    r.name,
                    r.result.__class__
                    if isinstance(r.result, Exception)
                    else r.result,
                    r.description,
                )
                for r in results_lib.Results.Get()
            ],
            [("TastVMTest", result, description)],
        )

    def testSuccess(self):
        """Perform a full test suite run."""
        self._SetSuite("good_test_suite", ["(bvt && chrome)", "(bvt && arc)"])
        self._test_results_data = [TastVMTestStageTest.PASSED_TEST]
        self.RunStage()
        self._VerifyStageResult(results_lib.Results.SUCCESS, None)

        self._mock_create_test_root.assert_called_once_with(self.build_root)
        self.assertEqual(self._mock_run_command.call_count, 1)
        self._VerifyArtifacts()

    def testNonZeroExitCode(self):
        """Tests that internal errors from the tast command are reported."""
        self._SetSuite("non_zero_exit_code_test_suite", [])
        self._test_results_data = [TastVMTestStageTest.FAILED_TEST]
        self._run_command_exit_code = 1

        self.assertRaises(failures_lib.TestFailure, self.RunStage)
        self._VerifyStageResult(
            failures_lib.TestFailure, tast_test_stages.FAILURE_EXIT_CODE % 1
        )

        self._mock_create_test_root.assert_called_once_with(self.build_root)
        self.assertEqual(self._mock_run_command.call_count, 1)
        self._VerifyArtifacts()

    def testFailedTest(self):
        """Tests that test failures are reported."""
        self._SetSuite("failed_test_suite", [])
        self._test_results_data = [
            TastVMTestStageTest.FAILED_TEST,
            TastVMTestStageTest.PASSED_TEST,
            TastVMTestStageTest.INCOMPLETE_TEST,
        ]
        self.assertRaises(failures_lib.TestFailure, self.RunStage)
        self._VerifyStageResult(
            failures_lib.TestFailure, tast_test_stages.FAILURE_TESTS_FAILED % 2
        )

        self._mock_create_test_root.assert_called_once_with(self.build_root)
        self.assertEqual(self._mock_run_command.call_count, 1)
        self._VerifyArtifacts()

    def testInformationalTest(self):
        """Tests that errors in informational tests don't fail the stage."""
        attr = tast_test_stages.RESULTS_INFORMATIONAL_ATTR
        self._SetSuite("info_test_suite", ["(" + attr + ")"])
        self._test_results_data = [
            {
                "name": "example.Informational",
                "start": "2019-05-03T16:28:31-07:00",
                "end": "2019-05-03T16:28:36-07:00",
                "attr": [attr],
                "errors": [{"reason": "Failed!"}],
            },
        ]

        self.RunStage()
        self._VerifyStageResult(results_lib.Results.SUCCESS, None)
        self._VerifyArtifacts()

    def testMissingResultsDir(self):
        """Tests that an error is returned if the results dir is missing."""
        self._SetSuite("missing_results_test_suite", [])
        self._test_results_data = None

        self.assertRaises(failures_lib.TestFailure, self.RunStage)
        self._VerifyStageResult(
            failures_lib.TestFailure,
            tast_test_stages.FAILURE_NO_RESULTS % self._test_root,
        )

    def testBadResultsFile(self):
        """Tests that an error is returned if the results file is unreadable."""
        self._SetSuite("bad_results_test_suite", [])
        self._test_results_data = "bogus"

        self.assertRaises(failures_lib.TestFailure, self.RunStage)
        # Python versions change the error message.
        if sys.version_info.major < 3:
            msg = "No JSON object could be decoded"
        else:
            msg = "Expecting value: line 1 column 1 (char 0)"
        self._VerifyStageResult(
            failures_lib.TestFailure,
            tast_test_stages.FAILURE_BAD_RESULTS
            % (self._GetResultsFilePath(), msg),
        )

    def testFailedArchive(self):
        """Tests that archive failures raise InfrastructureFailure."""
        self._SetSuite("failed_archive_test_suite", [])
        self._artifact_exception = Exception("upload failed")
        self.ConstructStage()
        self.assertRaises(
            failures_lib.InfrastructureFailure, self._stage.PerformStage
        )


class CopyResultsDirTest(cros_test_lib.TempDirTestCase):
    """Tests for tast_test_stages._CopyResultsDir."""

    def setUp(self):
        self.src = os.path.join(self.tempdir, "src")
        self.dest = os.path.join(self.tempdir, "dest")

    def _WriteSrcFile(self, path, data):
        """Creates a file within self.src.

        Args:
          path: String containing relative path to create within self.src.
          data: String data to write to file.
        """
        full_path = os.path.join(self.src, path)
        dir_path = os.path.dirname(full_path)
        if not os.path.exists(dir_path):
            os.makedirs(dir_path)
        with open(full_path, "w") as f:
            f.write(data)

    def _DoCopy(self):
        """Copies from src to dest directory."""
        # pylint: disable=protected-access
        tast_test_stages._CopyResultsDir(self.src, self.dest)

    def testCopyAll(self):
        """Tests that files and directories are recursively copied."""
        path1 = "myfile.txt"
        data1 = "foo"
        self._WriteSrcFile(path1, data1)

        path2 = "subdir/other.txt"
        data2 = "bar"
        self._WriteSrcFile(path2, data2)

        empty_dir = "empty"
        os.makedirs(os.path.join(self.src, empty_dir))

        self._DoCopy()
        self.assertFileContents(os.path.join(self.dest, path1), data1)
        self.assertFileContents(os.path.join(self.dest, path2), data2)
        self.assertExists(os.path.join(self.dest, empty_dir))

    def testDestAlreadyExists(self):
        """Tests that OSError is raised if the destination dir already exists."""
        self._WriteSrcFile("myfile.txt", "foo")
        os.makedirs(self.dest)
        self.assertRaises(OSError, self._DoCopy)

    def testSkipSymlink(self):
        """Tests that symlinks are skipped."""
        path = "myfile.txt"
        data = "foo"
        self._WriteSrcFile(path, data)

        link = "symlink.txt"
        os.symlink(path, os.path.join(self.src, link))

        self._DoCopy()
        self.assertFileContents(os.path.join(self.dest, path), data)
        self.assertNotExists(os.path.join(self.dest, link))
