From 8c1cc8c03f0c6602beda052738ae0aec6a4b75e1 Mon Sep 17 00:00:00 2001 From: Sebastien Robin <seb@nexedi.com> Date: Tue, 30 Oct 2012 16:24:51 +0100 Subject: [PATCH] erp5testnode: add test for getAndUpdateFullRevisionList --- erp5/tests/testERP5TestNode.py | 88 ++++++++++++++++++++++++++++------ erp5/util/testnode/testnode.py | 53 ++++++++++---------- 2 files changed, 103 insertions(+), 38 deletions(-) diff --git a/erp5/tests/testERP5TestNode.py b/erp5/tests/testERP5TestNode.py index 882dc82d92..4b168d9500 100644 --- a/erp5/tests/testERP5TestNode.py +++ b/erp5/tests/testERP5TestNode.py @@ -1,7 +1,7 @@ from unittest import TestCase 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/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', @@ -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/Jinja2-2.6-py2.7.egg', '/srv/slapgrid/slappart80/srv/runner/software/ba1e09f3364989dc92da955b64e72f8d/eggs/Werkzeug-0.8.3-py2.7.egg', - ] + ]) from erp5.util.testnode import TestNode -import tempfile -import shutil import os +import shutil +import subprocess +import tempfile class ERP5TestNode(TestCase): @@ -32,16 +33,23 @@ class ERP5TestNode(TestCase): self._tempdir = tempfile.mkdtemp() self.working_directory = os.path.join(self._tempdir, 'testnode') 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.slapos_directory) - self.remote_repository1 = os.path.join(self._tempdir, 'rep1') - self.remote_repository2 = os.path.join(self._tempdir, 'rep2') + os.mkdir(self.remote_repository0) + os.mkdir(self.remote_repository1) def tearDown(self): shutil.rmtree(self._tempdir, True) 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): node_test_suite.edit(working_directory=self.working_directory, @@ -49,14 +57,50 @@ class ERP5TestNode(TestCase): project_title="Foo", test_suite_title="Foo-Test", vcs_repository_list=[ - {'url': self.remote_repository1, + {'url': self.remote_repository0, 'profile_path': 'software.cfg', 'branch': 'master'}, - {'url': self.remote_repository2, - 'buildout_section_id': 'foo', + {'url': self.remote_repository1, + 'buildout_section_id': 'rep1', '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 """ @@ -80,6 +124,9 @@ class ERP5TestNode(TestCase): node_test_suite.working_directory) def test_03_constructProfile(self): + """ + Check if the software profile is correctly generated + """ test_node = self.getTestNode() node_test_suite = test_node.getNodeTestSuite('foo') self.updateNodeTestSuiteData(node_test_suite) @@ -89,11 +136,24 @@ class ERP5TestNode(TestCase): profile = open(node_test_suite.custom_profile_path, 'r') expected_profile = """ [buildout] -extends = %s/testnode/foo/rep1/software.cfg +extends = %s/testnode/foo/rep0/software.cfg -[foo] -repository = %s/testnode/foo/foo +[rep1] +repository = %s/testnode/foo/rep1 branch = master """ % (self._tempdir, self._tempdir) self.assertEquals(expected_profile, profile.read()) 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])) diff --git a/erp5/util/testnode/testnode.py b/erp5/util/testnode/testnode.py index dcc15a6487..6cff03cbcc 100644 --- a/erp5/util/testnode/testnode.py +++ b/erp5/util/testnode/testnode.py @@ -58,6 +58,10 @@ class SlapOSInstance(object): def edit(self, **kw): self.__dict__.update(**kw) + self._checkData() + + def _checkData(self): + pass class NodeTestSuite(SlapOSInstance): @@ -66,14 +70,25 @@ class NodeTestSuite(SlapOSInstance): self.reference = reference def edit(self, **kw): - if kw.has_key("working_directory"): - kw["working_directory"] = os.path.join(kw["working_directory"], - self.reference) - SlapOSControler.createFolder(kw["working_directory"]) - kw["custom_profile_path"] = os.path.join(kw['working_directory'], - 'software.cfg') super(NodeTestSuite, self).edit(**kw) + 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) + SlapOSControler.createFolder(self.working_directory) + self.custom_profile_path = os.path.join(self.working_directory, + 'software.cfg') + 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): def __init__(self, log, config): @@ -88,12 +103,12 @@ class TestNode(object): def checkOldTestSuite(self,test_suite_data): 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]) to_remove_reference_set = installed_reference_set.difference( wished_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) if os.path.isdir(fpath): shutil.rmtree(fpath) @@ -115,23 +130,11 @@ class TestNode(object): config = self.config profile_content = '' 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 for vcs_repository in node_test_suite.vcs_repository_list: url = vcs_repository['url'] buildout_section_id = vcs_repository.get('buildout_section_id', None) - repository_id = buildout_section_id or \ - 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 + repository_path = vcs_repository['repository_path'] try: profile_path = vcs_repository[PROFILE_PATH_KEY] except KeyError: @@ -158,7 +161,6 @@ branch = %(branch)s custom_profile = open(node_test_suite.custom_profile_path, 'w') custom_profile.write(profile_content) custom_profile.close() - config['repository_path'] = repository_path sys.path.append(repository_path) def getAndUpdateFullRevisionList(self, node_test_suite): @@ -251,7 +253,7 @@ branch = %(branch)s We will build slapos software needed by the testnode itself, 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, software_path_list=self.config.get("software_list")) @@ -304,7 +306,7 @@ branch = %(branch)s def cleanUp(self,test_result): log = self.log - log('Testnode.run, finally close') + log('Testnode.cleanUp') self.process_manager.killPreviousRun() if test_result is not None: try: @@ -324,6 +326,7 @@ branch = %(branch)s try: while True: try: + self.cleanUp(None) remote_test_result_needs_cleanup = False begin = time.time() self.prepareSlapOSForTestNode(test_node_slapos) @@ -367,6 +370,7 @@ branch = %(branch)s time.sleep(20) self.runTestSuite(node_test_suite,portal_url, slapos_controler) test_result.removeWatch(log_file_name) + self.cleanUp(test_result) except (SubprocessError, CalledProcessError) as e: log("SubprocessError", exc_info=sys.exc_info()) if test_result is not None: @@ -401,4 +405,5 @@ branch = %(branch)s # Nice way to kill *everything* generated by run process -- process # groups working only in POSIX compilant systems # Exceptions are swallowed during cleanup phas + log("GENERAL EXCEPTION, QUITING") self.cleanUp(test_result) -- 2.30.9