Skip to content

feat(interu): Add --check-test-definitions flag #30

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jan 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions tools/interu/fixtures/interu.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ runners:
- name: default
arch: amd64
size: large
disk: 50
disk-gb: 50
nodes: 3

default-arm64:
Expand All @@ -16,7 +16,7 @@ runners:
- name: default
arch: arm64
size: large
disk: 50
disk-gb: 50
nodes: 3

default-mixed:
Expand All @@ -26,12 +26,12 @@ runners:
- name: amd64-nodes
arch: amd64
size: large
disk: 50
disk-gb: 50
nodes: 3
- name: arm64-nodes
arch: arm64
size: large
disk: 50
disk-gb: 50
nodes: 3

profiles:
Expand Down
98 changes: 98 additions & 0 deletions tools/interu/fixtures/test-definition.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# COPIED FROM AIRFLOW-OPERATOR
---
dimensions:
- name: airflow
values:
- 2.9.2
- 2.9.3
- 2.10.2
# To use a custom image, add a comma and the full name after the product version
# - 2.8.1,docker.stackable.tech/sandbox/airflow:2.8.1-stackable0.0.0-dev
- name: airflow-latest
values:
- 2.10.2
# To use a custom image, add a comma and the full name after the product version
# - 2.8.1,docker.stackable.tech/sandbox/airflow:2.8.1-stackable0.0.0-dev
- name: ldap-authentication
values:
- no-tls
- insecure-tls
- server-verification-tls
- name: openshift
values:
- "false"
- name: executor
values:
- celery
- kubernetes
tests:
- name: smoke
dimensions:
- airflow
- openshift
- executor
- name: mount-dags-configmap
dimensions:
- airflow-latest
- openshift
- executor
- name: mount-dags-gitsync
dimensions:
- airflow-latest
- openshift
- executor
- name: ldap
dimensions:
- airflow-latest
- openshift
- ldap-authentication
- executor
- name: oidc
dimensions:
- airflow
- openshift
- name: resources
dimensions:
- airflow-latest
- openshift
- name: orphaned-resources
dimensions:
- airflow-latest
- openshift
- name: logging
dimensions:
- airflow
- openshift
- executor
- name: cluster-operation
dimensions:
- airflow-latest
- openshift
- name: overrides
dimensions:
- airflow-latest
- openshift
suites:
- name: nightly
# Run nightly with the latest airflow
patch:
- dimensions:
- name: airflow
expr: last
- name: smoke-latest
# Useful for development
select:
- smoke
patch:
- dimensions:
- expr: last
- name: openshift
# Run on OpenShift with latest airflow
patch:
- dimensions:
- expr: last
- dimensions:
- name: airflow
expr: last
- name: openshift
expr: "true"
16 changes: 14 additions & 2 deletions tools/interu/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ pub struct Cli {
option,
short = 'o',
long = "output",
description = "write configuration key=value pairs separated by newlines to file
Useful for CI tools which give a file to write env vars and outputs to which are used in subsequent steps"
description = "write configuration key=value pairs separated by newlines to file. Useful for CI tools which give a file to write env vars and outputs to which are used in subsequent steps"
)]
pub output: Option<PathBuf>,

Expand All @@ -33,6 +32,19 @@ pub struct Cli {
#[argh(switch, short = 'q', long = "quiet")]
pub quiet: bool,

/// validate the beku test definition of the selected profile
#[argh(switch, long = "check-test-definitions")]
pub check_test_definitions: bool,

/// path to beku test-definition file [default = tests/test-definition.yaml]
#[argh(
option,
short = 't',
long = "test-definitions",
default = r#"PathBuf::from("tests/test-definition.yaml")"#
)]
pub test_definitions: PathBuf,

/// which test profile to use
#[argh(positional)]
pub profile: String,
Expand Down
72 changes: 46 additions & 26 deletions tools/interu/src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use tracing::instrument;

use crate::{
config::{
profile::{Profile, StrategyValidationError, TestRun},
profile::{Profile, StrategyValidationError, TestOptions, TestRun},
runner::{
ConvertNodeGroupError, Distribution, ReplicatedNodeGroup, Runner, RunnerValidationError,
},
Expand All @@ -21,6 +21,7 @@ use crate::{

pub mod profile;
pub mod runner;
pub mod test;

/// Errors which can be encountered when reading and validating the config file.
#[derive(Debug, Snafu)]
Expand All @@ -43,6 +44,9 @@ pub enum Error {
path: PathBuf,
},

#[snafu(display("failed to validate test options"))]
ValidateTestOptions { source: StrategyValidationError },

#[snafu(display("failed to find profile named {profile_name:?}"))]
UnknownProfileName { profile_name: String },

Expand Down Expand Up @@ -92,25 +96,19 @@ impl Config {
Ok(config)
}

#[instrument(name = "validate_config", skip(self))]
fn validate(&self) -> Result<(), ValidationError> {
for (runner_name, runner) in &self.runners {
tracing::debug!(runner_name, "validate runner");

runner
.validate(runner_name)
.context(InvalidRunnerConfigSnafu)?;
}

for (profile_name, profile) in &self.profiles {
tracing::debug!(profile_name, "validate profile");

profile
.validate(profile_name, &self.runners)
.context(InvalidProfileConfigSnafu)?;
}
pub fn get_profile(&self, profile_name: &String) -> Result<&Profile, Error> {
self.profiles
.get(profile_name)
.context(UnknownProfileNameSnafu { profile_name })
}

Ok(())
pub fn validate_test_options<P>(&self, profile_name: &String, path: P) -> Result<(), Error>
where
P: AsRef<Path>,
{
self.get_profile(profile_name)?
.validate_test_options(&profile_name, path)
.context(ValidateTestOptionsSnafu)
}

/// Determines the final expanded parameters based on the provided profile.
Expand All @@ -120,10 +118,7 @@ impl Config {
instances: &'a Instances,
) -> Result<Parameters<'a>, Error> {
// First, lookup the profile by name. Error if the profile does't exist.
let profile = self
.profiles
.get(profile_name)
.context(UnknownProfileNameSnafu { profile_name })?;
let profile = self.get_profile(profile_name)?;

// Next, lookup the runner ref based on the profile strategy
let runner_ref = match &profile.strategy {
Expand All @@ -144,7 +139,11 @@ impl Config {
let runner = self.runners.get(runner_ref).unwrap();

// Get test options
let (test_parallelism, test_run, test_parameter) = profile.strategy.get_test_options();
let TestOptions {
parallelism,
test_run,
test_parameter,
} = profile.strategy.get_test_options();

// Convert our node groups to replicated node groups
let node_groups = runner
Expand All @@ -158,13 +157,34 @@ impl Config {
Ok(Parameters {
kubernetes_distribution: &runner.platform.distribution,
kubernetes_version: &runner.platform.version,
test_parallelism: *parallelism,
cluster_ttl: &runner.ttl,
test_parallelism,
test_parameter,
node_groups,
test_run,
})
}

#[instrument(name = "validate_config", skip(self))]
fn validate(&self) -> Result<(), ValidationError> {
for (runner_name, runner) in &self.runners {
tracing::debug!(runner_name, "validate runner");

runner
.validate(runner_name)
.context(InvalidRunnerConfigSnafu)?;
}

for (profile_name, profile) in &self.profiles {
tracing::debug!(profile_name, "validate profile");

profile
.validate(profile_name, &self.runners)
.context(InvalidProfileConfigSnafu)?;
}

Ok(())
}
}

/// Parameters which will be expanded into environment variables via the [`Display`] implementation.
Expand Down Expand Up @@ -221,7 +241,7 @@ impl<'a> Display for Parameters<'a> {
}

#[cfg(test)]
mod test {
mod tests {
use std::path::PathBuf;

use super::*;
Expand Down
Loading
Loading