Fix reading externals from old databases (#11118)

* Update Spec.prefix to have special case for 'None' in database path; regression test
* Update in database reader rather than spec
* Change assertion to conditional + raise
* Added test for concrete check in Spec.prefix
This commit is contained in:
Greg Becker 2019-04-05 14:58:57 -07:00 committed by Todd Gamblin
parent af3e91926a
commit 8a17282001
4 changed files with 36 additions and 2 deletions

View File

@ -112,7 +112,7 @@ def __init__(
installation_time=None
):
self.spec = spec
self.path = str(path)
self.path = str(path) if path else None
self.installed = bool(installed)
self.ref_count = ref_count
self.explicit = explicit
@ -132,6 +132,10 @@ def to_dict(self):
def from_dict(cls, spec, dictionary):
d = dict(dictionary.items())
d.pop('spec', None)
# Old databases may have "None" for path for externals
if d['path'] == 'None':
d['path'] = None
return InstallRecord(spec, **d)

View File

@ -1267,6 +1267,9 @@ def cshort_spec(self):
@property
def prefix(self):
if not self._concrete:
raise SpecError("Spec is not concrete: " + str(self))
if self._prefix is None:
upstream, record = spack.store.db.query_by_spec_hash(
self.dag_hash())

View File

@ -12,6 +12,7 @@
import multiprocessing
import os
import pytest
import json
from llnl.util.tty.colify import colify
@ -625,3 +626,23 @@ def test_regression_issue_8036(mutable_database, usr_folder_exists):
# Now install the external package and check again the `installed` property
s.package.do_install(fake=True)
assert s.package.installed
@pytest.mark.regression('11118')
def test_old_external_entries_prefix(mutable_database):
with open(spack.store.db._index_path, 'r') as f:
db_obj = json.loads(f.read())
s = spack.spec.Spec('externaltool')
s.concretize()
db_obj['database']['installs'][s.dag_hash()]['path'] = 'None'
with open(spack.store.db._index_path, 'w') as f:
f.write(json.dumps(db_obj))
record = spack.store.db.get_record(s)
assert record.path is None
assert record.spec._prefix is None
assert record.spec.prefix == record.spec.external_path

View File

@ -6,7 +6,7 @@
import sys
import pytest
from spack.spec import Spec, UnsatisfiableSpecError
from spack.spec import Spec, UnsatisfiableSpecError, SpecError
from spack.spec import substitute_abstract_variants, parse_anonymous_spec
from spack.variant import InvalidVariantValueError
from spack.variant import MultipleValuesInExclusiveVariantError
@ -835,3 +835,9 @@ class Pkg(object):
with pytest.raises(spack.directives.DirectiveError) as exc_info:
fn(Pkg())
assert "the default cannot be an empty string" in str(exc_info.value)
def test_abstract_spec_prefix_error(self):
spec = Spec('libelf')
with pytest.raises(SpecError):
spec.prefix