diff options
author | Todd Gamblin <tgamblin@llnl.gov> | 2014-10-01 23:32:36 -0700 |
---|---|---|
committer | Todd Gamblin <tgamblin@llnl.gov> | 2014-10-03 16:55:53 -0700 |
commit | da84764e97ead919bee7fb02d469c25a6b03ab63 (patch) | |
tree | 748059d635e1f55162cdafc94e9100b573f88fa7 /lib | |
parent | c74cd63389eff149d8c0db4f7d68d173a72b48b3 (diff) | |
download | spack-da84764e97ead919bee7fb02d469c25a6b03ab63.tar.gz spack-da84764e97ead919bee7fb02d469c25a6b03ab63.tar.bz2 spack-da84764e97ead919bee7fb02d469c25a6b03ab63.tar.xz spack-da84764e97ead919bee7fb02d469c25a6b03ab63.zip |
Add test case for git fetching.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/spack/spack/fetch_strategy.py | 15 | ||||
-rw-r--r-- | lib/spack/spack/package.py | 21 | ||||
-rw-r--r-- | lib/spack/spack/packages.py | 21 | ||||
-rw-r--r-- | lib/spack/spack/test/__init__.py | 3 | ||||
-rw-r--r-- | lib/spack/spack/test/git_fetch.py | 175 | ||||
-rw-r--r-- | lib/spack/spack/test/install.py | 5 |
6 files changed, 222 insertions, 18 deletions
diff --git a/lib/spack/spack/fetch_strategy.py b/lib/spack/spack/fetch_strategy.py index cba0ace6d3..328f45c3d6 100644 --- a/lib/spack/spack/fetch_strategy.py +++ b/lib/spack/spack/fetch_strategy.py @@ -225,15 +225,14 @@ class VCSFetchStrategy(FetchStrategy): "%s requires %s argument." % (self.__class__, name)) # Ensure that there's only one of the rev_types - if sum((k in kwargs for k in rev_types)) > 1: + if sum(k in kwargs for k in rev_types) > 1: raise FetchStrategyError( "Supply only one of %s to fetch with %s." % ( comma_or(rev_types), name)) # Set attributes for each rev type. for rt in rev_types: - setattr(self, rt, getattr(kwargs, rt, None)) - + setattr(self, rt, kwargs.get(rt, None)) def check(self): assert(self.stage) @@ -301,7 +300,14 @@ class GitFetchStrategy(VCSFetchStrategy): tty.msg("Already fetched %s." % self.stage.source_path) return - tty.msg("Trying to clone git repository: %s" % self.url) + args = [] + if self.commit: + args.append('at commit %s' % self.commit) + elif self.tag: + args.append('at tag %s' % self.branch) + elif self.branch: + args.append('on branch %s' % self.branch) + tty.msg("Trying to clone git repository:", self.url, *args) if self.commit: # Need to do a regular clone and check out everything if @@ -460,4 +466,3 @@ class NoDigestError(FetchStrategyError): class InvalidArgsError(FetchStrategyError): def __init__(self, msg, long_msg): super(InvalidArgsError, self).__init__(msg, long_msg) - diff --git a/lib/spack/spack/package.py b/lib/spack/spack/package.py index e9fca9ec49..c6e1fd90ef 100644 --- a/lib/spack/spack/package.py +++ b/lib/spack/spack/package.py @@ -372,10 +372,8 @@ class Package(object): if not hasattr(self, 'url'): self.url = None - # Set up a fetch strategy for this package. - self.fetcher = None - if self.spec.concrete: - self.fetcher = fs.from_args(self.versions[self.version], self) + # Init fetch strategy to None + self._fetcher = None # Set a default list URL (place to find available versions) if not hasattr(self, 'list_url'): @@ -458,6 +456,21 @@ class Package(object): return self._stage + @property + def fetcher(self): + if not self.spec.concrete: + raise ValueError("Can only get a fetcher for a concrete package.") + + if not self._fetcher: + self._fetcher = fs.from_args(self.versions[self.version], self) + return self._fetcher + + + @fetcher.setter + def fetcher(self, f): + self._fetcher = f + + def mirror_path(self): """Get path to this package's archive in a mirror.""" filename = "%s-%s." % (self.name, self.version) diff --git a/lib/spack/spack/packages.py b/lib/spack/spack/packages.py index 72f9403a64..047d82a93a 100644 --- a/lib/spack/spack/packages.py +++ b/lib/spack/spack/packages.py @@ -47,10 +47,10 @@ _package_file_name = 'package.py' def _autospec(function): """Decorator that automatically converts the argument of a single-arg function to a Spec.""" - def converter(self, spec_like): + def converter(self, spec_like, **kwargs): if not isinstance(spec_like, spack.spec.Spec): spec_like = spack.spec.Spec(spec_like) - return function(self, spec_like) + return function(self, spec_like, **kwargs) return converter @@ -63,10 +63,14 @@ class PackageDB(object): @_autospec - def get(self, spec): + def get(self, spec, **kwargs): if spec.virtual: raise UnknownPackageError(spec.name) + if kwargs.get('new', False): + if spec in self.instances: + del self.instances[spec] + if not spec in self.instances: package_class = self.get_class_for_package_name(spec.name) try: @@ -78,6 +82,17 @@ class PackageDB(object): @_autospec + def delete(self, spec): + """Force a package to be recreated.""" + del self.instances[spec] + + + def purge(self): + """Clear entire package instance cache.""" + self.instances.clear() + + + @_autospec def get_installed(self, spec): """Get all the installed specs that satisfy the provided spec constraint.""" return [s for s in self.installed_package_specs() if s.satisfies(spec)] diff --git a/lib/spack/spack/test/__init__.py b/lib/spack/spack/test/__init__.py index 8ddc7f227d..b00f9a31ce 100644 --- a/lib/spack/spack/test/__init__.py +++ b/lib/spack/spack/test/__init__.py @@ -47,7 +47,8 @@ test_names = ['versions', 'package_sanity', 'config', 'directory_layout', - 'python_version'] + 'python_version', + 'git_fetch'] def list_tests(): diff --git a/lib/spack/spack/test/git_fetch.py b/lib/spack/spack/test/git_fetch.py new file mode 100644 index 0000000000..c7c11621f9 --- /dev/null +++ b/lib/spack/spack/test/git_fetch.py @@ -0,0 +1,175 @@ +############################################################################## +# Copyright (c) 2013, Lawrence Livermore National Security, LLC. +# Produced at the Lawrence Livermore National Laboratory. +# +# This file is part of Spack. +# Written by Todd Gamblin, tgamblin@llnl.gov, All rights reserved. +# LLNL-CODE-647188 +# +# For details, see https://scalability-llnl.github.io/spack +# Please also see the LICENSE file for our notice and the LGPL. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License (as published by +# the Free Software Foundation) version 2.1 dated February 1999. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and +# conditions of the GNU General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +############################################################################## +import os +import unittest +import shutil +import tempfile +from contextlib import closing + +from llnl.util.filesystem import * + +import spack +from spack.version import ver +from spack.stage import Stage +from spack.util.executable import which +from spack.test.mock_packages_test import * + +test_repo_path = 'test-repo' +test_file_name = 'test-file.txt' + +test_branch = 'test-branch' +test_branch_file_name = 'branch-test-file' + +test_tag_branch = 'test-tag-branch' +test_tag = 'test-tag' +test_tag_file_name = 'tag-test-file' + +untracked = 'foobarbaz' + +git = which('git', required=True) + +def rev_hash(rev): + return git('rev-parse', rev, return_output=True).strip() + + +class GitFetchTest(MockPackagesTest): + """Tests fetching from a dummy git repository.""" + + def setUp(self): + """Create a git repository with master and two other branches, + and one tag, so that we can experiment on it.""" + super(GitFetchTest, self).setUp() + self.stage = Stage('fetch-test') + + self.repo_path = join_path(self.stage.path, test_repo_path) + mkdirp(self.repo_path) + + self.test_file = join_path(self.repo_path, test_file_name) + touch(self.test_file) + + with working_dir(self.repo_path): + git('init') + git('add', self.test_file) + git('commit', '-m', 'testing') + + git('branch', test_branch) + git('branch', test_tag_branch) + + git('checkout', test_branch) + touch(test_branch_file_name) + git('add', test_branch_file_name) + git('commit', '-m' 'branch test') + + git('checkout', test_tag_branch) + touch(test_tag_file_name) + git('add', test_tag_file_name) + git('commit', '-m' 'tag test') + git('tag', test_tag) + + git('checkout', 'master') + + self.commit = rev_hash(test_tag) + + spec = Spec('git-test') + spec.concretize() + self.pkg = spack.db.get(spec, new=True) + + + def tearDown(self): + """Destroy the stage space used by this test.""" + super(GitFetchTest, self).tearDown() + + if self.stage is not None: + self.stage.destroy() + + self.pkg.do_clean_dist() + + + def assert_rev(self, rev): + """Check that the current git revision is equal to the supplied rev.""" + self.assertEqual(rev_hash('HEAD'), rev_hash(rev)) + + + def try_fetch(self, rev, test_file, args): + """Tries to: + 1. Fetch the repo using a fetch strategy constructed with + supplied args. + 2. Check if the test_file is in the checked out repository. + 3. Assert that the repository is at the revision supplied. + 4. Add and remove some files, then reset the repo, and + ensure it's all there again. + """ + self.pkg.versions[ver('git')] = args + + self.pkg.do_stage() + self.assert_rev(rev) + + file_path = join_path(self.pkg.stage.source_path, test_file) + self.assertTrue(os.path.isdir(self.pkg.stage.source_path)) + self.assertTrue(os.path.isfile(file_path)) + + os.unlink(file_path) + self.assertFalse(os.path.isfile(file_path)) + + touch(untracked) + self.assertTrue(os.path.isfile(untracked)) + self.pkg.do_clean_work() + self.assertFalse(os.path.isfile(untracked)) + + self.assertTrue(os.path.isdir(self.pkg.stage.source_path)) + self.assertTrue(os.path.isfile(file_path)) + + self.assert_rev(rev) + + + def test_fetch_master(self): + """Test a default git checkout with no commit or tag specified.""" + self.try_fetch('master', test_file_name, { + 'git' : self.repo_path + }) + + + def test_fetch_branch(self): + """Test fetching a branch.""" + self.try_fetch(test_branch, test_branch_file_name, { + 'git' : self.repo_path, + 'branch' : test_branch + }) + + + def test_fetch_tag(self): + """Test fetching a tag.""" + self.try_fetch(test_tag, test_tag_file_name, { + 'git' : self.repo_path, + 'tag' : test_tag + }) + + + def test_fetch_commit(self): + """Test fetching a particular commit.""" + self.try_fetch(self.commit, test_tag_file_name, { + 'git' : self.repo_path, + 'commit' : self.commit + }) diff --git a/lib/spack/spack/test/install.py b/lib/spack/spack/test/install.py index 896f19ac01..0d53bb45c7 100644 --- a/lib/spack/spack/test/install.py +++ b/lib/spack/spack/test/install.py @@ -101,13 +101,8 @@ class InstallTest(MockPackagesTest): self.assertTrue(spec.concrete) # Get the package - print - print "======== GETTING PACKAGE ========" pkg = spack.db.get(spec) - print "======== GOT PACKAGE ========" - print - # Fake the URL for the package so it downloads from a file. archive_path = join_path(self.stage.path, archive_name) pkg.fetcher = URLFetchStrategy('file://' + archive_path) |