Source code for spack.test.cmd.uninstall

# Copyright 2013-2021 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# 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

uninstall = SpackCommand('uninstall')
install = SpackCommand('install')


[docs]class MockArgs(object): def __init__(self, packages, all=False, force=False, dependents=False): self.packages = packages self.all = all self.force = force self.dependents = dependents self.yes_to_all = True
[docs]@pytest.mark.db def test_multiple_matches(mutable_database): """Test unable to uninstall when multiple matches.""" with pytest.raises(SpackCommandError): uninstall('-y', 'mpileaks')
[docs]@pytest.mark.db def test_installed_dependents(mutable_database): """Test can't uninstall when there are installed dependents.""" with pytest.raises(SpackCommandError): uninstall('-y', 'libelf')
[docs]@pytest.mark.db def test_recursive_uninstall(mutable_database): """Test recursive uninstall.""" uninstall('-y', '-a', '--dependents', 'callpath') all_specs = spack.store.layout.all_specs() assert len(all_specs) == 9 # query specs with multiple configurations mpileaks_specs = [s for s in all_specs if s.satisfies('mpileaks')] callpath_specs = [s for s in all_specs if s.satisfies('callpath')] mpi_specs = [s for s in all_specs if s.satisfies('mpi')] assert len(mpileaks_specs) == 0 assert len(callpath_specs) == 0 assert len(mpi_specs) == 3
[docs]@pytest.mark.db @pytest.mark.regression('3690') @pytest.mark.parametrize('constraint,expected_number_of_specs', [ ('dyninst', 8), ('libelf', 6) ]) def test_uninstall_spec_with_multiple_roots( constraint, expected_number_of_specs, mutable_database ): uninstall('-y', '-a', '--dependents', constraint) all_specs = spack.store.layout.all_specs() assert len(all_specs) == expected_number_of_specs
[docs]@pytest.mark.db @pytest.mark.parametrize('constraint,expected_number_of_specs', [ ('dyninst', 14), ('libelf', 14) ]) def test_force_uninstall_spec_with_ref_count_not_zero( constraint, expected_number_of_specs, mutable_database ): uninstall('-f', '-y', constraint) all_specs = spack.store.layout.all_specs() assert len(all_specs) == expected_number_of_specs
[docs]@pytest.mark.db def test_force_uninstall_and_reinstall_by_hash(mutable_database): """Test forced uninstall and reinstall of old specs.""" # this is the spec to be removed callpath_spec = spack.store.db.query_one('callpath ^mpich') dag_hash = callpath_spec.dag_hash() # ensure can look up by hash and that it's a dependent of mpileaks def validate_callpath_spec(installed): assert installed is True or installed is False specs = spack.store.db.get_by_hash(dag_hash, installed=installed) assert len(specs) == 1 and specs[0] == callpath_spec specs = spack.store.db.get_by_hash(dag_hash[:7], installed=installed) assert len(specs) == 1 and specs[0] == callpath_spec specs = spack.store.db.get_by_hash(dag_hash, installed=any) assert len(specs) == 1 and specs[0] == callpath_spec specs = spack.store.db.get_by_hash(dag_hash[:7], installed=any) assert len(specs) == 1 and specs[0] == callpath_spec specs = spack.store.db.get_by_hash(dag_hash, installed=not installed) assert specs is None specs = spack.store.db.get_by_hash(dag_hash[:7], installed=not installed) assert specs is None mpileaks_spec = spack.store.db.query_one('mpileaks ^mpich') assert callpath_spec in mpileaks_spec spec = spack.store.db.query_one('callpath ^mpich', installed=installed) assert spec == callpath_spec spec = spack.store.db.query_one('callpath ^mpich', installed=any) assert spec == callpath_spec spec = spack.store.db.query_one('callpath ^mpich', installed=not installed) assert spec is None validate_callpath_spec(True) uninstall('-y', '-f', 'callpath ^mpich') # ensure that you can still look up by hash and see deps, EVEN though # the callpath spec is missing. validate_callpath_spec(False) # BUT, make sure that the removed callpath spec is not in queries def db_specs(): all_specs = spack.store.layout.all_specs() return ( all_specs, [s for s in all_specs if s.satisfies('mpileaks')], [s for s in all_specs if s.satisfies('callpath')], [s for s in all_specs if s.satisfies('mpi')] ) all_specs, mpileaks_specs, callpath_specs, mpi_specs = db_specs() total_specs = len(all_specs) assert total_specs == 14 assert len(mpileaks_specs) == 3 assert len(callpath_specs) == 2 assert len(mpi_specs) == 3 # Now, REINSTALL the spec and make sure everything still holds install('--fake', '/%s' % dag_hash[:7]) validate_callpath_spec(True) all_specs, mpileaks_specs, callpath_specs, mpi_specs = db_specs() assert len(all_specs) == total_specs + 1 # back to total_specs+1 assert len(mpileaks_specs) == 3 assert len(callpath_specs) == 3 # back to 3 assert len(mpi_specs) == 3
[docs]@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')