Skip to content

Commit

Permalink
integ: run push and pull from local registry when testing
Browse files Browse the repository at this point in the history
Co-authored-by: Jarrett Tierney <[email protected]>
  • Loading branch information
cbgbt and jmt-lab committed Oct 8, 2024
1 parent c0c8dff commit fe1a5a5
Show file tree
Hide file tree
Showing 9 changed files with 207 additions and 57 deletions.
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ home = "0.5"
indicatif = "0.17"
inotify = "0.10.2"
lazy_static = "1"
libc = "0.2"
log = "0.4"
maplit = "1"
nix = "0.28"
Expand All @@ -99,6 +100,7 @@ pentacle = "1.1"
rand = { version = "0.8", default-features = false }
regex = "1"
reqwest = { version = "0.11", default-features = false }
seccompiler = "0.4"
semver = "1"
serde = "1"
serde_json = "1"
Expand Down
3 changes: 3 additions & 0 deletions tests/integration-tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,8 @@ edition = "2021"
license = "MIT OR Apache-2.0"

[dev-dependencies]
libc.workspace = true
tempfile.workspace = true
tokio = { workspace = true, features = ["fs", "process", "rt-multi-thread"] }
toml.workspace = true
twoliter = { workspace = true }
85 changes: 82 additions & 3 deletions tests/integration-tests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

use std::ffi::OsStr;
use std::path::PathBuf;
use tokio::process::Command;
use std::process::Command;
use tempfile::TempDir;

mod twoliter_update;

Expand All @@ -14,7 +15,7 @@ pub fn test_projects_dir() -> PathBuf {
p.join("projects")
}

pub async fn run_command<I, S, E>(cmd: S, args: I, env: E) -> std::process::Output
pub fn run_command<I, S, E>(cmd: S, args: I, env: E) -> std::process::Output
where
I: IntoIterator<Item = S>,
E: IntoIterator<Item = (S, S)>,
Expand All @@ -35,10 +36,88 @@ where
.args(args.into_iter())
.envs(env.into_iter())
.output()
.await
.expect("failed to execute process");

println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
output
}

struct KitRegistry {
temp_dir: TempDir,
container_id: String,
}

impl KitRegistry {
fn new() -> Self {
let temp_dir = TempDir::new().expect("failed to create path for oci registry spinup");

let cert_dir = temp_dir.path().join("certs");
let cert_file = cert_dir.join("registry.crt");
std::fs::create_dir_all(&cert_dir).expect("failed to create nginx dir");
let output = run_command(
"openssl",
[
"req",
"-x509",
"-nodes",
"-days",
"365",
"-newkey",
"rsa:2048",
"-keyout",
cert_dir.join("registry.key").to_str().unwrap(),
"-out",
cert_file.to_str().unwrap(),
"-batch",
"-addext",
"subjectAltName=DNS:localhost",
],
[],
);
assert!(
output.status.success(),
"generate openssl self-signed certificates"
);

let output = run_command(
"docker",
[
"run",
"-d",
"--rm",
"--volume",
"./certs:/auth/certs",
"-e REGISTRY_HTTP_RELATIVEURLS=true",
"-e REGISTRY_HTTP_ADDR=0.0.0.0:5000",
"-e REGISTRY_HTTP_TLS_CERTIFICATE=/auth/certs/registry.crt",
"-e REGISTRY_HTTP_TLS_KEY=/auth/certs/registry.key",
"-p",
"5000:5000",
"public.ecr.aws/docker/library/registry:2.8.3",
],
[],
);
assert!(output.status.success(), "failed to start oci registry");
let container_id = String::from_utf8(output.stdout).unwrap().trim().to_string();

Self {
temp_dir,
container_id,
}
}

fn cert_file(&self) -> PathBuf {
self.temp_dir
.path()
.join("certs/registry.crt")
.to_path_buf()
}
}

impl Drop for KitRegistry {
fn drop(&mut self) {
let output = run_command("docker", ["kill", &self.container_id], []);
assert!(output.status.success(), "failed to stop oci registry");
}
}
158 changes: 109 additions & 49 deletions tests/integration-tests/src/twoliter_update.rs
Original file line number Diff line number Diff line change
@@ -1,74 +1,134 @@
use super::{run_command, test_projects_dir, TWOLITER_PATH};

const EXPECTED_LOCKFILE: &str = r#"schema-version = 1
[sdk]
name = "bottlerocket-sdk"
version = "0.42.0"
vendor = "bottlerocket"
source = "public.ecr.aws/bottlerocket/bottlerocket-sdk:v0.42.0"
digest = "myHHKE41h9qfeyR6V6HB0BfiLPwj3QEFLUFy4TXcR10="
[[kit]]
name = "bottlerocket-core-kit"
version = "2.0.0"
vendor = "custom-vendor"
source = "public.ecr.aws/bottlerocket/bottlerocket-core-kit:v2.0.0"
digest = "vlTsAAbSCzXFZofVmw8pLLkRjnG/y8mtb2QsQBSz1zk="
use super::{run_command, test_projects_dir, KitRegistry, TWOLITER_PATH};

const INFRA_TOML: &str = r#"
[vendor.bottlerocket]
registry = "localhost:5000"
"#;

const TWOLITER_OVERRIDE: &str = r#"
[custom-vendor.core-kit]
registry = "localhost:5000"
name = "core-kit-overridden"
"#;

#[tokio::test]
#[test]
#[ignore]
/// Generates a Twoliter.lock file for the `external-kit` project using docker
async fn test_twoliter_update_docker() {
/// Generates a Twoliter.lock file for the `external-kit` project using crane
fn test_twoliter_build_and_update() {
let external_kit = test_projects_dir().join("external-kit");

let lockfile = external_kit.join("Twoliter.lock");
tokio::fs::remove_file(&lockfile).await.ok();
std::fs::remove_file(&lockfile).ok();
let override_file = external_kit.join("Twoliter.override");
std::fs::remove_file(&override_file).ok();

// Build & push a local kit to the registry
let registry = KitRegistry::new();
LocalKit::build(&registry);

// Point twoliter to the local registry as an override
std::fs::write(&override_file, TWOLITER_OVERRIDE).unwrap();
let output = run_command(
TWOLITER_PATH,
[
"update",
"--project-path",
external_kit.join("Twoliter.toml").to_str().unwrap(),
],
[("TWOLITER_KIT_IMAGE_TOOL", "docker")],
)
.await;
[
("TWOLITER_KIT_IMAGE_TOOL", "crane"),
("SSL_CERT_FILE", registry.cert_file().to_str().unwrap()),
],
);

assert!(output.status.success());

let lock_contents = tokio::fs::read_to_string(&lockfile).await.unwrap();
assert_eq!(lock_contents, EXPECTED_LOCKFILE);
// Assert that we successfully create a lock
let lock_contents = std::fs::read_to_string(&lockfile).unwrap();
let parsed: toml::Value = toml::from_str(&lock_contents).unwrap();
let kits = parsed
.as_table()
.unwrap()
.get("kit")
.unwrap()
.as_array()
.unwrap();

assert_eq!(kits.len(), 1);
let core_kit = kits[0].as_table().unwrap();
assert_eq!(core_kit.get("name").unwrap().as_str().unwrap(), "core-kit");
assert_eq!(core_kit.get("version").unwrap().as_str().unwrap(), "1.0.0");
assert_eq!(
core_kit.get("vendor").unwrap().as_str().unwrap(),
"custom-vendor"
);
assert_eq!(
core_kit.get("source").unwrap().as_str().unwrap(),
"definitely-wont-resolve/core-kit:v1.0.0"
);

tokio::fs::remove_file(&lockfile).await.ok();
std::fs::remove_file(&lockfile).ok();
std::fs::remove_file(&override_file).ok();
}

#[tokio::test]
#[ignore]
/// Generates a Twoliter.lock file for the `external-kit` project using crane
async fn test_twoliter_update_crane() {
let external_kit = test_projects_dir().join("external-kit");
struct LocalKit;

let lockfile = external_kit.join("Twoliter.lock");
tokio::fs::remove_file(&lockfile).await.ok();
impl LocalKit {
fn build(registry: &KitRegistry) {
let local_kit = test_projects_dir().join("local-kit");

let output = run_command(
TWOLITER_PATH,
[
"update",
"--project-path",
external_kit.join("Twoliter.toml").to_str().unwrap(),
],
[("TWOLITER_KIT_IMAGE_TOOL", "crane")],
)
.await;
run_command(
TWOLITER_PATH,
[
"update",
"--project-path",
local_kit.join("Twoliter.toml").to_str().unwrap(),
],
[],
);

assert!(output.status.success());
run_command(
TWOLITER_PATH,
[
"fetch",
"--project-path",
local_kit.join("Twoliter.toml").to_str().unwrap(),
],
[],
);

let lock_contents = tokio::fs::read_to_string(&lockfile).await.unwrap();
assert_eq!(lock_contents, EXPECTED_LOCKFILE);
run_command(
TWOLITER_PATH,
[
"build",
"kit",
"core-kit",
"--project-path",
local_kit.join("Twoliter.toml").to_str().unwrap(),
],
[],
);

std::fs::write(local_kit.join("Infra.toml"), INFRA_TOML).unwrap();
run_command(
TWOLITER_PATH,
[
"publish",
"kit",
"--project-path",
local_kit.join("Twoliter.toml").to_str().unwrap(),
"core-kit",
"bottlerocket",
"core-kit-overridden",
],
[("SSL_CERT_FILE", registry.cert_file().to_str().unwrap())],
);
}
}

tokio::fs::remove_file(&lockfile).await.ok();
impl Drop for LocalKit {
fn drop(&mut self) {
let local_kit = test_projects_dir().join("local-kit");
std::fs::remove_file(local_kit.join("Twoliter.lock")).ok();
std::fs::remove_file(local_kit.join("Infra.toml")).ok();
}
}
2 changes: 2 additions & 0 deletions tests/projects/external-kit/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@
Test.toml
testsys.kubeconfig
Infra.toml
Twoliter.lock
Twoliter.override
6 changes: 3 additions & 3 deletions tests/projects/external-kit/Twoliter.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ release-version = "1.0.0"
registry = "public.ecr.aws/bottlerocket"

[vendor.custom-vendor]
registry = "public.ecr.aws/bottlerocket"
registry = "definitely-wont-resolve"

[[kit]]
name = "bottlerocket-core-kit"
version = "2.0.0"
name = "core-kit"
version = "1.0.0"
vendor = "custom-vendor"
1 change: 1 addition & 0 deletions tests/projects/local-kit/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@
Test.toml
testsys.kubeconfig
Infra.toml
Twoliter.lock
4 changes: 2 additions & 2 deletions tools/unplug/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ publish = false
anyhow.workspace = true

[target.'cfg(target_os = "linux")'.dependencies]
libc = "0.2.148"
seccompiler = "0.4.0"
libc.workspace = true
seccompiler.workspace = true

0 comments on commit fe1a5a5

Please sign in to comment.