From 55f5afaf3c5369ef80d111f2323da5bb496abc9d Mon Sep 17 00:00:00 2001 From: Massimiliano Culpo Date: Sun, 12 Apr 2020 22:14:59 +0200 Subject: database: maintain in-memory consistency on remove (#15777) The performance improvements done in #14693 where leaving the DB in an inconsistent state when specs were removed from it. This PR updates the DB internal state whenever the DB is written to a file. Note that we still cannot properly enumerate installed dependents, so there is a TODO in this code. Fixing that will require the dependents dictionaries in specs to be re-keyed (either by hash, or not keyed at all -- a list would do). See #11983 for details. --- lib/spack/spack/database.py | 6 ++++++ lib/spack/spack/test/cmd/uninstall.py | 16 +++++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/lib/spack/spack/database.py b/lib/spack/spack/database.py index ca9ed67fb5..001f96d1ff 100644 --- a/lib/spack/spack/database.py +++ b/lib/spack/spack/database.py @@ -1128,6 +1128,12 @@ class Database(object): del self._data[key] for dep in rec.spec.dependencies(_tracked_deps): + # FIXME: the two lines below needs to be updated once #11983 is + # FIXME: fixed. The "if" statement should be deleted and specs are + # FIXME: to be removed from dependents by hash and not by name. + # FIXME: See https://github.com/spack/spack/pull/15777#issuecomment-607818955 + if dep._dependents.get(spec.name): + del dep._dependents[spec.name] self._decrement_ref_count(dep) if rec.deprecated_for: diff --git a/lib/spack/spack/test/cmd/uninstall.py b/lib/spack/spack/test/cmd/uninstall.py index 882f075ec7..a5adcdc74b 100644 --- a/lib/spack/spack/test/cmd/uninstall.py +++ b/lib/spack/spack/test/cmd/uninstall.py @@ -4,6 +4,7 @@ # SPDX-License-Identifier: (Apache-2.0 OR MIT) import pytest +import llnl.util.tty as tty import spack.store from spack.main import SpackCommand, SpackCommandError @@ -30,7 +31,7 @@ def test_multiple_matches(mutable_database): @pytest.mark.db def test_installed_dependents(mutable_database): - """Test can't uninstall when ther are installed dependents.""" + """Test can't uninstall when there are installed dependents.""" with pytest.raises(SpackCommandError): uninstall('-y', 'libelf') @@ -155,3 +156,16 @@ def test_force_uninstall_and_reinstall_by_hash(mutable_database): assert len(mpileaks_specs) == 3 assert len(callpath_specs) == 3 # back to 3 assert len(mpi_specs) == 3 + + +@pytest.mark.db +@pytest.mark.regression('15773') +def test_in_memory_consistency_when_uninstalling( + mutable_database, monkeypatch +): + """Test that uninstalling doesn't raise warnings""" + def _warn(*args, **kwargs): + raise RuntimeError('a warning was triggered!') + monkeypatch.setattr(tty, 'warn', _warn) + # Now try to uninstall and check this doesn't trigger warnings + uninstall('-y', '-a') -- cgit v1.2.3-70-g09d2