Repository: spack/spack

Issue:
spack find not working as expected when passed specs
I ran `spack find gromacs ^plumed` to identify gromacs installations built against plumed and found that it unexpectedly returned all installations without regard to a plumed dependency.  I was able to reproduce this behavior with `openmpi`; it is not related to gromacs specifically. 

### Steps to reproduce the issue

Demonstrated with openmpi but I expect any app with at least two builds that have different dependencies could be used. Note that only the first openmpi package has a libfabric or slurm dependency.  

```console
$ spack find --deps -l openmpi
==> 2 installed packages
-- linux-rhel7-x86_64 / gcc@8.2.0 -------------------------------
s7t5pip    openmpi@3.1.3
l5rah2h        ^hwloc@1.11.9
qcb7t3u            ^libpciaccess@0.13.5
5nj33dj            ^libxml2@2.9.8
bcielpo                ^xz@5.2.4
hyog4nv                ^zlib@1.2.11
gv3qat4            ^numactl@2.0.11
5tma6et        ^libfabric@1.6.1
4grmoxm        ^slurm@17.11.8

bpu3gjm    openmpi@3.1.3
l5rah2h        ^hwloc@1.11.9
qcb7t3u            ^libpciaccess@0.13.5
5nj33dj            ^libxml2@2.9.8
bcielpo                ^xz@5.2.4
hyog4nv                ^zlib@1.2.11
gv3qat4            ^numactl@2.0.11


$ spack find -l openmpi ^libfabric
==> 2 installed packages
-- linux-rhel7-x86_64 / gcc@8.2.0 -------------------------------
s7t5pip openmpi@3.1.3  bpu3gjm openmpi@3.1.3


$ spack find -l openmpi ^slurm
==> 2 installed packages
-- linux-rhel7-x86_64 / gcc@8.2.0 -------------------------------
s7t5pip openmpi@3.1.3  bpu3gjm openmpi@3.1.3


```

### Information on your system

I am using spack 0.12.0 on RHEL 7.5.  



Discussion:
Why are you using Spack find?  If you're trying to build a script that will find / load / something installed packages, then that will be problematic; because `spack find` is non-deterministic.  It's a decent command-line tool, but definitely not robust.
I use `spack find` on the command line.  I noticed the oddity described above when trying to identify all packages with a certain dependency.  I have since learned via the spack channel of other ways to query that information.  @tgamblin pointed out that the behavior I described was a bug, though, so i opened this report to document it.
Confirmed this bug working with Spack at ffdde40f56d48c18ca9c45b0599221ef1dab40a2

Resolving patch:
diff --git a/lib/spack/spack/database.py b/lib/spack/spack/database.py
--- a/lib/spack/spack/database.py
+++ b/lib/spack/spack/database.py
@@ -1254,7 +1254,8 @@ def _query(
             if not (start_date < inst_date < end_date):
                 continue
 
-            if query_spec is any or rec.spec.satisfies(query_spec):
+            if (query_spec is any or
+                rec.spec.satisfies(query_spec, strict=True)):
                 results.append(rec.spec)
 
         return results
diff --git a/var/spack/repos/builtin.mock/packages/hdf5/package.py b/var/spack/repos/builtin.mock/packages/hdf5/package.py
new file mode 100644
--- /dev/null
+++ b/var/spack/repos/builtin.mock/packages/hdf5/package.py
@@ -0,0 +1,15 @@
+# Copyright 2013-2020 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)
+
+
+class Hdf5(Package):
+    homepage = "http://www.llnl.gov"
+    url      = "http://www.llnl.gov/hdf5-1.0.tar.gz"
+
+    version(2.3, 'foobarbaz')
+
+    variant('mpi', default=True, description='Debug variant')
+
+    depends_on('mpi', when='mpi')


Test patch:
diff --git a/lib/spack/spack/test/database.py b/lib/spack/spack/test/database.py
--- a/lib/spack/spack/test/database.py
+++ b/lib/spack/spack/test/database.py
@@ -729,3 +729,23 @@ def test_query_unused_specs(mutable_database):
     unused = spack.store.db.unused_specs
     assert len(unused) == 1
     assert unused[0].name == 'cmake'
+
+
+@pytest.mark.regression('10019')
+def test_query_spec_with_conditional_dependency(mutable_database):
+    # The issue is triggered by having dependencies that are
+    # conditional on a Boolean variant
+    s = spack.spec.Spec('hdf5~mpi')
+    s.concretize()
+    s.package.do_install(fake=True, explicit=True)
+
+    results = spack.store.db.query_local('hdf5 ^mpich')
+    assert not results
+
+
+@pytest.mark.regression('10019')
+def test_query_spec_with_non_conditional_virtual_dependency(database):
+    # Ensure the same issue doesn't come up for virtual
+    # dependency that are not conditional on variants
+    results = spack.store.db.query_local('mpileaks ^mpich')
+    assert len(results) == 1