Skip to content

Commit

Permalink
Unit/Integration CI test cleanup (#1143)
Browse files Browse the repository at this point in the history
* Tweak integration tests to always run all ignored tests

Also upgrade tarpaulin to see if there are any changes

Signed-off-by: clux <sszynrae@gmail.com>

* less recent tarpaulin... action seems abandoned

Signed-off-by: clux <sszynrae@gmail.com>

* fix doctests for remote_command

Signed-off-by: clux <sszynrae@gmail.com>

* different tarpaulin incantation

Signed-off-by: clux <sszynrae@gmail.com>

* make remote_command tests not ignored

Signed-off-by: clux <sszynrae@gmail.com>

* fix admission doc tests

Signed-off-by: clux <sszynrae@gmail.com>

* big test revamp

Signed-off-by: clux <sszynrae@gmail.com>

* revert most tarpaulin actions changes and limit rg check to ubuntu

Signed-off-by: clux <sszynrae@gmail.com>

* revert tarpaulin settings + run less stuff on windows

windows build slow

Signed-off-by: clux <sszynrae@gmail.com>

* remove references to deprecated '--all' flag

Signed-off-by: clux <sszynrae@gmail.com>

* back to older tarpaulin for now..

Signed-off-by: clux <sszynrae@gmail.com>

* also fix deprecation warning for gha set-output

Signed-off-by: clux <sszynrae@gmail.com>

* lol managed to screw up even that

Signed-off-by: clux <sszynrae@gmail.com>

* can use -j6 everywhere on ci

Signed-off-by: clux <sszynrae@gmail.com>

* avoid double ripgrep in release scripts

Signed-off-by: clux <sszynrae@gmail.com>

* dependencies link to tools

Signed-off-by: clux <sszynrae@gmail.com>

* use a more precise cargo tree

Signed-off-by: clux <sszynrae@gmail.com>

---------

Signed-off-by: clux <sszynrae@gmail.com>
  • Loading branch information
clux authored Feb 21, 2023
1 parent 7e77855 commit 53ad9ee
Show file tree
Hide file tree
Showing 12 changed files with 112 additions and 73 deletions.
57 changes: 25 additions & 32 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,29 +42,28 @@ jobs:
- name: Build workspace
run: cargo build

# Workspace tests
- name: Run workspace unit tests
run: cargo test --lib --all -j6
- name: Run workspace doc tests
run: cargo test --doc --all -j6
- name: Test examples
run: cargo test -p kube-examples --examples -j6
- name: Compile check remaining examples
# No OS specific code in examples, run this on fastest executor
# Workspace unit tests with various feature sets
- name: Run workspace unit tests (no default features)
run: cargo test --workspace --lib --no-default-features -j6
if: matrix.os == 'ubuntu-latest'
run: cargo build -j4 -p kube-examples

# Feature tests
- name: Test kube with features rustls-tls,ws,oauth
run: cargo test -p kube --lib --no-default-features --features=rustls-tls,ws,oauth
- name: Run workspace unit tests (default features)
run: cargo test --workspace --lib --exclude kube-examples --exclude e2e -j6
if: matrix.os == 'ubuntu-latest'
- name: Test kube with features openssl-tls,ws,oauth
run: cargo test -p kube --lib --no-default-features --features=openssl-tls,ws,oauth
if: matrix.os == 'ubuntu-latest'
# Feature tests in examples
- name: Test crd_derive_no_schema example
run: cargo test -p kube-examples --example crd_derive_no_schema --no-default-features --features=openssl-tls,latest
- name: Run workspace unit tests (all features)
run: cargo test --workspace --lib --all-features --exclude kube-examples --exclude e2e -j6
# Workspace documentation (all features only)
- name: Run workspace doc tests
run: cargo test --workspace --doc --all-features --exclude kube-examples --exclude e2e -j6
- name: Run ad-hoc doc test verification
run: |
if rg "\`\`\`ignored"; then
echo "ignored doctests are not allowed, use compile_fail or no_run"
exit 1
fi
if: matrix.os == 'ubuntu-latest'
# Examples
- name: Test examples
run: cargo test -p kube-examples --examples -j6

msrv:
# Run `cargo check` on our minimum supported Rust version
Expand All @@ -76,7 +75,7 @@ jobs:
run: |
MSRV=$(grep MSRV README.md | grep -oE "[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+")
echo $MSRV
echo ::set-output name=msrv::${MSRV}
echo "msrv=${MSRV}" >> $GITHUB_OUTPUT
- uses: actions-rs/toolchain@v1
with:
toolchain: ${{ steps.msrv.outputs.msrv }}
Expand All @@ -87,7 +86,7 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: check
args: --all
args: --workspace

- name: Check rust-version keys matches MSRV consistently
run: |
Expand Down Expand Up @@ -148,18 +147,12 @@ jobs:
run: cargo build

# Run the equivalent of `just integration`
- name: Run all default features integration library tests
run: cargo test --lib --all -- --ignored
- name: Run all facade integration library tests with extra features
run: cargo test -p kube --lib --features=derive,runtime -- --ignored --nocapture
- name: Run all integration library tests
run: cargo test --lib --workspace --exclude e2e --all-features -j6 -- --ignored
- name: Run crd example tests
run: cargo run -p kube-examples --example crd_api
- name: Run all client integration library tests with rustls and ws
run: cargo test -p kube-client --lib --features=rustls-tls,ws -- --ignored
- name: Run derive example tests
run: cargo run -p kube-examples --example crd_derive
- name: Run crd example tests
run: cargo run -p kube-examples --example crd_api

mk8sv:
# comile check e2e tests against mk8sv
Expand All @@ -172,8 +165,8 @@ jobs:
run: |
MK8SV=$(grep MK8SV README.md | grep -oE "[[:digit:]]+\.[[:digit:]]+" | head -n 1)
echo $MK8SV
echo ::set-output name=mk8sv::${MK8SV}
echo ::set-output name=mk8svdash::v${MK8SV/\./_}
echo "mk8sv=${MK8SV}" >> $GITHUB_OUTPUT
echo "mk8svdash=v${MK8SV/\./_}" >> $GITHUB_OUTPUT
- name: Check ci jobs run against advertised MK8SV
run: |
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/rustfmt.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# When pushed to main, run `cargo +nightly fmt --all` and open a PR.
# When pushed to main, run `cargo +nightly fmt` against all files and open a PR.
name: rustfmt
on:
push:
Expand Down
10 changes: 6 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ The easiest way set up a minimal Kubernetes cluster for these is with [`k3d`](ht

### Unit Tests & Documentation Tests

**Most** unit/doc tests are run from `cargo test --lib --doc --all`, but because of feature-sets, and examples, you will need a couple of extra invocations to replicate our CI.
Unit and doc tests are run against a particular crate with `cargo test -p KUBECRATE --lib --doc`, but because of feature-sets, you will need a couple of extra flags and invocations to replicate all our CI conditions.

For the complete variations, run the `just test` target in the `justfile`.
To run **all** unit tests, call: `just test`

All public interfaces must be documented, and most should have minor documentation examples to show usage.

Expand All @@ -57,7 +57,9 @@ Slower set of tests within the crates marked with an **`#[ignore]`** attribute.

:warning: These **WILL** try to modify resources in your current cluster :warning:

Most integration tests are run with `cargo test --all --lib -- --ignored`, but because of feature-sets, you will need a few invocations of these to replicate our CI. See `just test-integration`
Integration tests are run against a crate with `cargo test -p KUBECRATE --lib -- --ignored`, but because of feature-sets, you will need a few invocations of these to replicate our CI.

To run **all** integration tests, call: `just test-integration`

### End to End Tests

Expand All @@ -75,7 +77,7 @@ All public interfaces should have doc tests with examples for [docs.rs](https://

When adding new non-trivial pieces of logic that results in a drop in coverage you should add a test.

Cross-reference with the coverage build [![coverage build](https://codecov.io/gh/kube-rs/kube/branch/main/graph/badge.svg?token=9FCqEcyDTZ)](https://codecov.io/gh/kube-rs/kube) and go to your branch. Coverage can also be run locally with [`cargo tarpaulin`](https://github.com/xd009642/tarpaulin) at project root. This will use our [tarpaulin.toml](https://github.com/kube-rs/kube/blob/main/tarpaulin.toml) config, and **will run both unit and integration** tests.
Cross-reference with the coverage build [![coverage build](https://codecov.io/gh/kube-rs/kube/branch/main/graph/badge.svg?token=9FCqEcyDTZ)](https://app.codecov.io/gh/kube-rs/kube/tree/main) and go to your branch. Coverage can also be run locally with [`cargo tarpaulin`](https://github.com/xd009642/tarpaulin) at project root. This will use our [tarpaulin.toml](https://github.com/kube-rs/kube/blob/main/tarpaulin.toml) config, and **will run both unit and integration** tests.

#### What type of test

Expand Down
27 changes: 17 additions & 10 deletions justfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
VERSION := `git rev-parse HEAD`
open := if os() == "macos" { "open" } else { "xdg-open" }

[private]
default:
Expand All @@ -22,25 +23,31 @@ deny:

# Unit tests
test:
cargo test --lib --all
cargo test --doc --all
#!/usr/bin/env bash
if rg "\`\`\`ignored"; then
echo "ignored doctests are not allowed, use compile_fail or no_run"
exit 1
fi
# no default features
cargo test --workspace --lib --no-default-features
# default features
cargo test --workspace --lib --exclude kube-examples --exclude e2e
# all features
cargo test --workspace --lib --all-features --exclude kube-examples --exclude e2e
cargo test --workspace --doc --all-features --exclude kube-examples --exclude e2e
cargo test -p kube-examples --examples
cargo test -p kube --lib --no-default-features --features=rustls-tls,ws,oauth
cargo test -p kube --lib --no-default-features --features=openssl-tls,ws,oauth
cargo test -p kube --lib --no-default-features

# Integration tests (will modify your current context's cluster)
test-integration:
kubectl delete pod -lapp=kube-rs-test
cargo test --lib --all -- --ignored # also run tests that fail on github actions
cargo test -p kube --lib --features=derive,runtime -- --ignored
cargo test -p kube-client --lib --features=rustls-tls,ws -- --ignored
kubectl delete pod -lapp=kube-rs-test > /dev/null
cargo test --lib --workspace --exclude e2e --all-features -- --ignored
# some examples are canonical tests
cargo run -p kube-examples --example crd_derive
cargo run -p kube-examples --example crd_api

coverage:
cargo tarpaulin --out=Html --output-dir=.
#xdg-open tarpaulin-report.html
{{open}} tarpaulin-report.html

readme:
rustdoc README.md --test --edition=2021
Expand Down
39 changes: 33 additions & 6 deletions kube-client/src/api/remote_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,9 +161,15 @@ impl AttachedProcess {
}

/// Async writer to stdin.
/// ```ignore
/// ```no_run
/// # use kube_client::api::AttachedProcess;
/// # use tokio::io::{AsyncReadExt, AsyncWriteExt};
/// # async fn wrapper() -> Result<(), Box<dyn std::error::Error>> {
/// # let attached: AttachedProcess = todo!();
/// let mut stdin_writer = attached.stdin().unwrap();
/// stdin_writer.write(b"foo\n").await?;
/// # Ok(())
/// # }
/// ```
/// Only available if [`AttachParams`](super::AttachParams) had `stdin`.
pub fn stdin(&mut self) -> Option<impl AsyncWrite + Unpin> {
Expand All @@ -174,9 +180,16 @@ impl AttachedProcess {
}

/// Async reader for stdout outputs.
/// ```ignore
/// ```no_run
/// # use kube_client::api::AttachedProcess;
/// # use tokio::io::{AsyncReadExt, AsyncWriteExt};
/// # async fn wrapper() -> Result<(), Box<dyn std::error::Error>> {
/// # let attached: AttachedProcess = todo!();
/// let mut stdout_reader = attached.stdout().unwrap();
/// let next_stdout = stdout_reader.read().await?;
/// let mut buf = [0u8; 4];
/// stdout_reader.read_exact(&mut buf).await?;
/// # Ok(())
/// # }
/// ```
/// Only available if [`AttachParams`](super::AttachParams) had `stdout`.
pub fn stdout(&mut self) -> Option<impl AsyncRead + Unpin> {
Expand All @@ -187,9 +200,16 @@ impl AttachedProcess {
}

/// Async reader for stderr outputs.
/// ```ignore
/// ```no_run
/// # use kube_client::api::AttachedProcess;
/// # use tokio::io::{AsyncReadExt, AsyncWriteExt};
/// # async fn wrapper() -> Result<(), Box<dyn std::error::Error>> {
/// # let attached: AttachedProcess = todo!();
/// let mut stderr_reader = attached.stderr().unwrap();
/// let next_stderr = stderr_reader.read().await?;
/// let mut buf = [0u8; 4];
/// stderr_reader.read_exact(&mut buf).await?;
/// # Ok(())
/// # }
/// ```
/// Only available if [`AttachParams`](super::AttachParams) had `stderr`.
pub fn stderr(&mut self) -> Option<impl AsyncRead + Unpin> {
Expand Down Expand Up @@ -218,12 +238,19 @@ impl AttachedProcess {
}

/// Async writer to change the terminal size
/// ```ignore
/// ```no_run
/// # use kube_client::api::{AttachedProcess, TerminalSize};
/// # use tokio::io::{AsyncReadExt, AsyncWriteExt};
/// # use futures::SinkExt;
/// # async fn wrapper() -> Result<(), Box<dyn std::error::Error>> {
/// # let attached: AttachedProcess = todo!();
/// let mut terminal_size_writer = attached.terminal_size().unwrap();
/// terminal_size_writer.send(TerminalSize{
/// height: 100,
/// width: 200,
/// }).await?;
/// # Ok(())
/// # }
/// ```
/// Only available if [`AttachParams`](super::AttachParams) had `tty`.
pub fn terminal_size(&mut self) -> Option<TerminalSizeSender> {
Expand Down
2 changes: 1 addition & 1 deletion kube-client/src/config/file_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ pub struct ExecConfig {
/// Specifies which environment variables the host should avoid passing to the auth plugin.
///
/// This does currently not exist upstream and cannot be specified on disk.
/// It has been suggested in client-go via https://github.com/kubernetes/client-go/issues/1177
/// It has been suggested in client-go via <https://github.com/kubernetes/client-go/issues/1177>
#[serde(skip)]
pub drop_env: Option<Vec<String>>,

Expand Down
8 changes: 4 additions & 4 deletions kube-core/src/admission.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,11 @@ impl<T: Resource> TryInto<AdmissionRequest<T>> for AdmissionReview<T> {
///
/// In an admission controller scenario, this is extracted from an [`AdmissionReview`] via [`TryInto`]
///
/// ```ignore
/// ```no_run
/// use kube::api::{admission::{AdmissionRequest, AdmissionReview}, DynamicObject};
///
/// // The incoming AdmissionReview received by the controller.
/// let body: AdmissionReview<DynamicObject>;
/// let body: AdmissionReview<DynamicObject> = todo!();
/// let req: AdmissionRequest<_> = body.try_into().unwrap();
/// ```
///
Expand Down Expand Up @@ -204,14 +204,14 @@ pub enum Operation {

/// An outgoing [`AdmissionReview`] response. Constructed from the corresponding
/// [`AdmissionRequest`].
/// ```ignore
/// ```no_run
/// use kube::api::{
/// admission::{AdmissionRequest, AdmissionResponse, AdmissionReview},
/// DynamicObject,
/// };
///
/// // The incoming AdmissionReview received by the controller.
/// let body: AdmissionReview<DynamicObject>;
/// let body: AdmissionReview<DynamicObject> = todo!();
/// let req: AdmissionRequest<_> = body.try_into().unwrap();
///
/// // A normal response with no side effects.
Expand Down
2 changes: 1 addition & 1 deletion kube-derive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ proc-macro = true
[dev-dependencies]
serde = { version = "1.0.130", features = ["derive"] }
serde_yaml = "0.8.21"
kube = { path = "../kube", default-features = false, version = "<1.0.0, >=0.61.0", features = ["derive"] }
kube = { path = "../kube", version = "<1.0.0, >=0.61.0", features = ["derive", "client"] }
k8s-openapi = { version = "0.17.0", default-features = false, features = ["v1_26"] }
schemars = { version = "0.8.6", features = ["chrono"] }
validator = { version = "0.16.0", features = ["derive"] }
Expand Down
30 changes: 20 additions & 10 deletions kube-derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,22 @@ mod custom_resource;
/// and optionally status. The **generated** type `Foo` can be used with the [`kube`] crate
/// as an `Api<Foo>` object (`FooSpec` can not be used with [`Api`][`kube::Api`]).
///
/// ```rust,ignore
/// let client = Client::try_default().await?;
/// let foos: Api<Foo> = Api::namespaced(client.clone(), "default");
///
/// ```no_run
/// # use k8s_openapi::apiextensions_apiserver::pkg::apis::apiextensions::v1::CustomResourceDefinition;
/// # use kube_derive::CustomResource;
/// # use kube::{api::{Api, Patch, PatchParams}, Client, CustomResourceExt};
/// # use serde::{Deserialize, Serialize};
/// # async fn wrapper() -> Result<(), Box<dyn std::error::Error>> {
/// # #[derive(CustomResource, Clone, Debug, Deserialize, Serialize, schemars::JsonSchema)]
/// # #[kube(group = "clux.dev", version = "v1", kind = "Foo", namespaced)]
/// # struct FooSpec {}
/// # let client: Client = todo!();
/// let foos: Api<Foo> = Api::default_namespaced(client.clone());
/// let crds: Api<CustomResourceDefinition> = Api::all(client.clone());
/// crds.patch("foos.clux.dev", &ssapply, serde_yaml::to_vec(&Foo::crd())?).await
/// let crd_yaml = serde_yaml::to_vec(&Foo::crd())?;
/// crds.patch("foos.clux.dev", &PatchParams::apply("myapp"), &Patch::Apply(crd_yaml)).await;
/// # Ok(())
/// # }
/// ```
///
/// This example posts the generated `::crd` to the `CustomResourceDefinition` API.
Expand Down Expand Up @@ -177,8 +187,8 @@ mod custom_resource;
///
/// # Generated code
///
/// The example above will roughly generate:
/// ```ignore
/// The example above will **roughly** generate:
/// ```compile_fail
/// #[derive(Serialize, Deserialize, Debug, PartialEq, Clone, JsonSchema)]
/// #[serde(rename_all = "camelCase")]
/// pub struct FooCrd {
Expand All @@ -188,11 +198,11 @@ mod custom_resource;
/// spec: FooSpec,
/// status: Option<FooStatus>,
/// }
/// impl kube::Resource for FooCrd {...}
/// impl kube::Resource for FooCrd { .. }
///
/// impl FooCrd {
/// pub fn new(name: &str, spec: FooSpec) -> Self { ... }
/// pub fn crd() -> k8s_openapi::...::CustomResourceDefinition { ... }
/// pub fn new(name: &str, spec: FooSpec) -> Self { .. }
/// pub fn crd() -> CustomResourceDefinition { .. }
/// }
/// ```
///
Expand Down
2 changes: 1 addition & 1 deletion release.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Release process :: cargo-release >= 0.18.3
#
# Dependencies: cargo-release, cargo-tree, sd, ripgrep
# Dependencies: https://kube.rs/tools
#
# 0. (optional) cargo release minor ; verify readme + changelog bumped; then git reset --hard
# 1. PUBLISH_GRACE_SLEEP=20 cargo release minor --execute
Expand Down
2 changes: 1 addition & 1 deletion scripts/release-post.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ set -euo pipefail

main() {
cd "$(dirname "${BASH_SOURCE[0]}")" && cd .. # aka $WORKSPACE_ROOT
local -r CURRENT_VER="$(rg "kube =" README.md | head -n 1 | rg 'version = "(\S*)"' -or '$1')"
local -r CURRENT_VER="$(rg 'kube = \{ version = "(\S*)"' -or '$1' README.md | head -n1)"
git tag -a "${CURRENT_VER}" -m "${CURRENT_VER}"
git push
git push --tags
Expand Down
4 changes: 2 additions & 2 deletions scripts/release-pre.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ replace-docs() {
}

sanity() {
CARGO_TREE_OPENAPI="$(cargo tree -i k8s-openapi | head -n 1 | choose 1)"
CARGO_TREE_OPENAPI="$(cargo tree -i k8s-openapi --depth=0 -e=normal | choose 1)"
USED_K8S_OPENAPI="${CARGO_TREE_OPENAPI:1}"
RECOMMENDED_K8S_OPENAPI="$(rg "k8s-openapi =" README.md | head -n 1)" # only check first instance
if ! [[ $RECOMMENDED_K8S_OPENAPI =~ $USED_K8S_OPENAPI ]]; then
Expand All @@ -29,7 +29,7 @@ sanity() {
main() {
# We only want this to run ONCE at workspace level
cd "$(dirname "${BASH_SOURCE[0]}")" && cd .. # aka $WORKSPACE_ROOT
local -r CURRENT_VER="$(rg "kube =" README.md | head -n 1 | rg 'version = "(\S*)"' -or '$1')"
local -r CURRENT_VER="$(rg 'kube = \{ version = "(\S*)"' -or '$1' README.md | head -n1)"

# If the main README has been bumped, assume we are done:
if [[ "${NEW_VERSION}" = "${CURRENT_VER}" ]]; then
Expand Down

0 comments on commit 53ad9ee

Please sign in to comment.