litcheck_lit/formats/
executable.rs1use std::{path::Path, time::Duration};
2
3use litcheck::diagnostics::DiagResult;
4use serde::Deserialize;
5
6use crate::{
7 config::BooleanExpr,
8 format::TestFormat,
9 test::{DefaultTestRegistry, Test, TestRegistry, TestResult, TestStatus},
10 Config,
11};
12
13#[derive(Default, Clone, Debug, Deserialize)]
14pub struct ExecutableTest {
15 #[serde(default)]
19 unsupported: Vec<BooleanExpr>,
20}
21impl TestFormat for ExecutableTest {
22 #[inline(always)]
23 fn name(&self) -> &'static str {
24 "executable"
25 }
26
27 #[inline(always)]
28 fn registry(&self) -> &dyn TestRegistry {
29 &DefaultTestRegistry
30 }
31
32 fn execute(&self, test: &Test, config: &Config) -> DiagResult<TestResult> {
33 const ARGV: &[&Path] = &[];
34
35 if let Some(unsupported_features) = test.config.unsupported_features(&self.unsupported) {
36 return Ok(TestResult::new(TestStatus::Unsupported)
37 .with_stderr(unsupported_features.into_bytes()));
38 }
39
40 if config.no_execute {
41 return Ok(TestResult::new(TestStatus::Pass));
42 }
43
44 let mut command = crate::utils::ShellCommand::new(test.source_path());
45 command
46 .args(ARGV)
47 .current_dir(test.suite.working_dir())
48 .envs(test.config.env.iter().map(|(k, v)| (&**k, &**v)))
49 .paths(config.search_paths.as_slice())?;
50
51 Ok(command.wait_with_timeout(
52 config
53 .timeout
54 .map(Duration::from_secs)
55 .unwrap_or(Duration::ZERO),
56 ))
57 }
58}