use super::*;
pub(crate) fn env_string(name: &str, default: &str) -> String {
match env::var(name) {
Ok(value) if !value.is_empty() => value,
_ => default.to_owned(),
}
}
pub(crate) fn env_path(name: &str, default: &Path) -> PathBuf {
match env::var_os(name) {
Some(value) if !value.is_empty() => PathBuf::from(value),
_ => default.to_path_buf(),
}
}
pub(crate) fn parse_levels(name: &str, value: &str) -> Result<Vec<u32>, String> {
let mut levels: Vec<u32> = Vec::new();
for level in value.split_whitespace() {
match level.parse::<u32>() {
Ok(parsed) => levels.push(parsed),
Err(error) => return Err(format!("invalid {name} value {level}: {error}")),
}
}
Ok(levels)
}
pub(crate) fn config_from_env() -> Result<Config, String> {
let working: PathBuf = match env::current_dir() {
Ok(path) => path,
Err(error) => return Err(format!("could not resolve the working directory: {error}")),
};
let local_harness: PathBuf = working.join(PERFORMANCE_DIRECTORY);
let default_root: PathBuf = if local_harness.is_dir() {
local_harness
} else {
working
};
let root: PathBuf = env_path(ENV_ROOT, &default_root);
let certs: PathBuf = env_path(ENV_CERTS, &root.join(DEFAULT_CERTS_DIR));
let connections_value: String = env_string(ENV_CONNECTIONS, DEFAULT_CONNECTIONS);
let short_value: String = env_string(ENV_CONNECTIONS_SHORT, DEFAULT_CONNECTIONS_SHORT);
let repeats_value: String = env_string(ENV_REPEATS, DEFAULT_REPEATS);
let repeats: u32 = match repeats_value.parse::<u32>() {
Ok(value) => value,
Err(error) => {
return Err(format!(
"invalid {ENV_REPEATS} value {repeats_value}: {error}"
));
}
};
let cooldown_value: String = env_string(ENV_COOLDOWN_SHORT, DEFAULT_COOLDOWN_SHORT);
let cooldown_short: u64 = match cooldown_value.parse::<u64>() {
Ok(value) => value,
Err(error) => {
return Err(format!(
"invalid {ENV_COOLDOWN_SHORT} value {cooldown_value}: {error}"
));
}
};
Ok(Config {
results: env_path(ENV_RESULTS, &root.join(DEFAULT_RESULTS_DIR)),
network: env_string(ENV_NETWORK, DEFAULT_NETWORK),
image_prefix: env_string(ENV_IMAGE_PREFIX, DEFAULT_IMAGE_PREFIX),
server_cpus: env_string(ENV_SERVER_CPUS, DEFAULT_SERVER_CPUS),
loadgen_cpus: env_string(ENV_LOADGEN_CPUS, DEFAULT_LOADGEN_CPUS),
memory: env_string(ENV_MEMORY, DEFAULT_MEMORY),
connections: parse_levels(ENV_CONNECTIONS, &connections_value)?,
connections_short: parse_levels(ENV_CONNECTIONS_SHORT, &short_value)?,
duration: env_string(ENV_DURATION, DEFAULT_DURATION),
warmup: env_string(ENV_WARMUP, DEFAULT_WARMUP),
repeats,
protocols: env_string(ENV_PROTOCOLS, DEFAULT_PROTOCOLS)
.split_whitespace()
.map(str::to_owned)
.collect(),
modes: env_string(ENV_MODES, DEFAULT_MODES)
.split_whitespace()
.map(str::to_owned)
.collect(),
cooldown_short,
rate_short: env_string(ENV_RATE_SHORT, DEFAULT_RATE_SHORT),
ca_cert: env_path(ENV_CA_CERT, &certs.join(CA_FILE_NAME)),
tls_certificate: env_path(ENV_TLS_CERT, &certs.join(LEAF_CERT_FILE_NAME)),
tls_key: env_path(ENV_TLS_KEY, &certs.join(LEAF_KEY_FILE_NAME)),
root,
certs,
})
}