mod common;
use common::TestWashInstance;
use anyhow::{bail, Context, Result};
use serial_test::serial;
use tokio::process::Command;
use wash_lib::cli::output::{
GetClaimsCommandOutput, GetHostInventoriesCommandOutput, GetHostsCommandOutput,
LinkQueryCommandOutput,
};
#[tokio::test]
#[serial]
async fn integration_get_hosts_serial() -> Result<()> {
let wash_instance = TestWashInstance::create().await?;
let output = Command::new(env!("CARGO_BIN_EXE_wash"))
.args([
"get",
"hosts",
"--output",
"json",
"--ctl-port",
&wash_instance.nats_port.to_string(),
])
.kill_on_drop(true)
.output()
.await
.context("failed to execute get hosts")?;
assert!(output.status.success(), "executed get hosts query");
let cmd_output: GetHostsCommandOutput = serde_json::from_slice(&output.stdout)?;
assert!(cmd_output.success, "command returned success");
assert_eq!(cmd_output.hosts.len(), 1, "hosts contains one host");
assert_eq!(
cmd_output.hosts[0].id(),
wash_instance.host_id,
"single host ID matches has the wash ID"
);
Ok(())
}
#[tokio::test]
#[serial]
async fn integration_get_links_serial() -> Result<()> {
let wash_instance = TestWashInstance::create().await?;
let output = Command::new(env!("CARGO_BIN_EXE_wash"))
.args([
"get",
"links",
"--output",
"json",
"--ctl-port",
&wash_instance.nats_port.to_string(),
])
.kill_on_drop(true)
.output()
.await
.context("failed to execute get links")?;
assert!(output.status.success(), "executed get links query");
let cmd_output: LinkQueryCommandOutput = serde_json::from_slice(&output.stdout)?;
assert!(cmd_output.success, "command returned success");
assert_eq!(cmd_output.links.len(), 0, "links list is empty");
Ok(())
}
#[tokio::test]
#[serial]
async fn integration_get_host_inventory_serial() -> Result<()> {
let wash_instance = TestWashInstance::create().await?;
let output = Command::new(env!("CARGO_BIN_EXE_wash"))
.args([
"get",
"inventory",
&wash_instance.host_id,
"--output",
"json",
"--ctl-port",
&wash_instance.nats_port.to_string(),
])
.kill_on_drop(true)
.output()
.await
.context("failed to execute get inventory")?;
if !output.status.success() {
bail!(
"failed to execute `wash get inventory`, stdout: {} \nstderr: {}",
String::from_utf8_lossy(&output.stdout),
String::from_utf8_lossy(&output.stderr),
);
}
let cmd_output: GetHostInventoriesCommandOutput = serde_json::from_slice(&output.stdout)?;
assert!(cmd_output.success, "command returned success");
assert!(
cmd_output.inventories.len() == 1,
"one host inventory returned"
);
let inventory = &cmd_output.inventories[0];
assert!(
inventory.components().is_empty(),
"host inventory contains no components "
);
assert_eq!(
inventory.host_id(),
wash_instance.host_id,
"host ID matches request"
);
assert!(
!inventory.labels().is_empty(),
"at least one label on the host"
);
assert!(
inventory.labels().contains_key("hostcore.os"),
"hostcore.os label is present"
);
assert!(
inventory.labels().contains_key("hostcore.arch"),
"hostcore.arch label is present"
);
assert!(
inventory.labels().contains_key("hostcore.osfamily"),
"hostcore.osfmaily label is present"
);
assert!(inventory.providers().is_empty(), "host has no providers");
Ok(())
}
#[tokio::test]
#[serial]
#[ignore]
async fn integration_get_claims_serial() -> Result<()> {
let wash_instance = TestWashInstance::create().await?;
let output = Command::new(env!("CARGO_BIN_EXE_wash"))
.args([
"get",
"claims",
"--output",
"json",
"--ctl-port",
&wash_instance.nats_port.to_string(),
])
.kill_on_drop(true)
.output()
.await
.context("failed to execute get claims")?;
assert!(output.status.success(), "executed get claims query");
let cmd_output: GetClaimsCommandOutput = serde_json::from_slice(&output.stdout)?;
assert!(cmd_output.success, "command returned success");
Ok(())
}
#[tokio::test]
#[serial]
async fn integration_get_host_inventory_labels_sorted_serial() -> Result<()> {
let wash_instance = TestWashInstance::create_with_extra_args(vec![
"--label", "three=3", "--label", "two=2", "--label", "one=1",
])
.await?;
let output = Command::new(env!("CARGO_BIN_EXE_wash"))
.args([
"get",
"inventory",
&wash_instance.host_id,
"--output",
"json",
"--ctl-port",
&wash_instance.nats_port.to_string(),
])
.kill_on_drop(true)
.output()
.await
.context("failed to execute get inventory")?;
if !output.status.success() {
bail!(
"failed to execute `wash get inventory`, stdout: {} \nstderr: {}",
String::from_utf8_lossy(&output.stdout),
String::from_utf8_lossy(&output.stderr),
);
}
let stdout = String::from_utf8_lossy(&output.stdout);
let one_idx = stdout
.find(r#""one": "1""#)
.context("missing JSON list entry for one")?;
let two_idx = stdout
.find(r#""three": "3""#)
.context("missing JSON list entry for two")?;
let three_idx = stdout
.find(r#""two": "2""#)
.context("missing JSON list entry for three")?;
assert!(
one_idx < two_idx && two_idx < three_idx,
"one before two before three "
);
Ok(())
}