Commit 8c1cc8c0 authored by Sebastien Robin's avatar Sebastien Robin

erp5testnode: add test for getAndUpdateFullRevisionList

parent dcbd597f
from unittest import TestCase from unittest import TestCase
import sys import sys
sys.path[0:0] = [ sys.path.extend([
'/srv/slapgrid/slappart80/srv/runner/software/ba1e09f3364989dc92da955b64e72f8d/eggs/slapos.cookbook-0.65-py2.7.egg', '/srv/slapgrid/slappart80/srv/runner/software/ba1e09f3364989dc92da955b64e72f8d/eggs/slapos.cookbook-0.65-py2.7.egg',
'/srv/slapgrid/slappart80/srv/runner/software/ba1e09f3364989dc92da955b64e72f8d/eggs/zc.recipe.egg-1.3.2-py2.7.egg', '/srv/slapgrid/slappart80/srv/runner/software/ba1e09f3364989dc92da955b64e72f8d/eggs/zc.recipe.egg-1.3.2-py2.7.egg',
'/srv/slapgrid/slappart80/srv/runner/software/ba1e09f3364989dc92da955b64e72f8d/eggs/zc.buildout-1.6.0_dev_SlapOS_010-py2.7.egg', '/srv/slapgrid/slappart80/srv/runner/software/ba1e09f3364989dc92da955b64e72f8d/eggs/zc.buildout-1.6.0_dev_SlapOS_010-py2.7.egg',
...@@ -19,12 +19,13 @@ sys.path[0:0] = [ ...@@ -19,12 +19,13 @@ sys.path[0:0] = [
'/srv/slapgrid/slappart80/srv/runner/software/ba1e09f3364989dc92da955b64e72f8d/eggs/meld3-0.6.8-py2.7.egg', '/srv/slapgrid/slappart80/srv/runner/software/ba1e09f3364989dc92da955b64e72f8d/eggs/meld3-0.6.8-py2.7.egg',
'/srv/slapgrid/slappart80/srv/runner/software/ba1e09f3364989dc92da955b64e72f8d/eggs/Jinja2-2.6-py2.7.egg', '/srv/slapgrid/slappart80/srv/runner/software/ba1e09f3364989dc92da955b64e72f8d/eggs/Jinja2-2.6-py2.7.egg',
'/srv/slapgrid/slappart80/srv/runner/software/ba1e09f3364989dc92da955b64e72f8d/eggs/Werkzeug-0.8.3-py2.7.egg', '/srv/slapgrid/slappart80/srv/runner/software/ba1e09f3364989dc92da955b64e72f8d/eggs/Werkzeug-0.8.3-py2.7.egg',
] ])
from erp5.util.testnode import TestNode from erp5.util.testnode import TestNode
import tempfile
import shutil
import os import os
import shutil
import subprocess
import tempfile
class ERP5TestNode(TestCase): class ERP5TestNode(TestCase):
...@@ -32,16 +33,23 @@ class ERP5TestNode(TestCase): ...@@ -32,16 +33,23 @@ class ERP5TestNode(TestCase):
self._tempdir = tempfile.mkdtemp() self._tempdir = tempfile.mkdtemp()
self.working_directory = os.path.join(self._tempdir, 'testnode') self.working_directory = os.path.join(self._tempdir, 'testnode')
self.slapos_directory = os.path.join(self._tempdir, 'slapos') self.slapos_directory = os.path.join(self._tempdir, 'slapos')
self.remote_repository0 = os.path.join(self._tempdir, 'rep0')
self.remote_repository1 = os.path.join(self._tempdir, 'rep1')
os.mkdir(self.working_directory) os.mkdir(self.working_directory)
os.mkdir(self.slapos_directory) os.mkdir(self.slapos_directory)
self.remote_repository1 = os.path.join(self._tempdir, 'rep1') os.mkdir(self.remote_repository0)
self.remote_repository2 = os.path.join(self._tempdir, 'rep2') os.mkdir(self.remote_repository1)
def tearDown(self): def tearDown(self):
shutil.rmtree(self._tempdir, True) shutil.rmtree(self._tempdir, True)
def getTestNode(self): def getTestNode(self):
return TestNode(None, None) def log(*args):
for arg in args:
print "TESTNODE LOG : %r" % (arg,)
# XXX how to get property the git path ?
config = {"git_binary": "/srv/slapgrid/slappart80/srv/runner/software/ba1e09f3364989dc92da955b64e72f8d/parts/git/bin/git"}
return TestNode(log, config)
def updateNodeTestSuiteData(self, node_test_suite): def updateNodeTestSuiteData(self, node_test_suite):
node_test_suite.edit(working_directory=self.working_directory, node_test_suite.edit(working_directory=self.working_directory,
...@@ -49,14 +57,50 @@ class ERP5TestNode(TestCase): ...@@ -49,14 +57,50 @@ class ERP5TestNode(TestCase):
project_title="Foo", project_title="Foo",
test_suite_title="Foo-Test", test_suite_title="Foo-Test",
vcs_repository_list=[ vcs_repository_list=[
{'url': self.remote_repository1, {'url': self.remote_repository0,
'profile_path': 'software.cfg', 'profile_path': 'software.cfg',
'branch': 'master'}, 'branch': 'master'},
{'url': self.remote_repository2, {'url': self.remote_repository1,
'buildout_section_id': 'foo', 'buildout_section_id': 'rep1',
'branch': 'master'}]) 'branch': 'master'}])
def test_01_GetDelNodeTestSuite(self): def getCaller(self, **kw):
class Caller(object):
def __init__(self, **kw):
self.__dict__.update(**kw)
def __call__(self, command):
return subprocess.check_output(command, **self.__dict__)
return Caller(**kw)
def generateTestRepositoryList(self):
last_commit_list = []
for i, repository_path in enumerate([self.remote_repository0,
self.remote_repository1]):
call = self.getCaller(cwd=repository_path)
call("git init".split())
call("touch first_file".split())
call("git add first_file".split())
call("git commit -v -m first_commit".split() + ['--author="a b <a@b.c>"'])
my_file = open(os.path.join(repository_path, 'first_file'), 'w')
my_file.write("initial_content%i" % i)
my_file.close()
call("git commit -av -m next_commit".split() + ['--author="a b <a@b.c>"'])
output = call("git log --oneline".split())
output_line_list = output.split("\n")
self.assertEquals(3, len(output_line_list))
# remove additional return line
output_line_list = output_line_list[0:2]
expected_commit_list = ["next_commit", "first_commit"]
last_commit_list.append(output_line_list[0].split())
commit_list = [x.split()[1] for x in output_line_list]
self.assertEquals(expected_commit_list, commit_list)
# looks like [('d3d09e6', 'next_commit'), ('c4c15e0', 'next_commit')]
# for respectively rep0 and rep1
return last_commit_list
def test_01_getDelNodeTestSuite(self):
""" """
We should be able to get/delete NodeTestSuite objects inside test_node We should be able to get/delete NodeTestSuite objects inside test_node
""" """
...@@ -80,6 +124,9 @@ class ERP5TestNode(TestCase): ...@@ -80,6 +124,9 @@ class ERP5TestNode(TestCase):
node_test_suite.working_directory) node_test_suite.working_directory)
def test_03_constructProfile(self): def test_03_constructProfile(self):
"""
Check if the software profile is correctly generated
"""
test_node = self.getTestNode() test_node = self.getTestNode()
node_test_suite = test_node.getNodeTestSuite('foo') node_test_suite = test_node.getNodeTestSuite('foo')
self.updateNodeTestSuiteData(node_test_suite) self.updateNodeTestSuiteData(node_test_suite)
...@@ -89,11 +136,24 @@ class ERP5TestNode(TestCase): ...@@ -89,11 +136,24 @@ class ERP5TestNode(TestCase):
profile = open(node_test_suite.custom_profile_path, 'r') profile = open(node_test_suite.custom_profile_path, 'r')
expected_profile = """ expected_profile = """
[buildout] [buildout]
extends = %s/testnode/foo/rep1/software.cfg extends = %s/testnode/foo/rep0/software.cfg
[foo] [rep1]
repository = %s/testnode/foo/foo repository = %s/testnode/foo/rep1
branch = master branch = master
""" % (self._tempdir, self._tempdir) """ % (self._tempdir, self._tempdir)
self.assertEquals(expected_profile, profile.read()) self.assertEquals(expected_profile, profile.read())
profile.close() profile.close()
def test_04_getAndUpdateFullRevisionList(self):
"""
Check if we clone correctly repositories and git right revisions
"""
commit_list = self.generateTestRepositoryList()
test_node = self.getTestNode()
node_test_suite = test_node.getNodeTestSuite('foo')
self.updateNodeTestSuiteData(node_test_suite)
result = test_node.getAndUpdateFullRevisionList(node_test_suite)
self.assertEquals(2, len(result))
self.assertTrue(result[0].startswith('rep0=2-%s' % commit_list[0][0]))
self.assertTrue(result[1].startswith('rep1=2-%s' % commit_list[1][0]))
...@@ -58,6 +58,10 @@ class SlapOSInstance(object): ...@@ -58,6 +58,10 @@ class SlapOSInstance(object):
def edit(self, **kw): def edit(self, **kw):
self.__dict__.update(**kw) self.__dict__.update(**kw)
self._checkData()
def _checkData(self):
pass
class NodeTestSuite(SlapOSInstance): class NodeTestSuite(SlapOSInstance):
...@@ -66,13 +70,24 @@ class NodeTestSuite(SlapOSInstance): ...@@ -66,13 +70,24 @@ class NodeTestSuite(SlapOSInstance):
self.reference = reference self.reference = reference
def edit(self, **kw): def edit(self, **kw):
if kw.has_key("working_directory"): super(NodeTestSuite, self).edit(**kw)
kw["working_directory"] = os.path.join(kw["working_directory"],
def _checkData(self):
if getattr(self, "working_directory", None) is not None:
if not(self.working_directory.endswith(os.path.sep + self.reference)):
self.working_directory = os.path.join(self.working_directory,
self.reference) self.reference)
SlapOSControler.createFolder(kw["working_directory"]) SlapOSControler.createFolder(self.working_directory)
kw["custom_profile_path"] = os.path.join(kw['working_directory'], self.custom_profile_path = os.path.join(self.working_directory,
'software.cfg') 'software.cfg')
super(NodeTestSuite, self).edit(**kw) if getattr(self, "vcs_repository_list", None) is not None:
for vcs_repository in self.vcs_repository_list:
buildout_section_id = vcs_repository.get('buildout_section_id', None)
repository_id = buildout_section_id or \
vcs_repository.get('url').split('/')[-1].split('.')[0]
repository_path = os.path.join(self.working_directory,repository_id)
vcs_repository['repository_id'] = repository_id
vcs_repository['repository_path'] = repository_path
class TestNode(object): class TestNode(object):
...@@ -88,12 +103,12 @@ class TestNode(object): ...@@ -88,12 +103,12 @@ class TestNode(object):
def checkOldTestSuite(self,test_suite_data): def checkOldTestSuite(self,test_suite_data):
config = self.config config = self.config
installed_reference_set = set(os.listdir(config['slapos_directory'])) installed_reference_set = set(os.listdir(config['working_directory']))
wished_reference_set = set([x['test_suite_reference'] for x in test_suite_data]) wished_reference_set = set([x['test_suite_reference'] for x in test_suite_data])
to_remove_reference_set = installed_reference_set.difference( to_remove_reference_set = installed_reference_set.difference(
wished_reference_set) wished_reference_set)
for y in to_remove_reference_set: for y in to_remove_reference_set:
fpath = os.path.join(config['slapos_directory'],y) fpath = os.path.join(config['working_directory'],y)
self.delNodeTestSuite(y) self.delNodeTestSuite(y)
if os.path.isdir(fpath): if os.path.isdir(fpath):
shutil.rmtree(fpath) shutil.rmtree(fpath)
...@@ -115,23 +130,11 @@ class TestNode(object): ...@@ -115,23 +130,11 @@ class TestNode(object):
config = self.config config = self.config
profile_content = '' profile_content = ''
assert len(node_test_suite.vcs_repository_list), "we must have at least one repository" assert len(node_test_suite.vcs_repository_list), "we must have at least one repository"
try:
# BBB: Accept global profile_path, which is the same as setting it for the
# first configured repository.
profile_path = config.pop(PROFILE_PATH_KEY)
except KeyError:
pass
else:
node_test_suite.vcs_repository_list[0][PROFILE_PATH_KEY] = profile_path
profile_path_count = 0 profile_path_count = 0
for vcs_repository in node_test_suite.vcs_repository_list: for vcs_repository in node_test_suite.vcs_repository_list:
url = vcs_repository['url'] url = vcs_repository['url']
buildout_section_id = vcs_repository.get('buildout_section_id', None) buildout_section_id = vcs_repository.get('buildout_section_id', None)
repository_id = buildout_section_id or \ repository_path = vcs_repository['repository_path']
url.split('/')[-1].split('.')[0]
repository_path = os.path.join(node_test_suite.working_directory,repository_id)
vcs_repository['repository_id'] = repository_id
vcs_repository['repository_path'] = repository_path
try: try:
profile_path = vcs_repository[PROFILE_PATH_KEY] profile_path = vcs_repository[PROFILE_PATH_KEY]
except KeyError: except KeyError:
...@@ -158,7 +161,6 @@ branch = %(branch)s ...@@ -158,7 +161,6 @@ branch = %(branch)s
custom_profile = open(node_test_suite.custom_profile_path, 'w') custom_profile = open(node_test_suite.custom_profile_path, 'w')
custom_profile.write(profile_content) custom_profile.write(profile_content)
custom_profile.close() custom_profile.close()
config['repository_path'] = repository_path
sys.path.append(repository_path) sys.path.append(repository_path)
def getAndUpdateFullRevisionList(self, node_test_suite): def getAndUpdateFullRevisionList(self, node_test_suite):
...@@ -251,7 +253,7 @@ branch = %(branch)s ...@@ -251,7 +253,7 @@ branch = %(branch)s
We will build slapos software needed by the testnode itself, We will build slapos software needed by the testnode itself,
like the building of selenium-runner by default like the building of selenium-runner by default
""" """
return self._prepareSlapOS(self.config['slapos_directory'], self._prepareSlapOS(self.config['slapos_directory'],
test_node_slapos, create_partition=0, test_node_slapos, create_partition=0,
software_path_list=self.config.get("software_list")) software_path_list=self.config.get("software_list"))
...@@ -304,7 +306,7 @@ branch = %(branch)s ...@@ -304,7 +306,7 @@ branch = %(branch)s
def cleanUp(self,test_result): def cleanUp(self,test_result):
log = self.log log = self.log
log('Testnode.run, finally close') log('Testnode.cleanUp')
self.process_manager.killPreviousRun() self.process_manager.killPreviousRun()
if test_result is not None: if test_result is not None:
try: try:
...@@ -324,6 +326,7 @@ branch = %(branch)s ...@@ -324,6 +326,7 @@ branch = %(branch)s
try: try:
while True: while True:
try: try:
self.cleanUp(None)
remote_test_result_needs_cleanup = False remote_test_result_needs_cleanup = False
begin = time.time() begin = time.time()
self.prepareSlapOSForTestNode(test_node_slapos) self.prepareSlapOSForTestNode(test_node_slapos)
...@@ -367,6 +370,7 @@ branch = %(branch)s ...@@ -367,6 +370,7 @@ branch = %(branch)s
time.sleep(20) time.sleep(20)
self.runTestSuite(node_test_suite,portal_url, slapos_controler) self.runTestSuite(node_test_suite,portal_url, slapos_controler)
test_result.removeWatch(log_file_name) test_result.removeWatch(log_file_name)
self.cleanUp(test_result)
except (SubprocessError, CalledProcessError) as e: except (SubprocessError, CalledProcessError) as e:
log("SubprocessError", exc_info=sys.exc_info()) log("SubprocessError", exc_info=sys.exc_info())
if test_result is not None: if test_result is not None:
...@@ -401,4 +405,5 @@ branch = %(branch)s ...@@ -401,4 +405,5 @@ branch = %(branch)s
# Nice way to kill *everything* generated by run process -- process # Nice way to kill *everything* generated by run process -- process
# groups working only in POSIX compilant systems # groups working only in POSIX compilant systems
# Exceptions are swallowed during cleanup phas # Exceptions are swallowed during cleanup phas
log("GENERAL EXCEPTION, QUITING")
self.cleanUp(test_result) self.cleanUp(test_result)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment