improves workings
Signed-off-by: Jochen Maes <jochen@sejo-it.be>
This commit is contained in:
parent
55fc77b728
commit
71ee0aaab0
44
.drone.yml
Normal file
44
.drone.yml
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
---
|
||||||
|
kind: pipeline
|
||||||
|
type: docker
|
||||||
|
name: "Mouse release"
|
||||||
|
|
||||||
|
platform:
|
||||||
|
arch: amd64
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
event:
|
||||||
|
- tag
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
- name: dockersock
|
||||||
|
host:
|
||||||
|
path: /var/run/docker.sock
|
||||||
|
- name: artifacts
|
||||||
|
temp: {}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: build amd64
|
||||||
|
image: rust:1.73
|
||||||
|
commands:
|
||||||
|
- rustup target add x86_64-unknown-linux-musl
|
||||||
|
- rustup target add aarch64-unknown-linux-musl
|
||||||
|
- cargo build --target x86_64-unknown-linux-musl --bins -r
|
||||||
|
- cargo build --target aarch64-unknown-linux-musl --bins -r
|
||||||
|
- cp target/x86_64-unknown-linux-musl/release/mouse /artifcats/mouse-amd64
|
||||||
|
- cp target/aarch64-unknown-linux-musl/release/mouse /artifcats/mouse-arm64
|
||||||
|
volumes:
|
||||||
|
- name: artifacts
|
||||||
|
path: /artifcats/
|
||||||
|
|
||||||
|
- name: create gitea release
|
||||||
|
image: plugins/gitea-release
|
||||||
|
settings:
|
||||||
|
api_key:
|
||||||
|
from_secret: gitea_api_key
|
||||||
|
base_url: https://gitea.sejo-it.be
|
||||||
|
checksum: sha265
|
||||||
|
files: /artifacts/*
|
||||||
|
volumes:
|
||||||
|
- name: artifacts
|
||||||
|
path: /artifcats/
|
20
Cargo.lock
generated
20
Cargo.lock
generated
@ -52,9 +52,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "4.4.6"
|
version = "4.4.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d04704f56c2cde07f43e8e2c154b43f216dc5c92fc98ada720177362f953b956"
|
checksum = "ac495e00dcec98c83465d5ad66c5c4fabd652fd6686e7c6269b117e729a6f17b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap_builder",
|
"clap_builder",
|
||||||
"clap_derive",
|
"clap_derive",
|
||||||
@ -62,9 +62,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap_builder"
|
name = "clap_builder"
|
||||||
version = "4.4.6"
|
version = "4.4.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0e231faeaca65ebd1ea3c737966bf858971cd38c3849107aa3ea7de90a804e45"
|
checksum = "c77ed9a32a62e6ca27175d00d29d05ca32e396ea1eb5fb01d8256b669cec7663"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anstream",
|
"anstream",
|
||||||
"anstyle",
|
"anstyle",
|
||||||
@ -74,9 +74,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap_derive"
|
name = "clap_derive"
|
||||||
version = "4.4.2"
|
version = "4.4.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873"
|
checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heck",
|
"heck",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
@ -86,9 +86,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap_lex"
|
name = "clap_lex"
|
||||||
version = "0.5.1"
|
version = "0.6.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961"
|
checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "colorchoice"
|
name = "colorchoice"
|
||||||
@ -125,9 +125,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.14.1"
|
version = "0.14.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12"
|
checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "heck"
|
name = "heck"
|
||||||
|
@ -8,7 +8,7 @@ edition = "2021"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = { version = "4.4.6", features = ["derive"] }
|
clap = { version = "4.4.7", features = ["derive"] }
|
||||||
csv = "1.3.0"
|
csv = "1.3.0"
|
||||||
serde = { version = "1.0.189", features = ["std", "derive"] }
|
serde = { version = "1.0.189", features = ["std", "derive"] }
|
||||||
serde_json = "1.0.107"
|
serde_json = "1.0.107"
|
||||||
|
@ -1,23 +1,28 @@
|
|||||||
use crate::types::fact::{FactData, Fact};
|
use crate::types::fact::Fact;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use serde_json::Value;
|
||||||
use std::env;
|
use std::env;
|
||||||
|
|
||||||
pub struct EnvironmentData {}
|
pub struct EnvironmentData {}
|
||||||
|
impl EnvironmentData {}
|
||||||
|
|
||||||
impl EnvironmentData {
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub struct EnvironmentValue {
|
||||||
|
key: String,
|
||||||
|
value: String,
|
||||||
|
time_set: u128,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Fact for EnvironmentData {
|
impl Fact for EnvironmentData {
|
||||||
fn gather(&self) -> Vec<FactData>{
|
fn gather(&self) -> String {
|
||||||
let mut vfd: Vec<FactData> = vec![];
|
let mut outmap: Vec<Value> = vec![];
|
||||||
let time_set = self.get_epoch_ms();
|
|
||||||
for (key, value) in env::vars() {
|
for (key, value) in env::vars() {
|
||||||
let fd = FactData{
|
let entry = json!({
|
||||||
name: String::from("env_") + &key,
|
"key": &key,
|
||||||
value: value,
|
"value": value,
|
||||||
time_set: time_set
|
});
|
||||||
};
|
outmap.append(&mut vec![entry]);
|
||||||
vfd.push(fd);
|
|
||||||
}
|
}
|
||||||
return vfd;
|
serde_json::to_string(&outmap).unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,107 +1,29 @@
|
|||||||
use crate::{types::fact::{Fact, FactData}, util::command::get_result_as_string};
|
use crate::{types::fact::Fact, util::command::get_result_as_string};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use serde_json::Value;
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
pub struct IPData {}
|
pub struct IPData {}
|
||||||
|
|
||||||
impl IPData {}
|
impl IPData {}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
|
||||||
struct IpAddrInfo {
|
|
||||||
family: String,
|
|
||||||
local: String,
|
|
||||||
prefixlen: i32,
|
|
||||||
broadcast: Option<String>,
|
|
||||||
scope: String,
|
|
||||||
dynamic: Option<bool>,
|
|
||||||
noprefixroute: Option<bool>,
|
|
||||||
label: Option<String>,
|
|
||||||
valid_life_time: i64,
|
|
||||||
preferred_life_time: i64,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
|
||||||
struct IpAddr {
|
|
||||||
ifindex: i32,
|
|
||||||
ifname: String,
|
|
||||||
flags: Vec<String>,
|
|
||||||
mtu: i32,
|
|
||||||
qdisc: String,
|
|
||||||
operstate: String,
|
|
||||||
group: String,
|
|
||||||
txqlen: i32,
|
|
||||||
link_type: String,
|
|
||||||
address: Option<String>,
|
|
||||||
broadcast: Option<String>,
|
|
||||||
addr_info: Vec<IpAddrInfo>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Fact for IPData {
|
impl Fact for IPData {
|
||||||
fn gather(&self) -> Vec<FactData> {
|
fn gather(&self) -> String {
|
||||||
let mut vfd: Vec<FactData> = vec![];
|
let res = get_result_as_string("ip", vec!["-j", "addr"]);
|
||||||
let time_set = self.get_epoch_ms();
|
let jsonres: Value = serde_json::from_str(res.as_str()).unwrap();
|
||||||
let ips: Vec<IpAddr> = serde_json::from_str(get_result_as_string("ip", vec!["-j", "addr"]).as_str()).unwrap();
|
let out = json!({ "ip_addr": jsonres });
|
||||||
for ip in ips {
|
out.to_string()
|
||||||
if ip.ifname != "lo" {
|
|
||||||
for addr_info in ip.addr_info {
|
|
||||||
let fd = FactData {
|
|
||||||
name: format!("ip_addr_{}_{}_addr", ip.ifname, addr_info.family),
|
|
||||||
value: addr_info.local,
|
|
||||||
time_set: time_set,
|
|
||||||
};
|
|
||||||
vfd.push(fd);
|
|
||||||
vfd.push(FactData {
|
|
||||||
name: format!("ip_addr_{}_{}_prefixlen", ip.ifname, addr_info.family),
|
|
||||||
value: addr_info.prefixlen.to_string(),
|
|
||||||
time_set: time_set,
|
|
||||||
});
|
|
||||||
if addr_info.label.is_some() {
|
|
||||||
vfd.push(FactData {
|
|
||||||
name: format!("ip_addr_{}_{}_label", ip.ifname, addr_info.family),
|
|
||||||
value: addr_info.label.unwrap(),
|
|
||||||
time_set: time_set,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if addr_info.broadcast.is_some() {
|
|
||||||
vfd.push(FactData {
|
|
||||||
name: format!("ip_addr_{}_{}_broadcast", ip.ifname, addr_info.family),
|
|
||||||
value: addr_info.broadcast.unwrap(),
|
|
||||||
time_set: time_set,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if ip.address.is_some() {
|
|
||||||
vfd.push(FactData {
|
|
||||||
name: format!("ip_addr_{}_macaddr", ip.ifname),
|
|
||||||
value: ip.address.clone().unwrap(),
|
|
||||||
time_set: time_set,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return vfd;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub struct IPRouteData {}
|
||||||
|
impl IPRouteData {}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
impl Fact for IPRouteData {
|
||||||
struct IpRoute {
|
fn gather(&self) -> String {
|
||||||
dst: String,
|
let res = get_result_as_string("ip", vec!["-j", "route"]);
|
||||||
gateway: Option<String>,
|
let jsonres: Value = serde_json::from_str(res.as_str()).unwrap();
|
||||||
dev: String,
|
let out = json!({
|
||||||
protocol: Option<String>,
|
"ip_route": jsonres
|
||||||
metric: Option<i32>,
|
});
|
||||||
flags: Vec<String>,
|
out.to_string()
|
||||||
scope: String,
|
|
||||||
prefsrc: String,
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Fact for IpRoute {
|
|
||||||
fn gather(&self) -> Vec<FactData> {
|
|
||||||
let mut vfd: Vec<FactData> = vec![];
|
|
||||||
let time_set = self.get_epoch_ms();
|
|
||||||
|
|
||||||
let routes: Vec<IpRoute> = serde_json::from_str(get_result_as_string("ip", vec!["-j", "route"]).as_str()).unwrap();
|
|
||||||
|
|
||||||
return vfd;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
pub mod environment;
|
pub mod environment;
|
||||||
pub mod ip;
|
pub mod ip;
|
||||||
|
114
src/main.rs
114
src/main.rs
@ -1,14 +1,16 @@
|
|||||||
mod types;
|
|
||||||
mod gatherers;
|
mod gatherers;
|
||||||
|
mod types;
|
||||||
mod util;
|
mod util;
|
||||||
|
|
||||||
use std::collections::HashSet;
|
#[macro_use]
|
||||||
use crate::types::fact::{Fact, FactData};
|
extern crate serde_json;
|
||||||
use crate::gatherers::environment::EnvironmentData;
|
|
||||||
use crate::gatherers::ip::IPData;
|
|
||||||
use clap::Parser;
|
|
||||||
use csv::Writer;
|
|
||||||
|
|
||||||
|
use crate::gatherers::environment::EnvironmentData;
|
||||||
|
use crate::gatherers::ip::{IPData, IPRouteData};
|
||||||
|
use crate::types::fact::Fact;
|
||||||
|
use clap::Parser;
|
||||||
|
use serde_json::Value;
|
||||||
|
use std::collections::{HashMap, HashSet};
|
||||||
|
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
#[clap(author, version, about, long_about = None)]
|
#[clap(author, version, about, long_about = None)]
|
||||||
@ -17,69 +19,61 @@ struct Args {
|
|||||||
#[arg(short, long)]
|
#[arg(short, long)]
|
||||||
gatherer: Option<Vec<String>>,
|
gatherer: Option<Vec<String>>,
|
||||||
/// Output format, yaml, json are supported
|
/// Output format, yaml, json are supported
|
||||||
#[arg(short, long, default_value="yaml")]
|
#[arg(short, long, default_value = "yaml")]
|
||||||
output: String,
|
output: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gather_all() -> Vec<FactData>{
|
fn gather_list(gatherers: HashSet<String>, output: &str) -> String {
|
||||||
let mut data: Vec<FactData> = vec![];
|
let mut outmap: HashMap<String, Value> = HashMap::new();
|
||||||
data.append(&mut gather(&EnvironmentData{}));
|
|
||||||
data.append(&mut gather(&IPData{}));
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn gather_list(gatherers: HashSet<String>) -> Vec<FactData> {
|
|
||||||
let mut data: Vec<FactData> = vec![];
|
|
||||||
for g in gatherers {
|
for g in gatherers {
|
||||||
match g.as_str() {
|
match g.as_str() {
|
||||||
"all" => for d in gather_all(){
|
"env" => {
|
||||||
data.push(d);
|
outmap.insert(
|
||||||
},
|
"environment".to_string(),
|
||||||
"env" => for d in gather(&EnvironmentData{}) {
|
serde_json::from_str(&EnvironmentData {}.gather()).unwrap(),
|
||||||
data.push(d);
|
);
|
||||||
},
|
}
|
||||||
"ip" => for d in gather(&IPData{}) {
|
"ipaddr" => {
|
||||||
data.push(d);
|
outmap.insert(
|
||||||
|
"ipaddr".to_string(),
|
||||||
|
serde_json::from_str(&IPData {}.gather()).unwrap(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
"iproute" => {
|
||||||
|
outmap.insert(
|
||||||
|
"iproute".to_string(),
|
||||||
|
serde_json::from_str(&IPRouteData {}.gather()).unwrap(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
x => {
|
||||||
|
println!("unknown gatherer: {x}");
|
||||||
}
|
}
|
||||||
_ => for d in gather_all() {
|
|
||||||
data.push(d);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return data;
|
match output {
|
||||||
}
|
"json" => serde_json::to_string(&outmap).unwrap(),
|
||||||
fn gather (t: &dyn Fact) -> Vec<FactData> {
|
"yaml" => serde_yaml::to_string(&outmap).unwrap(),
|
||||||
return t.gather();
|
x => format!("Unknown output format {x}"),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fn main() {
|
fn main() {
|
||||||
let args = Args::parse();
|
let args = Args::parse();
|
||||||
let mut data:Vec<FactData> = vec![];
|
let output_format = match args.output.as_str() {
|
||||||
|
"json" => "json",
|
||||||
if args.gatherer.is_none() {
|
"yaml" => "yaml",
|
||||||
data.append(&mut gather_all());
|
_ => "yaml",
|
||||||
} else {
|
|
||||||
// sanitize the gatherer list
|
|
||||||
let ugatherers: HashSet<String> = match &args.gatherer {
|
|
||||||
Some(x) => x.into_iter().map(|name| name).cloned().collect::<HashSet<String>>(),
|
|
||||||
None => HashSet::<String>::new(),
|
|
||||||
};
|
|
||||||
data.append(&mut gather_list(ugatherers));
|
|
||||||
}
|
|
||||||
match args.output.as_str() {
|
|
||||||
"json" => {
|
|
||||||
let serialized_json = serde_json::to_string(&data).unwrap();
|
|
||||||
println!("{}", serialized_json);
|
|
||||||
},
|
|
||||||
"csv" => {
|
|
||||||
let mut writer = Writer::from_writer(vec![]);
|
|
||||||
for fd in data {
|
|
||||||
writer.serialize(fd).unwrap();
|
|
||||||
}
|
|
||||||
println!("{}", String::from_utf8(writer.into_inner().unwrap()).unwrap());
|
|
||||||
}
|
|
||||||
&_ => {
|
|
||||||
let serialized_yaml = serde_yaml::to_string(&data).unwrap();
|
|
||||||
println!("{}", serialized_yaml);
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
let all: HashSet<String> = HashSet::from([
|
||||||
|
"env".to_string(),
|
||||||
|
"ipaddr".to_string(),
|
||||||
|
"iproute".to_string(),
|
||||||
|
]);
|
||||||
|
let data_output: String = match args.gatherer {
|
||||||
|
None => gather_list(all, output_format),
|
||||||
|
Some(x) => {
|
||||||
|
let gatherers: HashSet<String> = x.into_iter().collect::<HashSet<String>>();
|
||||||
|
gather_list(gatherers, output_format)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
println!("{}", data_output);
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,12 @@
|
|||||||
use std::time::{UNIX_EPOCH, SystemTime};
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
use serde::{Serialize, Deserialize};
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
pub trait Fact: Send + Sync {
|
||||||
pub struct FactData {
|
fn gather(&self) -> String;
|
||||||
pub name: String,
|
|
||||||
pub value: String,
|
|
||||||
pub time_set: u128,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait Fact : Send + Sync {
|
|
||||||
fn gather(&self) -> Vec<FactData>;
|
|
||||||
|
|
||||||
fn get_epoch_ms(&self) -> u128 {
|
fn get_epoch_ms(&self) -> u128 {
|
||||||
SystemTime::now()
|
SystemTime::now()
|
||||||
.duration_since(UNIX_EPOCH)
|
.duration_since(UNIX_EPOCH)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.as_millis()
|
.as_millis()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1 +1 @@
|
|||||||
pub mod fact;
|
pub mod fact;
|
||||||
|
@ -10,33 +10,35 @@ fn get_output_from_command(cmd: &str, args: Vec<&str>) -> Output {
|
|||||||
fn get_stdout_as_string(output: Output) -> String {
|
fn get_stdout_as_string(output: Output) -> String {
|
||||||
return match String::from_utf8(output.stdout) {
|
return match String::from_utf8(output.stdout) {
|
||||||
Ok(x) => x.strip_suffix("\n").unwrap().to_string(),
|
Ok(x) => x.strip_suffix("\n").unwrap().to_string(),
|
||||||
Err(e) => e.to_string()
|
Err(e) => e.to_string(),
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_stderr_as_string(output: Output) -> String {
|
fn get_stderr_as_string(output: Output) -> String {
|
||||||
return match String::from_utf8(output.stderr) {
|
return match String::from_utf8(output.stderr) {
|
||||||
Ok(x) => x.strip_suffix("\n").unwrap().to_string(),
|
Ok(x) => x.strip_suffix("\n").unwrap().to_string(),
|
||||||
Err(e) => e.to_string()
|
Err(e) => e.to_string(),
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_result_as_string(cmd: &str, args:Vec<&str>) -> String {
|
pub fn get_result_as_string(cmd: &str, args: Vec<&str>) -> String {
|
||||||
let output = get_output_from_command(cmd, args);
|
let output = get_output_from_command(cmd, args);
|
||||||
match output.status.code() {
|
match output.status.code() {
|
||||||
Some(0) => get_stdout_as_string(output),
|
Some(0) => get_stdout_as_string(output),
|
||||||
_ => get_stderr_as_string(output)
|
_ => get_stderr_as_string(output),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::util::command::{get_result_as_string};
|
use crate::util::command::get_result_as_string;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_get_output_from_command() {
|
fn test_get_output_from_command() {
|
||||||
assert_eq!("Linux", get_result_as_string("uname", vec![]));
|
assert_eq!("Linux", get_result_as_string("uname", vec![]));
|
||||||
assert_eq!("ls: cannot access '/dev/mouse': No such file or directory",
|
assert_eq!(
|
||||||
get_result_as_string("ls", vec!["/dev/mouse",]))
|
"ls: cannot access '/dev/mouse': No such file or directory",
|
||||||
|
get_result_as_string("ls", vec!["/dev/mouse",])
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1 +1 @@
|
|||||||
pub mod command;
|
pub mod command;
|
||||||
|
Loading…
Reference in New Issue
Block a user