Skip to content

Commit

Permalink
Merge pull request #2048 from cgwalters/rust-cmdspec-tests
Browse files Browse the repository at this point in the history
Add new Rust-based tests
  • Loading branch information
openshift-merge-robot authored Jun 2, 2020
2 parents 1293721 + 1f637bf commit 2598612
Show file tree
Hide file tree
Showing 13 changed files with 495 additions and 33 deletions.
2 changes: 1 addition & 1 deletion .cci.jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ codestyle: {
// Build FCOS and do a kola basic run
stage("More builds and test") {
parallel fcos: {
cosaPod(runAsUser: 0, memory: "2048Mi", cpu: "2") {
cosaPod(buildroot: true, runAsUser: 0, memory: "3072Mi", cpu: "4") {
stage("Build FCOS") {
checkout scm
unstash 'build'
Expand Down
32 changes: 1 addition & 31 deletions tests/basic-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

set -euo pipefail

echo "1..$((89 + ${extra_basic_tests:-0}))"
echo "1..$((86 + ${extra_basic_tests:-0}))"

CHECKOUT_U_ARG=""
CHECKOUT_H_ARGS="-H"
Expand Down Expand Up @@ -1031,17 +1031,6 @@ stat '--format=%Y' test2-checkout/baz/deeper > deeper-mtime
assert_file_has_content deeper-mtime 0
echo "ok content mtime"

cd ${test_tmpdir}
rm -rf test2-checkout
mkdir -p test2-checkout
cd test2-checkout
mkfifo afifo
if $OSTREE commit ${COMMIT_ARGS} -b test2 -s "Attempt to commit a FIFO" 2>../errmsg; then
assert_not_reached "Committing a FIFO unexpetedly succeeded!"
assert_file_has_content ../errmsg "Unsupported file type"
fi
echo "ok commit of fifo was rejected"

cd ${test_tmpdir}
rm repo2 -rf
mkdir repo2
Expand Down Expand Up @@ -1180,22 +1169,3 @@ if test "$(id -u)" != "0"; then
else
echo "ok # SKIP not run when root"
fi

cd ${test_tmpdir}
rm -rf test2-checkout
mkdir -p test2-checkout
cd test2-checkout
touch blah
stat --printf="%.Y\n" ${test_tmpdir}/repo > ${test_tmpdir}/timestamp-orig.txt
$OSTREE commit ${COMMIT_ARGS} -b test2 -s "Should bump the mtime"
stat --printf="%.Y\n" ${test_tmpdir}/repo > ${test_tmpdir}/timestamp-new.txt
cd ..
if cmp timestamp-{orig,new}.txt; then
assert_not_reached "failed to update mtime on repo"
fi
echo "ok mtime updated"

cd ${test_tmpdir}
$OSTREE init --mode=bare --repo=repo-extensions
assert_has_dir repo-extensions/extensions
echo "ok extensions dir"
2 changes: 2 additions & 0 deletions tests/inst/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
target/
Cargo.lock
42 changes: 42 additions & 0 deletions tests/inst/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
[package]
name = "ostree-test"
version = "0.1.0"
authors = ["Colin Walters <walters@verbum.org>"]
edition = "2018"

[[bin]]
name = "ostree-test"
path = "src/insttest.rs"

[dependencies]
clap = "2.32.0"
structopt = "0.2"
commandspec = "0.12.2"
anyhow = "1.0"
tempfile = "3.1.0"
gio = "0.8"
ostree = { version = "0.7.1", features = ["v2020_1"] }
libtest-mimic = "0.2.0"
twoway = "0.2.1"
hyper = "0.13"
futures = "0.3.4"
http = "0.2.0"
hyper-staticfile = "0.5.1"
tokio = { version = "0.2", features = ["full"] }
futures-util = "0.3.1"
base64 = "0.12.0"
procspawn = "0.8"
proc-macro2 = "0.4"
quote = "0.6"
syn = "0.15"
linkme = "0.2"

itest-macro = { path = "itest-macro" }

with-procspawn-tempdir = { git = "https://github.com/cgwalters/with-procspawn-tempdir" }
#with-procspawn-tempdir = { path = "/var/srv/walters/src/github/cgwalters/with-procspawn-tempdir" }

# See https://github.com/tcr/commandspec/pulls?q=is%3Apr+author%3Acgwalters+
[patch.crates-io]
commandspec = { git = "https://github.com/cgwalters/commandspec", branch = 'walters-master' }
#commandspec = { path = "/var/srv/walters/src/github/tcr/commandspec" }
14 changes: 14 additions & 0 deletions tests/inst/itest-macro/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[package]
name = "itest-macro"
version = "0.1.0"
edition = "2018"

[lib]
proc-macro = true
path = "src/itest-macro.rs"

[dependencies]
quote = "1.0.3"
proc-macro2 = "1.0.10"
syn = { version = "1.0.3", features = ["full"] }
anyhow = "1.0"
32 changes: 32 additions & 0 deletions tests/inst/itest-macro/src/itest-macro.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
extern crate proc_macro;

use proc_macro::TokenStream;
use proc_macro2::Span;
use quote::quote;

/// Wraps function using `procspawn` to allocate a new temporary directory,
/// make it the process' working directory, and run the function.
#[proc_macro_attribute]
pub fn itest(attrs: TokenStream, input: TokenStream) -> TokenStream {
let attrs = syn::parse_macro_input!(attrs as syn::AttributeArgs);
if attrs.len() > 0 {
return syn::Error::new_spanned(&attrs[0], "itest takes no attributes")
.to_compile_error()
.into();
}
let func = syn::parse_macro_input!(input as syn::ItemFn);
let fident = func.sig.ident.clone();
let varident = quote::format_ident!("ITEST_{}", fident);
let fidentstrbuf = format!(r#"{}"#, fident);
let fidentstr = syn::LitStr::new(&fidentstrbuf, Span::call_site());
let output = quote! {
#[linkme::distributed_slice(TESTS)]
#[allow(non_upper_case_globals)]
static #varident : Test = Test {
name: #fidentstr,
f: #fident,
};
#func
};
output.into()
}
46 changes: 46 additions & 0 deletions tests/inst/src/insttest.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
use anyhow::Result;
// use structopt::StructOpt;
// // https://github.com/clap-rs/clap/pull/1397
// #[macro_use]
// extern crate clap;

mod repobin;
mod sysroot;
mod test;

fn gather_tests() -> Vec<test::TestImpl> {
test::TESTS
.iter()
.map(|t| libtest_mimic::Test {
name: t.name.into(),
kind: "".into(),
is_ignored: false,
is_bench: false,
data: t,
})
.collect()
}

fn run_test(test: &test::TestImpl) -> libtest_mimic::Outcome {
if let Err(e) = (test.data.f)() {
libtest_mimic::Outcome::Failed {
msg: Some(e.to_string()),
}
} else {
libtest_mimic::Outcome::Passed
}
}

fn main() -> Result<()> {
procspawn::init();

// Ensure we're always in tempdir so we can rely on it globally
let tmp_dir = tempfile::Builder::new()
.prefix("ostree-insttest-top")
.tempdir()?;
std::env::set_current_dir(tmp_dir.path())?;

let args = libtest_mimic::Arguments::from_args();
let tests = gather_tests();
libtest_mimic::run_tests(&args, tests, run_test).exit();
}
121 changes: 121 additions & 0 deletions tests/inst/src/repobin.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
//! Tests that mostly use the CLI and operate on temporary
//! repositories.

use std::path::Path;

use crate::test::*;
use anyhow::{Context, Result};
use commandspec::{sh_command, sh_execute};
use tokio::runtime::Runtime;
use with_procspawn_tempdir::with_procspawn_tempdir;

#[itest]
fn test_basic() -> Result<()> {
sh_execute!(r"ostree --help >/dev/null")?;
Ok(())
}

#[itest]
#[with_procspawn_tempdir]
fn test_nofifo() -> Result<()> {
assert!(std::path::Path::new(".procspawn-tmpdir").exists());
sh_execute!(
r"ostree --repo=repo init --mode=archive
mkdir tmproot
mkfifo tmproot/afile
"
)?;
cmd_fails_with(
sh_command!(
r#"ostree --repo=repo commit -b fifotest -s "commit fifo" --tree=dir=./tmproot"#
)
.unwrap(),
"Not a regular file or symlink",
)?;
Ok(())
}

#[itest]
#[with_procspawn_tempdir]
fn test_mtime() -> Result<()> {
sh_execute!(
r"ostree --repo=repo init --mode=archive
mkdir tmproot
echo afile > tmproot/afile
ostree --repo=repo commit -b test --tree=dir=tmproot >/dev/null
"
)?;
let ts = Path::new("repo").metadata()?.modified().unwrap();
sh_execute!(
r#"ostree --repo=repo commit -b test -s "bump mtime" --tree=dir=tmproot >/dev/null"#
)?;
assert_ne!(ts, Path::new("repo").metadata()?.modified().unwrap());
Ok(())
}

#[itest]
#[with_procspawn_tempdir]
fn test_extensions() -> Result<()> {
sh_execute!(r"ostree --repo=repo init --mode=bare")?;
assert!(Path::new("repo/extensions").exists());
Ok(())
}

async fn impl_test_pull_basicauth() -> Result<()> {
let opts = TestHttpServerOpts {
basicauth: true,
..Default::default()
};
let serverrepo = Path::new("server/repo");
std::fs::create_dir_all(&serverrepo)?;
let addr = http_server(&serverrepo, opts).await?;
tokio::task::spawn_blocking(move || -> Result<()> {
let baseuri = http::Uri::from_maybe_shared(format!("http://{}/", addr).into_bytes())?;
let unauthuri =
http::Uri::from_maybe_shared(format!("http://unknown:badpw@{}/", addr).into_bytes())?;
let authuri = http::Uri::from_maybe_shared(
format!("http://{}@{}/", TEST_HTTP_BASIC_AUTH, addr).into_bytes(),
)?;
let osroot = Path::new("osroot");
mkroot(&osroot)?;
sh_execute!(
r#"ostree --repo={serverrepo} init --mode=archive
ostree --repo={serverrepo} commit -b os --tree=dir={osroot} >/dev/null
mkdir client
cd client
ostree --repo=repo init --mode=archive
ostree --repo=repo remote add --set=gpg-verify=false origin-unauth {baseuri}
ostree --repo=repo remote add --set=gpg-verify=false origin-badauth {unauthuri}
ostree --repo=repo remote add --set=gpg-verify=false origin-goodauth {authuri}
"#,
osroot = osroot.to_str(),
serverrepo = serverrepo.to_str(),
baseuri = baseuri.to_string(),
unauthuri = unauthuri.to_string(),
authuri = authuri.to_string()
)?;
for rem in &["unauth", "badauth"] {
cmd_fails_with(
sh_command!(
r#"ostree --repo=client/repo pull origin-{rem} os >/dev/null"#,
rem = *rem
)
.unwrap(),
"HTTP 403",
)
.context(rem)?;
}
sh_execute!(r#"ostree --repo=client/repo pull origin-goodauth os >/dev/null"#,)?;
Ok(())
})
.await??;
Ok(())
}

#[itest]
#[with_procspawn_tempdir]
fn test_pull_basicauth() -> Result<()> {
let mut rt = Runtime::new()?;
rt.block_on(async move { impl_test_pull_basicauth().await })?;
Ok(())
}
33 changes: 33 additions & 0 deletions tests/inst/src/sysroot.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//! Tests that mostly use the API and access the booted sysroot read-only.

use anyhow::Result;
use gio::prelude::*;
use ostree::prelude::*;

use crate::test::*;

#[itest]
fn test_sysroot_ro() -> Result<()> {
// TODO add a skipped identifier
if !std::path::Path::new("/run/ostree-booted").exists() {
return Ok(());
}
let cancellable = Some(gio::Cancellable::new());
let sysroot = ostree::Sysroot::new_default();
sysroot.load(cancellable.as_ref())?;
assert!(sysroot.is_booted());

let booted = sysroot.get_booted_deployment().expect("booted deployment");
assert!(!booted.is_staged());
let repo = sysroot.repo().expect("repo");

let csum = booted.get_csum().expect("booted csum");
let csum = csum.as_str();

let (root, rev) = repo.read_commit(csum, cancellable.as_ref())?;
assert_eq!(rev, csum);
let root = root.downcast::<ostree::RepoFile>().expect("downcast");
root.ensure_resolved()?;

Ok(())
}
Loading

0 comments on commit 2598612

Please sign in to comment.