flowey_lib_hvlite/_jobs/
build_and_run_nextest_unit_tests.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Build and run the cargo-nextest based unit tests.
5
6use crate::build_nextest_unit_tests::BuildNextestUnitTestMode;
7use crate::run_cargo_build::common::CommonProfile;
8use crate::run_cargo_nextest_run::NextestProfile;
9use flowey::node::prelude::*;
10use flowey_lib_common::run_cargo_nextest_run::build_params::PanicAbortTests;
11use std::collections::BTreeMap;
12
13flowey_request! {
14    pub struct Params {
15        /// Friendly label for report JUnit test results
16        pub junit_test_label: String,
17        /// Build and run unit tests for the specified target
18        pub target: target_lexicon::Triple,
19        /// Build and run unit tests with the specified cargo profile
20        pub profile: CommonProfile,
21        /// Whether to build tests with unstable `-Zpanic-abort-tests` flag
22        pub unstable_panic_abort_tests: Option<PanicAbortTests>,
23        /// Nextest profile to use when running the source code
24        pub nextest_profile: NextestProfile,
25
26        /// Whether the job should fail if any test has failed
27        pub fail_job_on_test_fail: bool,
28        /// If provided, also publish junit.xml test results as an artifact.
29        pub artifact_dir: Option<ReadVar<PathBuf>>,
30        pub done: WriteVar<SideEffect>,
31    }
32}
33
34new_simple_flow_node!(struct Node);
35
36impl SimpleFlowNode for Node {
37    type Request = Params;
38
39    fn imports(ctx: &mut ImportCtx<'_>) {
40        ctx.import::<flowey_lib_common::publish_test_results::Node>();
41        ctx.import::<crate::build_nextest_unit_tests::Node>();
42    }
43
44    fn process_request(request: Self::Request, ctx: &mut NodeCtx<'_>) -> anyhow::Result<()> {
45        let Params {
46            junit_test_label,
47            target,
48            profile,
49            unstable_panic_abort_tests,
50            nextest_profile,
51            fail_job_on_test_fail,
52            artifact_dir,
53            done,
54        } = request;
55
56        let results = ctx.reqv(|v| crate::build_nextest_unit_tests::Request {
57            profile,
58            target,
59            unstable_panic_abort_tests,
60            build_mode: BuildNextestUnitTestMode::ImmediatelyRun {
61                nextest_profile,
62                results: v,
63            },
64        });
65
66        let mut side_effects = Vec::new();
67
68        let junit_xml = results.map(ctx, |r| r.junit_xml);
69        let reported_results = ctx.reqv(|v| flowey_lib_common::publish_test_results::Request {
70            junit_xml,
71            test_label: junit_test_label,
72            attachments: BTreeMap::new(),
73            output_dir: artifact_dir,
74            done: v,
75        });
76
77        side_effects.push(reported_results);
78
79        ctx.emit_rust_step("report test results to overall pipeline status", |ctx| {
80            side_effects.claim(ctx);
81            done.claim(ctx);
82
83            let results = results.clone().claim(ctx);
84            move |rt| {
85                let results = rt.read(results);
86                if results.all_tests_passed {
87                    log::info!("all tests passed!");
88                } else {
89                    if fail_job_on_test_fail {
90                        anyhow::bail!("encountered test failures.")
91                    } else {
92                        log::error!("encountered test failures.")
93                    }
94                }
95
96                Ok(())
97            }
98        });
99
100        Ok(())
101    }
102}