Skip to main content

max / pom

3.7 KB · 122 lines History Blame Raw
1 use schemars::JsonSchema;
2 use serde::Deserialize;
3 use tracing::instrument;
4
5 use crate::checks::ssh;
6 use crate::db;
7
8 use super::PomServer;
9
10 #[derive(Debug, Deserialize, JsonSchema)]
11 pub struct RunTestsParams {
12 /// Target name to run tests on
13 pub target: String,
14 /// Optional filter to run specific tests
15 pub filter: Option<String>,
16 }
17
18 #[derive(Debug, Deserialize, JsonSchema)]
19 pub struct TestHistoryParams {
20 /// Filter by target name
21 pub target: Option<String>,
22 /// Number of results to return (default 10)
23 pub limit: Option<i64>,
24 }
25
26 #[derive(Debug, Deserialize, JsonSchema)]
27 pub struct LastTestOutputParams {
28 /// Target name to get output for
29 pub target: String,
30 }
31
32 impl PomServer {
33 #[instrument(skip_all)]
34 pub async fn run_tests_impl(
35 &self,
36 params: RunTestsParams,
37 ) -> crate::error::Result<String> {
38 let target = self.config.get_target(&params.target).ok_or_else(|| {
39 crate::error::PomError::Config(format!("Unknown target: {}", params.target))
40 })?;
41
42 let tests_config = target.tests.as_ref().ok_or_else(|| {
43 crate::error::PomError::Config(format!(
44 "Target '{}' has no test configuration",
45 params.target
46 ))
47 })?;
48
49 let run = ssh::run_tests(&params.target, tests_config, params.filter.as_deref()).await;
50 let run_id = db::insert_test_run(&self.pool, &run).await?;
51
52 // Store per-test details and detect regressions
53 if !run.summary.details.is_empty() {
54 db::insert_test_details(&self.pool, run_id, &run.summary.details).await?;
55 }
56 let regressions = db::get_test_regressions(&self.pool, &params.target, run_id)
57 .await
58 .unwrap_or_default();
59
60 // Return summary without raw_output (it can be huge)
61 let summary = serde_json::json!({
62 "target": run.target,
63 "passed": run.passed,
64 "exit_code": run.exit_code,
65 "duration_secs": run.duration_secs,
66 "started_at": run.started_at,
67 "finished_at": run.finished_at,
68 "filter": run.filter,
69 "summary": run.summary,
70 "regressions": regressions,
71 });
72
73 Ok(serde_json::to_string_pretty(&summary)?)
74 }
75
76 #[instrument(skip_all)]
77 pub async fn test_history_impl(
78 &self,
79 params: TestHistoryParams,
80 ) -> crate::error::Result<String> {
81 let limit = params.limit.unwrap_or(10);
82 let history = db::get_test_history(&self.pool, params.target.as_deref(), limit).await?;
83
84 if history.is_empty() {
85 return Ok("No test run history.".to_string());
86 }
87
88 // Return without raw_output
89 let summaries: Vec<serde_json::Value> = history
90 .iter()
91 .map(|run| {
92 serde_json::json!({
93 "id": run.id,
94 "target": run.target,
95 "passed": run.passed,
96 "exit_code": run.exit_code,
97 "duration_secs": run.duration_secs,
98 "started_at": run.started_at,
99 "finished_at": run.finished_at,
100 "filter": run.filter,
101 "summary": run.summary,
102 })
103 })
104 .collect();
105
106 Ok(serde_json::to_string_pretty(&summaries)?)
107 }
108
109 #[instrument(skip_all)]
110 pub async fn last_test_output_impl(
111 &self,
112 params: LastTestOutputParams,
113 ) -> crate::error::Result<String> {
114 let run = db::get_latest_test_run(&self.pool, &params.target).await?;
115
116 match run {
117 Some(r) => Ok(r.raw_output),
118 None => Ok(format!("No test runs found for target '{}'", params.target)),
119 }
120 }
121 }
122