k8s_test_framework/
up_down.rs

1use std::process::Command;
2
3use super::Result;
4use crate::util::{run_command, run_command_blocking};
5
6#[derive(Debug, Copy, Clone, Eq, PartialEq)]
7pub enum CommandToBuild {
8    Up,
9    Down,
10}
11
12pub trait CommandBuilder {
13    fn build(&self, command_to_build: CommandToBuild) -> Command;
14}
15
16/// Manages commands for bringing up and shutting down resources on the cluster.
17#[derive(Debug)]
18pub struct Manager<B>
19where
20    B: CommandBuilder,
21{
22    command_builder: B,
23    needs_drop: bool,
24}
25
26impl<B> Manager<B>
27where
28    B: CommandBuilder,
29{
30    /// Create a new Manager.
31    pub fn new(command_builder: B) -> Self {
32        Self {
33            command_builder,
34            needs_drop: false,
35        }
36    }
37
38    /// Bring up the resource.
39    pub async fn up(&mut self) -> Result<()> {
40        self.needs_drop = true;
41        self.exec(CommandToBuild::Up).await
42    }
43
44    /// Shut down the resource.
45    pub async fn down(&mut self) -> Result<()> {
46        self.needs_drop = false;
47        self.exec(CommandToBuild::Down).await
48    }
49
50    /// Bring up the resource, blocking execution.
51    pub fn up_blocking(&mut self) -> Result<()> {
52        self.needs_drop = true;
53        self.exec_blocking(CommandToBuild::Up)
54    }
55
56    /// Shut down the resource, blocking execution.
57    pub fn down_blocking(&mut self) -> Result<()> {
58        self.needs_drop = false;
59        self.exec_blocking(CommandToBuild::Down)
60    }
61
62    fn build(&self, command_to_build: CommandToBuild) -> Command {
63        self.command_builder.build(command_to_build)
64    }
65
66    async fn exec(&self, command_to_build: CommandToBuild) -> Result<()> {
67        let command = self.build(command_to_build);
68        run_command(tokio::process::Command::from(command)).await
69    }
70
71    fn exec_blocking(&self, command_to_build: CommandToBuild) -> Result<()> {
72        let command = self.build(command_to_build);
73        run_command_blocking(command)
74    }
75}
76
77impl<B> Drop for Manager<B>
78where
79    B: CommandBuilder,
80{
81    fn drop(&mut self) {
82        if self.needs_drop {
83            self.down_blocking().expect("turndown failed");
84        }
85    }
86}