From bc34ec414f562d1934d6662eb9b4857116b26baf Mon Sep 17 00:00:00 2001 From: Sam Thursfield Date: Tue, 18 Feb 2014 16:53:02 +0000 Subject: Add generic way to force a specific chunk version in a system-branch The old set_lighttpd_chunk_version() function is no longer needed. --- test_trove_upgrades.py | 88 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 72 insertions(+), 16 deletions(-) diff --git a/test_trove_upgrades.py b/test_trove_upgrades.py index f90cbb9..75580e2 100644 --- a/test_trove_upgrades.py +++ b/test_trove_upgrades.py @@ -58,6 +58,11 @@ import time import urlparse import yaml +# In general, tests should treat Morph as a black box rather than calling +# functions in morphlib to do stuff. It's better than copying and pasting +# stuff though! +import morphlib +import morphlib.plugins.branch_and_merge_plugin # The test host must have passwordless access to this machine. The tests set # set StrictHostKeyChecking=no for SSH connections so it does not need to be in @@ -360,12 +365,63 @@ class TroveUpgrade(Deployment): class SystemTestBranch(object): + '''Morph system-branch abstraction for use in Baserock system tests.''' def __init__(self, workspace_dir, name): self.workspace_dir = workspace_dir self.branch_dir = os.path.join(workspace_dir, name) self.morphs_dir = os.path.join( self.branch_dir, 'baserock:baserock', 'morphs') + def get_repo_and_ref_for_chunk(self, stratum, chunk): + stratum_morph_file = os.path.join( + self.morphs_dir, '%s.morph' % stratum) + stratum_morph = yaml.load(read_file(stratum_morph_file)) + + for chunkref in stratum_morph['chunks']: + if chunkref['name'] == chunk: + return chunkref['repo'], chunkref['ref'] + else: + raise Exception( + "Chunk %s not found in stratum %s" % (chunk, stratum)) + + def _copy_chunk_morph_if_missing(self, chunk_dir, chunk, original_ref): + chunk_morph_name = '%s.morph' % chunk + with set_directory(chunk_dir): + if os.path.exists(chunk_morph_name): + return + output = run_git(['ls-tree', original_ref, chunk_morph_name]) + original_ref_has_chunk_morph = (len(output) > 0) + if not original_ref_has_chunk_morph: + return + object_name = original_ref + ':' + chunk_morph_name + with open(chunk_morph_name, 'w') as f: + run_git(['cat-file', 'blob', object_name], stdout=f) + message = 'Add lighttpd.morph from branch %s' % BRANCH + run_git(['add', chunk_morph_name]) + run_git(['commit', '-m', message]) + + def set_chunk_version(self, system, stratum, chunk, + tag='baserock/morph'): + ''' + Force a specific version of a chunk to be built in a system self. + + Uses `morph edit` and `git reset` to achieve this. + ''' + chunk_repo_uri, original_ref = self.get_repo_and_ref_for_chunk( + branch, stratum, chunk) + + with set_directory(self.morphs_dir): + run_morph(['edit', system, stratum, chunk]) + run_git(['add', '%s.morph' % stratum]) + run_git(['commit', '-m', 'Edit %s chunk' % chunk]) + + plugin = morphlib.plugins.branch_and_merge_plugin.BranchAndMergePlugin + chunk_dir = os.path.join( + self.branch_dir, plugin.convert_uri_to_path(chunk_repo_uri)) + run_git(['reset', '--hard', tag], cwd=chunk_dir) + + self._copy_chunk_morph_if_missing(chunk_dir, chunk, original_ref) + class TestInitialDeployment(object): ''' @@ -476,22 +532,20 @@ class BaseTestSuite(object): return SystemTestBranch(workspace_dir, name) -class TestUpgrades(BaseTestSuite): - def set_lighttpd_version(self, branch, tag='baserock/morph'): - ''' - Use 'morph edit' and 'git reset' to force a specific lighttpd version. - ''' - run_morph(['edit', 'trove-system-x86_64', 'trove', 'lighttpd'], - cwd=branch.morphs_dir) - run_git(['add', 'trove.morph'], cwd=branch.morphs_dir) - run_git(['commit', '-m', 'Edit lighttpd chunk'], cwd=branch.morphs_dir) - - chunk_dir = os.path.join(branch.branch_dir, 'upstream:lighttpd') - # Set the system branch's corresponding Git branch in the chunk repo - # to the specific ref. This chunk doesn't have a chunk morphology so - # there's no further work to do! - run_git(['reset', '--hard', tag], cwd=chunk_dir) +@contextlib.contextmanager +def set_directory(path): + ''' + Context manager to set current working directory of a script. + ''' + old_path = os.getcwd() + os.chdir(path) + try: + yield + finally: + os.chdir(old_path) + +class TestUpgrades(BaseTestSuite): @contextlib.contextmanager def given_out_of_date_trove_instance(self, vm_name, fixture_dir, reuse=False): ''' @@ -503,7 +557,9 @@ class TestUpgrades(BaseTestSuite): instance.admin_id = os.path.join(branch.morphs_dir, 'testuser.key') else: branch = self.create_system_branch(fixture_dir, 'old') - self.set_lighttpd_version(branch, tag='lighttpd-1.3.14') + branch.set_chunk_version( + system='trove-system-x86_64', stratum='trove', + chunk='lighttpd', tag='lighttpd-1.3.14') instance = TroveInitialDeployment(branch, vm_name) instance.create_config() -- cgit v1.2.1