ftest/src/runner/init_scripts.rs
Aravinth Manivannan 8afea6fc81
feat & chore: define MinAppContext and FullAppContext
SUMMARY
    ftest when run as a local dev tool will only run one job during its
    runtime. Database and settings are not required for this purpose.

    This commit defines MinAppContext for running in a single job
    execution mode and FullAppContext for running as a daemon
2023-10-04 02:14:47 +05:30

111 lines
3.9 KiB
Rust

// SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
use std::collections::HashMap;
use crate::utils::get_random;
use crate::{complaince::target::Target, ctx::MinAppContext};
use super::results::{ArchivableContainer, ArchivableInitResult};
pub fn launch_init_containers(
ctx: &dyn MinAppContext,
target: &Target,
) -> Option<Vec<ArchivableInitResult>> {
if let Some(init_scripts) = target.init_scripts.as_ref() {
let mut init_results = Vec::with_capacity(init_scripts.len());
for init in init_scripts.iter() {
let mut env = HashMap::new();
let auth = get_random(32);
env.insert("FTEST_AUTH".into(), auth.clone());
if let Some(custom_vars) = init.env_vars.clone() {
env.extend(custom_vars);
}
let name = format!("{}--{}", init.name, &auth[0..5]);
ctx.docker_().run_container(
&name,
&init.container,
false,
&env,
Some("ftest".to_string()),
true,
);
let logs = ctx.docker_().get_logs(&name);
let exit_code = ctx.docker_().get_exit_status(&name);
ctx.docker_().rm_container(&name, true);
// TODO:fail when success == false
let c = ArchivableInitResult {
success: exit_code == 0,
exit_code,
container: ArchivableContainer {
name: name.clone(),
logs,
},
};
init_results.push(c);
}
Some(init_results)
} else {
None
}
}
#[cfg(test)]
mod tests {
use std::sync::Arc;
use url::Url;
use super::*;
use crate::docker_compose::DockerCompose;
use crate::{AppMinCtx, Ctx, Settings};
use crate::complaince::suite::Test;
#[actix_rt::test]
async fn launch_init_containers_works() {
let settings = Settings::new().unwrap();
let ctx = AppMinCtx::new(Arc::new(Ctx::new(settings.clone()).await));
// let base_dir = Path::new(&ctx.settings.repository.base_dir);
// let control = base_dir.join("control");
let compose = DockerCompose::new(
"../ftest-control/targets/forgejo".into(),
ctx.docker_().clone(),
);
compose.up();
let mut env_vars: HashMap<String, String> = HashMap::new();
env_vars.insert("FORGEJO_URL".into(), "http://forgejo".into());
env_vars.insert("FORGEJO_SSH_URL".into(), "http://forgejo:2222".into());
env_vars.insert("CI".into(), "true".into());
let target = Target {
version: "1".into(),
name: "launch_init_containers_works".into(),
container_host: Url::parse("http://launch_init_containers_works.service").unwrap(),
homepage: Url::parse("https://launch_init_containers_works.example.org").unwrap(),
repository: Url::parse("https://launch_init_containers_works.example.org").unwrap(),
init_scripts: Some(vec![Test {
name: "forgejo-configure".into(),
url: Url::parse("https://git.batsense.net/ForgeFlux/forgejo-init-script").unwrap(),
version: semver::Version::parse("1.0.1").unwrap(),
container: "forgeflux/forgejo-init-script".into(),
env_vars: Some(env_vars),
}]),
suites: Vec::default(),
};
let init = launch_init_containers(ctx.as_ref().as_ref(), &target);
assert!(init.is_some());
let init = init.unwrap();
assert_eq!(init.len(), 1);
let init = init.get(0).unwrap();
assert!(init.success);
assert_eq!(init.exit_code, 0);
assert!(init.container.logs.contains("All Good"));
compose.down(true, true);
}
}