ftest/src/docker_compose.rs

116 lines
3.4 KiB
Rust
Raw Normal View History

2023-09-06 13:34:02 +05:30
use std::path::PathBuf;
use std::process::Command;
use serde::{Deserialize, Serialize};
use serde_json::Value as JValue;
2023-09-26 15:38:55 +05:30
use crate::docker::Docker;
2023-09-06 13:34:02 +05:30
#[derive(Debug, Eq, PartialEq, Clone, Serialize, Deserialize)]
pub struct Container {
pub service: String,
pub name: String,
pub image: String,
}
pub struct DockerCompose {
base_dir: PathBuf,
}
impl DockerCompose {
pub fn new(base_dir: PathBuf) -> Self {
Self { base_dir }
}
pub fn version() -> String {
let version = Command::new("docker-compose")
.arg("--version")
.output()
.expect("unable to obtain DockerCompose version");
let x = String::from_utf8(version.stdout).unwrap();
let x: Vec<&str> = x.split("Docker Compose version ").collect();
x.get(1).unwrap().trim().to_string()
}
pub fn services(&self) -> Vec<Container> {
let ps = Command::new("docker-compose")
.current_dir(&self.base_dir)
.args(["ps", "--format", "json"])
.output()
.expect("unable to obtain DockerCompose version");
let ps = String::from_utf8(ps.stdout).unwrap();
let x: serde_json::Value = serde_json::from_str(&ps).unwrap();
if let JValue::Array(val) = x {
let mut containers = Vec::with_capacity(val.len());
for item in val.iter() {
if let JValue::Object(val) = item {
containers.push(Container {
name: val["Name"].as_str().unwrap().to_string(),
service: val["Service"].as_str().unwrap().to_string(),
image: val["Image"].as_str().unwrap().to_string(),
})
}
}
return containers;
}
return Vec::default();
}
pub fn up(&self) {
let mut child = Command::new("docker-compose")
.current_dir(&self.base_dir)
.args(["up", "--detach", "--remove-orphans"])
.spawn()
.expect("unable to run DockerCompose");
child.wait().unwrap();
}
pub fn logs(&self, service: &str) -> String {
2023-09-26 15:38:55 +05:30
Docker::get_logs(service)
}
2023-09-06 13:34:02 +05:30
pub fn down(&self, remove_orphans: bool, volumes: bool) {
let mut opts = vec!["down"];
if remove_orphans {
opts.push("--remove-orphans");
}
if volumes {
opts.push("--volumes");
}
2023-09-26 15:38:55 +05:30
let mut child = Command::new("docker-compose")
2023-09-06 13:34:02 +05:30
.current_dir(&self.base_dir)
.args(opts)
.spawn()
.expect(&format!("unable to remove"));
2023-09-26 15:38:55 +05:30
child.wait().unwrap();
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_docker_compose() {
DockerCompose::version();
let cmp = DockerCompose::new("./tests/".into());
assert!(cmp.services().is_empty());
cmp.up();
let services = cmp.services();
std::thread::sleep(std::time::Duration::new(5, 0));
assert_eq!(services.len(), 2);
for service in services.iter() {
println!("{}", service.name);
let logs = cmp.logs(&service.name);
println!("service: {} {:?}", service.name, logs);
println!("expecting: NAME={}", service.name);
assert!(logs.contains(&format!("NAME={}", service.name)));
}
cmp.down(true, true);
assert!(cmp.services().is_empty());
2023-09-06 13:34:02 +05:30
}
}