1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
use std::collections::HashMap;

use orchestrator::prelude::{CompilationResult, ExerciseResult, RunResult, TestResult};
use tokio::{
    process::Command,
    task::{JoinError, JoinSet},
};

use super::compile::RustCompiled;
#[derive(thiserror::Error, Debug)]
/// all the errors that could be generated by execution
pub enum RunError {
    #[error("JoinError: {0}")]
    JoinError(#[from] JoinError),
}
impl RustCompiled {
    /// execute and collect results
    pub async fn run(self) -> Result<ExerciseResult, RunError> {
        let mut set: JoinSet<(String, TestResult)> = JoinSet::new();

        //let's start executing all test in parallel
        for (name, mut test_result) in self.results {
            let exec = self.path.join("target").join("debug").join(&name);
            set.spawn(async move {
                if let CompilationResult::Built = test_result.compiled {
                    //let t = Command::new(exec).output().await?;
                    match Command::new(&exec).output().await {
                        Ok(output) if output.status.success() => {
                            //test_result.points_given = test_result.points;
                            test_result.runned = RunResult::Ok;
                        }
                        Ok(output) => {
                            test_result.points_given = 0.0;
                            test_result.runned = RunResult::Error(format!(
                                "Got this error while executing {} {}",
                                exec.to_str().unwrap(),
                                String::from_utf8(output.stderr).unwrap()
                            ));
                        }
                        Err(err) => {
                            test_result.points_given = 0.0;
                            test_result.runned = RunResult::Error(err.to_string())
                        }
                    }
                }
                (name, test_result)
            });
        }
        let mut tests = HashMap::new();
        while let Some(x) = set.join_next().await {
            let (name, result) = x?;
            tests.insert(name, result);
        }
        Ok(ExerciseResult { tests })
    }
}