Skip to content

required-features implicit binaries for test does not check for dep syntax #7853

Closed

Description

Problem
A project with a binary with required-features = ["dep_name/feature_name"] will only build the binary when the given dependency's feature is enabled. This feature syntax is not checked when the binary is built as an implicit dependency of an integration test, and thus the binary will not get built during cargo test --features dep_name/feature_name when I think it should.

Steps
The following patch updates one of Cargo's tests to exercise this case.

diff --git a/tests/testsuite/required_features.rs b/tests/testsuite/required_features.rs
index 6afd917ee..7d7b547c3 100644
--- a/tests/testsuite/required_features.rs
+++ b/tests/testsuite/required_features.rs
@@ -4,6 +4,7 @@ use cargo_test_support::install::{
     assert_has_installed_exe, assert_has_not_installed_exe, cargo_home,
 };
 use cargo_test_support::is_nightly;
+use cargo_test_support::paths::CargoPathExt;
 use cargo_test_support::project;

 #[cargo_test]
@@ -910,7 +911,17 @@ fn dep_feature_in_cmd_line() {
         )
         .file("src/main.rs", "fn main() {}")
         .file("examples/foo.rs", "fn main() {}")
-        .file("tests/foo.rs", "#[test]\nfn test() {}")
+        .file(
+            "tests/foo.rs",
+            r#"
+            #[test]
+            fn bin_is_built() {
+                let s = format!("target/debug/foo{}", std::env::consts::EXE_SUFFIX);
+                let p = std::path::Path::new(&s);
+                assert!(p.exists(), "foo does not exist");
+            }
+            "#,
+        )
         .file(
             "benches/foo.rs",
             r#"
@@ -936,7 +947,9 @@ fn dep_feature_in_cmd_line() {
         .file("bar/src/lib.rs", "")
         .build();

-    p.cargo("build").run();
+    // This is a no-op.
+    p.cargo("build").with_stderr("[FINISHED] dev [..]").run();
+    assert!(!p.bin("foo").is_file());

     // bin
     p.cargo("build --bin=foo")
@@ -967,19 +980,23 @@ Consider enabling them by passing, e.g., `--features=\"bar/a\"`
     assert!(p.bin("examples/foo").is_file());

     // test
+    // This is a no-op, since no tests are enabled.
     p.cargo("test")
         .with_stderr("[FINISHED] test [unoptimized + debuginfo] target(s) in [..]")
         .with_stdout("")
         .run();

+    // Delete the target directory so this can check if the main.rs gets built.
+    p.build_dir().rm_rf();
     p.cargo("test --test=foo --features bar/a")
         .with_stderr(
             "\
+[COMPILING] bar v0.0.1 ([CWD])
 [COMPILING] foo v0.0.1 ([CWD])
 [FINISHED] test [unoptimized + debuginfo] target(s) in [..]
 [RUNNING] target/debug/deps/foo-[..][EXE]",
         )
-        .with_stdout_contains("test test ... ok")
+        .with_stdout_contains("test bin_is_built ... ok")
         .run();

     // bench

Possible Solution(s)
The implicit binary check is done here. This does not check for the extended feature syntax, which is normally done here. Ideally the code for checking required-features should be shared.

Notes

cargo 1.42.0-nightly (f6449ba 2020-01-21)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    A-featuresArea: features — conditional compilationA-required-featuresArea: required-features settingC-bugCategory: bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions