blob: 79749591cfc4c435502df245be164f71fbcfecc0 [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 commands. Needs to be run inside of chroot for mox."""
import mox
import os
import sys
import tempfile
import unittest
import constants
sys.path.append(constants.SOURCE_ROOT)
from chromite.lib import cros_build_lib as cros_lib
from chromite.buildbot import patch as cros_patch
from chromite.buildbot import gerrit_helper
# pylint: disable=W0212,R0904
class GerritQueryTests(mox.MoxTestBase):
def setUp(self):
mox.MoxTestBase.setUp(self)
result = ('{"project":"chromiumos/chromite","branch":"master","id":'
'"Icb8e1d315d465a077ffcddd7d1ab2307573017d5","number":"2144",'
'"subject":"Add functionality to cbuildbot to patch in a set '
'of Gerrit CL\u0027s","owner":{"name":"Ryan Cui","email":'
'"rcui@chromium.org"},"url":'
'"http://gerrit.chromium.org/gerrit/2144","lastUpdated":'
'1307577655,"sortKey":"00158e2000000860","open":true,"status":'
'"NEW","currentPatchSet":{"number":"3",'
'"revision":"b1c82d0f1c916b7f66cfece625d67fb5ecea9ea7","ref":'
'"refs/changes/44/2144/3","uploader":{"name":"Ryan Cui","email":'
'"rcui@chromium.org"}}}\n'
'{"type":"stats","rowCount":1,"runTimeMilliseconds":4}')
self.result = result
self.mox.StubOutWithMock(cros_lib, 'RunCommand')
def testPatchInfoNotFound(self):
"""Test case where ChangeID isn't found on internal server."""
patches = ['1A3G2D1D2']
output_obj = cros_lib.CommandResult()
output_obj.returncode = 0
output_obj.output = ('{"type":"error",'
'"message":"Unsupported query:5S2D4D2D4"}')
cros_lib.RunCommand(mox.In('gerrit.chromium.org'),
redirect_stdout=True).AndReturn(output_obj)
self.mox.ReplayAll()
self.assertRaises(cros_patch.PatchException, cros_patch.GetGerritPatchInfo,
patches)
self.mox.VerifyAll()
def testGetInternalPatchInfo(self):
"""Test case where ChangeID is for an internal CL."""
patches = ['*1A3G2D1D2']
output_obj = cros_lib.CommandResult()
output_obj.returncode = 0
output_obj.output = self.result
cros_lib.RunCommand(mox.In('gerrit-int.chromium.org'),
redirect_stdout=True).AndReturn(output_obj)
self.mox.ReplayAll()
patch_info = cros_patch.GetGerritPatchInfo(patches)
self.assertEquals(patch_info[0].internal, True)
self.mox.VerifyAll()
def testGetExternalPatchInfo(self):
"""Test case where ChangeID is for an external CL."""
patches = ['1A3G2D1D2']
output_obj = cros_lib.CommandResult()
output_obj.returncode = 0
output_obj.output = self.result
cros_lib.RunCommand(mox.In('gerrit.chromium.org'),
redirect_stdout=True).AndReturn(output_obj)
self.mox.ReplayAll()
patch_info = cros_patch.GetGerritPatchInfo(patches)
self.assertEquals(patch_info[0].internal, False)
self.mox.VerifyAll()
def testPatchInfoParsing(self):
"""Test parsing of the JSON results."""
patches = ['1A3G2D1D2']
output_obj = cros_lib.CommandResult()
output_obj.returncode = 0
output_obj.output = self.result
cros_lib.RunCommand(mox.In('gerrit.chromium.org'),
redirect_stdout=True).AndReturn(output_obj)
self.mox.ReplayAll()
patch_info = cros_patch.GetGerritPatchInfo(patches)
self.assertEquals(patch_info[0].project, 'chromiumos/chromite')
self.assertEquals(patch_info[0].ref, 'refs/changes/44/2144/3')
self.mox.VerifyAll()
class GerritPatchTest(mox.MoxTestBase):
FAKE_PATCH_JSON = {
"project":"tacos/chromite", "branch":"master",
"id":"Iee5c89d929f1850d7d4e1a4ff5f21adda800025f",
"currentPatchSet": {
"number":"2", "ref":"refs/changes/72/5172/1",
"revision":"ff10979dd360e75ff21f5cf53b7f8647578785ef",
},
"number":"1112",
"subject":"chromite commit",
"owner":{"name":"Chromite Master", "email":"chromite@chromium.org"},
"url":"http://gerrit.chromium.org/gerrit/1112",
"lastUpdated":1311024529,
"sortKey":"00166e8700001052",
"open": True,
"status":"NEW",
}
def testGerritSubmit(self):
"""Tests submission review string looks correct."""
self.mox.StubOutWithMock(cros_lib, 'RunCommand')
my_patch = cros_patch.GerritPatch(self.FAKE_PATCH_JSON, False)
helper = gerrit_helper.GerritHelper(False)
cros_lib.RunCommand(
'ssh -p 29418 gerrit.chromium.org gerrit review '
'--submit 1112,2'.split(), error_ok=True)
self.mox.ReplayAll()
my_patch.Submit(helper, False)
self.mox.VerifyAll()
def testGerritHandleApplyError(self):
"""Tests review string looks correct."""
my_patch = cros_patch.GerritPatch(self.FAKE_PATCH_JSON, False)
helper = gerrit_helper.GerritHelper(False)
self.mox.ReplayAll()
my_patch.HandleCouldNotApply(helper, 'http://fake%20url/1234', True)
self.mox.VerifyAll()
def testGerritHandleSubmitError(self):
"""Tests review string looks correct."""
my_patch = cros_patch.GerritPatch(self.FAKE_PATCH_JSON, False)
helper = gerrit_helper.GerritHelper(False)
self.mox.ReplayAll()
my_patch.HandleCouldNotSubmit(helper, 'http://fake%20url/1234', True)
self.mox.VerifyAll()
def testGerritHandleVerifyError(self):
"""Tests review string looks correct."""
my_patch = cros_patch.GerritPatch(self.FAKE_PATCH_JSON, False)
helper = gerrit_helper.GerritHelper(False)
self.mox.ReplayAll()
my_patch.HandleCouldNotVerify(helper, 'http://fake%20url/1234', True)
self.mox.VerifyAll()
def GerritDepenedenciesHelper(self, git_rev_list, expected_return_tuple):
build_root = 'fake_build_root'
project_dir = 'fake_build_root/fake_project_dir'
self.mox.StubOutWithMock(cros_lib, 'RunCommand')
self.mox.StubOutWithMock(cros_patch, '_GetProjectManifestBranch')
self.mox.StubOutWithMock(cros_lib, 'GetProjectDir')
my_patch = cros_patch.GerritPatch(self.FAKE_PATCH_JSON, False)
cros_lib.GetProjectDir(build_root, 'tacos/chromite').AndReturn(project_dir)
# Ignore git fetch.
cros_lib.RunCommand(mox.IgnoreArg(), cwd=project_dir)
cros_patch._GetProjectManifestBranch(
build_root, 'tacos/chromite').AndReturn('m/master')
cros_lib.RunCommand(
['git', 'rev-list', 'm/master..FETCH_HEAD^'], cwd=project_dir,
redirect_stdout=True).AndReturn(git_rev_list)
self.mox.ReplayAll()
deps = my_patch.GerritDependencies(build_root)
self.mox.VerifyAll()
self.assertEqual(deps, expected_return_tuple)
def testGerritDependencies(self):
"""Tests that we can get dependencies from a commit with 2 dependencies."""
git_rev_list_obj = self.mox.CreateMock(cros_lib.CommandResult)
git_rev_list_obj.output = '\n'.join(['1234abcd', '1234abce'])
self.GerritDepenedenciesHelper(git_rev_list_obj, ['1234abcd', '1234abce'])
def testGerritNoDependencies(self):
"""Tests that we return an empty tuple if the commit has no deps."""
git_rev_list_obj = self.mox.CreateMock(cros_lib.CommandResult)
git_rev_list_obj.output = ''
self.GerritDepenedenciesHelper(git_rev_list_obj, [])
def NotestMockRemoveCommitReady(self):
"""Tests against sosa's test patch to remove Commit Ready bit on failure."""
my_patch = cros_patch.GerritPatch(self.FAKE_PATCH_JSON, False)
my_patch.gerrit_number = 8366 # Sosa's test change.
my_patch.patch_number = 1 # Sosa's test patch.
helper = gerrit_helper.GerritHelper(False)
my_patch.HandleCouldNotVerify(helper, 'some_url', False)
class PrepareLocalPatchesTests(mox.MoxTestBase):
def setUp(self):
mox.MoxTestBase.setUp(self)
self.patches = ['my/project:mybranch']
self.mox.StubOutWithMock(tempfile, 'mkdtemp')
self.mox.StubOutWithMock(os, 'listdir')
self.mox.StubOutWithMock(cros_lib, 'GetProjectDir')
self.mox.StubOutWithMock(cros_lib, 'GetCurrentBranch')
self.mox.StubOutWithMock(cros_patch, '_GetRemoteTrackingBranch')
self.mox.StubOutWithMock(cros_lib, 'RunCommand')
tempfile.mkdtemp(prefix=mox.IgnoreArg()).AndReturn('/tmp/trybot1')
os.listdir(mox.IgnoreArg()).AndReturn('test.patch')
def VerifyPatchInfo(self, patch_info, project, branch, tracking_branch):
"""Check the returned LocalPatchInfo against golden values."""
self.assertEquals(patch_info.project, project)
self.assertEquals(patch_info.local_branch, branch)
self.assertEquals(patch_info.tracking_branch, tracking_branch)
def testBranchSpecifiedSuccessRun(self):
"""Test success with branch specified by user."""
cros_lib.GetProjectDir(mox.IgnoreArg(), 'my/project').AndReturn('mydir')
cros_lib.RunCommand(mox.In('m/master..mybranch'),
redirect_stdout=mox.IgnoreArg(), cwd='mydir')
cros_patch._GetRemoteTrackingBranch('mydir',
'mybranch').AndReturn('tracking_branch')
self.mox.ReplayAll()
patch_info = cros_patch.PrepareLocalPatches(self.patches, 'master')
self.VerifyPatchInfo(patch_info[0], 'my/project', 'mybranch',
'tracking_branch')
self.mox.VerifyAll()
def testNoTrackingBranch(self):
"""Test when project branch does not track a remote branch."""
cros_lib.GetProjectDir(mox.IgnoreArg(), 'my/project').AndReturn('mydir')
cros_lib.RunCommand(mox.In('m/master..mybranch'),
redirect_stdout=mox.IgnoreArg(), cwd='mydir')
cros_patch._GetRemoteTrackingBranch(
'mydir',
'mybranch').AndRaise(cros_lib.NoTrackingBranchException('error'))
self.mox.ReplayAll()
self.assertRaises(cros_patch.PatchException, cros_patch.PrepareLocalPatches,
self.patches, 'master')
self.mox.VerifyAll()
class ApplyLocalPatchesTests(mox.MoxTestBase):
def setUp(self):
mox.MoxTestBase.setUp(self)
self.patch = cros_patch.LocalPatch('my/project', 'manifest_branch',
'/tmp/patch_dir/1', 'mybranch')
self.buildroot = '/b'
self.mox.StubOutWithMock(cros_lib, 'GetProjectDir')
self.mox.StubOutWithMock(cros_patch, '_GetProjectManifestBranch')
self.mox.StubOutWithMock(cros_patch.LocalPatch, '_GetFileList')
self.mox.StubOutWithMock(cros_lib, 'RunCommand')
def testSuccessRun(self):
"""Test a successful run."""
cros_patch._GetProjectManifestBranch(self.buildroot,
'my/project').AndReturn('manifest_branch')
cros_lib.GetProjectDir(mox.IgnoreArg(), 'my/project').AndReturn('mydir')
cros_lib.RunCommand(mox.In('repo') and mox.In('start'), cwd='mydir')
cros_patch.LocalPatch._GetFileList().AndReturn(['abc.patch', 'bbb.patch'])
cros_lib.RunCommand(mox.In('git') and mox.In('am') and mox.In('abc.patch'),
cwd='mydir')
self.mox.ReplayAll()
self.patch.Apply(self.buildroot)
self.mox.VerifyAll()
def testWrongTrackingBranch(self):
"""When the original patch branch does not track buildroot's branch."""
cros_patch._GetProjectManifestBranch(self.buildroot,
'my/project').AndReturn('different_branch')
self.mox.ReplayAll()
self.assertRaises(cros_patch.PatchException, self.patch.Apply,
self.buildroot)
self.mox.VerifyAll()
class HelperFunctionTests(mox.MoxTestBase):
def setUp(self):
mox.MoxTestBase.setUp(self)
def testRemovePatchRoot(self):
"""Test successful patch directory removal case."""
self.mox.StubOutWithMock(cros_patch.shutil, 'rmtree')
cros_patch.shutil.rmtree('/path/to/tmp/trybot_patch-1111')
self.mox.ReplayAll()
cros_patch.RemovePatchRoot('/path/to/tmp/trybot_patch-1111')
def testRemovePatchRootFail(self):
"""Test when patch directory does not have trybot prefix."""
self.mox.StubOutWithMock(cros_patch.shutil, 'rmtree')
self.mox.ReplayAll()
self.assertRaises(AssertionError, cros_patch.RemovePatchRoot,
'/path/to/tmp/bad_prefix-1111')
if __name__ == '__main__':
unittest.main()