blob: ee168eb901d341e9d0d72fb9ab46f9978254f2ea [file] [log] [blame]
#!/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 lkgm_manager. Needs to be run inside of chroot for mox."""
import mox
import os
import shutil
import sys
import tempfile
import threading
import time
import unittest
if __name__ == '__main__':
import constants
sys.path.append(constants.SOURCE_ROOT)
from chromite.buildbot import lkgm_manager
from chromite.buildbot import manifest_version
from chromite.buildbot import manifest_version_unittest
FAKE_VERSION_STRING = '1.2.3.4-rc3'
FAKE_VERSION_STRING_NEXT = '1.2.3.4-rc4'
class LKGMCandidateInfoTest(mox.MoxTestBase):
"""Test methods testing methods in _LKGMCandidateInfo class."""
def setUp(self):
mox.MoxTestBase.setUp(self)
self.tmpdir = tempfile.mkdtemp()
def testLoadFromString(self):
"""Tests whether we can load from a string."""
info = lkgm_manager._LKGMCandidateInfo(version_string=FAKE_VERSION_STRING)
self.assertEqual(info.VersionString(), FAKE_VERSION_STRING)
def testIncrementVersionPatch(self):
"""Tests whether we can increment a lkgm info."""
info = lkgm_manager._LKGMCandidateInfo(version_string=FAKE_VERSION_STRING)
info.IncrementVersion()
self.assertEqual(info.VersionString(), FAKE_VERSION_STRING_NEXT)
def testVersionCompare(self):
"""Tests whether our comparision method works."""
info1 = lkgm_manager._LKGMCandidateInfo('1.2.3.4-rc1')
info2 = lkgm_manager._LKGMCandidateInfo('1.2.3.4-rc2')
info3 = lkgm_manager._LKGMCandidateInfo('1.2.200.4-rc1')
info4 = lkgm_manager._LKGMCandidateInfo('1.4.3.4-rc1')
self.assertTrue(info2 > info1)
self.assertTrue(info3 > info1)
self.assertTrue(info3 > info2)
self.assertTrue(info4 > info1)
self.assertTrue(info4 > info2)
self.assertTrue(info4 > info3)
def tearDown(self):
shutil.rmtree(self.tmpdir)
class LKGMManagerTest(mox.MoxTestBase):
"""Tests for the BuildSpecs manager."""
def setUp(self):
mox.MoxTestBase.setUp(self)
self.tmpdir = tempfile.mkdtemp()
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()
lkgm_manager.LKGMManager._TMP_MANIFEST_DIR = self.tmpmandir
self.manager = lkgm_manager.LKGMManager(
self.tmpdir, self.source_repo, self.manifest_repo, self.branch,
self.build_name, dry_run=True)
self.manager.all_specs_dir = '/LKGM/path'
self.manager.SLEEP_TIMEOUT = 1
def _CommonTestLatestCandidateByVersion(self, version, expected_candidate,
no_all=False):
"""Common helper function for latest candidate tests.
Helper function to test given a version whether we can the right candidate
back.
Args:
version: The Chrome OS version to look for the latest candidate of.
expected_candidate: What we expect to come back.
"""
if not no_all:
self.manager.all = ['1.2.3.4-rc1',
'1.2.3.4-rc2',
'1.2.3.4-rc9',
'1.2.3.5-rc1',
'1.2.3.6-rc2',
'1.2.4.3-rc1',
]
info_for_test = manifest_version.VersionInfo(version)
candidate = self.manager._GetLatestCandidateByVersion(info_for_test)
self.assertEqual(candidate.VersionString(), expected_candidate)
def testGetLatestCandidateByVersionCommonCase(self):
"""Tests whether we can get the latest candidate under the common case.
This test tests whether or not we get the right candidate when we have
many of the same candidate version around but with different rc's.
"""
self._CommonTestLatestCandidateByVersion('1.2.3.4', '1.2.3.4-rc9')
def testGetLatestCandidateByVersionOnlyOne(self):
"""Tests whether we can get the latest candidate with only one rc."""
self._CommonTestLatestCandidateByVersion('1.2.3.6', '1.2.3.6-rc2')
def testGetLatestCandidateByVersionNone(self):
"""Tests whether we can get the latest candidate with no rc's."""
self._CommonTestLatestCandidateByVersion('1.2.5.7', '1.2.5.7-rc1')
def testGetLatestCandidateByVersionNoneNoAll(self):
"""Tests whether we can get the latest candidate with no rc's at all."""
self._CommonTestLatestCandidateByVersion('10.0.1.5', '10.0.1.5-rc1', True)
def _GetPathToManifest(self, info):
return os.path.join(self.manager.all_specs_dir, '%s.xml' %
info.VersionString())
def testCreateNewCandidate(self):
"""Tests that we can create a new candidate and uprev and old rc."""
# Let's stub out other LGKMManager calls cause they're already
# unit tested.
self.mox.StubOutWithMock(lkgm_manager.LKGMManager, '_GetCurrentVersionInfo')
self.mox.StubOutWithMock(lkgm_manager.LKGMManager, '_LoadSpecs')
self.mox.StubOutWithMock(lkgm_manager.LKGMManager,
'_GetLatestCandidateByVersion')
self.mox.StubOutWithMock(lkgm_manager.LKGMManager, '_CreateNewBuildSpec')
self.mox.StubOutWithMock(lkgm_manager.LKGMManager, '_SetInFlight')
my_info = manifest_version.VersionInfo('1.2.3.4')
most_recent_candidate = lkgm_manager._LKGMCandidateInfo('1.2.3.4-rc12')
new_candidate = lkgm_manager._LKGMCandidateInfo('1.2.3.4-rc13')
lkgm_manager.LKGMManager._GetCurrentVersionInfo(
self.version_file).AndReturn(my_info)
lkgm_manager.LKGMManager._LoadSpecs(my_info)
lkgm_manager.LKGMManager._GetLatestCandidateByVersion(my_info).AndReturn(
most_recent_candidate)
lkgm_manager.LKGMManager._CreateNewBuildSpec(
most_recent_candidate).AndReturn(new_candidate.VersionString())
lkgm_manager.LKGMManager._SetInFlight(
mox.StrContains(new_candidate.VersionString()))
self.mox.ReplayAll()
candidate_path = self.manager.CreateNewCandidate(self.version_file)
self.assertEqual(candidate_path, self._GetPathToManifest(new_candidate))
self.mox.VerifyAll()
def testCreateNewCandidateReturnNoneIfNoWorkToDo(self):
"""Tests that we return nothing if there is nothing to create."""
# Let's stub out other LGKMManager calls cause they're already
# unit tested.
self.mox.StubOutWithMock(lkgm_manager.LKGMManager, '_GetCurrentVersionInfo')
self.mox.StubOutWithMock(lkgm_manager.LKGMManager, '_LoadSpecs')
self.mox.StubOutWithMock(lkgm_manager.LKGMManager,
'_GetLatestCandidateByVersion')
self.mox.StubOutWithMock(lkgm_manager.LKGMManager, '_CreateNewBuildSpec')
self.mox.StubOutWithMock(lkgm_manager.LKGMManager, '_SetInFlight')
my_info = manifest_version.VersionInfo('1.2.3.4')
most_recent_candidate = lkgm_manager._LKGMCandidateInfo('1.2.3.4-rc12')
lkgm_manager.LKGMManager._GetCurrentVersionInfo(
self.version_file).AndReturn(my_info)
lkgm_manager.LKGMManager._LoadSpecs(my_info)
lkgm_manager.LKGMManager._GetLatestCandidateByVersion(my_info).AndReturn(
most_recent_candidate)
lkgm_manager.LKGMManager._CreateNewBuildSpec(
most_recent_candidate).AndReturn(None)
self.mox.ReplayAll()
candidate = self.manager.CreateNewCandidate(self.version_file)
self.assertEqual(candidate, None)
self.mox.VerifyAll()
def testGetLatestCandidate(self):
"""Makes sure we can get the latest created candidate manifest."""
self.mox.StubOutWithMock(lkgm_manager.LKGMManager, '_GetCurrentVersionInfo')
self.mox.StubOutWithMock(lkgm_manager.LKGMManager, '_LoadSpecs')
self.mox.StubOutWithMock(lkgm_manager.LKGMManager, '_SetInFlight')
my_info = manifest_version.VersionInfo('1.2.3.4')
most_recent_candidate = lkgm_manager._LKGMCandidateInfo('1.2.3.4-rc12')
lkgm_manager.LKGMManager._GetCurrentVersionInfo(
self.version_file).AndReturn(my_info)
lkgm_manager.LKGMManager._LoadSpecs(my_info)
lkgm_manager.LKGMManager._SetInFlight(
mox.StrContains(most_recent_candidate.VersionString()))
self.mox.ReplayAll()
self.manager.latest_unprocessed = '1.2.3.4-rc12'
candidate = self.manager.GetLatestCandidate(self.version_file)
self.assertEqual(candidate, self._GetPathToManifest(most_recent_candidate))
self.mox.VerifyAll()
def testGetLatestCandidateNone(self):
"""Makes sure we get nothing if there is no work to be done."""
self.mox.StubOutWithMock(lkgm_manager.LKGMManager, '_GetCurrentVersionInfo')
self.mox.StubOutWithMock(lkgm_manager.LKGMManager, '_LoadSpecs')
my_info = manifest_version.VersionInfo('1.2.3.4')
lkgm_manager.LKGMManager._GetCurrentVersionInfo(
self.version_file).AndReturn(my_info)
lkgm_manager.LKGMManager._LoadSpecs(my_info)
self.mox.ReplayAll()
candidate = self.manager.GetLatestCandidate(self.version_file)
self.assertEqual(candidate, None)
self.mox.VerifyAll()
def _CreateManifest(self):
"""Returns a created test manifest in tmpdir with its dir_pfx."""
self.manager.current_version = '1.2.3.4-rc21'
dir_pfx = '1.2'
manifest = os.path.join(self.manager.manifests_dir,
lkgm_manager.LKGMManager.LGKM_SUBDIR, 'buildspecs',
dir_pfx, '1.2.3.4-rc21.xml')
manifest_version_unittest.TouchFile(manifest)
return manifest, dir_pfx
@staticmethod
def _FinishBuilderHelper(manifest, path_for_builder, dir_pfx, status, wait=0):
time.sleep(wait)
manifest_version._CreateSymlink(
manifest, os.path.join(path_for_builder, status, dir_pfx,
os.path.basename(manifest)))
def _FinishBuild(self, manifest, path_for_builder, dir_pfx, status, wait=0):
"""Finishes a build by marking a status with optional delay."""
if wait > 0:
thread = threading.Thread(target=self._FinishBuilderHelper,
args=(manifest, path_for_builder, dir_pfx,
status, wait))
thread.start()
return thread
else:
self._FinishBuilderHelper(manifest, path_for_builder, dir_pfx, status, 0)
def testGetBuildersStatusBothFinished(self):
"""Tests GetBuilderStatus where both builds have finished."""
self.mox.StubOutWithMock(lkgm_manager, '_SyncGitRepo')
manifest, dir_pfx = self._CreateManifest()
for_build1 = os.path.join(self.manager.manifests_dir,
lkgm_manager.LKGMManager.LGKM_SUBDIR,
'build-name', 'build1')
for_build2 = os.path.join(self.manager.manifests_dir,
lkgm_manager.LKGMManager.LGKM_SUBDIR,
'build-name', 'build2')
self._FinishBuild(manifest, for_build1, dir_pfx, 'fail')
self._FinishBuild(manifest, for_build2, dir_pfx, 'pass')
lkgm_manager._SyncGitRepo(self.manager.manifests_dir)
self.mox.ReplayAll()
statuses = self.manager.GetBuildersStatus(['build1', 'build2'])
self.assertEqual(statuses['build1'], 'fail')
self.assertEqual(statuses['build2'], 'pass')
self.mox.VerifyAll()
def testGetBuildersStatusWaitForOne(self):
"""Tests GetBuilderStatus where both builds have finished with one delay."""
self.mox.StubOutWithMock(lkgm_manager, '_SyncGitRepo')
manifest, dir_pfx = self._CreateManifest()
for_build1 = os.path.join(self.manager.manifests_dir,
lkgm_manager.LKGMManager.LGKM_SUBDIR,
'build-name', 'build1')
for_build2 = os.path.join(self.manager.manifests_dir,
lkgm_manager.LKGMManager.LGKM_SUBDIR,
'build-name', 'build2')
self._FinishBuild(manifest, for_build1, dir_pfx, 'fail')
self._FinishBuild(manifest, for_build2, dir_pfx, 'pass', wait=3)
lkgm_manager._SyncGitRepo(self.manager.manifests_dir).MultipleTimes()
self.mox.ReplayAll()
statuses = self.manager.GetBuildersStatus(['build1', 'build2'])
self.assertEqual(statuses['build1'], 'fail')
self.assertEqual(statuses['build2'], 'pass')
self.mox.VerifyAll()
def testGetBuildersStatusReachTimeout(self):
"""Tests GetBuilderStatus where one build finishes and one never does."""
self.mox.StubOutWithMock(lkgm_manager, '_SyncGitRepo')
manifest, dir_pfx = self._CreateManifest()
for_build1 = os.path.join(self.manager.manifests_dir,
lkgm_manager.LKGMManager.LGKM_SUBDIR,
'build-name', 'build1')
for_build2 = os.path.join(self.manager.manifests_dir,
lkgm_manager.LKGMManager.LGKM_SUBDIR,
'build-name', 'build2')
self._FinishBuild(manifest, for_build1, dir_pfx, 'fail', wait=3)
thread = self._FinishBuild(manifest, for_build2, dir_pfx, 'pass', wait=5)
lkgm_manager._SyncGitRepo(self.manager.manifests_dir).MultipleTimes()
self.mox.ReplayAll()
# Let's reduce this.
self.manager.MAX_TIMEOUT_SECONDS = 5
statuses = self.manager.GetBuildersStatus(['build1', 'build2'])
self.assertEqual(statuses['build1'], 'fail')
self.assertEqual(statuses['build2'], None)
thread.join()
self.mox.VerifyAll()
def tearDown(self):
if os.path.exists(self.tmpdir): shutil.rmtree(self.tmpdir)
shutil.rmtree(self.tmpmandir)
if __name__ == '__main__':
unittest.main()