use std::fmt;
use solti_model::RunnerEnv;
use crate::metrics::MetricsHandle;
#[derive(Clone)]
pub struct BuildContext {
metrics: MetricsHandle,
env: RunnerEnv,
}
impl BuildContext {
pub fn new(env: RunnerEnv, metrics: MetricsHandle) -> Self {
Self { env, metrics }
}
pub fn env(&self) -> &RunnerEnv {
&self.env
}
pub fn metrics(&self) -> &MetricsHandle {
&self.metrics
}
pub fn with_env(mut self, env: RunnerEnv) -> Self {
self.env = env;
self
}
pub fn with_metrics(mut self, metrics: MetricsHandle) -> Self {
self.metrics = metrics;
self
}
}
impl Default for BuildContext {
fn default() -> Self {
Self {
env: RunnerEnv::default(),
metrics: crate::metrics::noop_metrics(),
}
}
}
impl fmt::Debug for BuildContext {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("BuildContext")
.field("env_len", &self.env.len())
.field("metrics", &"<handle>")
.finish()
}
}
impl fmt::Display for BuildContext {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "BuildContext(env_len={})", self.env.len())
}
}
#[cfg(test)]
mod tests {
use super::BuildContext;
use solti_model::RunnerEnv;
#[test]
fn default_build_context_has_empty_env_and_noop_metrics() {
let ctx = BuildContext::default();
assert_eq!(ctx.env().len(), 0);
}
#[test]
fn new_uses_provided_env_and_metrics() {
let mut env = RunnerEnv::new();
env.push("FOO", "bar");
env.push("BAZ", "qux");
let metrics = crate::metrics::noop_metrics();
let ctx = BuildContext::new(env.clone(), metrics);
assert_eq!(ctx.env().len(), env.len());
assert_eq!(ctx.env().get("FOO"), Some("bar"));
assert_eq!(ctx.env().get("BAZ"), Some("qux"));
}
#[test]
fn with_env_replaces_existing_env() {
let mut env1 = RunnerEnv::new();
env1.push("FOO", "one");
let mut env2 = RunnerEnv::new();
env2.push("BAR", "two");
let metrics = crate::metrics::noop_metrics();
let ctx = BuildContext::new(env1, metrics).with_env(env2.clone());
assert_eq!(ctx.env().len(), env2.len());
assert!(ctx.env().get("FOO").is_none());
assert_eq!(ctx.env().get("BAR"), Some("two"));
}
#[test]
fn with_metrics_replaces_backend() {
let env = RunnerEnv::new();
let metrics1 = crate::metrics::noop_metrics();
let metrics2 = crate::metrics::noop_metrics();
let ctx = BuildContext::new(env, metrics1).with_metrics(metrics2);
ctx.metrics()
.record_task_started(crate::RunnerType::Subprocess);
}
#[test]
fn display_includes_env_length() {
let mut env = RunnerEnv::new();
env.push("FOO", "bar");
let metrics = crate::metrics::noop_metrics();
let ctx = BuildContext::new(env, metrics);
let s = ctx.to_string();
assert_eq!(s, "BuildContext(env_len=1)");
}
#[test]
fn metrics_handle_can_be_cloned() {
let ctx = BuildContext::default();
let handle = ctx.metrics().clone();
handle.record_task_started(crate::RunnerType::Subprocess);
handle.record_task_completed(
crate::RunnerType::Subprocess,
crate::TaskOutcome::Success,
100,
);
}
}