#!/usr/bin/python

# Copyright (c) 2011 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.

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

import mox
import os
import shutil
import sys
import tempfile
import unittest

if __name__ == '__main__':
  import constants
  sys.path.append(constants.SOURCE_ROOT)

from chromite.buildbot import cbuildbot_config
from chromite.buildbot import manifest_version
from chromite.buildbot import repository
from chromite.lib import cros_build_lib as cros_lib

FAKE_VERSION = """
CHROMEOS_BUILD=1
CHROMEOS_BRANCH=2
CHROMEOS_PATCH=3
CHROME_BRANCH=13
"""

FAKE_VERSION_STRING = '1.2.3'
FAKE_VERSION_STRING_NEXT = '1.2.4'
CHROME_BRANCH = '13'

# Dir to use to sync repo for git testing.
GIT_DIR = '/tmp/repo_for_manifest_version_unittest'

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

def TouchFile(file_path):
  """Touches a file specified by file_path"""
  if not os.path.exists(os.path.dirname(file_path)):
    os.makedirs(os.path.dirname(file_path))

  touch_file = open(file_path, 'w+')
  touch_file.close()


class HelperMethodsTest(unittest.TestCase):
  """Test methods associated with methods not in a class."""

  def setUp(self):
    self.tmpdir = tempfile.mkdtemp()

  def testCreateSymlink(self):
    """Tests that we can create symlinks and remove a previous one."""
    (unused_fd, srcfile) = tempfile.mkstemp(dir=self.tmpdir)
    destfile1 = tempfile.mktemp(dir=os.path.join(self.tmpdir, 'other_dir1'))
    destfile2 = tempfile.mktemp(dir=os.path.join(self.tmpdir, 'other_dir2'))

    manifest_version.CreateSymlink(srcfile, destfile1, remove_file=None)
    self.assertTrue(os.path.lexists(destfile1),
                    'Unable to create symlink to %s' % destfile1)

    manifest_version.CreateSymlink(srcfile, destfile2, remove_file=destfile1)
    self.assertTrue(os.path.lexists(destfile2),
                    'Unable to create symlink to %s' % destfile2)
    self.assertFalse(os.path.lexists(destfile1),
                    'Unable to remove symlink %s' % destfile1)

  def testRemoveDirs(self):
    """Tests if _RemoveDirs works with a recursive directory structure."""
    otherdir1 = tempfile.mkdtemp(dir=self.tmpdir)
    tempfile.mkdtemp(dir=otherdir1)
    manifest_version._RemoveDirs(otherdir1)
    self.assertFalse(os.path.exists(otherdir1), 'Failed to rmdirs.')

  def testPushGitChanges(self):
    """Tests if we can append to an authors file and push it using dryrun."""
    if not os.path.exists(GIT_DIR): os.makedirs(GIT_DIR)
    init_cmd = ['repo', 'init', '-u', constants.MANIFEST_URL, '--repo-url',
                constants.REPO_URL, '-m', 'minilayout.xml']
    cros_lib.RunCommand(init_cmd, cwd=GIT_DIR, input='\n\ny\n')
    cros_lib.RunCommand(('repo sync --jobs 8').split(), cwd=GIT_DIR)
    git_dir = os.path.join(GIT_DIR, GIT_TEST_PATH)
    cros_lib.RunCommand(['git',
                         'config',
                         'url.%s.insteadof' % constants.GERRIT_SSH_URL,
                         constants.GIT_HTTP_URL], cwd=git_dir)

    manifest_version._PrepForChanges(git_dir, dry_run=True)

    # Change something.
    cros_lib.RunCommand(('tee --append %s/AUTHORS' % git_dir).split(),
                        input='TEST USER <test_user@chromium.org>')

    # Push the change with dryrun.
    manifest_version._PushGitChanges(git_dir, 'Test appending user.',
                                     dry_run=True)

  def testPushGitChangesWithRealPrep(self):
    """Another push test that tests push but on non-repo does it on a branch."""
    git_dir = tempfile.mktemp('manifest_dir')
    manifest_versions_url = cbuildbot_config.GetManifestVersionsRepoUrl(
        internal_build=False, read_only=True)
    cros_lib.RunCommand(['git', 'clone', manifest_versions_url, git_dir])
    try:
      cros_lib.RunCommand(['git',
                           'config',
                           'url.%s.insteadof' % constants.GERRIT_SSH_URL,
                           constants.GIT_HTTP_URL], cwd=git_dir)

      manifest_version._PrepForChanges(git_dir, dry_run=False)

      # This should not error out if we are running with dry_run=False for
      # prep for changes.
      cros_lib.RunCommand(['git', 'show', manifest_version._PUSH_BRANCH],
                          cwd=git_dir)

      # Change something.
      cros_lib.RunCommand(('tee --append %s/AUTHORS' % git_dir).split(),
                          input='TEST USER <test_user@chromium.org>')

      # Push the change with dryrun.
      manifest_version._PushGitChanges(git_dir, 'Test appending user.',
                                       dry_run=True)

      # This should not error out if we are running with dry_run=False for
      # prep for changes.
      cros_lib.RunCommand(['git', 'show', manifest_version._PUSH_BRANCH],
                          cwd=git_dir)
    finally:
      shutil.rmtree(git_dir)

  def tearDown(self):
    shutil.rmtree(self.tmpdir)


class VersionInfoTest(mox.MoxTestBase):
  """Test methods testing methods in VersionInfo class."""

  def setUp(self):
    mox.MoxTestBase.setUp(self)
    self.tmpdir = tempfile.mkdtemp()

  @classmethod
  def CreateFakeVersionFile(cls, tmpdir):
    """Helper method to create a version file from FAKE_VERSION."""
    (version_file_fh, version_file) = tempfile.mkstemp(dir=tmpdir)
    os.write(version_file_fh, FAKE_VERSION)
    os.close(version_file_fh)
    return version_file

  def testLoadFromFile(self):
    """Tests whether we can load from a version file."""
    version_file = self.CreateFakeVersionFile(self.tmpdir)
    info = manifest_version.VersionInfo(version_file=version_file)
    self.assertEqual(info.VersionString(), FAKE_VERSION_STRING)

  def testLoadFromString(self):
    """Tests whether we can load from a string."""
    info = manifest_version.VersionInfo(FAKE_VERSION_STRING, CHROME_BRANCH)
    self.assertEqual(info.VersionString(), FAKE_VERSION_STRING)

  def CommonTestIncrementVersion(self, incr_type):
    """Common test increment.  Returns path to new incremented file."""
    message = 'Incrementing cuz I sed so'
    self.mox.StubOutWithMock(manifest_version, '_PrepForChanges')
    self.mox.StubOutWithMock(manifest_version, '_PushGitChanges')

    manifest_version._PrepForChanges(self.tmpdir, False)

    version_file = self.CreateFakeVersionFile(self.tmpdir)

    manifest_version._PushGitChanges(self.tmpdir, message, dry_run=False)

    self.mox.ReplayAll()
    info = manifest_version.VersionInfo(version_file=version_file,
                                        incr_type=incr_type)
    info.IncrementVersion(message, dry_run=False)
    self.mox.VerifyAll()
    return version_file

  def testIncrementVersionPatch(self):
    """Tests whether we can increment a version file by patch number."""
    version_file = self.CommonTestIncrementVersion('patch')
    new_info = manifest_version.VersionInfo(version_file=version_file,
                                            incr_type='patch')
    self.assertEqual(new_info.VersionString(), FAKE_VERSION_STRING_NEXT)

  def testIncrementVersionBranch(self):
    """Tests whether we can increment a version file by branch number."""
    version_file = self.CommonTestIncrementVersion('branch')
    new_info = manifest_version.VersionInfo(version_file=version_file,
                                            incr_type='branch')
    self.assertEqual(new_info.VersionString(), '1.3.0')

  def testIncrementVersionBuild(self):
    """Tests whether we can increment a version file by build number."""
    version_file = self.CommonTestIncrementVersion('build')
    new_info = manifest_version.VersionInfo(version_file=version_file,
                                            incr_type='build')
    self.assertEqual(new_info.VersionString(), '2.0.0')

  def tearDown(self):
    shutil.rmtree(self.tmpdir)


class BuildSpecsManagerTest(mox.MoxTestBase):
  """Tests for the BuildSpecs manager."""

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

    self.tmpdir = tempfile.mkdtemp()
    os.makedirs(os.path.join(self.tmpdir, '.repo'))
    self.source_repo = 'ssh://source/repo'
    self.manifest_repo = 'ssh://manifest/repo'
    self.version_file = 'version-file.sh'
    self.branch = 'master'
    self.build_name = 'x86-generic'
    self.incr_type = 'patch'

    # Change default to something we clean up.
    self.tmpmandir = tempfile.mkdtemp()
    manifest_version.BuildSpecsManager._TMP_MANIFEST_DIR = self.tmpmandir

    self.manager = manifest_version.BuildSpecsManager(
      self.tmpdir, self.source_repo, self.manifest_repo, self.branch,
      self.build_name, self.incr_type, dry_run=True)

  def testLoadSpecs(self):
    """Tests whether we can load specs correctly."""
    self.mox.StubOutWithMock(manifest_version, '_RemoveDirs')
    self.mox.StubOutWithMock(repository, 'CloneGitRepo')
    info = manifest_version.VersionInfo(
        FAKE_VERSION_STRING, CHROME_BRANCH, incr_type='patch')
    m1 = os.path.join(self.manager._TMP_MANIFEST_DIR, 'buildspecs',
                      CHROME_BRANCH, '1.2.2.xml')
    m2 = os.path.join(self.manager._TMP_MANIFEST_DIR, 'buildspecs',
                      CHROME_BRANCH, '1.2.3.xml')
    m3 = os.path.join(self.manager._TMP_MANIFEST_DIR, 'buildspecs',
                      CHROME_BRANCH, '1.2.4.xml')
    m4 = os.path.join(self.manager._TMP_MANIFEST_DIR, 'buildspecs',
                      CHROME_BRANCH, '1.2.5.xml')
    for_build = os.path.join(self.manager._TMP_MANIFEST_DIR, 'build-name',
                             self.build_name)

    # Create fake buildspecs.
    TouchFile(m1)
    TouchFile(m2)
    TouchFile(m3)
    TouchFile(m4)

    # 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)))
    manifest_version._RemoveDirs(self.manager._TMP_MANIFEST_DIR)
    repository.CloneGitRepo(self.manager._TMP_MANIFEST_DIR,
                            self.manifest_repo)
    self.mox.StubOutWithMock(self.manager, '_GetSpecAge')
    self.manager._GetSpecAge('1.2.5').AndReturn(100)
    self.mox.ReplayAll()
    self.manager._LoadSpecs(info)
    self.mox.VerifyAll()
    self.assertEqual(self.manager.latest_unprocessed, '1.2.5')

  def testGetMatchingSpecs(self):
    """Tests whether we can get sorted specs correctly from a directory."""
    self.mox.StubOutWithMock(manifest_version, '_RemoveDirs')
    self.mox.StubOutWithMock(repository, 'CloneGitRepo')
    info = manifest_version.VersionInfo(
        '99.1.2', CHROME_BRANCH, incr_type='branch')

    specs_dir = os.path.join(self.manager._TMP_MANIFEST_DIR, 'buildspecs',
                             CHROME_BRANCH)
    m1 = os.path.join(specs_dir, '100.0.0.xml')
    m2 = os.path.join(specs_dir, '99.3.3.xml')
    m3 = os.path.join(specs_dir, '99.1.10.xml')
    m4 = os.path.join(specs_dir, '99.1.5.xml')

    # Create fake buildspecs.
    TouchFile(m1)
    TouchFile(m2)
    TouchFile(m3)
    TouchFile(m4)

    self.mox.ReplayAll()
    specs = self.manager._GetMatchingSpecs(info, specs_dir)
    self.mox.VerifyAll()
    # Should be the latest on the 99.1 branch
    self.assertEqual(specs[-1], '99.3.3')

  def testCreateNewBuildSpecNoCopy(self):
    """Tests whether we can create a new build spec correctly.

    Tests without pre-existing version file in manifest dir.
    """
    self.mox.StubOutWithMock(repository.RepoRepository, 'ExportManifest')
    self.mox.StubOutWithMock(manifest_version, '_PrepForChanges')
    self.mox.StubOutWithMock(manifest_version, '_PushGitChanges')
    info = manifest_version.VersionInfo(
        FAKE_VERSION_STRING, CHROME_BRANCH, incr_type='patch')

    self.manager.all_specs_dir = os.path.join(self.manager._TMP_MANIFEST_DIR,
                                              'buildspecs', '1.2')

    repository.RepoRepository.ExportManifest(mox.IgnoreArg())

    self.mox.ReplayAll()
    self.manager.all = []
    version = self.manager._CreateNewBuildSpec(info)
    self.mox.VerifyAll()
    self.assertEqual(FAKE_VERSION_STRING, version)

  def testCreateNewBuildIncrement(self):
    """Tests that we create a new version if a previous one exists."""
    self.mox.StubOutWithMock(manifest_version.VersionInfo, 'IncrementVersion')
    self.mox.StubOutWithMock(repository.RepoRepository, 'ExportManifest')
    self.mox.StubOutWithMock(repository.RepoRepository, 'Sync')

    version_file = VersionInfoTest.CreateFakeVersionFile(self.tmpdir)
    info = manifest_version.VersionInfo(version_file=version_file,
                                         incr_type='patch')
    self.manager.all_specs_dir = os.path.join(self.manager._TMP_MANIFEST_DIR,
                                              'buildspecs', '1.2')
    info.IncrementVersion(
        'Automatic: %s - Updating to a new version number from %s' % (
            self.build_name, FAKE_VERSION_STRING),
        dry_run=True).AndReturn(FAKE_VERSION_STRING_NEXT)

    # TODO(ferringb): Gut the cleanup=False added for 24709.
    repository.RepoRepository.Sync('default', cleanup=False)
    repository.RepoRepository.ExportManifest(mox.IgnoreArg())

    self.mox.ReplayAll()
    # Add to existing so we are forced to increment.
    self.manager.all = [FAKE_VERSION_STRING]
    version = self.manager._CreateNewBuildSpec(info)
    self.mox.VerifyAll()
    self.assertEqual(FAKE_VERSION_STRING_NEXT, version)

  def NotestGetNextBuildSpec(self):
    """Meta test.  Re-enable if you want to use it to do a big test."""
    print self.manager.GetNextBuildSpec(self.version_file, latest=True,
                                        retries=0)
    print self.manager.UpdateStatus('pass')

  def tearDown(self):
    if os.path.exists(self.tmpdir): shutil.rmtree(self.tmpdir)
    shutil.rmtree(self.tmpmandir)


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