use anyhow::Context as _;
use tonic::transport::Channel;
use tracing::Level;
use crate::proto::downward_api::downward_api_client::DownwardApiClient;
use crate::proto::downward_api::{self, ConsoleRequest};
use crate::proto::test::test_orchestrator_client::TestOrchestratorClient;
use crate::proto::test::{
AttachInfoMessageRequest, CasDigest, ConfiguredTargetHandle, EndOfTestResultsRequest,
ExecuteRequest2, ExecuteResponse2, ReportTestResultRequest, ReportTestSessionRequest,
ReportTestsDiscoveredRequest, TestResult, Testing, TtlConfig, UploadFileToCasRequest,
};
#[derive(Clone)]
pub struct Orchestrator {
orchestrator: TestOrchestratorClient<Channel>,
downward: DownwardApiClient<Channel>,
}
impl Orchestrator {
pub fn new(channel: Channel) -> Self {
let orchestrator = TestOrchestratorClient::new(channel.clone())
.max_decoding_message_size(usize::MAX)
.max_encoding_message_size(usize::MAX);
let downward = DownwardApiClient::new(channel)
.max_decoding_message_size(usize::MAX)
.max_encoding_message_size(usize::MAX);
Self {
orchestrator,
downward,
}
}
pub async fn execute2(&self, request: ExecuteRequest2) -> anyhow::Result<ExecuteResponse2> {
Ok(self
.orchestrator
.clone()
.execute2(request)
.await
.context("Execute2 RPC failed")?
.into_inner())
}
pub async fn report_tests_discovered(
&self,
target: ConfiguredTargetHandle,
suite: String,
tests: Vec<String>,
) -> anyhow::Result<()> {
self.orchestrator
.clone()
.report_tests_discovered(ReportTestsDiscoveredRequest {
target: Some(target),
testing: Some(Testing {
suite,
testcases: tests,
variant: None,
repeat_count: None,
}),
})
.await
.context("ReportTestsDiscovered RPC failed")?;
Ok(())
}
pub async fn report_test_result(&self, result: TestResult) -> anyhow::Result<()> {
self.orchestrator
.clone()
.report_test_result(ReportTestResultRequest {
result: Some(result),
})
.await
.context("ReportTestResult RPC failed")?;
Ok(())
}
pub async fn report_test_session(
&self,
session_info: String,
test_session_id: Option<String>,
) -> anyhow::Result<()> {
self.orchestrator
.clone()
.report_test_session(ReportTestSessionRequest {
session_info,
test_session_id,
})
.await
.context("ReportTestSession RPC failed")?;
Ok(())
}
pub async fn end_of_test_results(&self, exit_code: i32) -> anyhow::Result<()> {
self.orchestrator
.clone()
.end_of_test_results(EndOfTestResultsRequest { exit_code })
.await
.context("EndOfTestResults RPC failed")?;
Ok(())
}
pub async fn attach_info_message(&self, message: String) -> anyhow::Result<()> {
self.orchestrator
.clone()
.attach_info_message(AttachInfoMessageRequest { message })
.await
.context("AttachInfoMessage RPC failed")?;
Ok(())
}
pub async fn upload_file_to_cas(
&self,
local_path: String,
ttl_seconds: i64,
use_case: String,
) -> anyhow::Result<CasDigest> {
let response = self
.orchestrator
.clone()
.upload_file_to_cas(UploadFileToCasRequest {
local_path,
ttl_config: Some(TtlConfig {
ttl_seconds,
use_case,
}),
})
.await
.context("UploadFileToCas RPC failed")?
.into_inner();
response
.digest
.context("UploadFileToCas response missing digest")
}
pub async fn console(&self, level: Level, message: String) -> anyhow::Result<()> {
self.downward
.clone()
.console(ConsoleRequest {
level: Some(to_downward_level(level)),
message,
})
.await
.context("DownwardApi.Console RPC failed")?;
Ok(())
}
}
fn to_downward_level(level: Level) -> downward_api::LogLevel {
use downward_api::log_level::Value;
let value = match level {
Level::TRACE => Value::Trace,
Level::DEBUG => Value::Debug,
Level::INFO => Value::Info,
Level::WARN => Value::Warn,
Level::ERROR => Value::Error,
};
downward_api::LogLevel {
value: value as i32,
}
}