From 65c944f334124640551ef595b4c542108be2f518 Mon Sep 17 00:00:00 2001 From: Fabrizio Sestito Date: Mon, 4 Dec 2023 16:19:50 +0100 Subject: [PATCH 1/4] test: add integration tests Signed-off-by: Fabrizio Sestito --- Cargo.toml | 1 + tests/data/pod_creation_flux_cat.json | 174 ++++++++++++++ .../data/pod_with_privileged_containers.json | 173 ++++++++++++++ tests/data/raw_mutation.json | 5 + tests/data/raw_validation.json | 5 + tests/data/service_clusterip.json | 68 ++++++ tests/data/service_loadbalancer.json | 66 ++++++ tests/integration_test.rs | 216 ++++++++++++++++++ 8 files changed, 708 insertions(+) create mode 100644 tests/data/pod_creation_flux_cat.json create mode 100644 tests/data/pod_with_privileged_containers.json create mode 100644 tests/data/raw_mutation.json create mode 100644 tests/data/raw_validation.json create mode 100644 tests/data/service_clusterip.json create mode 100644 tests/data/service_loadbalancer.json create mode 100644 tests/integration_test.rs diff --git a/Cargo.toml b/Cargo.toml index 9f2fad22..e0df8962 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -71,3 +71,4 @@ k8s-openapi = { version = "0.20.0", default-features = false, features = [ ] } rstest = "0.18" test-context = "0.1" +tempfile = "3.8.1" diff --git a/tests/data/pod_creation_flux_cat.json b/tests/data/pod_creation_flux_cat.json new file mode 100644 index 00000000..29a70c1d --- /dev/null +++ b/tests/data/pod_creation_flux_cat.json @@ -0,0 +1,174 @@ +{ + "uid": "1299d386-525b-4032-98ae-1949f69f9cfc", + "kind": { + "group": "", + "version": "v1", + "kind": "Pod" + }, + "resource": { + "group": "", + "version": "v1", + "resource": "pods" + }, + "requestKind": { + "group": "", + "version": "v1", + "kind": "Pod" + }, + "requestResource": { + "group": "", + "version": "v1", + "resource": "pods" + }, + "name": "nginx", + "namespace": "default", + "operation": "CREATE", + "userInfo": { + "username": "kubernetes-admin", + "groups": ["system:masters", "system:authenticated"] + }, + "object": { + "kind": "Pod", + "apiVersion": "v1", + "metadata": { + "name": "nginx", + "namespace": "default", + "uid": "04dc7a5e-e1f1-4e34-8d65-2c9337a43e64", + "creationTimestamp": "2020-11-12T15:18:36Z", + "labels": { + "env": "test" + }, + "annotations": { + "kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"v1\",\"kind\":\"Pod\",\"metadata\":{\"annotations\":{},\"labels\":{\"env\":\"test\"},\"name\":\"nginx\",\"namespace\":\"default\"},\"spec\":{\"containers\":[{\"image\":\"nginx\",\"imagePullPolicy\":\"IfNotPresent\",\"name\":\"nginx\"}],\"tolerations\":[{\"effect\":\"NoSchedule\",\"key\":\"example-key\",\"operator\":\"Exists\"}]}}\n", + "fluxcd.io/cat": "felix" + }, + "managedFields": [ + { + "manager": "kubectl", + "operation": "Update", + "apiVersion": "v1", + "time": "2020-11-12T15:18:36Z", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + ".": {}, + "f:kubectl.kubernetes.io/last-applied-configuration": {} + }, + "f:labels": { + ".": {}, + "f:env": {} + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {}, + "f:tolerations": {} + } + } + } + ] + }, + "spec": { + "volumes": [ + { + "name": "default-token-pvpz7", + "secret": { + "secretName": "default-token-pvpz7" + } + } + ], + "containers": [ + { + "name": "sleeping-sidecar", + "image": "alpine", + "command": ["sleep", "1h"], + "resources": {}, + "volumeMounts": [ + { + "name": "default-token-pvpz7", + "readOnly": true, + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount" + } + ], + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "imagePullPolicy": "IfNotPresent" + }, + { + "name": "nginx", + "image": "nginx", + "resources": {}, + "volumeMounts": [ + { + "name": "default-token-pvpz7", + "readOnly": true, + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount" + } + ], + "securityContext": { + "privileged": true + }, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "imagePullPolicy": "IfNotPresent" + } + ], + "restartPolicy": "Always", + "terminationGracePeriodSeconds": 30, + "dnsPolicy": "ClusterFirst", + "serviceAccountName": "default", + "serviceAccount": "default", + "securityContext": {}, + "schedulerName": "default-scheduler", + "tolerations": [ + { + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "effect": "NoExecute", + "tolerationSeconds": 300 + }, + { + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "effect": "NoExecute", + "tolerationSeconds": 300 + }, + { + "key": "dedicated", + "operator": "Equal", + "value": "tenantA", + "effect": "NoSchedule" + } + ], + "priority": 0, + "enableServiceLinks": true, + "preemptionPolicy": "PreemptLowerPriority" + }, + "status": { + "phase": "Pending", + "qosClass": "BestEffort" + } + }, + "oldObject": null, + "dryRun": false, + "options": { + "kind": "CreateOptions", + "apiVersion": "meta.k8s.io/v1" + } +} diff --git a/tests/data/pod_with_privileged_containers.json b/tests/data/pod_with_privileged_containers.json new file mode 100644 index 00000000..2ab2ee8c --- /dev/null +++ b/tests/data/pod_with_privileged_containers.json @@ -0,0 +1,173 @@ +{ + "uid": "1299d386-525b-4032-98ae-1949f69f9cfc", + "kind": { + "group": "", + "version": "v1", + "kind": "Pod" + }, + "resource": { + "group": "", + "version": "v1", + "resource": "pods" + }, + "requestKind": { + "group": "", + "version": "v1", + "kind": "Pod" + }, + "requestResource": { + "group": "", + "version": "v1", + "resource": "pods" + }, + "name": "nginx", + "namespace": "default", + "operation": "CREATE", + "userInfo": { + "username": "kubernetes-admin", + "groups": ["system:masters", "system:authenticated"] + }, + "object": { + "kind": "Pod", + "apiVersion": "v1", + "metadata": { + "name": "nginx", + "namespace": "default", + "uid": "04dc7a5e-e1f1-4e34-8d65-2c9337a43e64", + "creationTimestamp": "2020-11-12T15:18:36Z", + "labels": { + "env": "test" + }, + "annotations": { + "kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"v1\",\"kind\":\"Pod\",\"metadata\":{\"annotations\":{},\"labels\":{\"env\":\"test\"},\"name\":\"nginx\",\"namespace\":\"default\"},\"spec\":{\"containers\":[{\"image\":\"nginx\",\"imagePullPolicy\":\"IfNotPresent\",\"name\":\"nginx\"}],\"tolerations\":[{\"effect\":\"NoSchedule\",\"key\":\"example-key\",\"operator\":\"Exists\"}]}}\n" + }, + "managedFields": [ + { + "manager": "kubectl", + "operation": "Update", + "apiVersion": "v1", + "time": "2020-11-12T15:18:36Z", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + ".": {}, + "f:kubectl.kubernetes.io/last-applied-configuration": {} + }, + "f:labels": { + ".": {}, + "f:env": {} + } + }, + "f:spec": { + "f:containers": { + "k:{\"name\":\"nginx\"}": { + ".": {}, + "f:image": {}, + "f:imagePullPolicy": {}, + "f:name": {}, + "f:resources": {}, + "f:terminationMessagePath": {}, + "f:terminationMessagePolicy": {} + } + }, + "f:dnsPolicy": {}, + "f:enableServiceLinks": {}, + "f:restartPolicy": {}, + "f:schedulerName": {}, + "f:securityContext": {}, + "f:terminationGracePeriodSeconds": {}, + "f:tolerations": {} + } + } + } + ] + }, + "spec": { + "volumes": [ + { + "name": "default-token-pvpz7", + "secret": { + "secretName": "default-token-pvpz7" + } + } + ], + "containers": [ + { + "name": "sleeping-sidecar", + "image": "alpine", + "command": ["sleep", "1h"], + "resources": {}, + "volumeMounts": [ + { + "name": "default-token-pvpz7", + "readOnly": true, + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount" + } + ], + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "imagePullPolicy": "IfNotPresent" + }, + { + "name": "nginx", + "image": "nginx", + "resources": {}, + "volumeMounts": [ + { + "name": "default-token-pvpz7", + "readOnly": true, + "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount" + } + ], + "securityContext": { + "privileged": true + }, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "imagePullPolicy": "IfNotPresent" + } + ], + "restartPolicy": "Always", + "terminationGracePeriodSeconds": 30, + "dnsPolicy": "ClusterFirst", + "serviceAccountName": "default", + "serviceAccount": "default", + "securityContext": {}, + "schedulerName": "default-scheduler", + "tolerations": [ + { + "key": "node.kubernetes.io/not-ready", + "operator": "Exists", + "effect": "NoExecute", + "tolerationSeconds": 300 + }, + { + "key": "node.kubernetes.io/unreachable", + "operator": "Exists", + "effect": "NoExecute", + "tolerationSeconds": 300 + }, + { + "key": "dedicated", + "operator": "Equal", + "value": "tenantA", + "effect": "NoSchedule" + } + ], + "priority": 0, + "enableServiceLinks": true, + "preemptionPolicy": "PreemptLowerPriority" + }, + "status": { + "phase": "Pending", + "qosClass": "BestEffort" + } + }, + "oldObject": null, + "dryRun": false, + "options": { + "kind": "CreateOptions", + "apiVersion": "meta.k8s.io/v1" + } +} diff --git a/tests/data/raw_mutation.json b/tests/data/raw_mutation.json new file mode 100644 index 00000000..0d0d7b51 --- /dev/null +++ b/tests/data/raw_mutation.json @@ -0,0 +1,5 @@ +{ + "user": "tonio", + "action": "eats", + "resource": "banana" +} diff --git a/tests/data/raw_validation.json b/tests/data/raw_validation.json new file mode 100644 index 00000000..78e795e9 --- /dev/null +++ b/tests/data/raw_validation.json @@ -0,0 +1,5 @@ +{ + "user": "tonio", + "action": "eats", + "resource": "hay" +} diff --git a/tests/data/service_clusterip.json b/tests/data/service_clusterip.json new file mode 100644 index 00000000..91ea8db2 --- /dev/null +++ b/tests/data/service_clusterip.json @@ -0,0 +1,68 @@ +{ + "uid": "1299d386-525b-4032-98ae-1949f69f9cfc", + "kind": { + "group": "", + "version": "v1", + "kind": "Service" + }, + "resource": { + "group": "", + "version": "v1", + "resource": "services" + }, + "requestKind": { + "group": "", + "version": "v1", + "kind": "Service" + }, + "requestResource": { + "group": "", + "version": "v1", + "resource": "services" + }, + "name": "nginx", + "namespace": "default", + "operation": "CREATE", + "userInfo": { + "username": "kubernetes-admin", + "groups": ["system:masters", "system:authenticated"] + }, + "object": { + "kind": "Service", + "apiVersion": "v1", + "metadata": { + "name": "nginx", + "namespace": "default", + "uid": "04dc7a5e-e1f1-4e34-8d65-2c9337a43e64", + "creationTimestamp": "2020-11-12T15:18:36Z", + "labels": { + "env": "test" + } + }, + "spec": { + "clusterIP": "10.43.22.39", + "clusterIPs": ["10.43.22.39"], + "ports": [ + { + "port": 80, + "protocol": "TCP", + "targetPort": 7878 + } + ], + "selector": { + "app": "nginx" + }, + "sessionAffinity": "None", + "type": "ClusterIP" + }, + "status": { + "loadBalancer": {} + } + }, + "oldObject": null, + "dryRun": false, + "options": { + "kind": "CreateOptions", + "apiVersion": "meta.k8s.io/v1" + } +} diff --git a/tests/data/service_loadbalancer.json b/tests/data/service_loadbalancer.json new file mode 100644 index 00000000..9e74fc04 --- /dev/null +++ b/tests/data/service_loadbalancer.json @@ -0,0 +1,66 @@ +{ + "uid": "1299d386-525b-4032-98ae-1949f69f9cfc", + "kind": { + "group": "", + "version": "v1", + "kind": "Service" + }, + "resource": { + "group": "", + "version": "v1", + "resource": "services" + }, + "requestKind": { + "group": "", + "version": "v1", + "kind": "Service" + }, + "requestResource": { + "group": "", + "version": "v1", + "resource": "services" + }, + "name": "nginx", + "namespace": "default", + "operation": "CREATE", + "userInfo": { + "username": "kubernetes-admin", + "groups": ["system:masters", "system:authenticated"] + }, + "object": { + "kind": "Service", + "apiVersion": "v1", + "metadata": { + "name": "nginx", + "namespace": "default", + "uid": "04dc7a5e-e1f1-4e34-8d65-2c9337a43e64", + "creationTimestamp": "2020-11-12T15:18:36Z", + "labels": { + "env": "test" + } + }, + "spec": { + "selector": { + "app": "nginx" + }, + "sessionAffinity": "None", + "type": "LoadBalancer", + "ports": [ + { + "port": 80, + "targetPort": 80, + "nodePort": 30080 + } + ] + }, + "status": { + "loadBalancer": {} + } + }, + "oldObject": null, + "dryRun": false, + "options": { + "kind": "CreateOptions", + "apiVersion": "meta.k8s.io/v1" + } +} diff --git a/tests/integration_test.rs b/tests/integration_test.rs new file mode 100644 index 00000000..9025d4d4 --- /dev/null +++ b/tests/integration_test.rs @@ -0,0 +1,216 @@ +#![allow(clippy::too_many_arguments)] + +use rstest::*; +use serde_json::json; + +use policy_evaluator::{ + admission_request::AdmissionRequest, + admission_response::AdmissionResponseStatus, + evaluation_context::EvaluationContext, + policy_evaluator::{PolicyExecutionMode, ValidateRequest}, + policy_evaluator_builder::PolicyEvaluatorBuilder, +}; +use policy_fetcher::PullDestination; + +#[rstest] +#[case::wapc( + PolicyExecutionMode::KubewardenWapc, + "ghcr.io/kubewarden/tests/pod-privileged:v0.2.1", + json!({}), + "pod_with_privileged_containers.json", + false, + false, + Some("Privileged container is not allowed".to_owned()), + None, + false +)] +#[case::gatekeeper( + PolicyExecutionMode::OpaGatekeeper, + "ghcr.io/kubewarden/tests/disallow-service-loadbalancer:v0.1.5", + json!({}), + "service_loadbalancer.json", + false, + false, + Some("Service of type LoadBalancer are not allowed".to_owned()), + None, + false +)] +#[case::wasi( + PolicyExecutionMode::Wasi, + "ghcr.io/kubewarden/tests/go-wasi-template:v0.1.0", + json!({ + "requiredAnnotations": { + "fluxcd.io/cat": "felix" + } + }), + "pod_creation_flux_cat.json", + false, + true, + None, + None, + false +)] +#[case::wasi_mutating( + PolicyExecutionMode::Wasi, + "ghcr.io/kubewarden/tests/go-wasi-template:v0.1.0", + json!({ + "requiredAnnotations": { + "fluxcd.io/cat": "felix" + } + }), + "service_clusterip.json", + false, + true, + None, + None, + true +)] +#[case::wapc_raw( + PolicyExecutionMode::KubewardenWapc, + "ghcr.io/kubewarden/tests/raw-validation-policy:v0.1.0", + json!({ + "validUsers": ["tonio", "wanda"], + "validActions": ["eats", "likes"], + "validResources": ["banana", "hay"], + }), + "raw_validation.json", + true, + true, + None, + None, + false +)] +#[case::wapc_raw_mutating( + PolicyExecutionMode::KubewardenWapc, + "ghcr.io/kubewarden/tests/raw-mutation-policy:v0.1.0", + json!({ + "forbiddenResources": ["banana", "carrot"], + "defaultResource": "hay", + }), + "raw_mutation.json", + true, + true, + None, + None, + true +)] +#[case::opa_raw( + PolicyExecutionMode::Opa, + "ghcr.io/kubewarden/tests/raw-validation-opa-policy:v0.1.0", + json!({}), + "raw_validation.json", + true, + true, + None, + None, + false +)] +#[case::wasi_raw( + PolicyExecutionMode::Wasi, + "ghcr.io/kubewarden/tests/raw-validation-wasi-policy:v0.1.0", + json!({ + "validUsers": ["tonio", "wanda"], + "validActions": ["eats", "likes"], + "validResources": ["banana", "hay"], + }), + "raw_validation.json", + true, + true, + None, + None, + false +)] +#[case::wasi_raw_mutating( + PolicyExecutionMode::Wasi, + "ghcr.io/kubewarden/tests/raw-mutation-wasi-policy:v0.1.0", + json!({ + "forbiddenResources": ["banana", "carrot"], + "defaultResource": "hay", + }), + "raw_mutation.json", + true, + true, + None, + None, + true +)] +#[tokio::test] +async fn test_policy_evaluator( + #[case] execution_mode: PolicyExecutionMode, + #[case] policy_uri: &str, + #[case] settings: serde_json::Value, + #[case] request_file_path: &str, + #[case] raw: bool, + #[case] allowed: bool, + #[case] message: Option, + #[case] code: Option, + #[case] mutating: bool, +) { + let tempdir = tempfile::TempDir::new().expect("cannot create tempdir"); + let policy = policy_evaluator::policy_fetcher::fetch_policy( + policy_uri, + PullDestination::LocalFile(tempdir.into_path()), + None, + ) + .await + .expect("cannot fetch policy"); + + let eval_ctx = EvaluationContext { + policy_id: "test".to_string(), + callback_channel: None, + ctx_aware_resources_allow_list: Default::default(), + }; + + let policy_evaluator_builder = PolicyEvaluatorBuilder::new() + .execution_mode(execution_mode) + .policy_file(&policy.local_path) + .expect("cannot read policy file") + .enable_wasmtime_cache() + .enable_epoch_interruptions(1, 2); + + let policy_evaluator_pre = policy_evaluator_builder + .build_pre() + .expect("cannot build policy evaluator pre"); + let mut policy_evaluator = policy_evaluator_pre + .rehydrate(&eval_ctx) + .expect("cannot rehydrate policy evaluator"); + + let request_file_path = std::path::Path::new(env!("CARGO_MANIFEST_DIR")) + .join("tests/data") + .join(request_file_path); + let request_data = std::fs::read(request_file_path).expect("cannot read request file"); + let request_json = serde_json::from_slice(&request_data).expect("cannot deserialize request"); + + let validation_request = if raw { + ValidateRequest::Raw(request_json) + } else { + let admission_request: AdmissionRequest = + serde_json::from_value(request_json).expect("cannot deserialize admission request"); + ValidateRequest::AdmissionRequest(admission_request) + }; + + let serde_json::Value::Object(settings) = settings else { + panic!("settings must be an object") + }; + let settings_validation_response = policy_evaluator.validate_settings(&settings); + assert!(settings_validation_response.valid); + + let admission_response = policy_evaluator.validate(validation_request, &settings); + + assert_eq!(allowed, admission_response.allowed); + if allowed { + assert!(admission_response.status.is_none()); + } else { + assert_eq!( + Some(AdmissionResponseStatus { message, code }), + admission_response.status + ); + } + + if mutating { + assert_eq!(Some("JSONPatch".to_owned()), admission_response.patch_type); + assert!(admission_response.patch.is_some()); + } else { + assert!(admission_response.patch.is_none()); + } +} From 1b4456012f30a5656b5d581265ec78cfd176cf24 Mon Sep 17 00:00:00 2001 From: Fabrizio Sestito Date: Tue, 12 Dec 2023 18:11:47 +0100 Subject: [PATCH 2/4] chore: move test_data under tests/data Signed-off-by: Fabrizio Sestito --- src/policy_evaluator/policy_evaluator_builder.rs | 2 +- src/runtimes/rego/context_aware.rs | 2 +- src/runtimes/wapc/runtime.rs | 2 +- {test_data => tests/data}/endless_wasm/.gitignore | 0 {test_data => tests/data}/endless_wasm/Makefile | 0 {test_data => tests/data}/endless_wasm/README.md | 0 {test_data => tests/data}/endless_wasm/wapc_endless_loop.wat | 0 {test_data => tests/data}/endless_wasm/wasm_endless_loop.wat | 0 .../kube_context/deployments/ingress/ingress-nginx.json | 0 .../fixtures/kube_context/deployments/kube-system/coredns.json | 0 .../deployments/kube-system/local-path-provisioner.json | 0 .../data}/fixtures/kube_context/namespaces/cert-manager.json | 0 .../data}/fixtures/kube_context/namespaces/kube-system.json | 0 .../fixtures/kube_context/services/kube-system/kube-dns.json | 0 .../kube_context/services/kube-system/metrics-server.json | 0 15 files changed, 3 insertions(+), 3 deletions(-) rename {test_data => tests/data}/endless_wasm/.gitignore (100%) rename {test_data => tests/data}/endless_wasm/Makefile (100%) rename {test_data => tests/data}/endless_wasm/README.md (100%) rename {test_data => tests/data}/endless_wasm/wapc_endless_loop.wat (100%) rename {test_data => tests/data}/endless_wasm/wasm_endless_loop.wat (100%) rename {test_data => tests/data}/fixtures/kube_context/deployments/ingress/ingress-nginx.json (100%) rename {test_data => tests/data}/fixtures/kube_context/deployments/kube-system/coredns.json (100%) rename {test_data => tests/data}/fixtures/kube_context/deployments/kube-system/local-path-provisioner.json (100%) rename {test_data => tests/data}/fixtures/kube_context/namespaces/cert-manager.json (100%) rename {test_data => tests/data}/fixtures/kube_context/namespaces/kube-system.json (100%) rename {test_data => tests/data}/fixtures/kube_context/services/kube-system/kube-dns.json (100%) rename {test_data => tests/data}/fixtures/kube_context/services/kube-system/metrics-server.json (100%) diff --git a/src/policy_evaluator/policy_evaluator_builder.rs b/src/policy_evaluator/policy_evaluator_builder.rs index 78033731..ade40dd8 100644 --- a/src/policy_evaluator/policy_evaluator_builder.rs +++ b/src/policy_evaluator/policy_evaluator_builder.rs @@ -239,7 +239,7 @@ mod tests { #[test] fn build_policy_evaluator_pre() { let engine = wasmtime::Engine::default(); - let wat = include_bytes!("../../test_data/endless_wasm/wapc_endless_loop.wat"); + let wat = include_bytes!("../../tests/data/endless_wasm/wapc_endless_loop.wat"); let module = wasmtime::Module::new(&engine, wat).expect("cannot compile WAT to wasm"); let policy_evaluator_builder = PolicyEvaluatorBuilder::new() diff --git a/src/runtimes/rego/context_aware.rs b/src/runtimes/rego/context_aware.rs index 622734d9..2d3d83d9 100644 --- a/src/runtimes/rego/context_aware.rs +++ b/src/runtimes/rego/context_aware.rs @@ -123,7 +123,7 @@ pub(crate) mod tests { namespace: Option<&str>, name: &str, ) -> Result { - let path = Path::new("test_data/fixtures/kube_context") + let path = Path::new("tests/data/fixtures/kube_context") .join(resource_type) .join(namespace.unwrap_or_default()) .join(format!("{name}.json")); diff --git a/src/runtimes/wapc/runtime.rs b/src/runtimes/wapc/runtime.rs index ec870049..6ba4d50d 100644 --- a/src/runtimes/wapc/runtime.rs +++ b/src/runtimes/wapc/runtime.rs @@ -190,7 +190,7 @@ mod tests { engine_conf.epoch_interruption(true); let engine = wasmtime::Engine::new(&engine_conf).expect("cannot create wasmtime engine"); - let wat = include_bytes!("../../../test_data/endless_wasm/wapc_endless_loop.wat"); + let wat = include_bytes!("../../../tests/data/endless_wasm/wapc_endless_loop.wat"); let module = wasmtime::Module::new(&engine, wat).expect("cannot compile WAT to wasm"); // Create the wapc engine, the code will be interrupted after 10 ticks diff --git a/test_data/endless_wasm/.gitignore b/tests/data/endless_wasm/.gitignore similarity index 100% rename from test_data/endless_wasm/.gitignore rename to tests/data/endless_wasm/.gitignore diff --git a/test_data/endless_wasm/Makefile b/tests/data/endless_wasm/Makefile similarity index 100% rename from test_data/endless_wasm/Makefile rename to tests/data/endless_wasm/Makefile diff --git a/test_data/endless_wasm/README.md b/tests/data/endless_wasm/README.md similarity index 100% rename from test_data/endless_wasm/README.md rename to tests/data/endless_wasm/README.md diff --git a/test_data/endless_wasm/wapc_endless_loop.wat b/tests/data/endless_wasm/wapc_endless_loop.wat similarity index 100% rename from test_data/endless_wasm/wapc_endless_loop.wat rename to tests/data/endless_wasm/wapc_endless_loop.wat diff --git a/test_data/endless_wasm/wasm_endless_loop.wat b/tests/data/endless_wasm/wasm_endless_loop.wat similarity index 100% rename from test_data/endless_wasm/wasm_endless_loop.wat rename to tests/data/endless_wasm/wasm_endless_loop.wat diff --git a/test_data/fixtures/kube_context/deployments/ingress/ingress-nginx.json b/tests/data/fixtures/kube_context/deployments/ingress/ingress-nginx.json similarity index 100% rename from test_data/fixtures/kube_context/deployments/ingress/ingress-nginx.json rename to tests/data/fixtures/kube_context/deployments/ingress/ingress-nginx.json diff --git a/test_data/fixtures/kube_context/deployments/kube-system/coredns.json b/tests/data/fixtures/kube_context/deployments/kube-system/coredns.json similarity index 100% rename from test_data/fixtures/kube_context/deployments/kube-system/coredns.json rename to tests/data/fixtures/kube_context/deployments/kube-system/coredns.json diff --git a/test_data/fixtures/kube_context/deployments/kube-system/local-path-provisioner.json b/tests/data/fixtures/kube_context/deployments/kube-system/local-path-provisioner.json similarity index 100% rename from test_data/fixtures/kube_context/deployments/kube-system/local-path-provisioner.json rename to tests/data/fixtures/kube_context/deployments/kube-system/local-path-provisioner.json diff --git a/test_data/fixtures/kube_context/namespaces/cert-manager.json b/tests/data/fixtures/kube_context/namespaces/cert-manager.json similarity index 100% rename from test_data/fixtures/kube_context/namespaces/cert-manager.json rename to tests/data/fixtures/kube_context/namespaces/cert-manager.json diff --git a/test_data/fixtures/kube_context/namespaces/kube-system.json b/tests/data/fixtures/kube_context/namespaces/kube-system.json similarity index 100% rename from test_data/fixtures/kube_context/namespaces/kube-system.json rename to tests/data/fixtures/kube_context/namespaces/kube-system.json diff --git a/test_data/fixtures/kube_context/services/kube-system/kube-dns.json b/tests/data/fixtures/kube_context/services/kube-system/kube-dns.json similarity index 100% rename from test_data/fixtures/kube_context/services/kube-system/kube-dns.json rename to tests/data/fixtures/kube_context/services/kube-system/kube-dns.json diff --git a/test_data/fixtures/kube_context/services/kube-system/metrics-server.json b/tests/data/fixtures/kube_context/services/kube-system/metrics-server.json similarity index 100% rename from test_data/fixtures/kube_context/services/kube-system/metrics-server.json rename to tests/data/fixtures/kube_context/services/kube-system/metrics-server.json From e0a4b1da3761cf78a1f27fd185edc2754f1a8772 Mon Sep 17 00:00:00 2001 From: Fabrizio Sestito Date: Wed, 13 Dec 2023 13:41:29 +0100 Subject: [PATCH 3/4] build(Makefile): add unit tests and integration tests target Signed-off-by: Fabrizio Sestito --- Makefile | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Makefile b/Makefile index a118a757..ec78336e 100644 --- a/Makefile +++ b/Makefile @@ -20,6 +20,14 @@ check: test: fmt lint cargo test --workspace +.PHONY: unit-tests +unit-test: fmt lint + cargo test --workspace --lib + +.PHONY: integration-test +integration-tests: fmt lint + cargo test --test '*' + .PHONY: clean clean: cargo clean From 6fabaf0b3c2e343d0e4249156e2d1212d84257d3 Mon Sep 17 00:00:00 2001 From: Fabrizio Sestito Date: Wed, 13 Dec 2023 13:41:49 +0100 Subject: [PATCH 4/4] ci: split unit tests and integration tests Signed-off-by: Fabrizio Sestito --- .github/workflows/tests.yml | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index c9d58289..b37ef8a0 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -24,7 +24,7 @@ jobs: command: check test: - name: Test Suite + name: Unit tests runs-on: ubuntu-latest steps: - uses: actions/checkout@1e31de5234b9f8995739874a8ce0492dc87873e2 # v4.0.0 @@ -36,7 +36,22 @@ jobs: - uses: actions-rs/cargo@844f36862e911db73fe0815f00a4a2602c279505 # v1.0.3 with: command: test - args: --workspace + args: --workspace --lib + + integration-test: + name: Integration tests + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@1e31de5234b9f8995739874a8ce0492dc87873e2 # v4.0.0 + - uses: actions-rs/toolchain@16499b5e05bf2e26879000db0c1d13f7e13fa3af # v1.0.7 + with: + profile: minimal + toolchain: stable + override: true + - uses: actions-rs/cargo@844f36862e911db73fe0815f00a4a2602c279505 # v1.0.3 + with: + command: test + args: --test '*' fmt: name: Rustfmt