X Tutup
Skip to content

Commit 23e85f4

Browse files
authored
Environments: unify the spec objects on first concretization (spack#29948)
Currently environments are indexed by build hashes. When looking into this bug I noticed there is a disconnect between environments that are concretized in memory for the first time and environments that are read from a `spack.lock`. The issue is that specs read from a `spack.lock` don't have a full hash, since they are indexed by a build hash which is strictly coarser. They are also marked "final" as they are read from a file, so we can't compute additional hashes. This bugfix PR makes "first concretization" equivalent to re-reading the specs from a corresponding `spack.lock`, and doing so unveiled a few tests were we were making wrong assumptions and relying on the fact that a `spack.lock` file was not there already. * Add unit test * Modify mpich to trigger jobs in pipelines * Fix two failing unit tests * Fix another full_hash vs. build_hash mismatch in tests
1 parent dfff935 commit 23e85f4

File tree

5 files changed

+43
-9
lines changed

5 files changed

+43
-9
lines changed

lib/spack/spack/environment/environment.py

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1271,11 +1271,33 @@ def _concretize_separately(self, tests=False):
12711271

12721272
finish = time.time()
12731273
tty.msg('Environment concretized in %.2f seconds.' % (finish - start))
1274-
results = []
1274+
by_hash = {}
12751275
for abstract, concrete in zip(root_specs, concretized_root_specs):
12761276
self._add_concrete_spec(abstract, concrete)
1277-
results.append((abstract, concrete))
1277+
by_hash[concrete.build_hash()] = concrete
1278+
1279+
# Unify the specs objects, so we get correct references to all parents
1280+
self._read_lockfile_dict(self._to_lockfile_dict())
1281+
1282+
# Re-attach information on test dependencies
1283+
if tests:
1284+
# This is slow, but the information on test dependency is lost
1285+
# after unification or when reading from a lockfile.
1286+
for h in self.specs_by_hash:
1287+
current_spec, computed_spec = self.specs_by_hash[h], by_hash[h]
1288+
for node in computed_spec.traverse():
1289+
test_deps = node.dependencies(deptype='test')
1290+
for test_dependency in test_deps:
1291+
if test_dependency in current_spec[node.name]:
1292+
continue
1293+
current_spec[node.name].add_dependency_edge(
1294+
test_dependency.copy(), deptype='test'
1295+
)
12781296

1297+
results = [
1298+
(abstract, self.specs_by_hash[h]) for abstract, h in
1299+
zip(self.concretized_user_specs, self.concretized_order)
1300+
]
12791301
return results
12801302

12811303
def concretize_and_add(self, user_spec, concrete_spec=None, tests=False):

lib/spack/spack/test/ci.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -579,3 +579,15 @@ def test_get_spec_filter_list(mutable_mock_env_path, config, mutable_mock_repo):
579579
'libelf'])
580580

581581
assert affected_pkg_names == expected_affected_pkg_names
582+
583+
584+
@pytest.mark.regression('29947')
585+
def test_affected_specs_on_first_concretization(mutable_mock_env_path, config):
586+
e = ev.create('first_concretization')
587+
e.add('hdf5~mpi~szip')
588+
e.add('hdf5~mpi+szip')
589+
e.concretize()
590+
591+
affected_specs = spack.ci.get_spec_filter_list(e, ['zlib'])
592+
hdf5_specs = [s for s in affected_specs if s.name == 'hdf5']
593+
assert len(hdf5_specs) == 2

lib/spack/spack/test/cmd/ci.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1731,12 +1731,12 @@ def test_ci_reproduce(tmpdir, mutable_mock_env_path,
17311731
job_spec_yaml_path = os.path.join(
17321732
working_dir.strpath, 'archivefiles.yaml')
17331733
with open(job_spec_yaml_path, 'w') as fd:
1734-
fd.write(job_spec.to_yaml(hash=ht.full_hash))
1734+
fd.write(job_spec.to_yaml(hash=ht.build_hash))
17351735

17361736
root_spec_yaml_path = os.path.join(
17371737
working_dir.strpath, 'root.yaml')
17381738
with open(root_spec_yaml_path, 'w') as fd:
1739-
fd.write(root_spec.to_yaml(hash=ht.full_hash))
1739+
fd.write(root_spec.to_yaml(hash=ht.build_hash))
17401740

17411741
artifacts_root = os.path.join(working_dir.strpath, 'scratch_dir')
17421742
pipeline_path = os.path.join(artifacts_root, 'pipeline.yml')

lib/spack/spack/test/cmd/install.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -851,7 +851,7 @@ def test_install_no_add_in_env(tmpdir, mock_fetch, install_mockery,
851851
# but not added as a root
852852
mpi_spec_yaml_path = tmpdir.join('{0}.yaml'.format(mpi_spec.name))
853853
with open(mpi_spec_yaml_path.strpath, 'w') as fd:
854-
fd.write(mpi_spec.to_yaml(hash=ht.full_hash))
854+
fd.write(mpi_spec.to_yaml(hash=ht.build_hash))
855855

856856
install('--no-add', '-f', mpi_spec_yaml_path.strpath)
857857
assert(mpi_spec not in e.roots())

var/spack/repos/builtin/packages/mpich/package.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -174,10 +174,10 @@ class Mpich(AutotoolsPackage):
174174
depends_on('argobots', when='+argobots')
175175

176176
# building from git requires regenerating autotools files
177-
depends_on('automake@1.15:', when='@develop', type=("build"))
178-
depends_on('libtool@2.4.4:', when='@develop', type=("build"))
179-
depends_on("m4", when="@develop", type=("build")),
180-
depends_on("autoconf@2.67:", when='@develop', type=("build"))
177+
depends_on('automake@1.15:', when='@develop', type='build')
178+
depends_on('libtool@2.4.4:', when='@develop', type='build')
179+
depends_on("m4", when="@develop", type='build'),
180+
depends_on("autoconf@2.67:", when='@develop', type='build')
181181

182182
# building with "+hwloc' also requires regenerating autotools files
183183
depends_on('automake@1.15:', when='@3.3:3.3.99 +hwloc', type="build")

0 commit comments

Comments
 (0)
X Tutup