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

"""Unittests for manifest_version. Needs to be run inside of chroot."""

import os
from unittest import mock

from chromite.cbuildbot import build_status
from chromite.cbuildbot import manifest_version
from chromite.cbuildbot import repository
from chromite.lib import builder_status_lib
from chromite.lib import chromeos_version
from chromite.lib import cros_test_lib
from chromite.lib import git
from chromite.lib import osutils
from chromite.lib import timeout_util
from chromite.lib.buildstore import BuildIdentifier
from chromite.lib.buildstore import FakeBuildStore
from chromite.lib.chromeos_version_unittest import VersionInfoTest


FAKE_VERSION = """
CHROMEOS_BUILD=%(build_number)s
CHROMEOS_BRANCH=%(branch_build_number)s
CHROMEOS_PATCH=%(patch_number)s
CHROME_BRANCH=%(chrome_branch)s
"""

FAKE_WHITELISTED_REMOTES = ("cros", "chromium")
FAKE_NON_WHITELISTED_REMOTE = "hottubtimemachine"

FAKE_VERSION_STRING = "1.2.3"
FAKE_VERSION_STRING_NEXT = "1.2.4"
CHROME_BRANCH = "13"

# Use the chromite repo to actually test git changes.
GIT_TEST_PATH = "chromite"

MOCK_BUILD_ID = 162345


# pylint: disable=protected-access


class HelperMethodsTest(cros_test_lib.TempDirTestCase):
    """Test methods associated with methods not in a class."""

    def testCreateSymlink(self):
        """Tests that we can create symlinks and remove a previous one."""
        srcfile = os.path.join(self.tempdir, "src")
        osutils.Touch(srcfile)
        other_dir = os.path.join(self.tempdir, "other_dir")
        os.makedirs(other_dir)
        destfile = os.path.join(other_dir, "dest")

        manifest_version.CreateSymlink(srcfile, destfile)
        self.assertTrue(
            os.path.lexists(destfile),
            "Unable to create symlink to %s" % destfile,
        )


class ResolveHelpersTest(cros_test_lib.TempDirTestCase):
    """Test the buildspec resolution helper functions."""

    def setUp(self):
        self.mv_path = self.tempdir

        self.version = "1.2.3"
        self.resolvedVersionSpec = os.path.join(
            self.mv_path, "buildspecs", "12", "1.2.3.xml"
        )

        self.invalidSpec = os.path.join("invalid", "spec")

        self.validSpec = os.path.join("valid", "spec")
        self.resolvedValidSpec = os.path.join(self.mv_path, "valid", "spec.xml")

        osutils.Touch(self.resolvedVersionSpec, makedirs=True)
        osutils.Touch(self.resolvedValidSpec, makedirs=True)

    def testResolveBuildspec(self):
        """Test ResolveBuildspec."""
        result = manifest_version.ResolveBuildspec(self.mv_path, self.validSpec)
        self.assertEqual(result, self.resolvedValidSpec)

        result = manifest_version.ResolveBuildspec(
            self.mv_path, self.validSpec + ".xml"
        )
        self.assertEqual(result, self.resolvedValidSpec)

        with self.assertRaises(manifest_version.BuildSpecsValueError):
            manifest_version.ResolveBuildspec(self.mv_path, self.invalidSpec)

    def testResolveBuildspecVersion(self):
        """Test ResolveBuildspecVersion."""
        result = manifest_version.ResolveBuildspecVersion(
            self.mv_path, self.version
        )
        self.assertEqual(result, self.resolvedVersionSpec)

        with self.assertRaises(manifest_version.BuildSpecsValueError):
            manifest_version.ResolveBuildspecVersion(self.mv_path, "1.2.0")


class FilterManifestTest(cros_test_lib.TempDirTestCase):
    """Test for FilterManifest."""

    def testSimple(self):
        """Basic check of functionality."""
        path = os.path.join(self.tempdir, "input.xml")
        osutils.WriteFile(
            path,
            """\
<?xml version="1.0" encoding="UTF-8"?>
<manifest>
  <include name="default.xml" />
</manifest>
""",
        )
        new_path = manifest_version.FilterManifest(path)
        self.assertEqual(
            """\
<?xml version="1.0" encoding="utf-8"?><manifest>
<include name="default.xml"/>
</manifest>\
""",
            osutils.ReadFile(new_path),
        )


class BuildSpecFunctionsTest(cros_test_lib.MockTempDirTestCase):
    """Tests for methods related to publishing buildspecs."""

    def setUp(self):
        self.version_info = chromeos_version.VersionInfo("1.2.3", "11")

        self.manifest_versions_int = os.path.join(
            self.tempdir, "manifest_versions_int"
        )
        self.manifest_versions_ext = os.path.join(
            self.tempdir, "manifest_versions_ext"
        )

    def testOfficialBuildSpecPath(self):
        """Test OfficialBuildSpecPath."""
        result = manifest_version.OfficialBuildSpecPath(self.version_info)
        self.assertEqual(result, "buildspecs/11/1.2.3.xml")

    def testPopulateAndPublishBuildSpec(self):
        """Test PopulateAndPublishBuildSpec."""
        commitMock = self.PatchObject(manifest_version, "_CommitAndPush")

        filter_out = os.path.join(self.tempdir, "filter_out")
        osutils.WriteFile(filter_out, "filtered mani")
        self.PatchObject(
            manifest_version, "FilterManifest", return_value=filter_out
        )

        manifest_version.PopulateAndPublishBuildSpec(
            "spec",
            "int mani",
            self.manifest_versions_int,
            self.manifest_versions_ext,
            dryrun=True,
        )

        self.assertEqual(
            commitMock.call_args_list,
            [
                mock.call(
                    self.manifest_versions_int,
                    (
                        "https://chrome-internal.googlesource.com/chromeos/"
                        "manifest-versions"
                    ),
                    "spec",
                    "int mani",
                    True,
                ),
                mock.call(
                    self.manifest_versions_ext,
                    (
                        "https://chromium.googlesource.com/chromiumos/"
                        "manifest-versions"
                    ),
                    "spec",
                    "filtered mani",
                    True,
                ),
            ],
        )

    def testPopulateAndPublishBuildSpecIntOnly(self):
        """Test PopulateAndPublishBuildSpec without external manifest versions."""
        commitMock = self.PatchObject(manifest_version, "_CommitAndPush")

        filter_out = os.path.join(self.tempdir, "filter_out")
        osutils.WriteFile(filter_out, "filtered mani")
        self.PatchObject(
            manifest_version, "FilterManifest", return_value=filter_out
        )

        manifest_version.PopulateAndPublishBuildSpec(
            "spec", "int mani", self.manifest_versions_int, None, dryrun=False
        )

        self.assertEqual(
            commitMock.call_args_list,
            [
                mock.call(
                    self.manifest_versions_int,
                    (
                        "https://chrome-internal.googlesource.com/chromeos/"
                        "manifest-versions"
                    ),
                    "spec",
                    "int mani",
                    False,
                ),
            ],
        )


class BuildSpecsManagerTest(cros_test_lib.MockTempDirTestCase):
    """Tests for the BuildSpecs manager."""

    def setUp(self):
        os.makedirs(os.path.join(self.tempdir, ".repo"))
        self.source_repo = "ssh://source/repo"
        self.manifest_repo = "ssh://manifest/repo"
        self.version_file = "version-file.sh"
        self.branch = "master"
        self.build_names = ["amd64-generic-release"]
        self.incr_type = "branch"
        # Change default to something we clean up.
        self.tmpmandir = os.path.join(self.tempdir, "man")
        osutils.SafeMakedirs(self.tmpmandir)
        self.manager = None

        self.PatchObject(
            builder_status_lib.SlaveBuilderStatus, "_InitSlaveInfo"
        )

        self.db = mock.Mock()
        self.buildstore = FakeBuildStore(self.db)
        self.buildbucket_client_mock = mock.Mock()

    def BuildManager(self, config=None, metadata=None, buildbucket_client=None):
        repo = repository.RepoRepository(
            self.source_repo, self.tempdir, self.branch
        )
        manager = manifest_version.BuildSpecsManager(
            repo,
            self.manifest_repo,
            self.build_names,
            self.incr_type,
            False,
            branch=self.branch,
            dry_run=True,
            config=config,
            metadata=metadata,
            buildstore=self.buildstore,
            buildbucket_client=buildbucket_client,
        )
        manager.manifest_dir = self.tmpmandir
        # Shorten the sleep between attempts.
        manager.SLEEP_TIMEOUT = 1

        return manager

    def testPublishManifestCommitMessageWithBuildId(self):
        """Tests that PublishManifest writes a build id."""
        self.manager = self.BuildManager()
        expected_message = (
            "Automatic: Start amd64-generic-release master 1\n"
            "CrOS-Build-Id: %s" % MOCK_BUILD_ID
        )
        push_mock = self.PatchObject(self.manager, "PushSpecChanges")

        info = chromeos_version.VersionInfo(
            FAKE_VERSION_STRING, CHROME_BRANCH, incr_type="branch"
        )

        # Create a fake manifest file.
        m = os.path.join(self.tmpmandir, "1.xml")
        osutils.Touch(m)
        self.manager.InitializeManifestVariables(info)

        self.manager.PublishManifest(m, "1", build_id=MOCK_BUILD_ID)

        push_mock.assert_called_once_with(expected_message)

    def testPublishManifestCommitMessageWithNegativeBuildId(self):
        """Tests that PublishManifest doesn't write a negative build_id"""
        self.manager = self.BuildManager()
        expected_message = "Automatic: Start amd64-generic-release master 1"
        push_mock = self.PatchObject(self.manager, "PushSpecChanges")

        info = chromeos_version.VersionInfo(
            FAKE_VERSION_STRING, CHROME_BRANCH, incr_type="branch"
        )

        # Create a fake manifest file.
        m = os.path.join(self.tmpmandir, "1.xml")
        osutils.Touch(m)
        self.manager.InitializeManifestVariables(info)

        self.manager.PublishManifest(m, "1", build_id=-1)

        push_mock.assert_called_once_with(expected_message)

    def testPublishManifestCommitMessageWithNoneBuildId(self):
        """Tests that PublishManifest doesn't write a non-existant build_id"""
        self.manager = self.BuildManager()
        expected_message = "Automatic: Start amd64-generic-release master 1"
        push_mock = self.PatchObject(self.manager, "PushSpecChanges")

        info = chromeos_version.VersionInfo(
            FAKE_VERSION_STRING, CHROME_BRANCH, incr_type="branch"
        )

        # Create a fake manifest file.
        m = os.path.join(self.tmpmandir, "1.xml")
        osutils.Touch(m)
        self.manager.InitializeManifestVariables(info)

        self.manager.PublishManifest(m, "1")

        push_mock.assert_called_once_with(expected_message)

    def _buildManifest(self):
        mpath = os.path.join(
            self.manager.manifest_dir, "buildspecs", CHROME_BRANCH
        )
        manifest_paths = [
            os.path.join(mpath, "1.2.%d.xml" % x) for x in [2, 3, 4, 5]
        ]
        # Create fake buildspecs.
        osutils.SafeMakedirs(os.path.join(mpath))
        for m in manifest_paths:
            osutils.Touch(m)

        return manifest_paths

    def testInitializeManifestVariablesWithUnprocessedBuild(self):
        """Test InitializeManifestVariables with unprocessed build."""
        self.manager = self.BuildManager()
        info = chromeos_version.VersionInfo(
            FAKE_VERSION_STRING, CHROME_BRANCH, incr_type="branch"
        )
        for_build = os.path.join(
            self.manager.manifest_dir, "build-name", self.build_names[0]
        )

        m1, m2, _, _ = self._buildManifest()
        # Fail 1, pass 2, leave 3,4 unprocessed.
        manifest_version.CreateSymlink(
            m1,
            os.path.join(
                for_build, "fail", CHROME_BRANCH, os.path.basename(m1)
            ),
        )
        manifest_version.CreateSymlink(
            m1,
            os.path.join(
                for_build, "pass", CHROME_BRANCH, os.path.basename(m2)
            ),
        )

        self.manager.buildstore.fake_cidb.GetBuildHistory.return_value = None
        self.manager.InitializeManifestVariables(info)
        self.assertEqual(self.manager.latest_unprocessed, "1.2.5")
        self.assertIsNone(self.manager._latest_build)

    def testInitializeManifestVariablesWithPassedBuild(self):
        """Test InitializeManifestVariables with passed build."""
        self.manager = self.BuildManager()
        info = chromeos_version.VersionInfo(
            FAKE_VERSION_STRING, CHROME_BRANCH, incr_type="branch"
        )
        for_build = os.path.join(
            self.manager.manifest_dir, "build-name", self.build_names[0]
        )

        m1, m2, m3, m4 = self._buildManifest()
        # Fail 1, pass 2, pass 3, pass 4
        manifest_version.CreateSymlink(
            m1,
            os.path.join(
                for_build, "fail", CHROME_BRANCH, os.path.basename(m1)
            ),
        )
        for m in [m2, m3, m4]:
            manifest_version.CreateSymlink(
                m,
                os.path.join(
                    for_build, "pass", CHROME_BRANCH, os.path.basename(m)
                ),
            )

        latest_builds = [
            {
                "build_config": self.build_names[0],
                "status": "pass",
                "platform_version": "1.2.5",
            }
        ]
        self.manager.buildstore.fake_cidb.GetBuildHistory.return_value = (
            latest_builds
        )
        self.manager.InitializeManifestVariables(info)
        self.assertIsNone(self.manager.latest_unprocessed)
        self.assertEqual(self.manager._latest_build, latest_builds[0])

    def testLatestSpecFromDir(self):
        """Tests whether we can get sorted specs correctly from a directory."""
        self.manager = self.BuildManager()
        self.PatchObject(git, "Clone", side_effect=Exception())
        info = chromeos_version.VersionInfo(
            "99.1.2", CHROME_BRANCH, incr_type="branch"
        )

        specs_dir = os.path.join(
            self.manager.manifest_dir, "buildspecs", CHROME_BRANCH
        )
        m1, m2, m3, m4 = [
            os.path.join(specs_dir, x)
            for x in ["100.0.0.xml", "99.3.3.xml", "99.1.10.xml", "99.1.5.xml"]
        ]

        # Create fake buildspecs.
        osutils.SafeMakedirs(specs_dir)
        for m in [m1, m2, m3, m4]:
            osutils.Touch(m)

        spec = self.manager._LatestSpecFromDir(info, specs_dir)
        # Should be the latest on the 99.1 branch.
        self.assertEqual(spec, "99.1.10")

    def testGetNextVersionNoIncrement(self):
        """Tests whether we can get the next version to be built correctly.

        Tests without pre-existing version in manifest dir.
        """
        self.manager = self.BuildManager()
        info = chromeos_version.VersionInfo(
            FAKE_VERSION_STRING, CHROME_BRANCH, incr_type="branch"
        )

        self.manager.latest = None
        version = self.manager.GetNextVersion(info)
        self.assertEqual(FAKE_VERSION_STRING, version)

    def testGetNextVersionIncrement(self):
        """Tests that we create a new version if a previous one exists."""
        self.manager = self.BuildManager()
        self.manager.dry_run = False
        m = self.PatchObject(chromeos_version.VersionInfo, "UpdateVersionFile")
        version_file = VersionInfoTest.CreateFakeVersionFile(self.tempdir)
        info = chromeos_version.VersionInfo(
            version_file=version_file, incr_type="branch"
        )

        self.manager.latest = FAKE_VERSION_STRING
        version = self.manager.GetNextVersion(info)
        self.assertEqual(FAKE_VERSION_STRING_NEXT, version)
        m.assert_called_once_with(
            "Automatic: %s - Updating to a new version number from %s"
            % (self.build_names[0], FAKE_VERSION_STRING),
            dry_run=False,
        )

    def testGetNextVersionDryRun(self):
        """Tests that we reuse a previous version if it is a dryrun."""
        self.manager = self.BuildManager()
        m = self.PatchObject(chromeos_version.VersionInfo, "UpdateVersionFile")
        version_file = VersionInfoTest.CreateFakeVersionFile(self.tempdir)
        info = chromeos_version.VersionInfo(
            version_file=version_file, incr_type="branch"
        )

        self.manager.latest = FAKE_VERSION_STRING
        version = self.manager.GetNextVersion(info)
        self.assertEqual(FAKE_VERSION_STRING, version)
        m.assert_called_once_with(
            "Automatic: %s - Updating to a new version number from %s"
            % (self.build_names[0], FAKE_VERSION_STRING),
            dry_run=True,
        )

    def testGetNextBuildSpec(self):
        """End-to-end test of updating the manifest."""
        self.manager = self.BuildManager()
        my_info = chromeos_version.VersionInfo("1.2.3", chrome_branch="4")
        self.PatchObject(
            manifest_version.BuildSpecsManager,
            "GetCurrentVersionInfo",
            return_value=my_info,
        )
        self.PatchObject(repository.RepoRepository, "Sync")
        self.PatchObject(
            repository.RepoRepository,
            "ExportManifest",
            return_value="<manifest />",
        )
        rc = self.StartPatcher(cros_test_lib.RunCommandMock())
        rc.SetDefaultCmdResult()

        self.manager.GetNextBuildSpec(retries=0)
        self.manager.UpdateStatus({self.build_names[0]: True})

    def testDidLastBuildFailReturnsFalse(self):
        """Test DidLastBuildFail returns False."""
        self.manager = self.BuildManager()
        self.assertFalse(self.manager.DidLastBuildFail())

    # pylint: disable=attribute-defined-outside-init
    def testDidLastBuildFailReturnsTrue(self):
        """Test DidLastBuildFailReturns True."""
        self.manager = self.BuildManager()
        self._latest_build = {
            "build_config": self.build_names[0],
            "status": "fail",
            "platform_version": "1.2.5",
        }
        self.assertFalse(self.manager.DidLastBuildFail())

    def testWaitForSlavesToCompleteWithEmptyBuildersArray(self):
        """Test WaitForSlavesToComplete with an empty builders_array."""
        self.manager = self.BuildManager()
        self.manager.WaitForSlavesToComplete(1, [])

    def testWaitForSlavesToComplete(self):
        """Test WaitForSlavesToComplete."""
        self.PatchObject(build_status.SlaveStatus, "UpdateSlaveStatus")
        self.PatchObject(
            build_status.SlaveStatus, "ShouldWait", return_value=False
        )
        self.manager = self.BuildManager()
        self.manager.WaitForSlavesToComplete(
            BuildIdentifier(cidb_id=1, buildbucket_id=1234),
            ["build_1", "build_2"],
        )

    def testWaitForSlavesToCompleteWithTimeout(self):
        """Test WaitForSlavesToComplete raises timeout."""
        self.PatchObject(build_status.SlaveStatus, "UpdateSlaveStatus")
        self.PatchObject(
            build_status.SlaveStatus, "ShouldWait", return_value=True
        )
        self.manager = self.BuildManager()
        self.assertRaises(
            timeout_util.TimeoutError,
            self.manager.WaitForSlavesToComplete,
            BuildIdentifier(cidb_id=1, buildbucket_id=1234),
            ["build_1", "build_2"],
            timeout=1,
            ignore_timeout_exception=False,
        )
