Add basic gclient smoke tests.
The unit tests are unbearable and the next change forces me to trash them. Thus adding smoke tests before. The current tests aren't involved enough yet but are a good base for further testing. I plan to only test the most important functionalities, the ones used in the continuous build and try server. TEST=new smoke test BUG=23328 Review URL: http://codereview.chromium.org/2092012 git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@47580 0039d316-1c4b-4281-b951-d872f2087c98experimental/szager/collated-output
parent
1f440c497e
commit
83bea09ad2
@ -0,0 +1,203 @@
|
||||
#!/usr/bin/python
|
||||
# Copyright (c) 2010 The Chromium Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
"""Generate fake repositories for testing."""
|
||||
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
|
||||
def addKill():
|
||||
"""Add kill() method to subprocess.Popen for python <2.6"""
|
||||
if getattr(subprocess.Popen, 'kill', None):
|
||||
return
|
||||
if sys.platform.startswith('win'):
|
||||
def kill_win(process):
|
||||
import win32process
|
||||
return win32process.TerminateProcess(process._handle, -1)
|
||||
subprocess.kill = kill_win
|
||||
else:
|
||||
def kill_nix(process):
|
||||
import signal
|
||||
return os.kill(process.pid, signal.SIGKILL)
|
||||
subprocess.kill = kill_nix
|
||||
|
||||
|
||||
def rmtree(path):
|
||||
"""Delete a directory."""
|
||||
if os.path.exists(path):
|
||||
shutil.rmtree(path)
|
||||
|
||||
|
||||
def write(path, content):
|
||||
f = open(path, 'wb')
|
||||
f.write(content)
|
||||
f.close()
|
||||
|
||||
|
||||
class FakeRepos(object):
|
||||
def __init__(self, trial_dir, leak, local_only):
|
||||
self.trial_dir = trial_dir
|
||||
self.repos_dir = os.path.join(self.trial_dir, 'repos')
|
||||
self.leak = leak
|
||||
self.local_only = local_only
|
||||
self.svnserve = []
|
||||
self.gitdaemon = []
|
||||
addKill()
|
||||
rmtree(self.trial_dir)
|
||||
os.mkdir(self.trial_dir)
|
||||
os.mkdir(self.repos_dir)
|
||||
|
||||
def setUp(self):
|
||||
self.setUpSVN()
|
||||
self.setUpGIT()
|
||||
|
||||
def tearDown(self):
|
||||
for i in self.svnserve:
|
||||
i.kill()
|
||||
for i in self.gitdaemon:
|
||||
i.kill()
|
||||
if not self.leak:
|
||||
rmtree(self.trial_dir)
|
||||
|
||||
def setUpSVN(self):
|
||||
"""Creates subversion repositories and start the servers."""
|
||||
assert not self.svnserve
|
||||
join = os.path.join
|
||||
root = join(self.repos_dir, 'svn')
|
||||
rmtree(root)
|
||||
subprocess.check_call(['svnadmin', 'create', root])
|
||||
write(join(root, 'conf', 'svnserve.conf'),
|
||||
'[general]\n'
|
||||
'anon-access = read\n'
|
||||
'auth-access = write\n'
|
||||
'password-db = passwd\n')
|
||||
write(join(root, 'conf', 'passwd'),
|
||||
'[users]\n'
|
||||
'user1 = foo\n'
|
||||
'user2 = bar\n')
|
||||
|
||||
# Repos
|
||||
repo = join(self.repos_dir, 'svn_import')
|
||||
rmtree(repo)
|
||||
os.mkdir(repo)
|
||||
os.mkdir(join(repo, 'trunk'))
|
||||
os.mkdir(join(repo, 'trunk', 'src'))
|
||||
write(join(repo, 'trunk', 'src', 'DEPS'), """
|
||||
# Smoke test DEPS file.
|
||||
# Many DEPS functionalities need to be tested:
|
||||
# Var
|
||||
# File
|
||||
# From
|
||||
# deps_os
|
||||
# hooks
|
||||
# use_relative_paths
|
||||
#
|
||||
# Types of dependencies:
|
||||
# Relative urls
|
||||
# Full urls
|
||||
# svn
|
||||
# git
|
||||
|
||||
deps = {
|
||||
'src/other': 'svn://%(host)s/svn/trunk/other',
|
||||
'src/third_party': '/trunk/third_party',
|
||||
}
|
||||
|
||||
deps_os = {
|
||||
'mac': 'repo_4'
|
||||
}
|
||||
""" % {
|
||||
'host': 'localhost',
|
||||
})
|
||||
write(join(repo, 'trunk', 'src', 'origin'), "svn/trunk/src")
|
||||
os.mkdir(join(repo, 'trunk', 'other'))
|
||||
write(join(repo, 'trunk', 'other', 'origin'), "svn/trunk/other")
|
||||
os.mkdir(join(repo, 'trunk', 'third_party'))
|
||||
write(join(repo, 'trunk', 'third_party', 'origin'), "svn/trunk/third_party")
|
||||
|
||||
# Start the daemon.
|
||||
cmd = ['svnserve', '-d', '--foreground', '-r', self.repos_dir]
|
||||
if self.local_only:
|
||||
cmd.append('--listen-host=127.0.0.1')
|
||||
self.svnserve.append(subprocess.Popen(cmd, cwd=root))
|
||||
|
||||
# Import the repo.
|
||||
subprocess.check_call(['svn', 'import', repo,
|
||||
'svn://127.0.0.1/svn', '-m', 'foo', '-q',
|
||||
'--no-auto-props', '--non-interactive', '--no-auth-cache',
|
||||
'--username', 'user1', '--password', 'foo'])
|
||||
|
||||
def setUpGIT(self):
|
||||
"""Creates git repositories and start the servers."""
|
||||
assert not self.gitdaemon
|
||||
join = os.path.join
|
||||
root = join(self.repos_dir, 'git')
|
||||
rmtree(root)
|
||||
os.mkdir(root)
|
||||
# Repo 1
|
||||
repo = join(root, 'repo_1')
|
||||
subprocess.check_call(['git', 'init', '-q', repo])
|
||||
write(join(repo, 'DEPS'), """
|
||||
# Smoke test DEPS file.
|
||||
# Many DEPS functionalities need to be tested:
|
||||
# Var
|
||||
# File
|
||||
# From
|
||||
# deps_os
|
||||
# hooks
|
||||
# use_relative_paths
|
||||
#
|
||||
# Types of dependencies:
|
||||
# Relative urls
|
||||
# Full urls
|
||||
# svn
|
||||
# git
|
||||
|
||||
deps = {
|
||||
'repo2': 'git://%(host)s/git/repo_2',
|
||||
'repo2/repo3': '/repo_3',
|
||||
}
|
||||
|
||||
deps_os = {
|
||||
'mac': 'repo_4'
|
||||
}
|
||||
""" % {
|
||||
'host': 'localhost',
|
||||
})
|
||||
write(join(repo, 'origin'), "git/repo_1")
|
||||
subprocess.check_call(['git', 'add', '-A', '-f'], cwd=repo)
|
||||
subprocess.check_call(['git', 'commit', '-q', '-m', 'foo'], cwd=repo)
|
||||
|
||||
# Repo 2
|
||||
repo = join(root, 'repo_2')
|
||||
subprocess.check_call(['git', 'init', '-q', repo])
|
||||
write(join(repo, 'origin'), "git/repo_2")
|
||||
subprocess.check_call(['git', 'add', '-A', '-f'], cwd=repo)
|
||||
subprocess.check_call(['git', 'commit', '-q', '-m', 'foo'], cwd=repo)
|
||||
|
||||
# Repo 3
|
||||
repo = join(root, 'repo_3')
|
||||
subprocess.check_call(['git', 'init', '-q', repo])
|
||||
write(join(repo, 'origin'), "git/repo_3")
|
||||
subprocess.check_call(['git', 'add', '-A', '-f'], cwd=repo)
|
||||
subprocess.check_call(['git', 'commit', '-q', '-m', 'foo'], cwd=repo)
|
||||
|
||||
# Start the daemon.
|
||||
cmd = ['git', 'daemon', '--export-all', '--base-path=' + self.repos_dir]
|
||||
if self.local_only:
|
||||
cmd.append('--listen=127.0.0.1')
|
||||
self.gitdaemon.append(subprocess.Popen(cmd, cwd=self.repos_dir,
|
||||
stderr=subprocess.PIPE))
|
||||
|
||||
if __name__ == '__main__':
|
||||
fake = FakeRepos(os.path.dirname(os.path.abspath(__file__)), False)
|
||||
try:
|
||||
fake.setUp()
|
||||
sys.stdin.readline()
|
||||
finally:
|
||||
fake.tearDown()
|
@ -0,0 +1,135 @@
|
||||
#!/usr/bin/python
|
||||
# Copyright (c) 2010 The Chromium Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
"""Smoke tests for gclient.py.
|
||||
|
||||
Shell out 'gclient' and run basic conformance tests.
|
||||
|
||||
This test assumes GClientSmokeBase.URL_BASE is valid.
|
||||
"""
|
||||
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from fake_repos import rmtree, FakeRepos
|
||||
|
||||
SHOULD_LEAK = False
|
||||
UNITTEST_DIR = os.path.abspath(os.path.dirname(__file__))
|
||||
GCLIENT_PATH = os.path.join(os.path.dirname(UNITTEST_DIR), 'gclient')
|
||||
# all tests outputs goes there.
|
||||
TRIAL_DIR = os.path.join(UNITTEST_DIR, '_trial')
|
||||
# In case you want to use another machine to create the fake repos, e.g.
|
||||
# not on Windows.
|
||||
HOST = '127.0.0.1'
|
||||
|
||||
|
||||
class GClientSmokeBase(unittest.TestCase):
|
||||
# This subversion repository contains a test repository.
|
||||
ROOT_DIR = os.path.join(TRIAL_DIR, 'smoke')
|
||||
|
||||
def setUp(self):
|
||||
# Vaguely inspired by twisted.
|
||||
# Make sure it doesn't try to auto update when testing!
|
||||
self.env = os.environ.copy()
|
||||
self.env['DEPOT_TOOLS_UPDATE'] = '0'
|
||||
# Remove left overs
|
||||
self.root_dir = os.path.join(self.ROOT_DIR, self.id())
|
||||
rmtree(self.root_dir)
|
||||
if not os.path.exists(self.ROOT_DIR):
|
||||
os.mkdir(self.ROOT_DIR)
|
||||
os.mkdir(self.root_dir)
|
||||
self.svn_base = 'svn://%s/svn/' % HOST
|
||||
self.git_base = 'git://%s/git/' % HOST
|
||||
|
||||
def tearDown(self):
|
||||
if not SHOULD_LEAK:
|
||||
rmtree(self.root_dir)
|
||||
|
||||
def gclient(self, cmd, cwd=None):
|
||||
if not cwd:
|
||||
cwd = self.root_dir
|
||||
process = subprocess.Popen([GCLIENT_PATH] + cmd, cwd=cwd, env=self.env,
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
||||
shell=sys.platform.startswith('win'))
|
||||
(stdout, stderr) = process.communicate()
|
||||
return (stdout, stderr, process.returncode)
|
||||
|
||||
def check(self, expected, results):
|
||||
def checkString(expected, result):
|
||||
if expected != result:
|
||||
while expected and result and expected[0] == result[0]:
|
||||
expected = expected[1:]
|
||||
result = result[1:]
|
||||
self.assertEquals(expected, result)
|
||||
checkString(expected[0], results[0])
|
||||
checkString(expected[1], results[1])
|
||||
self.assertEquals(expected[2], results[2])
|
||||
|
||||
|
||||
class GClientSmoke(GClientSmokeBase):
|
||||
def testCommands(self):
|
||||
"""This test is to make sure no new command was added."""
|
||||
result = self.gclient(['help'])
|
||||
self.assertEquals(3189, len(result[0]))
|
||||
self.assertEquals(0, len(result[1]))
|
||||
self.assertEquals(0, result[2])
|
||||
|
||||
def testNotConfigured(self):
|
||||
res = ("", "Error: client not configured; see 'gclient config'\n", 1)
|
||||
self.check(res, self.gclient(['cleanup']))
|
||||
self.check(res, self.gclient(['diff']))
|
||||
self.check(res, self.gclient(['export', 'foo']))
|
||||
self.check(res, self.gclient(['pack']))
|
||||
self.check(res, self.gclient(['revert']))
|
||||
self.check(res, self.gclient(['revinfo']))
|
||||
self.check(res, self.gclient(['runhooks']))
|
||||
self.check(res, self.gclient(['status']))
|
||||
self.check(res, self.gclient(['sync']))
|
||||
self.check(res, self.gclient(['update']))
|
||||
|
||||
|
||||
class GClientSmokeSync(GClientSmokeBase):
|
||||
"""sync is the most important command. Hence test it more."""
|
||||
def testSyncSvn(self):
|
||||
"""Test pure gclient svn checkout, example of Chromium checkout"""
|
||||
self.gclient(['config', self.svn_base + 'trunk/src/'])
|
||||
results = self.gclient(['sync'])
|
||||
self.assertEquals(0, results[2])
|
||||
results = self.gclient(['sync', '--revision', 'a@32'])
|
||||
self.assertEquals(0, results[2])
|
||||
|
||||
def testSyncGit(self):
|
||||
"""Test pure gclient git checkout, example of Chromium OS checkout"""
|
||||
self.gclient(['config', self.git_base + 'repo_1'])
|
||||
results = self.gclient(['sync'])
|
||||
print results[0]
|
||||
print results[1]
|
||||
self.assertEquals(0, results[2])
|
||||
|
||||
|
||||
class GClientSmokeRevert(GClientSmokeBase):
|
||||
"""revert is the second most important command. Hence test it more."""
|
||||
def setUp(self):
|
||||
GClientSmokeBase.setUp(self)
|
||||
self.gclient(['config', self.URL_BASE])
|
||||
|
||||
|
||||
class GClientSmokeRevInfo(GClientSmokeBase):
|
||||
"""revert is the second most important command. Hence test it more."""
|
||||
def setUp(self):
|
||||
GClientSmokeBase.setUp(self)
|
||||
self.gclient(['config', self.URL_BASE])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
fake = FakeRepos(TRIAL_DIR, SHOULD_LEAK, True)
|
||||
try:
|
||||
fake.setUp()
|
||||
unittest.main()
|
||||
finally:
|
||||
fake.tearDown()
|
Loading…
Reference in New Issue