Repository: conda/conda-build

Issue:
Building a package with build and test requirement, the test requirement is used
We have seperate build and test stages, so we build once with `--no-test` and another time with `-t`.

A package that has an asymetric build and test requirement will favor the test requirement in the build stage even when `--no-test` is specified...

Example:

lets suppose cmake is available in version 3.5, so the build requirement is satisfied, but not the test requirement. We are building with `--no-test`.  So in any case I'd expect CB to build,

```
package:
  name: "teskpkg"
  version: "1.0.0"
  
requiremnts:
  build:
    - cmake >= 3.5
     
test:
  requires:
    - cmake >= 3.7
```

When cmake 3.5 is available and we build with `conda build . --no-test` we get an error that the requriement cmake >= 3.7 cannot be not satisfied.

I noticed that in contrast to CB2 the test requirements are evaluated even before build. That might be the reason for htis. I dont specially like this because it breaks isolation between build and test stage, which imho should be isolated to allow for multi-stage building


Discussion:
Thanks for the report.  This is due to https://github.com/conda/conda-build/pull/2102 which was done to make conda-build error out sooner without doing unnecessary work.

It is a bug, however, that this behavior holds even when --no-test is passed.  @mandeep, if you have a moment today, let's talk about how to fix this.

Resolving patch:
diff --git a/conda_build/build.py b/conda_build/build.py
--- a/conda_build/build.py
+++ b/conda_build/build.py
@@ -830,7 +830,8 @@ def scan_metadata(path):
 }
 
 
-def build(m, post=None, need_source_download=True, need_reparse_in_env=False, built_packages=None):
+def build(m, post=None, need_source_download=True, need_reparse_in_env=False, built_packages=None,
+          notest=False):
     '''
     Build the package with the specified metadata.
 
@@ -928,19 +929,20 @@ def build(m, post=None, need_source_download=True, need_reparse_in_env=False, bu
                                                     channel_urls=tuple(m.config.channel_urls))
 
         try:
-            # make sure test deps are available before taking time to create build env
-            environ.get_install_actions(m.config.test_prefix,
-                                        tuple(test_run_ms_deps), 'test',
-                                        subdir=m.config.build_subdir,
-                                        debug=m.config.debug,
-                                        verbose=m.config.verbose,
-                                        locking=m.config.locking,
-                                        bldpkgs_dirs=tuple(m.config.bldpkgs_dirs),
-                                        timeout=m.config.timeout,
-                                        disable_pip=m.config.disable_pip,
-                                        max_env_retry=m.config.max_env_retry,
-                                        output_folder=m.config.output_folder,
-                                        channel_urls=tuple(m.config.channel_urls))
+            if not notest:
+                # make sure test deps are available before taking time to create build env
+                environ.get_install_actions(m.config.test_prefix,
+                                            tuple(test_run_ms_deps), 'test',
+                                            subdir=m.config.build_subdir,
+                                            debug=m.config.debug,
+                                            verbose=m.config.verbose,
+                                            locking=m.config.locking,
+                                            bldpkgs_dirs=tuple(m.config.bldpkgs_dirs),
+                                            timeout=m.config.timeout,
+                                            disable_pip=m.config.disable_pip,
+                                            max_env_retry=m.config.max_env_retry,
+                                            output_folder=m.config.output_folder,
+                                            channel_urls=tuple(m.config.channel_urls))
         except DependencyNeedsBuildingError as e:
             # subpackages are not actually missing.  We just haven't built them yet.
             missing_deps = set(e.packages) - set(out.name()
@@ -1613,6 +1615,7 @@ def build_tree(recipe_list, config, build_only=False, post=False, notest=False,
                                            need_source_download=need_source_download,
                                            need_reparse_in_env=need_reparse_in_env,
                                            built_packages=built_packages,
+                                           notest=notest,
                                            )
                 if not notest:
                     for pkg, dict_and_meta in packages_from_this.items():


Test patch:
diff --git a/tests/test-recipes/metadata/_test_dependencies/meta.yaml b/tests/test-recipes/metadata/_test_dependencies/meta.yaml
new file mode 100644
--- /dev/null
+++ b/tests/test-recipes/metadata/_test_dependencies/meta.yaml
@@ -0,0 +1,14 @@
+package:
+  name: conda-build-test-depedencies
+  version: 1.0
+
+build:
+  string: abc
+
+requirements:
+  build:
+    - python
+
+test:
+  requires:
+    - somenonexistentpackage1
\ No newline at end of file
diff --git a/tests/test_api_build.py b/tests/test_api_build.py
--- a/tests/test_api_build.py
+++ b/tests/test_api_build.py
@@ -32,6 +32,7 @@
 from conda_build.utils import (copy_into, on_win, check_call_env, convert_path_for_cygwin_or_msys2,
                                package_has_file, check_output_env, get_conda_operation_locks)
 from conda_build.os_utils.external import find_executable
+from conda_build.exceptions import DependencyNeedsBuildingError
 
 from .utils import is_valid_dir, metadata_dir, fail_dir, add_mangling, FileNotFoundError
 
@@ -1094,3 +1095,14 @@ def test_indirect_numpy_dependency(testing_metadata):
     testing_metadata.meta['requirements']['build'] = ['arrow-cpp 0.5.*']
     testing_metadata.config.channel_urls = ['conda-forge']
     api.build(testing_metadata, numpy=1.13)
+
+
+def test_dependencies_with_notest(testing_workdir, testing_config):
+    recipe = os.path.join(metadata_dir, '_test_dependencies')
+    api.build(recipe, config=testing_config, notest=True)
+
+    with pytest.raises(DependencyNeedsBuildingError) as excinfo:
+        api.build(recipe, config=testing_config, notest=False)
+
+    assert 'Unsatisfiable dependencies for platform' in str(excinfo.value)
+    assert 'somenonexistentpackage1' in str(excinfo.value)