summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorTamara Dahlgren <35777542+tldahlgren@users.noreply.github.com>2019-06-13 11:14:35 -0700
committerPeter Scheibel <scheibel1@llnl.gov>2019-06-13 11:14:35 -0700
commit5cf62e69ce080348f06b43c3e79b2d6d30d25e1e (patch)
tree5250edf0e389c2737175ab4ec2e3cc6d12b4af63 /lib
parentaca1bfdb6a6498b96126fd121989be8b8767a29f (diff)
downloadspack-5cf62e69ce080348f06b43c3e79b2d6d30d25e1e.tar.gz
spack-5cf62e69ce080348f06b43c3e79b2d6d30d25e1e.tar.bz2
spack-5cf62e69ce080348f06b43c3e79b2d6d30d25e1e.tar.xz
spack-5cf62e69ce080348f06b43c3e79b2d6d30d25e1e.zip
Always treat DIYStage as expanded (#11663)
DIYStage, used to treat a user-managed directory as a staging area, should always be considered expanded (i.e. the source has been decompressed if it was stored in an archive). This also: * Adds checks to ensure that the path used to instantiate a DIYStage refers to an existing directory. * Adds tests to check the behavior of DIYStage (including behavior added here, but it was generally untested before).
Diffstat (limited to 'lib')
-rw-r--r--lib/spack/spack/stage.py17
-rw-r--r--lib/spack/spack/test/stage.py58
2 files changed, 73 insertions, 2 deletions
diff --git a/lib/spack/spack/stage.py b/lib/spack/spack/stage.py
index 34d19860fa..474fda3538 100644
--- a/lib/spack/spack/stage.py
+++ b/lib/spack/spack/stage.py
@@ -597,6 +597,12 @@ class DIYStage(object):
"""Simple class that allows any directory to be a spack stage."""
def __init__(self, path):
+ if path is None:
+ raise ValueError("Cannot construct DIYStage without a path.")
+ elif not os.path.isdir(path):
+ raise StagePathError("The stage path directory does not exist:",
+ path)
+
self.archive_file = None
self.path = path
self.source_path = path
@@ -618,8 +624,13 @@ class DIYStage(object):
def expand_archive(self):
tty.msg("Using source directory: %s" % self.source_path)
+ @property
+ def expanded(self):
+ """Returns True since the source_path must exist."""
+ return True
+
def restage(self):
- tty.die("Cannot restage DIY stage.")
+ raise RestageError("Cannot restage a DIY stage.")
def create(self):
self.created = True
@@ -650,6 +661,10 @@ class StageError(spack.error.SpackError):
""""Superclass for all errors encountered during staging."""
+class StagePathError(StageError):
+ """"Error encountered with stage path."""
+
+
class RestageError(StageError):
""""Error encountered during restaging."""
diff --git a/lib/spack/spack/test/stage.py b/lib/spack/spack/test/stage.py
index ba0249f6eb..83d8056119 100644
--- a/lib/spack/spack/test/stage.py
+++ b/lib/spack/spack/test/stage.py
@@ -19,7 +19,7 @@ import spack.stage
import spack.util.executable
from spack.resource import Resource
-from spack.stage import Stage, StageComposite, ResourceStage
+from spack.stage import Stage, StageComposite, ResourceStage, DIYStage
# The following values are used for common fetch and stage mocking fixtures:
_archive_base = 'test-files'
@@ -699,3 +699,59 @@ class TestStage(object):
testpath = str(tmpdir)
with Stage('file:///does-not-exist', path=testpath) as stage:
assert stage.path == testpath
+
+ def test_diystage_path_none(self):
+ """Ensure DIYStage for path=None behaves as expected."""
+ with pytest.raises(ValueError):
+ DIYStage(None)
+
+ def test_diystage_path_invalid(self):
+ """Ensure DIYStage for an invalid path behaves as expected."""
+ with pytest.raises(spack.stage.StagePathError):
+ DIYStage('/path/does/not/exist')
+
+ def test_diystage_path_valid(self, tmpdir):
+ """Ensure DIYStage for a valid path behaves as expected."""
+ path = str(tmpdir)
+ stage = DIYStage(path)
+ assert stage.path == path
+ assert stage.source_path == path
+
+ # Order doesn't really matter for DIYStage since they are
+ # basically NOOPs; however, call each since they are part
+ # of the normal stage usage and to ensure full test coverage.
+ stage.create() # Only sets the flag value
+ assert stage.created
+
+ stage.cache_local() # Only outputs a message
+ stage.fetch() # Only outputs a message
+ stage.check() # Only outputs a message
+ stage.expand_archive() # Only outputs a message
+
+ assert stage.expanded # The path/source_path does exist
+
+ with pytest.raises(spack.stage.RestageError):
+ stage.restage()
+
+ stage.destroy() # A no-op
+ assert stage.path == path # Ensure can still access attributes
+ assert os.path.exists(stage.source_path) # Ensure path still exists
+
+ def test_diystage_preserve_file(self, tmpdir):
+ """Ensure DIYStage preserves an existing file."""
+ # Write a file to the temporary directory
+ fn = tmpdir.join(_readme_fn)
+ fn.write(_readme_contents)
+
+ # Instantiate the DIYStage and ensure the above file is unchanged.
+ path = str(tmpdir)
+ stage = DIYStage(path)
+ assert os.path.isdir(path)
+ assert os.path.isfile(str(fn))
+
+ stage.create() # Only sets the flag value
+
+ readmefn = str(fn)
+ assert os.path.isfile(readmefn)
+ with open(readmefn) as _file:
+ _file.read() == _readme_contents