Skip to content

Commit 9f35be5

Browse files
authored
Merge pull request #560 from imageworks/296-test-trait
Move test definition behind a trait
2 parents aa7ba1b + a260882 commit 9f35be5

File tree

12 files changed

+232
-138
lines changed

12 files changed

+232
-138
lines changed

crates/spk-cli/cmd-test/src/cmd_test.rs

Lines changed: 24 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,14 @@
44
use std::str::FromStr;
55
use std::sync::Arc;
66

7-
use anyhow::Result;
7+
use anyhow::{Context, Result};
88
use clap::Args;
99
use spk_build::BuildSource;
1010
use spk_cli_common::{flags, CommandArgs, Run};
1111
use spk_schema::foundation::format::{FormatIdent, FormatOptionMap};
1212
use spk_schema::foundation::ident_build::Build;
1313
use spk_schema::foundation::option_map::{host_options, OptionMap};
14+
use spk_schema::prelude::*;
1415
use spk_schema::{Recipe, TestStage, Variant};
1516

1617
use crate::test::{PackageBuildTester, PackageInstallTester, PackageSourceTester, Tester};
@@ -23,7 +24,7 @@ mod cmd_test_test;
2324
///
2425
/// In order to run install tests the package must have been built already
2526
#[derive(Args)]
26-
pub struct Test {
27+
pub struct CmdTest {
2728
#[clap(flatten)]
2829
pub options: flags::Options,
2930
#[clap(flatten)]
@@ -57,7 +58,7 @@ pub struct Test {
5758
}
5859

5960
#[async_trait::async_trait]
60-
impl Run for Test {
61+
impl Run for CmdTest {
6162
async fn run(&mut self) -> Result<i32> {
6263
let options = self.options.get_options()?;
6364
let (_runtime, repos) = tokio::try_join!(
@@ -123,11 +124,15 @@ impl Run for Test {
123124
continue;
124125
}
125126

126-
for (index, test) in recipe.get_tests(&opts)?.into_iter().enumerate() {
127-
if test.stage != stage {
128-
continue;
129-
}
130-
127+
let selected = recipe
128+
.get_tests(stage, &opts)
129+
.context("Failed to select tests for this variant")?;
130+
tracing::info!(
131+
variant=%opts.format_option_map(),
132+
"Running {} relevant tests for this variant",
133+
selected.len()
134+
);
135+
for (index, test) in selected.into_iter().enumerate() {
131136
let mut builder = self
132137
.formatter_settings
133138
.get_formatter_builder(self.verbose)?;
@@ -140,31 +145,27 @@ impl Run for Test {
140145

141146
let mut tester: Box<dyn Tester> = match stage {
142147
TestStage::Sources => {
143-
let mut tester = PackageSourceTester::new(
144-
(*recipe).clone(),
145-
test.script.join("\n"),
146-
);
148+
let mut tester =
149+
PackageSourceTester::new((*recipe).clone(), test.script());
147150

148151
tester
149152
.with_options(opts.clone())
150153
.with_repositories(repos.iter().cloned())
151-
.with_requirements(test.requirements.clone())
154+
.with_requirements(test.additional_requirements())
152155
.with_source(source.clone())
153156
.watch_environment_resolve(&src_formatter);
154157

155158
Box::new(tester)
156159
}
157160

158161
TestStage::Build => {
159-
let mut tester = PackageBuildTester::new(
160-
(*recipe).clone(),
161-
test.script.join("\n"),
162-
);
162+
let mut tester =
163+
PackageBuildTester::new((*recipe).clone(), test.script());
163164

164165
tester
165166
.with_options(opts.clone())
166167
.with_repositories(repos.iter().cloned())
167-
.with_requirements(test.requirements.clone())
168+
.with_requirements(test.additional_requirements())
168169
.with_source(
169170
source.clone().map(BuildSource::LocalPath).unwrap_or_else(
170171
|| {
@@ -186,40 +187,24 @@ impl Run for Test {
186187
TestStage::Install => {
187188
let mut tester = PackageInstallTester::new(
188189
(*recipe).clone(),
189-
test.script.join("\n"),
190+
test.script(),
190191
variant,
191192
);
192193

193194
tester
194195
.with_options(opts.clone())
195196
.with_repositories(repos.iter().cloned())
196-
.with_requirements(test.requirements.clone())
197+
.with_requirements(test.additional_requirements())
197198
.with_source(source.clone())
198199
.watch_environment_resolve(&install_formatter);
199200

200201
Box::new(tester)
201202
}
202203
};
203204

204-
let mut selected = false;
205-
for selector in test.selectors.iter() {
206-
let mut selected_opts = opts.clone();
207-
selected_opts.extend(selector.clone());
208-
if selected_opts.digest() == digest {
209-
selected = true;
210-
}
211-
}
212-
if !selected && !test.selectors.is_empty() {
213-
tracing::info!(
214-
"SKIP #{index}: variant not selected: {}",
215-
opts.format_option_map()
216-
);
217-
continue;
218-
}
219-
220205
tracing::info!(
221-
"Running test #{index} variant={}",
222-
opts.format_option_map()
206+
variant=%opts.format_option_map(),
207+
"Running selected test #{index}",
223208
);
224209

225210
tester.test().await?
@@ -231,7 +216,7 @@ impl Run for Test {
231216
}
232217
}
233218

234-
impl CommandArgs for Test {
219+
impl CommandArgs for CmdTest {
235220
fn get_positional_args(&self) -> Vec<String> {
236221
// The important positional args for a test are the packages
237222
self.packages.clone()

crates/spk-cli/cmd-test/src/cmd_test_test.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use spk_cmd_build::cmd_build::Build;
1212
use spk_schema::foundation::fixtures::*;
1313
use spk_storage::fixtures::*;
1414

15-
use super::Test;
15+
use super::CmdTest;
1616

1717
#[derive(Parser)]
1818
struct BuildOpt {
@@ -23,7 +23,7 @@ struct BuildOpt {
2323
#[derive(Parser)]
2424
struct TestOpt {
2525
#[clap(flatten)]
26-
test: Test,
26+
test: CmdTest,
2727
}
2828

2929
macro_rules! build_package {

crates/spk-schema/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ mod requirements_list;
2222
mod source_spec;
2323
mod spec;
2424
mod template;
25-
mod test_spec;
25+
mod test;
2626
pub mod v0;
2727
mod validation;
2828
pub mod variant;
@@ -57,7 +57,7 @@ pub use spk_schema_foundation::{
5757
};
5858
pub use spk_schema_ident::{self as ident, AnyIdent, BuildIdent, Request, VersionIdent};
5959
pub use template::{Template, TemplateData, TemplateExt};
60-
pub use test_spec::TestStage;
60+
pub use test::{Test, TestStage};
6161
pub use validation::{default_validators, ValidationSpec, Validator};
6262
pub use variant::{Variant, VariantExt};
6363
pub use {serde_json, spk_schema_validators as validators};

crates/spk-schema/src/prelude.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ pub use super::{
1111
Package,
1212
Recipe,
1313
Template,
14+
Test,
1415
Variant,
1516
VariantExt,
1617
};

crates/spk-schema/src/recipe.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@ use spk_schema_ident::VersionIdent;
1010
use crate::foundation::option_map::OptionMap;
1111
use crate::foundation::spec_ops::{Named, Versioned};
1212
use crate::ident::Request;
13-
use crate::test_spec::TestSpec;
14-
use crate::{Package, Result, Variant};
13+
use crate::{Package, Result, TestStage, Variant};
1514

1615
/// Return the resolved packages from a solution.
1716
pub trait BuildEnv {
@@ -27,6 +26,7 @@ pub trait Recipe:
2726
{
2827
type Output: super::Package;
2928
type Variant: super::Variant + Clone;
29+
type Test: super::Test;
3030

3131
/// Build an identifier to represent this recipe.
3232
///
@@ -53,8 +53,8 @@ pub trait Recipe:
5353
where
5454
V: Variant;
5555

56-
/// Return the tests defined for this package.
57-
fn get_tests<V>(&self, variant: &V) -> Result<Vec<TestSpec>>
56+
/// Return the tests defined for this package at the given stage.
57+
fn get_tests<V>(&self, stage: TestStage, variant: &V) -> Result<Vec<Self::Test>>
5858
where
5959
V: Variant;
6060

@@ -75,6 +75,7 @@ where
7575
{
7676
type Output = T::Output;
7777
type Variant = T::Variant;
78+
type Test = T::Test;
7879

7980
fn ident(&self) -> &VersionIdent {
8081
(**self).ident()
@@ -98,11 +99,11 @@ where
9899
(**self).get_build_requirements(variant)
99100
}
100101

101-
fn get_tests<V>(&self, variant: &V) -> Result<Vec<TestSpec>>
102+
fn get_tests<V>(&self, stage: TestStage, variant: &V) -> Result<Vec<Self::Test>>
102103
where
103104
V: Variant,
104105
{
105-
(**self).get_tests(variant)
106+
(**self).get_tests(stage, variant)
106107
}
107108

108109
fn generate_source_build(&self, root: &Path) -> Result<Self::Output> {
@@ -125,6 +126,7 @@ where
125126
{
126127
type Output = T::Output;
127128
type Variant = T::Variant;
129+
type Test = T::Test;
128130

129131
fn ident(&self) -> &VersionIdent {
130132
(**self).ident()
@@ -148,11 +150,11 @@ where
148150
(**self).get_build_requirements(variant)
149151
}
150152

151-
fn get_tests<V>(&self, variant: &V) -> Result<Vec<TestSpec>>
153+
fn get_tests<V>(&self, stage: TestStage, variant: &V) -> Result<Vec<Self::Test>>
152154
where
153155
V: Variant,
154156
{
155-
(**self).get_tests(variant)
157+
(**self).get_tests(stage, variant)
156158
}
157159

158160
fn generate_source_build(&self, root: &Path) -> Result<Self::Output> {

crates/spk-schema/src/spec.rs

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ use crate::foundation::option_map::OptionMap;
1919
use crate::foundation::spec_ops::prelude::*;
2020
use crate::foundation::version::{Compat, Compatibility, Version};
2121
use crate::ident::{PkgRequest, Request, Satisfy, VarRequest};
22-
use crate::test_spec::TestSpec;
2322
use crate::{
2423
v0,
2524
BuildEnv,
@@ -34,6 +33,8 @@ use crate::{
3433
Result,
3534
Template,
3635
TemplateExt,
36+
Test,
37+
TestStage,
3738
Variant,
3839
};
3940

@@ -231,6 +232,7 @@ pub enum SpecRecipe {
231232
impl Recipe for SpecRecipe {
232233
type Output = Spec;
233234
type Variant = SpecVariant;
235+
type Test = SpecTest;
234236

235237
fn ident(&self) -> &VersionIdent {
236238
match self {
@@ -271,12 +273,16 @@ impl Recipe for SpecRecipe {
271273
}
272274
}
273275

274-
fn get_tests<V>(&self, variant: &V) -> Result<Vec<TestSpec>>
276+
fn get_tests<V>(&self, stage: TestStage, variant: &V) -> Result<Vec<Self::Test>>
275277
where
276278
V: Variant,
277279
{
278280
match self {
279-
SpecRecipe::V0Package(r) => r.get_tests(variant),
281+
SpecRecipe::V0Package(r) => Ok(r
282+
.get_tests(stage, variant)?
283+
.into_iter()
284+
.map(SpecTest::V0)
285+
.collect()),
280286
}
281287
}
282288

@@ -395,6 +401,24 @@ impl std::fmt::Display for SpecVariant {
395401
}
396402
}
397403

404+
pub enum SpecTest {
405+
V0(v0::TestSpec),
406+
}
407+
408+
impl Test for SpecTest {
409+
fn script(&self) -> String {
410+
match self {
411+
Self::V0(t) => t.script(),
412+
}
413+
}
414+
415+
fn additional_requirements(&self) -> Vec<Request> {
416+
match self {
417+
Self::V0(t) => t.additional_requirements(),
418+
}
419+
}
420+
}
421+
398422
/// Specifies some data object within the spk ecosystem.
399423
///
400424
/// All resolve-able types have a spec representation that can be serialized

0 commit comments

Comments
 (0)