1b8a62b91Sopenharmony_ciuse std::process::Command;
2b8a62b91Sopenharmony_ci
3b8a62b91Sopenharmony_ci#[test]
4b8a62b91Sopenharmony_cifn test_backends() {
5b8a62b91Sopenharmony_ci    // Pick an arbitrary platform where linux_raw is enabled by default and
6b8a62b91Sopenharmony_ci    // ensure that the use-default crate uses it.
7b8a62b91Sopenharmony_ci    #[cfg(all(target_os = "linux", target_arch = "aarch64"))]
8b8a62b91Sopenharmony_ci    {
9b8a62b91Sopenharmony_ci        assert!(
10b8a62b91Sopenharmony_ci            has_dependency(
11b8a62b91Sopenharmony_ci                "test-crates/use-default",
12b8a62b91Sopenharmony_ci                &[],
13b8a62b91Sopenharmony_ci                &[],
14b8a62b91Sopenharmony_ci                &["RUSTFLAGS"],
15b8a62b91Sopenharmony_ci                "linux-raw-sys"
16b8a62b91Sopenharmony_ci            ),
17b8a62b91Sopenharmony_ci            "use-default does not depend on linux-raw-sys"
18b8a62b91Sopenharmony_ci        );
19b8a62b91Sopenharmony_ci    }
20b8a62b91Sopenharmony_ci
21b8a62b91Sopenharmony_ci    // Pick an arbitrary platform where linux_raw is enabled by default and
22b8a62b91Sopenharmony_ci    // ensure that the use-rustix-auxv crate uses it, and does not use libc.
23b8a62b91Sopenharmony_ci    #[cfg(all(target_os = "linux", target_arch = "aarch64"))]
24b8a62b91Sopenharmony_ci    {
25b8a62b91Sopenharmony_ci        // TODO: Re-enable this test once io-lifetimes can depend on Rust 1.63
26b8a62b91Sopenharmony_ci        // and always use std, so it can drop its libc dependency.
27b8a62b91Sopenharmony_ci        /*
28b8a62b91Sopenharmony_ci        assert!(
29b8a62b91Sopenharmony_ci            !has_dependency(
30b8a62b91Sopenharmony_ci                "test-crates/use-rustix-auxv",
31b8a62b91Sopenharmony_ci                &[],
32b8a62b91Sopenharmony_ci                &[],
33b8a62b91Sopenharmony_ci                &["RUSTFLAGS"],
34b8a62b91Sopenharmony_ci                "libc"
35b8a62b91Sopenharmony_ci            ),
36b8a62b91Sopenharmony_ci            "use-rustix-auxv depends on libc"
37b8a62b91Sopenharmony_ci        );
38b8a62b91Sopenharmony_ci        */
39b8a62b91Sopenharmony_ci
40b8a62b91Sopenharmony_ci        assert!(
41b8a62b91Sopenharmony_ci            has_dependency(
42b8a62b91Sopenharmony_ci                "test-crates/use-rustix-auxv",
43b8a62b91Sopenharmony_ci                &[],
44b8a62b91Sopenharmony_ci                &[],
45b8a62b91Sopenharmony_ci                &["RUSTFLAGS"],
46b8a62b91Sopenharmony_ci                "linux-raw-sys"
47b8a62b91Sopenharmony_ci            ),
48b8a62b91Sopenharmony_ci            "use-rustix-auxv does not depend on linux-raw-sys"
49b8a62b91Sopenharmony_ci        );
50b8a62b91Sopenharmony_ci    }
51b8a62b91Sopenharmony_ci
52b8a62b91Sopenharmony_ci    #[cfg(windows)]
53b8a62b91Sopenharmony_ci    let libc_dep = "windows-sys";
54b8a62b91Sopenharmony_ci    #[cfg(unix)]
55b8a62b91Sopenharmony_ci    let libc_dep = "libc";
56b8a62b91Sopenharmony_ci
57b8a62b91Sopenharmony_ci    // Test the use-libc crate, which enables the "use-libc" cargo feature.
58b8a62b91Sopenharmony_ci    assert!(
59b8a62b91Sopenharmony_ci        has_dependency("test-crates/use-libc", &[], &[], &["RUSTFLAGS"], libc_dep),
60b8a62b91Sopenharmony_ci        "use-libc doesn't depend on {}",
61b8a62b91Sopenharmony_ci        libc_dep
62b8a62b91Sopenharmony_ci    );
63b8a62b91Sopenharmony_ci
64b8a62b91Sopenharmony_ci    // Test the use-default crate with `--cfg=rustix_use_libc`.
65b8a62b91Sopenharmony_ci    assert!(
66b8a62b91Sopenharmony_ci        has_dependency(
67b8a62b91Sopenharmony_ci            "test-crates/use-default",
68b8a62b91Sopenharmony_ci            &[],
69b8a62b91Sopenharmony_ci            &[("RUSTFLAGS", "--cfg=rustix_use_libc")],
70b8a62b91Sopenharmony_ci            &[],
71b8a62b91Sopenharmony_ci            libc_dep
72b8a62b91Sopenharmony_ci        ),
73b8a62b91Sopenharmony_ci        "use-default with --cfg=rustix_use_libc does not depend on {}",
74b8a62b91Sopenharmony_ci        libc_dep
75b8a62b91Sopenharmony_ci    );
76b8a62b91Sopenharmony_ci
77b8a62b91Sopenharmony_ci    // Test the use-default crate with `--features=rustix/use-libc`.
78b8a62b91Sopenharmony_ci    assert!(
79b8a62b91Sopenharmony_ci        has_dependency(
80b8a62b91Sopenharmony_ci            "test-crates/use-default",
81b8a62b91Sopenharmony_ci            &["--features=rustix/use-libc"],
82b8a62b91Sopenharmony_ci            &[],
83b8a62b91Sopenharmony_ci            &[],
84b8a62b91Sopenharmony_ci            libc_dep
85b8a62b91Sopenharmony_ci        ),
86b8a62b91Sopenharmony_ci        "use-default with --features=rustix/use-libc does not depend on {}",
87b8a62b91Sopenharmony_ci        libc_dep
88b8a62b91Sopenharmony_ci    );
89b8a62b91Sopenharmony_ci}
90b8a62b91Sopenharmony_ci
91b8a62b91Sopenharmony_ci/// Test whether the crate at directory `dir` has a dependency on `dependency`,
92b8a62b91Sopenharmony_ci/// setting the environment variables `envs` and unsetting the environment
93b8a62b91Sopenharmony_ci/// variables `remove_envs` when running `cargo`.
94b8a62b91Sopenharmony_cifn has_dependency(
95b8a62b91Sopenharmony_ci    dir: &str,
96b8a62b91Sopenharmony_ci    args: &[&str],
97b8a62b91Sopenharmony_ci    envs: &[(&str, &str)],
98b8a62b91Sopenharmony_ci    remove_envs: &[&str],
99b8a62b91Sopenharmony_ci    dependency: &str,
100b8a62b91Sopenharmony_ci) -> bool {
101b8a62b91Sopenharmony_ci    let mut command = Command::new("cargo");
102b8a62b91Sopenharmony_ci
103b8a62b91Sopenharmony_ci    command
104b8a62b91Sopenharmony_ci        .arg("tree")
105b8a62b91Sopenharmony_ci        .arg("--quiet")
106b8a62b91Sopenharmony_ci        .arg("--edges=normal")
107b8a62b91Sopenharmony_ci        .arg(&format!("--invert={}", dependency))
108b8a62b91Sopenharmony_ci        .current_dir(dir);
109b8a62b91Sopenharmony_ci
110b8a62b91Sopenharmony_ci    command.args(args);
111b8a62b91Sopenharmony_ci    for (key, value) in envs {
112b8a62b91Sopenharmony_ci        command.env(key, value);
113b8a62b91Sopenharmony_ci    }
114b8a62b91Sopenharmony_ci    for key in remove_envs {
115b8a62b91Sopenharmony_ci        command.env_remove(key);
116b8a62b91Sopenharmony_ci    }
117b8a62b91Sopenharmony_ci
118b8a62b91Sopenharmony_ci    let child = command.output().unwrap();
119b8a62b91Sopenharmony_ci
120b8a62b91Sopenharmony_ci    // `cargo tree --invert=foo` can fail in two different ways: it exits with
121b8a62b91Sopenharmony_ci    // a non-zero status if the dependency is not present in the Cargo.toml
122b8a62b91Sopenharmony_ci    // configuration, and it exists with a zero status and prints nothing if
123b8a62b91Sopenharmony_ci    // the dependency is present but optional and not enabled. So we check for
124b8a62b91Sopenharmony_ci    // both here.
125b8a62b91Sopenharmony_ci    child.status.success() && !child.stdout.is_empty()
126b8a62b91Sopenharmony_ci}
127