mirror of
https://github.com/imjasonh/krust
synced 2026-07-07 22:35:25 +00:00
Add e2e tests and CI integration for docker run workflow
- Add comprehensive e2e tests for build functionality - Add integration job to CI that tests `docker run $(krust build)` - Test KRUST_REPO environment variable usage - Test --no-push flag and clean stdout for command substitution - Add tests for verbose logging - Remove outdated basic_test.rs 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
2cf7ab1c17
commit
93bb4561fc
3 changed files with 168 additions and 31 deletions
51
.github/workflows/ci.yml
vendored
51
.github/workflows/ci.yml
vendored
|
|
@ -69,14 +69,53 @@ jobs:
|
|||
- name: Run clippy
|
||||
run: cargo clippy -- -D warnings
|
||||
|
||||
coverage:
|
||||
name: Code coverage
|
||||
integration:
|
||||
name: Integration Test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install Rust
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
- name: Install cargo-tarpaulin
|
||||
run: cargo install cargo-tarpaulin
|
||||
- name: Generate code coverage
|
||||
run: cargo tarpaulin --verbose --workspace
|
||||
with:
|
||||
targets: x86_64-unknown-linux-musl
|
||||
- name: Install musl tools
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y musl-tools
|
||||
- name: Build krust
|
||||
run: cargo build --release
|
||||
- name: Add krust to PATH
|
||||
run: echo "${{ github.workspace }}/target/release" >> $GITHUB_PATH
|
||||
- name: Test krust version
|
||||
run: krust version
|
||||
- name: Build and run example with krust
|
||||
run: |
|
||||
cd example/hello-krust
|
||||
# Build and push to ttl.sh (ephemeral registry)
|
||||
export KRUST_REPO=ttl.sh/${{ github.run_id }}
|
||||
IMAGE_REF=$(krust build ./)
|
||||
echo "Built image: $IMAGE_REF"
|
||||
# Run the image
|
||||
docker run --rm $IMAGE_REF
|
||||
- name: Test docker run with command substitution
|
||||
run: |
|
||||
cd example/hello-krust
|
||||
export KRUST_REPO=ttl.sh/${{ github.run_id }}-test2
|
||||
docker run --rm $(krust build ./)
|
||||
- name: Test build with --no-push
|
||||
run: |
|
||||
cd example/hello-krust
|
||||
krust build --no-push --image local.test/hello:latest ./
|
||||
|
||||
# Takes too long to run on CI, so it's commented out for now.
|
||||
# coverage:
|
||||
# name: Code coverage
|
||||
# runs-on: ubuntu-latest
|
||||
# steps:
|
||||
# - uses: actions/checkout@v4
|
||||
# - name: Install Rust
|
||||
# uses: dtolnay/rust-toolchain@stable
|
||||
# - name: Install cargo-tarpaulin
|
||||
# run: cargo install cargo-tarpaulin
|
||||
# - name: Generate code coverage
|
||||
# run: cargo tarpaulin --verbose --workspace
|
||||
|
|
|
|||
|
|
@ -1,25 +0,0 @@
|
|||
use std::process::Command;
|
||||
|
||||
#[test]
|
||||
fn test_help_flag() {
|
||||
let output = Command::new("cargo")
|
||||
.args(&["run", "--", "--version"])
|
||||
.output()
|
||||
.expect("Failed to execute command");
|
||||
|
||||
let stdout = String::from_utf8_lossy(&output.stdout);
|
||||
assert!(stdout.contains("krust"));
|
||||
assert!(output.status.success());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_basic_run() {
|
||||
let output = Command::new("cargo")
|
||||
.arg("run")
|
||||
.output()
|
||||
.expect("Failed to execute command");
|
||||
|
||||
let stdout = String::from_utf8_lossy(&output.stdout);
|
||||
assert!(stdout.contains("Hello from krust!"));
|
||||
assert!(output.status.success());
|
||||
}
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
use anyhow::Result;
|
||||
use assert_cmd::Command;
|
||||
use predicates::prelude::*;
|
||||
use std::env;
|
||||
use std::process::Command as StdCommand;
|
||||
|
||||
#[test]
|
||||
fn test_version_command() -> Result<()> {
|
||||
|
|
@ -41,3 +43,124 @@ fn test_build_help() -> Result<()> {
|
|||
));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_build_requires_repo_or_image() -> Result<()> {
|
||||
// Use the example directory
|
||||
let example_dir = env::current_dir()?.join("example").join("hello-krust");
|
||||
|
||||
// Run krust build without KRUST_REPO or --image
|
||||
let mut cmd = Command::cargo_bin("krust")?;
|
||||
cmd.arg("build")
|
||||
.arg("--no-push")
|
||||
.current_dir(&example_dir)
|
||||
.env_remove("KRUST_REPO");
|
||||
|
||||
cmd.assert()
|
||||
.failure()
|
||||
.stderr(predicate::str::contains(
|
||||
"Either --image or KRUST_REPO must be set",
|
||||
));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_build_with_krust_repo_env() -> Result<()> {
|
||||
// Use the example directory
|
||||
let example_dir = env::current_dir()?.join("example").join("hello-krust");
|
||||
|
||||
// Run krust build with KRUST_REPO env var
|
||||
let mut cmd = Command::cargo_bin("krust")?;
|
||||
cmd.arg("build")
|
||||
.arg("--no-push")
|
||||
.env("KRUST_REPO", "test.local")
|
||||
.current_dir(&example_dir);
|
||||
|
||||
cmd.assert().success().stderr(predicate::str::contains(
|
||||
"Building Rust project",
|
||||
)).stderr(predicate::str::contains(
|
||||
"Successfully built image: test.local/hello-krust:latest",
|
||||
));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_command_substitution_syntax() -> Result<()> {
|
||||
// Get the example project directory
|
||||
let example_dir = env::current_dir()?.join("example").join("hello-krust");
|
||||
|
||||
// Test that output is clean for command substitution
|
||||
let mut cmd = Command::cargo_bin("krust")?;
|
||||
let output = cmd
|
||||
.arg("build")
|
||||
.arg("--no-push")
|
||||
.arg("--image")
|
||||
.arg("test.local/hello:latest")
|
||||
.current_dir(&example_dir)
|
||||
.output()?;
|
||||
|
||||
// Stdout should be empty when --no-push is used
|
||||
let stdout = String::from_utf8_lossy(&output.stdout);
|
||||
assert!(stdout.trim().is_empty(), "Stdout should be empty with --no-push");
|
||||
|
||||
// Stderr should contain log messages
|
||||
let stderr = String::from_utf8_lossy(&output.stderr);
|
||||
assert!(stderr.contains("Building Rust project"));
|
||||
assert!(stderr.contains("Successfully built image"));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_verbose_logging() -> Result<()> {
|
||||
let example_dir = env::current_dir()?.join("example").join("hello-krust");
|
||||
|
||||
let mut cmd = Command::cargo_bin("krust")?;
|
||||
cmd.arg("--verbose")
|
||||
.arg("build")
|
||||
.arg("--no-push")
|
||||
.arg("--image")
|
||||
.arg("test.local/hello:latest")
|
||||
.current_dir(&example_dir);
|
||||
|
||||
cmd.assert()
|
||||
.success()
|
||||
.stderr(predicate::str::contains("DEBUG"));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore] // This test requires Docker and a registry
|
||||
fn test_full_build_and_run_workflow() -> Result<()> {
|
||||
// Skip if Docker is not available
|
||||
if StdCommand::new("docker").arg("version").output().is_err() {
|
||||
eprintln!("Skipping test: Docker not available");
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// Get the example project directory
|
||||
let example_dir = env::current_dir()?.join("example").join("hello-krust");
|
||||
|
||||
// Build and push to ttl.sh
|
||||
let mut cmd = Command::cargo_bin("krust")?;
|
||||
let output = cmd
|
||||
.arg("build")
|
||||
.env("KRUST_REPO", "ttl.sh/krust-test")
|
||||
.current_dir(&example_dir)
|
||||
.output()?;
|
||||
|
||||
assert!(output.status.success(), "Build failed");
|
||||
|
||||
// Get the image reference from stdout
|
||||
let image_ref = String::from_utf8_lossy(&output.stdout).trim().to_string();
|
||||
assert!(image_ref.starts_with("ttl.sh/krust-test/hello-krust@sha256:"));
|
||||
|
||||
// Try to run the image
|
||||
let docker_output = StdCommand::new("docker")
|
||||
.args(&["run", "--rm", &image_ref])
|
||||
.output()?;
|
||||
|
||||
assert!(docker_output.status.success(), "Docker run failed");
|
||||
let docker_stdout = String::from_utf8_lossy(&docker_output.stdout);
|
||||
assert!(docker_stdout.contains("Hello from krust example!"));
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue