diff --git a/.github/actions/e2e-common/exec-tests.sh b/.github/actions/e2e-common/exec-tests.sh index 3a412782cd..3f68f05721 100755 --- a/.github/actions/e2e-common/exec-tests.sh +++ b/.github/actions/e2e-common/exec-tests.sh @@ -137,6 +137,8 @@ else export CAMEL_K_GLOBAL_OPERATOR_NS="default" fi +export CAMEL_K_E2E_FAST_SETUP="true" + # Then run all integration tests rather than ending on first failure set -e exit_code=0 diff --git a/.github/actions/kamel-config-cluster-kind/action.yml b/.github/actions/kamel-config-cluster-kind/action.yml index 96648d8dee..6722ee287d 100644 --- a/.github/actions/kamel-config-cluster-kind/action.yml +++ b/.github/actions/kamel-config-cluster-kind/action.yml @@ -23,7 +23,7 @@ runs: steps: - id: install-cluster name: Install Cluster - uses: container-tools/kind-action@v2.0.3 + uses: container-tools/kind-action@v2.0.4 if: ${{ env.CLUSTER_KIND_CONFIGURED != 'true' }} with: version: v0.19.0 diff --git a/.github/actions/kamel-prepare-env/action.yml b/.github/actions/kamel-prepare-env/action.yml index fd76c31cc2..4fce0bca5c 100644 --- a/.github/actions/kamel-prepare-env/action.yml +++ b/.github/actions/kamel-prepare-env/action.yml @@ -97,7 +97,7 @@ runs: # Install a version of kubectl for generic access to cluster # - id: install-kubectl - uses: azure/setup-kubectl@v3 + uses: azure/setup-kubectl@v4 if: ${{ env.KAMEL_PREPARE_ENV != 'true' }} with: version: 'v1.27.4' diff --git a/.github/actions/release-nightly/action.yml b/.github/actions/release-nightly/action.yml index 49defbd81d..c43ed89599 100644 --- a/.github/actions/release-nightly/action.yml +++ b/.github/actions/release-nightly/action.yml @@ -110,7 +110,6 @@ runs: shell: bash run: | make VERSION=${{ env.VERSION }} IMAGE_NAME=${{ env.IMAGE_NAME }} images-nightly - make IMAGE_ARCH=arm64 VERSION=${{ env.VERSION }} IMAGE_NAME=${{ env.IMAGE_NAME }} images-nightly make VERSION=${{ env.VERSION }} IMAGE_NAME=${{ env.IMAGE_NAME }} release-nightly - name: Generate SBOM diff --git a/.github/workflows/common.yml b/.github/workflows/common.yml index fde4cafa0a..31dacc8f86 100644 --- a/.github/workflows/common.yml +++ b/.github/workflows/common.yml @@ -90,7 +90,7 @@ jobs: -p "${{ github.event.inputs.skip-problematic }}" \ -q "${{ github.event.inputs.log-level }}" \ -t "${{ github.event.inputs.test-filters }}" - - name: Smoke tests + - name: Common tests uses: ./.github/actions/e2e-common with: cluster-config-data: ${{ secrets.E2E_CLUSTER_CONFIG }} diff --git a/.github/workflows/native.yml b/.github/workflows/native.yml index adcb1f4f0f..edeb79905d 100644 --- a/.github/workflows/native.yml +++ b/.github/workflows/native.yml @@ -65,7 +65,7 @@ concurrency: jobs: higher-memory: if: contains(github.event.pull_request.labels.*.name, 'trigger native test') - runs-on: macos-12 + runs-on: ubuntu-latest steps: - name: Checkout code @@ -90,7 +90,8 @@ jobs: lower-memory: if: contains(github.event.pull_request.labels.*.name, 'trigger native test') - runs-on: macos-12 + runs-on: ubuntu-latest + steps: - name: Checkout code diff --git a/.github/workflows/nightly-native-test.yml b/.github/workflows/nightly-native-test.yml index a3a357d2e0..8b1b7bed8b 100644 --- a/.github/workflows/nightly-native-test.yml +++ b/.github/workflows/nightly-native-test.yml @@ -34,7 +34,7 @@ jobs: ref-branch: [main] if: github.repository == 'apache/camel-k' - runs-on: macos-12 + runs-on: ubuntu-latest steps: - name: "Checkout code" uses: actions/checkout@v4 diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 80811f831c..a54e396701 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -51,9 +51,9 @@ jobs: go-version-file: 'go.mod' check-latest: true - name: golangci-lint - uses: golangci/golangci-lint-action@v3 + uses: golangci/golangci-lint-action@v4 env: GOGC: 20 with: - version: v1.53.3 + version: v1.55.2 args: --verbose --deadline 15m --config .golangci.yml diff --git a/.golangci.yml b/.golangci.yml index 78fb370cc5..ac4df3b6c9 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -18,8 +18,10 @@ linters-settings: lll: line-length: 170 - goconst: - ignore-tests: true +run: + tests: false + skip-files: + - test_support.go linters: enable-all: true disable: diff --git a/CHANGELOG.md b/CHANGELOG.md index 701518f4a1..6c65b87d6a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,16 +6,37 @@ **Closed issues:** +- Camelk | AtlasMap Support [\#5261](https://github.com/apache/camel-k/issues/5261) +- release-nightly does not build/push multiarch manifest [\#5252](https://github.com/apache/camel-k/issues/5252) +- XSD might be wrong [\#5250](https://github.com/apache/camel-k/issues/5250) +- Pipe error handler not working with Camel 4.4.0 [\#5242](https://github.com/apache/camel-k/issues/5242) +- Integration builds fail with arm64 base image [\#5238](https://github.com/apache/camel-k/issues/5238) +- Update buil/Dokerfile to use go 1.21 [\#5231](https://github.com/apache/camel-k/issues/5231) +- Error java.lang.ClassNotFoundException: io.quarkus.bootstrap.runner.QuarkusEntryPoint [\#5225](https://github.com/apache/camel-k/issues/5225) +- Deployment Trait maxUnavailable and maxSurge default values differ from documentation and do not support % values [\#5223](https://github.com/apache/camel-k/issues/5223) +- Misleading "Monitor: Integration needs a rebuild" message [\#5219](https://github.com/apache/camel-k/issues/5219) +- Route parameters are ignored for `path` parameters [\#5203](https://github.com/apache/camel-k/issues/5203) +- Flaky `kamel run --dev` test [\#5197](https://github.com/apache/camel-k/issues/5197) +- Builder property failure when using non xml tag characters [\#5195](https://github.com/apache/camel-k/issues/5195) +- Error configuring property: camel.component.test\[00001\]port\[80\]tcp.addr because cannot find component with name test\[00001\]port\[80\]tcp. [\#5179](https://github.com/apache/camel-k/issues/5179) - Get environment variable value is empty in properties file [\#5178](https://github.com/apache/camel-k/issues/5178) +- Install operator image according to the target architecture [\#5169](https://github.com/apache/camel-k/issues/5169) - Debug Integrations failing [\#5161](https://github.com/apache/camel-k/issues/5161) +- Multiple crons at the same Integration do not run as expected [\#5158](https://github.com/apache/camel-k/issues/5158) +- Kamel delete KameletBinding only removes integration resource [\#5156](https://github.com/apache/camel-k/issues/5156) - Performance regression due to configmap/secrets whole cluster watch [\#5143](https://github.com/apache/camel-k/issues/5143) +- Running integrations fail when the used registry has a port other than default 80 [\#5141](https://github.com/apache/camel-k/issues/5141) - camel-jackson configure configure "autoDiscoverObjectMapper" property for non-spring boot application [\#5140](https://github.com/apache/camel-k/issues/5140) +- Update github actions to a version that use node 20 [\#5130](https://github.com/apache/camel-k/issues/5130) +- Monitor Camel Integrations in K8s Deployments [\#5120](https://github.com/apache/camel-k/issues/5120) - Integrations remain in Initialization loop when referenced config map has owner references [\#5114](https://github.com/apache/camel-k/issues/5114) - Externally built Integrations are deployed without a command in Camel-K 2.2.0 [\#5112](https://github.com/apache/camel-k/issues/5112) - Coverage report wrong percentage [\#5108](https://github.com/apache/camel-k/issues/5108) - Add possibility to configure annotation for the builder pods [\#5106](https://github.com/apache/camel-k/issues/5106) - Include the operator node-selector in the helm chart [\#5103](https://github.com/apache/camel-k/issues/5103) - TestCreateCatalog fail when DEFAULT\_RUNTIME\_VERSION=3.6.0-SNAPSHOT [\#5099](https://github.com/apache/camel-k/issues/5099) +- Remove secondary IntegrationPlatform in favor of using IntegrationProfile settings [\#5097](https://github.com/apache/camel-k/issues/5097) +- Basic example fails on Docker Desktop MacOS [\#5095](https://github.com/apache/camel-k/issues/5095) - Quartz builds failing to start when using native builds [\#5088](https://github.com/apache/camel-k/issues/5088) - Ability to set different resources for jvm and native containers when both are used in the same Integration [\#5065](https://github.com/apache/camel-k/issues/5065) - Don't run dependabot on forked repos [\#5063](https://github.com/apache/camel-k/issues/5063) @@ -26,18 +47,26 @@ - Nightly check against latest runtime failure [\#5042](https://github.com/apache/camel-k/issues/5042) - Provide a page linking to Camel DSLs [\#5037](https://github.com/apache/camel-k/issues/5037) - Nightly SBOM procedure should not run if there are no changes [\#5033](https://github.com/apache/camel-k/issues/5033) +- Polish trait conditions [\#5027](https://github.com/apache/camel-k/issues/5027) - Nightly release soft failure [\#5023](https://github.com/apache/camel-k/issues/5023) - \[Discussion\] Camel K 2024 roadmap [\#5019](https://github.com/apache/camel-k/issues/5019) - Unable to authenticate with Docker Hub API v2 [\#5017](https://github.com/apache/camel-k/issues/5017) - Data type Kamelet hardcoded [\#5014](https://github.com/apache/camel-k/issues/5014) - Quarkus buildMode should sort JVM before Native execution [\#5001](https://github.com/apache/camel-k/issues/5001) - Failing to build native integration [\#5000](https://github.com/apache/camel-k/issues/5000) +- Route diagram not visible in hawtio console: JMX connector not running [\#4990](https://github.com/apache/camel-k/issues/4990) +- Azure Key Vault Trait: Support Azure Identity as authentication method [\#4983](https://github.com/apache/camel-k/issues/4983) +- Move handling of IntegrationPlatformResource to a separate operator [\#4948](https://github.com/apache/camel-k/issues/4948) +- Quarkus native check failing [\#4885](https://github.com/apache/camel-k/issues/4885) - Use generated trait [\#4811](https://github.com/apache/camel-k/issues/4811) +- Upgrade to Go 1.21 [\#4795](https://github.com/apache/camel-k/issues/4795) - Pointer to an external schema/CRD [\#4788](https://github.com/apache/camel-k/issues/4788) - Pipe using simple language expressions causing failure [\#4777](https://github.com/apache/camel-k/issues/4777) - 1st Integration after Camel K runtime version update failing [\#4776](https://github.com/apache/camel-k/issues/4776) - Provide alternative publishing strategy via pipeline [\#4747](https://github.com/apache/camel-k/issues/4747) +- Provide full description for trait in CRD [\#4727](https://github.com/apache/camel-k/issues/4727) - Quarkus native checks failure [\#4723](https://github.com/apache/camel-k/issues/4723) +- Build waiting condition [\#4542](https://github.com/apache/camel-k/issues/4542) - Add DataTypeRegistry as bean in Camel context [\#3845](https://github.com/apache/camel-k/issues/3845) - Remove duplication of the default platform creation [\#3433](https://github.com/apache/camel-k/issues/3433) - Use `go:embed` instead of vfsgen for embedded resources handling [\#3384](https://github.com/apache/camel-k/issues/3384) @@ -46,9 +75,52 @@ **Merged pull requests:** +- feat\(catalog\): support placeholders [\#5268](https://github.com/apache/camel-k/pull/5268) ([squakez](https://github.com/squakez)) +- chore\(deps\): bump github.com/prometheus/common from 0.50.0 to 0.51.0 [\#5267](https://github.com/apache/camel-k/pull/5267) ([dependabot[bot]](https://github.com/apps/dependabot)) +- chore\(trait\): add executed trait condition [\#5266](https://github.com/apache/camel-k/pull/5266) ([squakez](https://github.com/squakez)) +- doc\(trait\): sourceless Integrations [\#5265](https://github.com/apache/camel-k/pull/5265) ([squakez](https://github.com/squakez)) +- chore\(deps\): bump github.com/docker/docker from 24.0.7+incompatible to 24.0.9+incompatible [\#5263](https://github.com/apache/camel-k/pull/5263) ([dependabot[bot]](https://github.com/apps/dependabot)) +- feat\(traits\): builder image platforms [\#5262](https://github.com/apache/camel-k/pull/5262) ([squakez](https://github.com/squakez)) +- chore: Use camel case for Pipe error handler ref [\#5260](https://github.com/apache/camel-k/pull/5260) ([christophd](https://github.com/christophd)) +- fix\(ci\): use ubuntu which now have 16 GB memory [\#5259](https://github.com/apache/camel-k/pull/5259) ([squakez](https://github.com/squakez)) +- chore\(deps\): bump github.com/onsi/gomega from 1.31.1 to 1.32.0 [\#5257](https://github.com/apache/camel-k/pull/5257) ([dependabot[bot]](https://github.com/apps/dependabot)) +- Fix wrong Kamelet sample content [\#5255](https://github.com/apache/camel-k/pull/5255) ([claudio4j](https://github.com/claudio4j)) +- Add Kamelet v1alpha1 sample [\#5254](https://github.com/apache/camel-k/pull/5254) ([claudio4j](https://github.com/claudio4j)) +- \[\#5252\] release-nightly does not build/push multiarch manifest [\#5253](https://github.com/apache/camel-k/pull/5253) ([tdiesler](https://github.com/tdiesler)) +- feat\(trait\): move runtime logic into trait catalog [\#5251](https://github.com/apache/camel-k/pull/5251) ([squakez](https://github.com/squakez)) +- chore\(ci\): Upgrade kind action to 2.0.4 [\#5249](https://github.com/apache/camel-k/pull/5249) ([gansheer](https://github.com/gansheer)) +- chore: propagate capabilities to Kit [\#5247](https://github.com/apache/camel-k/pull/5247) ([squakez](https://github.com/squakez)) +- Azure Key Vault Trait: Support Azure Identity as authentication method [\#5244](https://github.com/apache/camel-k/pull/5244) ([oscerd](https://github.com/oscerd)) +- chore\(ci\): Upgrade setup-kubectl action [\#5243](https://github.com/apache/camel-k/pull/5243) ([gansheer](https://github.com/gansheer)) +- chore\(e2e\): Fix smoke tests [\#5240](https://github.com/apache/camel-k/pull/5240) ([christophd](https://github.com/christophd)) +- chore\(e2e\): Separate common-it E2E tests, so they run more efficient [\#5239](https://github.com/apache/camel-k/pull/5239) ([christophd](https://github.com/christophd)) +- fix\(cmd\): delete KameletBinding until they exists [\#5237](https://github.com/apache/camel-k/pull/5237) ([squakez](https://github.com/squakez)) +- fix\(ctrl\): message digest change [\#5236](https://github.com/apache/camel-k/pull/5236) ([squakez](https://github.com/squakez)) +- fix\(build\): Upgrade container image to golang 1.21 [\#5235](https://github.com/apache/camel-k/pull/5235) ([gansheer](https://github.com/gansheer)) +- \[Regression\] fix\(quarkus\): don't override application.properties [\#5234](https://github.com/apache/camel-k/pull/5234) ([squakez](https://github.com/squakez)) +- fix\(trait\): revert persisted status [\#5233](https://github.com/apache/camel-k/pull/5233) ([squakez](https://github.com/squakez)) +- chore\(deps\): bump github.com/prometheus/common from 0.48.0 to 0.50.0 [\#5232](https://github.com/apache/camel-k/pull/5232) ([dependabot[bot]](https://github.com/apps/dependabot)) +- fix\(traits\): use Comparable matches [\#5230](https://github.com/apache/camel-k/pull/5230) ([squakez](https://github.com/squakez)) +- fix\(trait\): Add documentation and test on multiple sources [\#5229](https://github.com/apache/camel-k/pull/5229) ([gansheer](https://github.com/gansheer)) +- chore\(deps\): bump github.com/cloudevents/sdk-go/v2 from 2.13.0 to 2.15.2 [\#5228](https://github.com/apache/camel-k/pull/5228) ([dependabot[bot]](https://github.com/apps/dependabot)) +- chore\(lint\): Update golangci-lint version to 1.55 [\#5227](https://github.com/apache/camel-k/pull/5227) ([christophd](https://github.com/christophd)) +- fix\(ci\): swap deprecation notice [\#5226](https://github.com/apache/camel-k/pull/5226) ([squakez](https://github.com/squakez)) +- fix\(trait\): changing data type for rollingUpdateMaxSurge and rollingU… [\#5224](https://github.com/apache/camel-k/pull/5224) ([lsergio](https://github.com/lsergio)) +- chore\(traits\): deprecate registry [\#5222](https://github.com/apache/camel-k/pull/5222) ([squakez](https://github.com/squakez)) +- feat\(ci\): upgrade golang to 1.21 [\#5221](https://github.com/apache/camel-k/pull/5221) ([squakez](https://github.com/squakez)) +- fix\(trait\): watch for resource versions... [\#5218](https://github.com/apache/camel-k/pull/5218) ([squakez](https://github.com/squakez)) +- chore\(deps\): bump golang.org/x/oauth2 from 0.17.0 to 0.18.0 [\#5214](https://github.com/apache/camel-k/pull/5214) ([dependabot[bot]](https://github.com/apps/dependabot)) +- fix\(ci\): add snapshot repo [\#5209](https://github.com/apache/camel-k/pull/5209) ([squakez](https://github.com/squakez)) +- chore\(deps\): bump github.com/stretchr/testify from 1.8.4 to 1.9.0 [\#5208](https://github.com/apache/camel-k/pull/5208) ([dependabot[bot]](https://github.com/apps/dependabot)) +- fix\(e2e\): stricter pipe test check [\#5202](https://github.com/apache/camel-k/pull/5202) ([squakez](https://github.com/squakez)) +- fix\(trait\): deprecate operator inspecting secrets [\#5201](https://github.com/apache/camel-k/pull/5201) ([squakez](https://github.com/squakez)) +- Install operator image according to the target architecture [\#5200](https://github.com/apache/camel-k/pull/5200) ([tdiesler](https://github.com/tdiesler)) +- fix\(trait\): catalog to drive dependencies [\#5199](https://github.com/apache/camel-k/pull/5199) ([squakez](https://github.com/squakez)) +- fix\(quarkus\): build time properties into file [\#5198](https://github.com/apache/camel-k/pull/5198) ([squakez](https://github.com/squakez)) - chore\(deps\): bump github.com/prometheus/client\_golang from 1.18.0 to 1.19.0 [\#5193](https://github.com/apache/camel-k/pull/5193) ([dependabot[bot]](https://github.com/apps/dependabot)) - update quarkus-native.adoc [\#5190](https://github.com/apache/camel-k/pull/5190) ([bvahdat](https://github.com/bvahdat)) - chore: use constants for config types [\#5189](https://github.com/apache/camel-k/pull/5189) ([squakez](https://github.com/squakez)) +- chore\(e2e\): Improve E2E tests [\#5188](https://github.com/apache/camel-k/pull/5188) ([christophd](https://github.com/christophd)) - fix\(builder\): strenghten matching dependencies heuristic [\#5187](https://github.com/apache/camel-k/pull/5187) ([squakez](https://github.com/squakez)) - chore\(knative\): configure via properties [\#5186](https://github.com/apache/camel-k/pull/5186) ([squakez](https://github.com/squakez)) - chore\(cmd\): deprecate -d file feature [\#5185](https://github.com/apache/camel-k/pull/5185) ([squakez](https://github.com/squakez)) @@ -67,6 +139,7 @@ - chore\(deps\): bump github.com/prometheus/common from 0.46.0 to 0.47.0 [\#5159](https://github.com/apache/camel-k/pull/5159) ([dependabot[bot]](https://github.com/apps/dependabot)) - feat\(build\): Add Build waiting condition [\#5157](https://github.com/apache/camel-k/pull/5157) ([gansheer](https://github.com/gansheer)) - Reduce write to hash, prepare string from secret, configmap [\#5155](https://github.com/apache/camel-k/pull/5155) ([lfabriko](https://github.com/lfabriko)) +- \[chore\] improve metrics for integration [\#5154](https://github.com/apache/camel-k/pull/5154) ([lgarciaaco](https://github.com/lgarciaaco)) - feat\(traits\): persist generated status [\#5153](https://github.com/apache/camel-k/pull/5153) ([squakez](https://github.com/squakez)) - fix\(core\): Externally built Integrations run command configuration from jvm trait [\#5151](https://github.com/apache/camel-k/pull/5151) ([gansheer](https://github.com/gansheer)) - fix\(ci\): Java required by automatic-updates [\#5150](https://github.com/apache/camel-k/pull/5150) ([gansheer](https://github.com/gansheer)) diff --git a/README.adoc b/README.adoc index e335e9edf4..6f602ad4e3 100644 --- a/README.adoc +++ b/README.adoc @@ -11,7 +11,7 @@ image:https://github.com/apache/camel-k/workflows/kubernetes/badge.svg["Kubernet image:https://github.com/apache/camel-k/workflows/knative/badge.svg["Knative", link="https://github.com/apache/camel-k/actions/workflows/knative.yml"] image:https://github.com/apache/camel-k/actions/workflows/nightly-release.yml/badge.svg["Nightly releases", link="https://github.com/apache/camel-k/actions/workflows/nightly-release.yml"] image:https://github.com/apache/camel-k/actions/workflows/nightly-native-test.yml/badge.svg["Quarkus native", link="https://github.com/apache/camel-k/actions/workflows/nightly-native-test.yml"] -image:https://img.shields.io/badge/Coverage-36.2%25-yellow.svg["Go coverage", link="https://github.com/apache/camel-k/actions/workflows/nightly-coverage.yml"] +image:https://img.shields.io/badge/Coverage-37.2%25-yellow.svg["Go coverage", link="https://github.com/apache/camel-k/actions/workflows/nightly-coverage.yml"] image:https://img.shields.io/badge/zulip-join_chat-brightgreen.svg["Chat on Zulip", link="https://camel.zulipchat.com"] Apache Camel K is a lightweight integration framework built from **Apache Camel** that runs natively on Kubernetes and is specifically designed for serverless and microservice architectures. Users of `Camel K` can instantly run integration code written in Camel DSL on their preferred **Cloud** provider. diff --git a/addons/keda/keda_test.go b/addons/keda/keda_test.go index d43ed1f63b..cc2bc95c0a 100644 --- a/addons/keda/keda_test.go +++ b/addons/keda/keda_test.go @@ -32,6 +32,7 @@ import ( "github.com/apache/camel-k/v2/pkg/util/test" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -53,10 +54,10 @@ func TestManualConfig(t *testing.T) { env := createBasicTestEnvironment() res, condition, err := keda.Configure(env) - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, res) assert.Nil(t, condition) - assert.NoError(t, keda.Apply(env)) + require.NoError(t, keda.Apply(env)) so := getScaledObject(env) assert.NotNil(t, so) assert.Len(t, so.Spec.Triggers, 1) @@ -92,10 +93,10 @@ func TestConfigFromSecret(t *testing.T) { }) res, condition, err := keda.Configure(env) - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, res) assert.Nil(t, condition) - assert.NoError(t, keda.Apply(env)) + require.NoError(t, keda.Apply(env)) so := getScaledObject(env) assert.NotNil(t, so) assert.Len(t, so.Spec.Triggers, 1) @@ -180,10 +181,10 @@ func TestKameletAutoDetection(t *testing.T) { }) res, condition, err := keda.Configure(env) - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, res) assert.Nil(t, condition) - assert.NoError(t, keda.Apply(env)) + require.NoError(t, keda.Apply(env)) so := getScaledObject(env) assert.NotNil(t, so) assert.Len(t, so.Spec.Triggers, 1) @@ -281,24 +282,24 @@ func TestPipeAutoDetection(t *testing.T) { }) it, err := pipe.CreateIntegrationFor(env.Ctx, env.Client, &klb) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, it) env.Integration = it it.Status.Phase = camelv1.IntegrationPhaseInitialization init := trait.NewInitTrait() ok, condition, err := init.Configure(env) - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, ok) assert.Nil(t, condition) - assert.NoError(t, init.Apply(env)) + require.NoError(t, init.Apply(env)) it.Status.Phase = camelv1.IntegrationPhaseDeploying res, condition, err := keda.Configure(env) - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, res) assert.Nil(t, condition) - assert.NoError(t, keda.Apply(env)) + require.NoError(t, keda.Apply(env)) so := getScaledObject(env) assert.NotNil(t, so) assert.Len(t, so.Spec.Triggers, 1) @@ -345,14 +346,14 @@ func TestHackReplicas(t *testing.T) { ) res, condition, err := keda.Configure(env) - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, res) assert.Nil(t, condition) - assert.NoError(t, keda.Apply(env)) + require.NoError(t, keda.Apply(env)) scalesClient, err := env.Client.ScalesClient() - assert.NoError(t, err) + require.NoError(t, err) sc, err := scalesClient.Scales("test").Get(env.Ctx, camelv1.SchemeGroupVersion.WithResource("integrations").GroupResource(), "my-it", metav1.GetOptions{}) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, int32(1), sc.Spec.Replicas) } @@ -393,14 +394,14 @@ func TestHackKLBReplicas(t *testing.T) { ) res, condition, err := keda.Configure(env) - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, res) assert.Nil(t, condition) - assert.NoError(t, keda.Apply(env)) + require.NoError(t, keda.Apply(env)) scalesClient, err := env.Client.ScalesClient() - assert.NoError(t, err) + require.NoError(t, err) sc, err := scalesClient.Scales("test").Get(env.Ctx, camelv1.SchemeGroupVersion.WithResource("pipes").GroupResource(), "my-klb", metav1.GetOptions{}) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, int32(1), sc.Spec.Replicas) } diff --git a/addons/master/master.go b/addons/master/master.go index b28730784b..476f68bf8a 100644 --- a/addons/master/master.go +++ b/addons/master/master.go @@ -112,7 +112,7 @@ func (t *masterTrait) Configure(e *trait.Environment) (bool, *trait.TraitConditi } } if !pointer.BoolDeref(t.Enabled, false) { - return false, trait.NewIntegrationConditionUserDisabled(), nil + return false, trait.NewIntegrationConditionUserDisabled("Master"), nil } if t.IncludeDelegateDependencies == nil || *t.IncludeDelegateDependencies { t.delegateDependencies = findAdditionalDependencies(e, meta) diff --git a/addons/strimzi/strimzi_test.go b/addons/strimzi/strimzi_test.go index ba35e19412..92d7a061bc 100644 --- a/addons/strimzi/strimzi_test.go +++ b/addons/strimzi/strimzi_test.go @@ -29,6 +29,7 @@ import ( "github.com/apache/camel-k/v2/pkg/util/bindings" "github.com/apache/camel-k/v2/pkg/util/test" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -38,7 +39,7 @@ func TestStrimziDirect(t *testing.T) { defer cancel() client, err := test.NewFakeClient() - assert.NoError(t, err) + require.NoError(t, err) bindingContext := bindings.BindingContext{ Ctx: ctx, @@ -61,7 +62,7 @@ func TestStrimziDirect(t *testing.T) { binding, err := BindingProvider{}.Translate(bindingContext, bindings.EndpointContext{ Type: camelv1.EndpointTypeSink, }, endpoint) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, binding) assert.Equal(t, "kafka:mytopic?brokers=my-cluster-kafka-bootstrap%3A9092", binding.URI) assert.Equal(t, camelv1.Traits{}, binding.Traits) @@ -121,7 +122,7 @@ func TestStrimziLookup(t *testing.T) { binding, err := provider.Translate(bindingContext, bindings.EndpointContext{ Type: camelv1.EndpointTypeSink, }, endpoint) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, binding) assert.Equal(t, "kafka:mytopicy?brokers=my-clusterx-kafka-bootstrap%3A9092", binding.URI) assert.Equal(t, camelv1.Traits{}, binding.Traits) diff --git a/addons/telemetry/discovery/locator.go b/addons/telemetry/discovery/locator.go index ec30a808b9..94cf94f3de 100644 --- a/addons/telemetry/discovery/locator.go +++ b/addons/telemetry/discovery/locator.go @@ -30,5 +30,5 @@ var TelemetryLocators []TelemetryLocator // TelemetryLocator is able to find the address of an available telemetry OTLP endpoint. type TelemetryLocator interface { - FindEndpoint(context.Context, client.Client, log.Logger, *trait.Environment) (string, error) + FindEndpoint(ctx context.Context, c client.Client, logger log.Logger, env *trait.Environment) (string, error) } diff --git a/addons/telemetry/telemetry.go b/addons/telemetry/telemetry.go index a3975bd047..e77f8b97b1 100644 --- a/addons/telemetry/telemetry.go +++ b/addons/telemetry/telemetry.go @@ -103,6 +103,7 @@ func (t *telemetryTrait) Configure(e *trait.Environment) (bool, *trait.TraitCond if endpoint != "" { t.L.Infof("Using tracing endpoint: %s", endpoint) condition = trait.NewIntegrationCondition( + "Telemetry", v1.IntegrationConditionTraitInfo, corev1.ConditionTrue, "TracingEndpoint", diff --git a/addons/telemetry/telemetry_test.go b/addons/telemetry/telemetry_test.go index c15af2894d..3f4428b46a 100644 --- a/addons/telemetry/telemetry_test.go +++ b/addons/telemetry/telemetry_test.go @@ -28,6 +28,7 @@ import ( "github.com/apache/camel-k/v2/pkg/util/camel" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestTelemetryTraitOnDefaultQuarkus(t *testing.T) { @@ -37,12 +38,12 @@ func TestTelemetryTraitOnDefaultQuarkus(t *testing.T) { tt.Enabled = pointer.Bool(true) tt.Endpoint = "http://endpoint3" ok, condition, err := telemetry.Configure(e) - assert.Nil(t, err) + require.NoError(t, err) assert.True(t, ok) assert.Nil(t, condition) err = telemetry.Apply(e) - assert.Nil(t, err) + require.NoError(t, err) assert.Empty(t, e.ApplicationProperties["quarkus.opentelemetry.enabled"]) assert.Equal(t, "http://endpoint3", e.ApplicationProperties["quarkus.opentelemetry.tracer.exporter.otlp.endpoint"]) @@ -63,12 +64,12 @@ func TestTelemetryTraitWithValues(t *testing.T) { tt.SamplerRatio = "0.001" tt.SamplerParentBased = pointer.Bool(false) ok, condition, err := telemetry.Configure(e) - assert.Nil(t, err) + require.NoError(t, err) assert.True(t, ok) assert.Nil(t, condition) err = telemetry.Apply(e) - assert.Nil(t, err) + require.NoError(t, err) assert.Empty(t, e.ApplicationProperties["quarkus.opentelemetry.enabled"]) assert.Equal(t, "http://endpoint3", e.ApplicationProperties["quarkus.opentelemetry.tracer.exporter.otlp.endpoint"]) @@ -82,7 +83,7 @@ func createEnvironment(t *testing.T, catalogGen func() (*camel.RuntimeCatalog, e t.Helper() catalog, err := catalogGen() - assert.Nil(t, err) + require.NoError(t, err) e := trait.Environment{ CamelCatalog: catalog, diff --git a/addons/threescale/3scale_test.go b/addons/threescale/3scale_test.go index d7a3a35c2c..65a934bd38 100644 --- a/addons/threescale/3scale_test.go +++ b/addons/threescale/3scale_test.go @@ -25,6 +25,7 @@ import ( "github.com/apache/camel-k/v2/pkg/util/camel" "github.com/apache/camel-k/v2/pkg/util/kubernetes" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/utils/pointer" @@ -32,7 +33,7 @@ import ( func TestThreeScaleDisabled(t *testing.T) { catalog, err := camel.DefaultCatalog() - assert.Nil(t, err) + require.NoError(t, err) e := &trait.Environment{ CamelCatalog: catalog, @@ -40,7 +41,7 @@ func TestThreeScaleDisabled(t *testing.T) { threeScale := NewThreeScaleTrait() enabled, condition, err := threeScale.Configure(e) - assert.Nil(t, err) + require.NoError(t, err) assert.False(t, enabled) assert.Nil(t, condition) } @@ -51,12 +52,12 @@ func TestThreeScaleInjection(t *testing.T) { tst, _ := threeScale.(*threeScaleTrait) tst.Enabled = pointer.Bool(true) ok, condition, err := threeScale.Configure(e) - assert.Nil(t, err) + require.NoError(t, err) assert.True(t, ok) assert.Nil(t, condition) err = threeScale.Apply(e) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "true", svc.Labels["discovery.3scale.net"]) assert.Equal(t, "http", svc.Annotations["discovery.3scale.net/scheme"]) @@ -72,12 +73,12 @@ func TestThreeScaleInjectionNoAPIPath(t *testing.T) { tst.Enabled = pointer.Bool(true) tst.DescriptionPath = pointer.String("") ok, condition, err := threeScale.Configure(e) - assert.Nil(t, err) + require.NoError(t, err) assert.True(t, ok) assert.Nil(t, condition) err = threeScale.Apply(e) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "true", svc.Labels["discovery.3scale.net"]) assert.Equal(t, "http", svc.Annotations["discovery.3scale.net/scheme"]) @@ -91,7 +92,7 @@ func createEnvironment(t *testing.T) (*corev1.Service, *trait.Environment) { t.Helper() catalog, err := camel.DefaultCatalog() - assert.Nil(t, err) + require.NoError(t, err) e := trait.Environment{ CamelCatalog: catalog, diff --git a/addons/tracing/discovery/locator.go b/addons/tracing/discovery/locator.go index a6aea7eeaa..023cf3b044 100644 --- a/addons/tracing/discovery/locator.go +++ b/addons/tracing/discovery/locator.go @@ -30,5 +30,5 @@ var TracingLocators []TracingLocator // TracingLocator is able to find the address of an available tracing endpoint. type TracingLocator interface { - FindEndpoint(context.Context, client.Client, log.Logger, *trait.Environment) (string, error) + FindEndpoint(ctx context.Context, c client.Client, logger log.Logger, env *trait.Environment) (string, error) } diff --git a/addons/tracing/tracing_test.go b/addons/tracing/tracing_test.go index 25865c02be..f441a9d46c 100644 --- a/addons/tracing/tracing_test.go +++ b/addons/tracing/tracing_test.go @@ -28,6 +28,7 @@ import ( "github.com/apache/camel-k/v2/pkg/util/camel" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestTracingTraitOnQuarkus(t *testing.T) { @@ -37,12 +38,12 @@ func TestTracingTraitOnQuarkus(t *testing.T) { tt.Enabled = pointer.Bool(true) tt.Endpoint = "http://endpoint3" ok, condition, err := tracing.Configure(e) - assert.Nil(t, err) + require.NoError(t, err) assert.True(t, ok) assert.Nil(t, condition) err = tracing.Apply(e) - assert.Nil(t, err) + require.NoError(t, err) assert.Empty(t, e.ApplicationProperties["quarkus.jaeger.enabled"]) assert.Equal(t, "http://endpoint3", e.ApplicationProperties["quarkus.jaeger.endpoint"]) @@ -55,7 +56,7 @@ func createEnvironment(t *testing.T, catalogGen func() (*camel.RuntimeCatalog, e t.Helper() catalog, err := catalogGen() - assert.Nil(t, err) + require.NoError(t, err) e := trait.Environment{ CamelCatalog: catalog, diff --git a/addons/vault/aws/aws_secrets_manager_test.go b/addons/vault/aws/aws_secrets_manager_test.go index ce48f5ab34..443c257779 100644 --- a/addons/vault/aws/aws_secrets_manager_test.go +++ b/addons/vault/aws/aws_secrets_manager_test.go @@ -31,6 +31,7 @@ import ( "github.com/apache/camel-k/v2/pkg/util/camel" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "k8s.io/apimachinery/pkg/runtime" ) @@ -44,12 +45,12 @@ func TestAwsSecretsManagerTraitApply(t *testing.T) { secrets.AccessKey = "access-key" secrets.SecretKey = "secret-key" ok, condition, err := secrets.Configure(e) - assert.Nil(t, err) + require.NoError(t, err) assert.True(t, ok) assert.Nil(t, condition) err = secrets.Apply(e) - assert.Nil(t, err) + require.NoError(t, err) assert.Empty(t, e.ApplicationProperties["quarkus.jaeger.enabled"]) assert.Equal(t, "eu-west-1", e.ApplicationProperties["camel.vault.aws.region"]) @@ -67,12 +68,12 @@ func TestAwsSecretsManagerTraitNoDefaultCreds(t *testing.T) { secrets.AccessKey = "access-key" secrets.SecretKey = "secret-key" ok, condition, err := secrets.Configure(e) - assert.Nil(t, err) + require.NoError(t, err) assert.True(t, ok) assert.Nil(t, condition) err = secrets.Apply(e) - assert.Nil(t, err) + require.NoError(t, err) assert.Empty(t, e.ApplicationProperties["quarkus.jaeger.enabled"]) assert.Equal(t, "eu-west-1", e.ApplicationProperties["camel.vault.aws.region"]) @@ -107,12 +108,12 @@ func TestAwsSecretsManagerTraitWithSecrets(t *testing.T) { secrets.AccessKey = "secret:my-secret2/aws-access-key" secrets.SecretKey = "secret:my-secret1/aws-secret-key" ok, condition, err := secrets.Configure(e) - assert.Nil(t, err) + require.NoError(t, err) assert.True(t, ok) assert.Nil(t, condition) err = secrets.Apply(e) - assert.Nil(t, err) + require.NoError(t, err) assert.Empty(t, e.ApplicationProperties["quarkus.jaeger.enabled"]) assert.Equal(t, "eu-west-1", e.ApplicationProperties["camel.vault.aws.region"]) @@ -147,12 +148,12 @@ func TestAwsSecretsManagerTraitWithConfigMap(t *testing.T) { secrets.AccessKey = "configmap:my-configmap2/aws-access-key" secrets.SecretKey = "configmap:my-configmap1/aws-secret-key" ok, condition, err := secrets.Configure(e) - assert.Nil(t, err) + require.NoError(t, err) assert.True(t, ok) assert.Nil(t, condition) err = secrets.Apply(e) - assert.Nil(t, err) + require.NoError(t, err) assert.Empty(t, e.ApplicationProperties["quarkus.jaeger.enabled"]) assert.Equal(t, "eu-west-1", e.ApplicationProperties["camel.vault.aws.region"]) @@ -166,7 +167,7 @@ func createEnvironment(t *testing.T, catalogGen func() (*camel.RuntimeCatalog, e catalog, err := catalogGen() client, _ := test.NewFakeClient(objects...) - assert.Nil(t, err) + require.NoError(t, err) e := trait.Environment{ CamelCatalog: catalog, diff --git a/addons/vault/azure/azure_key_vault.go b/addons/vault/azure/azure_key_vault.go index 6a639442ba..a02fd2c17b 100644 --- a/addons/vault/azure/azure_key_vault.go +++ b/addons/vault/azure/azure_key_vault.go @@ -42,7 +42,7 @@ import ( // // To enable the automatic context reload on secrets updates you should define // the following trait options: -// -t azure-key-vault.enabled=true -t azure-key-vault.tenant-id="tenant-id" -t azure-key-vault.client-id="client-id" -t azure-key-vault.client-secret="client-secret" -t azure-key-vault.vault-name="vault-name" -t azure-key-vault.context-reload-enabled="true" -t azure-key-vault.refresh-enabled="true" -t azure-key-vault.refresh-period="30000" -t azure-key-vault.secrets="test*" -t azure-key-vault.eventhub-connection-string="connection-string" -t azure-key-vault.blob-account-name="account-name" -t azure-key-vault.blob-container-name="container-name" -t azure-key-vault.blob-access-key="account-name" +// -t azure-key-vault.enabled=true -t azure-key-vault.tenant-id="tenant-id" -t azure-key-vault.client-id="client-id" -t azure-key-vault.client-secret="client-secret" -t azure-key-vault.vault-name="vault-name" -t azure-key-vault.context-reload-enabled="true" -t azure-key-vault.refresh-enabled="true" -t azure-key-vault.refresh-period="30000" -t azure-key-vault.secrets="test*" -t azure-key-vault.eventhub-connection-string="connection-string" -t azure-key-vault.blob-account-name="account-name" -t azure-key-vault.blob-container-name="container-name" -t azure-key-vault.blob-access-key="account-name" -t azure-key-vault.azure-identity-enabled="true" // // +camel-k:trait=azure-key-vault. type Trait struct { @@ -63,6 +63,8 @@ type Trait struct { ContextReloadEnabled *bool `property:"context-reload-enabled" json:"contextReloadEnabled,omitempty"` // Define if we want to use the Refresh Feature for secrets RefreshEnabled *bool `property:"refresh-enabled" json:"refreshEnabled,omitempty"` + // Whether the Azure Identity Authentication should be used or not + AzureIdentityEnabled *bool `property:"azure-identity-enabled" json:"azureIdentityEnabled,omitempty"` // If Refresh is enabled, this defines the interval to check the refresh event RefreshPeriod string `property:"refresh-period" json:"refreshPeriod,omitempty"` // If Refresh is enabled, the regular expression representing the secrets we want to track @@ -107,6 +109,10 @@ func (t *azureKeyVaultTrait) Configure(environment *trait.Environment) (bool, *t t.RefreshEnabled = pointer.Bool(false) } + if t.AzureIdentityEnabled == nil { + t.AzureIdentityEnabled = pointer.Bool(false) + } + return true, nil, nil } @@ -143,6 +149,7 @@ func (t *azureKeyVaultTrait) Apply(environment *trait.Environment) error { environment.ApplicationProperties["camel.vault.azure.clientId"] = t.ClientID environment.ApplicationProperties["camel.vault.azure.vaultName"] = t.VaultName environment.ApplicationProperties["camel.vault.azure.refreshEnabled"] = strconv.FormatBool(*t.RefreshEnabled) + environment.ApplicationProperties["camel.vault.azure.azureIdentityEnabled"] = strconv.FormatBool(*t.AzureIdentityEnabled) environment.ApplicationProperties["camel.main.context-reload-enabled"] = strconv.FormatBool(*t.ContextReloadEnabled) environment.ApplicationProperties["camel.vault.azure.refreshPeriod"] = t.RefreshPeriod if t.Secrets != "" { diff --git a/addons/vault/azure/azure_key_vault_test.go b/addons/vault/azure/azure_key_vault_test.go index 7f3299ba40..cc9c611712 100644 --- a/addons/vault/azure/azure_key_vault_test.go +++ b/addons/vault/azure/azure_key_vault_test.go @@ -31,6 +31,7 @@ import ( "github.com/apache/camel-k/v2/pkg/util/camel" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "k8s.io/apimachinery/pkg/runtime" ) @@ -44,12 +45,12 @@ func TestAzureKeyVaultTraitApply(t *testing.T) { secrets.ClientSecret = "secret" secrets.VaultName = "my-vault" ok, condition, err := secrets.Configure(e) - assert.Nil(t, err) + require.NoError(t, err) assert.True(t, ok) assert.Nil(t, condition) err = secrets.Apply(e) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "client-id", e.ApplicationProperties["camel.vault.azure.clientId"]) assert.Equal(t, "secret", e.ApplicationProperties["camel.vault.azure.clientSecret"]) @@ -87,12 +88,12 @@ func TestAzureKeyVaultTraitApplyWithConfigmapAndRefresh(t *testing.T) { secrets.BlobAccountName = "camel-k" secrets.BlobContainerName = "camel-k-container" ok, condition, err := secrets.Configure(e) - assert.Nil(t, err) + require.NoError(t, err) assert.True(t, ok) assert.Nil(t, condition) err = secrets.Apply(e) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "client-id", e.ApplicationProperties["camel.vault.azure.clientId"]) assert.Equal(t, "my-secret-key", e.ApplicationProperties["camel.vault.azure.clientSecret"]) @@ -134,12 +135,12 @@ func TestAzureKeyVaultTraitApplyWithSecretAndRefresh(t *testing.T) { secrets.BlobAccountName = "camel-k" secrets.BlobContainerName = "camel-k-container" ok, condition, err := secrets.Configure(e) - assert.Nil(t, err) + require.NoError(t, err) assert.True(t, ok) assert.Nil(t, condition) err = secrets.Apply(e) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "client-id", e.ApplicationProperties["camel.vault.azure.clientId"]) assert.Equal(t, "my-secret-key", e.ApplicationProperties["camel.vault.azure.clientSecret"]) @@ -151,12 +152,61 @@ func TestAzureKeyVaultTraitApplyWithSecretAndRefresh(t *testing.T) { assert.True(t, true, e.ApplicationProperties["camel.vault.azure.refreshEnabled"]) } +func TestAzureKeyVaultTraitAzureIdentityEnabledApplyWithSecretAndRefresh(t *testing.T) { + e := createEnvironment(t, camel.QuarkusCatalog, &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "test", + Name: "my-secret1", + }, + Data: map[string][]byte{ + "azure-client-secret": []byte("my-secret-key"), + }, + }, &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "test", + Name: "my-secret2", + }, + Data: map[string][]byte{ + "azure-storage-blob-key": []byte("my-access-key"), + }, + }) + azure := NewAzureKeyVaultTrait() + secrets, _ := azure.(*azureKeyVaultTrait) + secrets.Enabled = pointer.Bool(true) + secrets.TenantID = "tenant-id" + secrets.ClientID = "client-id" + secrets.ClientSecret = "secret:my-secret1/azure-client-secret" + secrets.VaultName = "my-vault" + secrets.RefreshEnabled = pointer.Bool(true) + secrets.AzureIdentityEnabled = pointer.Bool(true) + secrets.BlobAccessKey = "secret:my-secret2/azure-storage-blob-key" + secrets.BlobAccountName = "camel-k" + secrets.BlobContainerName = "camel-k-container" + ok, condition, err := secrets.Configure(e) + require.NoError(t, err) + assert.True(t, ok) + assert.Nil(t, condition) + + err = secrets.Apply(e) + require.NoError(t, err) + + assert.Equal(t, "client-id", e.ApplicationProperties["camel.vault.azure.clientId"]) + assert.Equal(t, "my-secret-key", e.ApplicationProperties["camel.vault.azure.clientSecret"]) + assert.Equal(t, "tenant-id", e.ApplicationProperties["camel.vault.azure.tenantId"]) + assert.Equal(t, "my-vault", e.ApplicationProperties["camel.vault.azure.vaultName"]) + assert.Equal(t, "camel-k", e.ApplicationProperties["camel.vault.azure.blobAccountName"]) + assert.Equal(t, "camel-k-container", e.ApplicationProperties["camel.vault.azure.blobContainerName"]) + assert.Equal(t, "my-access-key", e.ApplicationProperties["camel.vault.azure.blobAccessKey"]) + assert.True(t, true, e.ApplicationProperties["camel.vault.azure.refreshEnabled"]) + assert.True(t, true, e.ApplicationProperties["camel.vault.azure.azureIdentityEnabled"]) +} + func createEnvironment(t *testing.T, catalogGen func() (*camel.RuntimeCatalog, error), objects ...runtime.Object) *trait.Environment { t.Helper() catalog, err := catalogGen() client, _ := test.NewFakeClient(objects...) - assert.Nil(t, err) + require.NoError(t, err) e := trait.Environment{ CamelCatalog: catalog, diff --git a/addons/vault/gcp/gcp_secret_manager_test.go b/addons/vault/gcp/gcp_secret_manager_test.go index 2d01c57cb0..47001eaca8 100644 --- a/addons/vault/gcp/gcp_secret_manager_test.go +++ b/addons/vault/gcp/gcp_secret_manager_test.go @@ -28,6 +28,7 @@ import ( "github.com/apache/camel-k/v2/pkg/util/camel" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestGcpSecretManagerTraitApply(t *testing.T) { @@ -39,12 +40,12 @@ func TestGcpSecretManagerTraitApply(t *testing.T) { secrets.ProjectID = "project-gcp" secrets.ServiceAccountKey = "file:////usr/local/serviceaccount.json" ok, condition, err := secrets.Configure(e) - assert.Nil(t, err) + require.NoError(t, err) assert.True(t, ok) assert.Nil(t, condition) err = secrets.Apply(e) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "project-gcp", e.ApplicationProperties["camel.vault.gcp.projectId"]) assert.Equal(t, "file:////usr/local/serviceaccount.json", e.ApplicationProperties["camel.vault.gcp.serviceAccountKey"]) @@ -60,12 +61,12 @@ func TestGcpSecretManagerTraitNoDefaultCreds(t *testing.T) { secrets.ProjectID = "project-gcp" secrets.ServiceAccountKey = "file:////usr/local/serviceaccount.json" ok, condition, err := secrets.Configure(e) - assert.Nil(t, err) + require.NoError(t, err) assert.True(t, ok) assert.Nil(t, condition) err = secrets.Apply(e) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "project-gcp", e.ApplicationProperties["camel.vault.gcp.projectId"]) assert.Equal(t, "file:////usr/local/serviceaccount.json", e.ApplicationProperties["camel.vault.gcp.serviceAccountKey"]) @@ -76,7 +77,7 @@ func createEnvironment(t *testing.T, catalogGen func() (*camel.RuntimeCatalog, e t.Helper() catalog, err := catalogGen() - assert.Nil(t, err) + require.NoError(t, err) e := trait.Environment{ CamelCatalog: catalog, diff --git a/addons/vault/hashicorp/hashicorp_vault_test.go b/addons/vault/hashicorp/hashicorp_vault_test.go index 975cc3be13..ed21fb6c0e 100644 --- a/addons/vault/hashicorp/hashicorp_vault_test.go +++ b/addons/vault/hashicorp/hashicorp_vault_test.go @@ -31,6 +31,7 @@ import ( "github.com/apache/camel-k/v2/pkg/util/camel" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "k8s.io/apimachinery/pkg/runtime" ) @@ -45,12 +46,12 @@ func TestHashicorpVaultTraitApply(t *testing.T) { secrets.Port = "9091" secrets.Scheme = "http" ok, condition, err := secrets.Configure(e) - assert.Nil(t, err) + require.NoError(t, err) assert.True(t, ok) assert.Nil(t, condition) err = secrets.Apply(e) - assert.Nil(t, err) + require.NoError(t, err) assert.Empty(t, e.ApplicationProperties["quarkus.jaeger.enabled"]) assert.Equal(t, "test", e.ApplicationProperties["camel.vault.hashicorp.engine"]) @@ -79,12 +80,12 @@ func TestHashicorpVaultTraitWithSecretApply(t *testing.T) { secrets.Port = "9091" secrets.Scheme = "http" ok, condition, err := secrets.Configure(e) - assert.Nil(t, err) + require.NoError(t, err) assert.True(t, ok) assert.Nil(t, condition) err = secrets.Apply(e) - assert.Nil(t, err) + require.NoError(t, err) assert.Empty(t, e.ApplicationProperties["quarkus.jaeger.enabled"]) assert.Equal(t, "test", e.ApplicationProperties["camel.vault.hashicorp.engine"]) @@ -113,12 +114,12 @@ func TestHashicorpVaultTraitWithConfigMapApply(t *testing.T) { secrets.Port = "9091" secrets.Scheme = "http" ok, condition, err := secrets.Configure(e) - assert.Nil(t, err) + require.NoError(t, err) assert.True(t, ok) assert.Nil(t, condition) err = secrets.Apply(e) - assert.Nil(t, err) + require.NoError(t, err) assert.Empty(t, e.ApplicationProperties["quarkus.jaeger.enabled"]) assert.Equal(t, "test", e.ApplicationProperties["camel.vault.hashicorp.engine"]) @@ -133,7 +134,7 @@ func createEnvironment(t *testing.T, catalogGen func() (*camel.RuntimeCatalog, e catalog, err := catalogGen() client, _ := test.NewFakeClient(objects...) - assert.Nil(t, err) + require.NoError(t, err) e := trait.Environment{ CamelCatalog: catalog, diff --git a/badge.out b/badge.out index 293d863e42..1707b478fe 100644 --- a/badge.out +++ b/badge.out @@ -1,2 +1,2 @@ -![Coverage](https://img.shields.io/badge/Coverage-36.2%25-yellow) \ No newline at end of file +![Coverage](https://img.shields.io/badge/Coverage-37.2%25-yellow) \ No newline at end of file diff --git a/build/Dockerfile b/build/Dockerfile index 3160d6a9bf..e495e40f30 100644 --- a/build/Dockerfile +++ b/build/Dockerfile @@ -15,6 +15,8 @@ FROM eclipse-temurin:17-jdk as base +ARG IMAGE_ARCH + ARG MAVEN_DEFAULT_VERSION="3.8.6" ARG MAVEN_HOME="/usr/share/maven" ARG MAVEN_DIST_URL="https://archive.apache.org/dist/maven/maven-3/${MAVEN_DEFAULT_VERSION}/binaries/apache-maven-${MAVEN_DEFAULT_VERSION}-bin.zip" @@ -59,9 +61,9 @@ RUN chgrp -R 0 ${MVN_REPO} \ USER 1001:0 -ADD build/_output/bin/kamel /usr/local/bin/kamel +ADD build/_output/bin/kamel-${IMAGE_ARCH} /usr/local/bin/kamel -FROM golang:1.20 as go +FROM golang:1.21 as go RUN go install github.com/go-delve/delve/cmd/dlv@latest diff --git a/coverage b/coverage index b82d77ecc4..ad4af79d82 100644 --- a/coverage +++ b/coverage @@ -1 +1 @@ -36.2 +37.2 diff --git a/coverage.out b/coverage.out index c25673c030..7041f819be 100644 --- a/coverage.out +++ b/coverage.out @@ -33,7 +33,7 @@ github.com/apache/camel-k/v2/addons/strimzi/strimzi.go:204: getBootstrapSer github.com/apache/camel-k/v2/addons/strimzi/strimzi.go:225: Order 0.0% github.com/apache/camel-k/v2/addons/telemetry/telemetry.go:84: NewTelemetryTrait 100.0% github.com/apache/camel-k/v2/addons/telemetry/telemetry.go:90: Configure 47.4% -github.com/apache/camel-k/v2/addons/telemetry/telemetry.go:129: Apply 94.7% +github.com/apache/camel-k/v2/addons/telemetry/telemetry.go:130: Apply 94.7% github.com/apache/camel-k/v2/addons/threescale/3scale.go:84: NewThreeScaleTrait 100.0% github.com/apache/camel-k/v2/addons/threescale/3scale.go:90: Configure 93.3% github.com/apache/camel-k/v2/addons/threescale/3scale.go:117: Apply 100.0% @@ -43,16 +43,16 @@ github.com/apache/camel-k/v2/addons/tracing/tracing.go:89: Configure 5 github.com/apache/camel-k/v2/addons/tracing/tracing.go:125: Apply 93.3% github.com/apache/camel-k/v2/addons/vault/aws/aws_secrets_manager.go:79: NewAwsSecretsManagerTrait 100.0% github.com/apache/camel-k/v2/addons/vault/aws/aws_secrets_manager.go:85: Configure 81.8% -github.com/apache/camel-k/v2/addons/vault/aws/aws_secrets_manager.go:107: Apply 82.8% -github.com/apache/camel-k/v2/addons/vault/azure/azure_key_vault.go:87: NewAzureKeyVaultTrait 100.0% -github.com/apache/camel-k/v2/addons/vault/azure/azure_key_vault.go:93: Configure 77.8% -github.com/apache/camel-k/v2/addons/vault/azure/azure_key_vault.go:113: Apply 84.8% +github.com/apache/camel-k/v2/addons/vault/aws/aws_secrets_manager.go:107: Apply 85.7% +github.com/apache/camel-k/v2/addons/vault/azure/azure_key_vault.go:89: NewAzureKeyVaultTrait 100.0% +github.com/apache/camel-k/v2/addons/vault/azure/azure_key_vault.go:95: Configure 81.8% +github.com/apache/camel-k/v2/addons/vault/azure/azure_key_vault.go:119: Apply 87.9% github.com/apache/camel-k/v2/addons/vault/gcp/gcp_secret_manager.go:72: NewGcpSecretManagerTrait 100.0% github.com/apache/camel-k/v2/addons/vault/gcp/gcp_secret_manager.go:78: Configure 72.7% -github.com/apache/camel-k/v2/addons/vault/gcp/gcp_secret_manager.go:102: Apply 78.6% +github.com/apache/camel-k/v2/addons/vault/gcp/gcp_secret_manager.go:102: Apply 84.6% github.com/apache/camel-k/v2/addons/vault/hashicorp/hashicorp_vault.go:65: NewHashicorpVaultTrait 100.0% github.com/apache/camel-k/v2/addons/vault/hashicorp/hashicorp_vault.go:71: Configure 60.0% -github.com/apache/camel-k/v2/addons/vault/hashicorp/hashicorp_vault.go:83: Apply 83.3% +github.com/apache/camel-k/v2/addons/vault/hashicorp/hashicorp_vault.go:83: Apply 88.2% github.com/apache/camel-k/v2/pkg/apis/camel/v1/build_types_support.go:25: NewBuild 0.0% github.com/apache/camel-k/v2/pkg/apis/camel/v1/build_types_support.go:38: NewBuildList 0.0% github.com/apache/camel-k/v2/pkg/apis/camel/v1/build_types_support.go:48: BuilderPodNamespace 0.0% @@ -113,7 +113,7 @@ github.com/apache/camel-k/v2/pkg/apis/camel/v1/camelcatalog_types_support.go:262 github.com/apache/camel-k/v2/pkg/apis/camel/v1/camelcatalog_types_support.go:270: GetScheme 0.0% github.com/apache/camel-k/v2/pkg/apis/camel/v1/camelcatalog_types_support.go:279: consumerScheme 0.0% github.com/apache/camel-k/v2/pkg/apis/camel/v1/camelcatalog_types_support.go:283: producerScheme 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/common_types.go:318: String 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/common_types.go:321: String 0.0% github.com/apache/camel-k/v2/pkg/apis/camel/v1/common_types_support.go:33: String 0.0% github.com/apache/camel-k/v2/pkg/apis/camel/v1/common_types_support.go:37: String 0.0% github.com/apache/camel-k/v2/pkg/apis/camel/v1/common_types_support.go:41: CapabilityDependencies 0.0% @@ -155,34 +155,34 @@ github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:92: github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:96: AddFlows 0.0% github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:100: AddConfiguration 100.0% github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:107: AddDependency 100.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:120: GetConfigurationProperty 100.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:132: trimFirstLeadingSpace 100.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:139: AddOrReplaceGeneratedSources 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:158: AddConfigurationsIfMissing 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:173: Configurations 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:181: Configurations 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:189: Configurations 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:201: NewSourceSpec 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:212: SetOperatorID 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:216: SetIntegrationPlatform 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:227: SetIntegrationKit 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:260: GetIntegrationKitNamespace 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:274: IsConditionTrue 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:287: SetReadyCondition 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:292: SetReadyConditionError 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:297: IsSynthetic 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:302: GetCondition 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:312: SetCondition 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:321: SetErrorCondition 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:334: SetConditions 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:374: RemoveCondition 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:387: GetConditions 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:395: GetType 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:399: GetStatus 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:403: GetLastUpdateTime 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:407: GetLastTransitionTime 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:411: GetReason 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:415: GetMessage 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:120: AddConfigurationProperty 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:125: GetConfigurationProperty 100.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:137: trimFirstLeadingSpace 100.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:144: AddOrReplaceGeneratedSources 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:163: Configurations 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:171: Configurations 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:179: Configurations 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:191: NewSourceSpec 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:202: SetOperatorID 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:206: SetIntegrationPlatform 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:217: SetIntegrationKit 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:250: GetIntegrationKitNamespace 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:264: IsConditionTrue 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:277: SetReadyCondition 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:282: SetReadyConditionError 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:287: IsSynthetic 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:292: GetCondition 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:302: SetCondition 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:311: SetErrorCondition 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:324: SetConditions 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:364: RemoveCondition 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:377: GetConditions 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:385: GetType 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:389: GetStatus 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:393: GetLastUpdateTime 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:397: GetLastTransitionTime 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:401: GetReason 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/integration_types_support.go:405: GetMessage 0.0% github.com/apache/camel-k/v2/pkg/apis/camel/v1/integrationkit_types_support.go:29: NewIntegrationKit 0.0% github.com/apache/camel-k/v2/pkg/apis/camel/v1/integrationkit_types_support.go:42: NewIntegrationKitList 0.0% github.com/apache/camel-k/v2/pkg/apis/camel/v1/integrationkit_types_support.go:51: Configurations 0.0% @@ -191,18 +191,19 @@ github.com/apache/camel-k/v2/pkg/apis/camel/v1/integrationkit_types_support.go:6 github.com/apache/camel-k/v2/pkg/apis/camel/v1/integrationkit_types_support.go:72: SetIntegrationPlatform 0.0% github.com/apache/camel-k/v2/pkg/apis/camel/v1/integrationkit_types_support.go:88: HasHigherPriorityThan 0.0% github.com/apache/camel-k/v2/pkg/apis/camel/v1/integrationkit_types_support.go:105: IsExternal 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/integrationkit_types_support.go:110: GetCondition 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/integrationkit_types_support.go:120: SetCondition 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/integrationkit_types_support.go:131: SetErrorCondition 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/integrationkit_types_support.go:146: SetConditions 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/integrationkit_types_support.go:171: RemoveCondition 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/integrationkit_types_support.go:184: GetConditions 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/integrationkit_types_support.go:192: GetType 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/integrationkit_types_support.go:196: GetStatus 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/integrationkit_types_support.go:200: GetLastUpdateTime 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/integrationkit_types_support.go:204: GetLastTransitionTime 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/integrationkit_types_support.go:208: GetReason 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/integrationkit_types_support.go:212: GetMessage 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/integrationkit_types_support.go:110: HasCapability 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/integrationkit_types_support.go:121: GetCondition 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/integrationkit_types_support.go:131: SetCondition 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/integrationkit_types_support.go:142: SetErrorCondition 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/integrationkit_types_support.go:157: SetConditions 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/integrationkit_types_support.go:182: RemoveCondition 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/integrationkit_types_support.go:195: GetConditions 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/integrationkit_types_support.go:203: GetType 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/integrationkit_types_support.go:207: GetStatus 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/integrationkit_types_support.go:211: GetLastUpdateTime 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/integrationkit_types_support.go:215: GetLastTransitionTime 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/integrationkit_types_support.go:219: GetReason 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/integrationkit_types_support.go:223: GetMessage 0.0% github.com/apache/camel-k/v2/pkg/apis/camel/v1/integrationplatform_types_support.go:26: NewIntegrationPlatformList 0.0% github.com/apache/camel-k/v2/pkg/apis/camel/v1/integrationplatform_types_support.go:36: NewIntegrationPlatform 0.0% github.com/apache/camel-k/v2/pkg/apis/camel/v1/integrationplatform_types_support.go:50: Configurations 0.0% @@ -261,6 +262,7 @@ github.com/apache/camel-k/v2/pkg/apis/camel/v1/kamelet_types_support.go:180: github.com/apache/camel-k/v2/pkg/apis/camel/v1/kamelet_types_support.go:184: ValidKameletProperties 0.0% github.com/apache/camel-k/v2/pkg/apis/camel/v1/kamelet_types_support.go:195: NewKamelet 0.0% github.com/apache/camel-k/v2/pkg/apis/camel/v1/kamelet_types_support.go:209: NewKameletList 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/kamelet_types_support.go:219: SetOperatorID 0.0% github.com/apache/camel-k/v2/pkg/apis/camel/v1/knative/types.go:28: NewCamelEnvironment 100.0% github.com/apache/camel-k/v2/pkg/apis/camel/v1/knative/types.go:66: ResourceDescription 0.0% github.com/apache/camel-k/v2/pkg/apis/camel/v1/knative/types_support.go:27: BuildCamelServiceDefinition 100.0% @@ -312,252 +314,254 @@ github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:122: github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:130: DeepCopyInto 0.0% github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:137: DeepCopy 0.0% github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:147: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:166: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:176: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:190: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:200: DeepCopyObject 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:208: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:222: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:232: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:258: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:268: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:280: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:290: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:315: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:325: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:360: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:370: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:381: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:391: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:396: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:406: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:415: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:425: DeepCopyObject 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:433: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:440: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:450: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:464: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:474: DeepCopyObject 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:482: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:502: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:512: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:524: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:534: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:557: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:567: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:574: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:584: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:596: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:606: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:171: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:181: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:195: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:205: DeepCopyObject 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:213: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:227: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:237: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:263: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:273: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:285: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:295: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:320: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:330: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:365: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:375: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:386: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:396: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:401: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:411: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:420: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:430: DeepCopyObject 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:438: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:445: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:455: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:469: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:479: DeepCopyObject 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:487: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:507: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:517: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:529: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:539: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:562: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:572: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:577: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:587: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:594: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:604: DeepCopyInto 0.0% github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:616: DeepCopy 0.0% github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:626: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:631: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:641: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:647: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:657: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:667: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:677: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:682: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:692: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:714: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:724: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:743: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:753: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:653: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:663: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:668: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:678: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:684: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:694: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:704: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:714: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:719: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:729: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:751: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:761: DeepCopyInto 0.0% github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:780: DeepCopy 0.0% github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:790: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:800: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:810: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:821: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:831: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:817: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:827: DeepCopyInto 0.0% github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:837: DeepCopy 0.0% github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:847: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:857: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:867: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:878: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:888: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:898: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:908: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:918: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:928: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:933: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:943: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:960: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:970: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:977: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:987: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:993: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1003: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1008: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1018: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1028: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1038: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1043: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1053: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:858: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:868: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:874: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:884: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:894: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:904: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:915: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:925: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:935: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:945: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:955: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:965: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:970: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:980: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:997: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1007: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1014: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1024: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1030: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1040: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1045: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1055: DeepCopyInto 0.0% github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1065: DeepCopy 0.0% github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1075: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1085: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1095: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1104: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1114: DeepCopyObject 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1122: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1140: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1150: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1159: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1169: DeepCopyObject 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1177: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1184: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1194: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1208: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1218: DeepCopyObject 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1226: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1254: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1264: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1287: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1297: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1329: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1339: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1353: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1363: DeepCopyObject 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1371: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1380: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1390: DeepCopyObject 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1398: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1423: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1433: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1440: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1450: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1460: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1470: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1484: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1494: DeepCopyObject 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1502: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1515: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1525: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1545: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1555: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1564: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1574: DeepCopyObject 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1582: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1594: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1604: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1611: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1621: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1631: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1641: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1655: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1665: DeepCopyObject 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1673: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1681: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1691: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1704: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1080: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1090: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1102: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1112: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1122: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1132: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1141: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1151: DeepCopyObject 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1159: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1177: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1187: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1196: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1206: DeepCopyObject 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1214: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1221: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1231: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1245: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1255: DeepCopyObject 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1263: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1296: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1306: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1328: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1338: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1370: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1380: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1394: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1404: DeepCopyObject 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1412: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1421: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1431: DeepCopyObject 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1439: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1464: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1474: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1481: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1491: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1501: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1511: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1525: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1535: DeepCopyObject 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1543: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1556: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1566: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1586: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1596: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1605: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1615: DeepCopyObject 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1623: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1635: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1645: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1652: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1662: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1672: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1682: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1696: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1706: DeepCopyObject 0.0% github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1714: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1764: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1774: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1823: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1833: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1843: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1853: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1925: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1935: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1962: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1972: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1979: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1989: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1998: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2008: DeepCopyObject 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2016: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2023: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2033: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2047: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2057: DeepCopyObject 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2065: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2070: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2080: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2085: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2095: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2136: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2146: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2163: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2173: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2186: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2196: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2206: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2216: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2221: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2231: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2249: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2259: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2297: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2307: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2317: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2327: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2332: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2342: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2351: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2361: DeepCopyObject 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2369: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2383: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2393: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2407: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2417: DeepCopyObject 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2425: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2454: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2464: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2481: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2491: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2499: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2509: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2515: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2525: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2535: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2545: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2551: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2561: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2572: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2582: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2595: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2605: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2663: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2673: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2679: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2689: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2700: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2710: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2716: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2726: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2735: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2745: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2750: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2760: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2767: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2777: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2782: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2792: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2816: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2826: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2832: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2842: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2855: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2865: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2881: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2891: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2898: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2908: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2920: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2930: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2975: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2985: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2995: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:3005: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1722: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1732: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1745: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1755: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1805: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1815: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1863: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1873: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1883: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1893: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1965: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:1975: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2002: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2012: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2019: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2029: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2038: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2048: DeepCopyObject 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2056: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2063: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2073: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2087: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2097: DeepCopyObject 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2105: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2110: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2120: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2125: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2135: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2176: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2186: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2203: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2213: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2226: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2236: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2246: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2256: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2261: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2271: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2289: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2299: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2337: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2347: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2357: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2367: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2372: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2382: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2391: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2401: DeepCopyObject 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2409: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2423: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2433: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2447: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2457: DeepCopyObject 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2465: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2494: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2504: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2521: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2531: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2539: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2549: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2555: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2565: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2575: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2585: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2591: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2601: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2612: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2622: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2635: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2645: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2703: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2713: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2719: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2729: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2740: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2750: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2756: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2766: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2775: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2785: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2790: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2800: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2807: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2817: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2822: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2832: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2856: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2866: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2872: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2882: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2895: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2905: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2921: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2931: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2938: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2948: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2960: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:2970: DeepCopyInto 0.0% github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:3015: DeepCopy 0.0% github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:3025: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:3031: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:3041: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:3248: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:3258: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:3274: DeepCopy 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:3284: DeepCopyInto 0.0% -github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:3299: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:3035: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:3045: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:3055: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:3065: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:3071: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:3081: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:3288: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:3298: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:3314: DeepCopy 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:3324: DeepCopyInto 0.0% +github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.deepcopy.go:3339: DeepCopy 0.0% github.com/apache/camel-k/v2/pkg/apis/camel/v1/zz_generated.defaults.go:15: RegisterDefaults 0.0% github.com/apache/camel-k/v2/pkg/apis/camel/v1alpha1/error_handler_types_support.go:42: Type 0.0% github.com/apache/camel-k/v2/pkg/apis/camel/v1alpha1/error_handler_types_support.go:47: Endpoint 0.0% @@ -685,7 +689,7 @@ github.com/apache/camel-k/v2/pkg/builder/image.go:149: imageContext 0 github.com/apache/camel-k/v2/pkg/builder/image.go:180: listPublishedImages 81.2% github.com/apache/camel-k/v2/pkg/builder/image.go:222: findBestImage 0.0% github.com/apache/camel-k/v2/pkg/builder/jib.go:44: Do 0.0% -github.com/apache/camel-k/v2/pkg/builder/jib.go:151: cleanRegistryConfig 0.0% +github.com/apache/camel-k/v2/pkg/builder/jib.go:155: cleanRegistryConfig 0.0% github.com/apache/camel-k/v2/pkg/builder/project.go:36: init 100.0% github.com/apache/camel-k/v2/pkg/builder/project.go:69: cleanUpBuildDir 0.0% github.com/apache/camel-k/v2/pkg/builder/project.go:82: generateJavaKeystore 0.0% @@ -693,19 +697,20 @@ github.com/apache/camel-k/v2/pkg/builder/project.go:98: generateProjectSet github.com/apache/camel-k/v2/pkg/builder/project.go:129: injectServersIntoMavenSettings 63.6% github.com/apache/camel-k/v2/pkg/builder/project.go:146: encodeXMLNoHeader 87.5% github.com/apache/camel-k/v2/pkg/builder/project.go:160: getServerTagIndex 76.2% -github.com/apache/camel-k/v2/pkg/builder/project.go:190: injectDependencies 0.0% -github.com/apache/camel-k/v2/pkg/builder/project.go:195: sanitizeDependencies 0.0% +github.com/apache/camel-k/v2/pkg/builder/project.go:190: injectDependencies 100.0% +github.com/apache/camel-k/v2/pkg/builder/project.go:195: sanitizeDependencies 100.0% github.com/apache/camel-k/v2/pkg/builder/project.go:199: injectProfiles 0.0% github.com/apache/camel-k/v2/pkg/builder/quarkus.go:36: init 100.0% -github.com/apache/camel-k/v2/pkg/builder/quarkus.go:64: resolveBuildSources 0.0% -github.com/apache/camel-k/v2/pkg/builder/quarkus.go:81: prepareProjectWithSources 0.0% -github.com/apache/camel-k/v2/pkg/builder/quarkus.go:111: loadCamelQuarkusCatalog 0.0% -github.com/apache/camel-k/v2/pkg/builder/quarkus.go:128: generateQuarkusProject 0.0% -github.com/apache/camel-k/v2/pkg/builder/quarkus.go:146: GenerateQuarkusProjectCommon 0.0% -github.com/apache/camel-k/v2/pkg/builder/quarkus.go:216: buildQuarkusRunner 0.0% -github.com/apache/camel-k/v2/pkg/builder/quarkus.go:239: BuildQuarkusRunnerCommon 0.0% -github.com/apache/camel-k/v2/pkg/builder/quarkus.go:264: computeQuarkusDependencies 0.0% -github.com/apache/camel-k/v2/pkg/builder/quarkus.go:282: ProcessQuarkusTransitiveDependencies 0.0% +github.com/apache/camel-k/v2/pkg/builder/quarkus.go:64: resolveBuildSources 28.6% +github.com/apache/camel-k/v2/pkg/builder/quarkus.go:81: prepareProjectWithSources 72.2% +github.com/apache/camel-k/v2/pkg/builder/quarkus.go:111: loadCamelQuarkusCatalog 85.7% +github.com/apache/camel-k/v2/pkg/builder/quarkus.go:128: generateQuarkusProject 100.0% +github.com/apache/camel-k/v2/pkg/builder/quarkus.go:143: generateQuarkusProjectCommon 100.0% +github.com/apache/camel-k/v2/pkg/builder/quarkus.go:183: buildQuarkusRunner 83.3% +github.com/apache/camel-k/v2/pkg/builder/quarkus.go:206: BuildQuarkusRunnerCommon 66.7% +github.com/apache/camel-k/v2/pkg/builder/quarkus.go:223: computeApplicationProperties 80.0% +github.com/apache/camel-k/v2/pkg/builder/quarkus.go:264: computeQuarkusDependencies 90.9% +github.com/apache/camel-k/v2/pkg/builder/quarkus.go:282: ProcessQuarkusTransitiveDependencies 84.6% github.com/apache/camel-k/v2/pkg/builder/runtime_support.go:41: BuildCommands 0.0% github.com/apache/camel-k/v2/pkg/builder/runtime_support.go:46: Directory 0.0% github.com/apache/camel-k/v2/pkg/builder/runtime_support.go:51: TargetDirectory 0.0% @@ -772,13 +777,14 @@ github.com/apache/camel-k/v2/pkg/cmd/debug.go:39: newCmdDebug 100.0% github.com/apache/camel-k/v2/pkg/cmd/debug.go:70: validateArgs 0.0% github.com/apache/camel-k/v2/pkg/cmd/debug.go:77: run 0.0% github.com/apache/camel-k/v2/pkg/cmd/debug.go:136: toggleDebug 0.0% -github.com/apache/camel-k/v2/pkg/cmd/delete.go:37: newCmdDelete 57.1% -github.com/apache/camel-k/v2/pkg/cmd/delete.go:63: validate 0.0% -github.com/apache/camel-k/v2/pkg/cmd/delete.go:74: run 0.0% -github.com/apache/camel-k/v2/pkg/cmd/delete.go:126: getIntegration 0.0% -github.com/apache/camel-k/v2/pkg/cmd/delete.go:138: deleteIntegration 0.0% -github.com/apache/camel-k/v2/pkg/cmd/delete.go:151: deletePipeIfExists 0.0% -github.com/apache/camel-k/v2/pkg/cmd/delete.go:175: findCreator 0.0% +github.com/apache/camel-k/v2/pkg/cmd/delete.go:38: newCmdDelete 57.1% +github.com/apache/camel-k/v2/pkg/cmd/delete.go:64: validate 0.0% +github.com/apache/camel-k/v2/pkg/cmd/delete.go:75: run 0.0% +github.com/apache/camel-k/v2/pkg/cmd/delete.go:127: getIntegration 0.0% +github.com/apache/camel-k/v2/pkg/cmd/delete.go:139: deleteIntegration 0.0% +github.com/apache/camel-k/v2/pkg/cmd/delete.go:161: deletePipeIfExists 0.0% +github.com/apache/camel-k/v2/pkg/cmd/delete.go:185: deleteKameletBindingIfExists 0.0% +github.com/apache/camel-k/v2/pkg/cmd/delete.go:209: findCreator 0.0% github.com/apache/camel-k/v2/pkg/cmd/describe.go:35: describeObjectMeta 0.0% github.com/apache/camel-k/v2/pkg/cmd/describe.go:56: describeTraits 0.0% github.com/apache/camel-k/v2/pkg/cmd/describe.go:76: newCmdDescribe 100.0% @@ -809,25 +815,24 @@ github.com/apache/camel-k/v2/pkg/cmd/dump.go:209: dumpConditions 0.0% github.com/apache/camel-k/v2/pkg/cmd/dump.go:215: dumpLogs 0.0% github.com/apache/camel-k/v2/pkg/cmd/get.go:37: newCmdGet 100.0% github.com/apache/camel-k/v2/pkg/cmd/get.go:52: run 0.0% -github.com/apache/camel-k/v2/pkg/cmd/install.go:59: newCmdInstall 89.9% -github.com/apache/camel-k/v2/pkg/cmd/install.go:212: install 0.0% -github.com/apache/camel-k/v2/pkg/cmd/install.go:258: setupEnvVars 0.0% -github.com/apache/camel-k/v2/pkg/cmd/install.go:273: tryInstallViaOLM 0.0% -github.com/apache/camel-k/v2/pkg/cmd/install.go:315: installOperator 0.0% -github.com/apache/camel-k/v2/pkg/cmd/install.go:386: getOperatorID 0.0% -github.com/apache/camel-k/v2/pkg/cmd/install.go:400: setupOperator 0.0% -github.com/apache/camel-k/v2/pkg/cmd/install.go:444: isInstallAllowed 0.0% -github.com/apache/camel-k/v2/pkg/cmd/install.go:457: setupRegistrySecret 0.0% -github.com/apache/camel-k/v2/pkg/cmd/install.go:469: setupIntegrationPlatform 0.0% -github.com/apache/camel-k/v2/pkg/cmd/install.go:612: printOutput 0.0% -github.com/apache/camel-k/v2/pkg/cmd/install.go:634: waitForPlatformReady 0.0% -github.com/apache/camel-k/v2/pkg/cmd/install.go:655: postRun 0.0% -github.com/apache/camel-k/v2/pkg/cmd/install.go:670: decode 94.4% -github.com/apache/camel-k/v2/pkg/cmd/install.go:695: validate 0.0% -github.com/apache/camel-k/v2/pkg/cmd/install.go:788: decodeMavenSettings 100.0% -github.com/apache/camel-k/v2/pkg/cmd/install.go:792: decodeSecretKeySelector 0.0% -github.com/apache/camel-k/v2/pkg/cmd/install.go:809: createDefaultMavenSettingsConfigMap 0.0% -github.com/apache/camel-k/v2/pkg/cmd/install.go:844: settingsConfigMap 0.0% +github.com/apache/camel-k/v2/pkg/cmd/install.go:57: newCmdInstall 89.9% +github.com/apache/camel-k/v2/pkg/cmd/install.go:210: install 0.0% +github.com/apache/camel-k/v2/pkg/cmd/install.go:256: setupEnvVars 0.0% +github.com/apache/camel-k/v2/pkg/cmd/install.go:271: tryInstallViaOLM 0.0% +github.com/apache/camel-k/v2/pkg/cmd/install.go:313: installOperator 0.0% +github.com/apache/camel-k/v2/pkg/cmd/install.go:391: getOperatorID 0.0% +github.com/apache/camel-k/v2/pkg/cmd/install.go:405: setupOperator 0.0% +github.com/apache/camel-k/v2/pkg/cmd/install.go:449: isInstallAllowed 0.0% +github.com/apache/camel-k/v2/pkg/cmd/install.go:462: setupRegistrySecret 0.0% +github.com/apache/camel-k/v2/pkg/cmd/install.go:474: setupIntegrationPlatform 0.0% +github.com/apache/camel-k/v2/pkg/cmd/install.go:617: printOutput 0.0% +github.com/apache/camel-k/v2/pkg/cmd/install.go:639: waitForPlatformReady 0.0% +github.com/apache/camel-k/v2/pkg/cmd/install.go:660: postRun 0.0% +github.com/apache/camel-k/v2/pkg/cmd/install.go:675: decode 94.4% +github.com/apache/camel-k/v2/pkg/cmd/install.go:701: validate 0.0% +github.com/apache/camel-k/v2/pkg/cmd/install.go:794: decodeSecretKeySelector 0.0% +github.com/apache/camel-k/v2/pkg/cmd/install.go:811: createDefaultMavenSettingsConfigMap 0.0% +github.com/apache/camel-k/v2/pkg/cmd/install.go:846: settingsConfigMap 0.0% github.com/apache/camel-k/v2/pkg/cmd/kamelet.go:24: newCmdKamelet 100.0% github.com/apache/camel-k/v2/pkg/cmd/kamelet_add_repo.go:35: newKameletAddRepoCmd 57.1% github.com/apache/camel-k/v2/pkg/cmd/kamelet_add_repo.go:69: validate 0.0% @@ -868,8 +873,8 @@ github.com/apache/camel-k/v2/pkg/cmd/modeline.go:220: extractModelineOptio github.com/apache/camel-k/v2/pkg/cmd/modeline.go:252: getRefPathOrProperty 100.0% github.com/apache/camel-k/v2/pkg/cmd/modeline.go:259: getFullPathOrProperty 100.0% github.com/apache/camel-k/v2/pkg/cmd/modeline.go:266: expandModelineEnvVarOptions 43.8% -github.com/apache/camel-k/v2/pkg/cmd/operator.go:30: newCmdOperator 100.0% -github.com/apache/camel-k/v2/pkg/cmd/operator.go:57: run 0.0% +github.com/apache/camel-k/v2/pkg/cmd/operator.go:29: newCmdOperator 100.0% +github.com/apache/camel-k/v2/pkg/cmd/operator.go:56: run 0.0% github.com/apache/camel-k/v2/pkg/cmd/promote.go:48: newCmdPromote 100.0% github.com/apache/camel-k/v2/pkg/cmd/promote.go:76: validate 57.1% github.com/apache/camel-k/v2/pkg/cmd/promote.go:89: run 55.2% @@ -905,71 +910,71 @@ github.com/apache/camel-k/v2/pkg/cmd/reset.go:137: deleteAllPipes 0.0 github.com/apache/camel-k/v2/pkg/cmd/reset.go:152: deleteAllKameletBindings 0.0% github.com/apache/camel-k/v2/pkg/cmd/reset.go:166: resetIntegrationPlatform 0.0% github.com/apache/camel-k/v2/pkg/cmd/reset.go:182: isIntegrationOwned 0.0% -github.com/apache/camel-k/v2/pkg/cmd/root.go:55: NewKamelCommand 87.5% -github.com/apache/camel-k/v2/pkg/cmd/root.go:75: kamelPreAddCommandInit 100.0% -github.com/apache/camel-k/v2/pkg/cmd/root.go:95: kamelPostAddCommandInit 88.9% -github.com/apache/camel-k/v2/pkg/cmd/root.go:133: addKamelSubcommands 100.0% -github.com/apache/camel-k/v2/pkg/cmd/root.go:156: addHelpSubCommands 90.0% -github.com/apache/camel-k/v2/pkg/cmd/root.go:175: preRun 82.4% -github.com/apache/camel-k/v2/pkg/cmd/root.go:209: checkAndShowCompatibilityWarning 71.4% -github.com/apache/camel-k/v2/pkg/cmd/root.go:225: GetCmdClient 100.0% -github.com/apache/camel-k/v2/pkg/cmd/root.go:236: GetCamelCmdClient 0.0% -github.com/apache/camel-k/v2/pkg/cmd/root.go:245: NewCmdClient 100.0% -github.com/apache/camel-k/v2/pkg/cmd/root.go:249: PrintVerboseOut 0.0% -github.com/apache/camel-k/v2/pkg/cmd/root.go:255: PrintfVerboseOutf 0.0% -github.com/apache/camel-k/v2/pkg/cmd/root.go:260: PrintfVerboseErrf 0.0% -github.com/apache/camel-k/v2/pkg/cmd/root.go:266: wrappedFlagUsages 0.0% -github.com/apache/camel-k/v2/pkg/cmd/run.go:81: newCmdRun 100.0% -github.com/apache/camel-k/v2/pkg/cmd/run.go:173: decode 87.0% -github.com/apache/camel-k/v2/pkg/cmd/run.go:240: validateArgs 100.0% -github.com/apache/camel-k/v2/pkg/cmd/run.go:248: validate 80.6% -github.com/apache/camel-k/v2/pkg/cmd/run.go:304: filterBuildPropertyFiles 100.0% -github.com/apache/camel-k/v2/pkg/cmd/run.go:315: run 28.3% -github.com/apache/camel-k/v2/pkg/cmd/run.go:405: postRun 18.2% -github.com/apache/camel-k/v2/pkg/cmd/run.go:426: waitForIntegrationReady 0.0% -github.com/apache/camel-k/v2/pkg/cmd/run.go:445: syncIntegration 0.0% -github.com/apache/camel-k/v2/pkg/cmd/run.go:506: createOrUpdateIntegration 75.5% -github.com/apache/camel-k/v2/pkg/cmd/run.go:605: showIntegrationOutput 100.0% -github.com/apache/camel-k/v2/pkg/cmd/run.go:613: getIntegration 88.9% -github.com/apache/camel-k/v2/pkg/cmd/run.go:641: applyLabels 16.7% -github.com/apache/camel-k/v2/pkg/cmd/run.go:653: applyAnnotations 42.1% -github.com/apache/camel-k/v2/pkg/cmd/run.go:692: resolveSources 85.7% -github.com/apache/camel-k/v2/pkg/cmd/run.go:723: convertOptionsToTraits 50.0% -github.com/apache/camel-k/v2/pkg/cmd/run.go:761: parseAndConvertToTrait 22.2% -github.com/apache/camel-k/v2/pkg/cmd/run.go:782: convertToTrait 0.0% -github.com/apache/camel-k/v2/pkg/cmd/run.go:786: applyProperties 84.6% -github.com/apache/camel-k/v2/pkg/cmd/run.go:807: convertToTraitParameter 78.6% -github.com/apache/camel-k/v2/pkg/cmd/run.go:830: applyDependencies 21.1% -github.com/apache/camel-k/v2/pkg/cmd/run.go:867: getPlatform 0.0% -github.com/apache/camel-k/v2/pkg/cmd/run.go:890: GetIntegrationName 100.0% -github.com/apache/camel-k/v2/pkg/cmd/run.go:905: mergePropertiesWithPrecedence 92.9% -github.com/apache/camel-k/v2/pkg/cmd/run.go:931: extractProperties 60.0% -github.com/apache/camel-k/v2/pkg/cmd/run.go:945: loadPropertyFile 71.4% -github.com/apache/camel-k/v2/pkg/cmd/run.go:957: resolvePodTemplate 73.3% -github.com/apache/camel-k/v2/pkg/cmd/run.go:988: parseFileURI 0.0% -github.com/apache/camel-k/v2/pkg/cmd/run.go:1002: getRegistry 0.0% -github.com/apache/camel-k/v2/pkg/cmd/run.go:1010: skipChecksums 0.0% -github.com/apache/camel-k/v2/pkg/cmd/run.go:1014: skipPom 0.0% -github.com/apache/camel-k/v2/pkg/cmd/run.go:1018: classpath 0.0% -github.com/apache/camel-k/v2/pkg/cmd/run.go:1022: getTargetPath 0.0% -github.com/apache/camel-k/v2/pkg/cmd/run.go:1027: uploadDependency 0.0% -github.com/apache/camel-k/v2/pkg/cmd/run.go:1107: getMountPath 0.0% -github.com/apache/camel-k/v2/pkg/cmd/run.go:1121: uploadPomFromJar 0.0% -github.com/apache/camel-k/v2/pkg/cmd/run.go:1163: extractFromZip 0.0% -github.com/apache/camel-k/v2/pkg/cmd/run.go:1180: extractGav 0.0% -github.com/apache/camel-k/v2/pkg/cmd/run.go:1220: uploadAsMavenArtifact 0.0% -github.com/apache/camel-k/v2/pkg/cmd/run.go:1238: extractGavFromPom 0.0% -github.com/apache/camel-k/v2/pkg/cmd/run.go:1263: uploadChecksumFiles 0.0% -github.com/apache/camel-k/v2/pkg/cmd/run.go:1274: uploadChecksumFile 0.0% -github.com/apache/camel-k/v2/pkg/cmd/run.go:1296: writeChecksumToFile 0.0% -github.com/apache/camel-k/v2/pkg/cmd/run.go:1307: getSpectrumOptions 0.0% -github.com/apache/camel-k/v2/pkg/cmd/run.go:1326: getArtifactHTTPPath 0.0% -github.com/apache/camel-k/v2/pkg/cmd/run.go:1340: createDefaultGav 0.0% -github.com/apache/camel-k/v2/pkg/cmd/run.go:1361: isPom 0.0% -github.com/apache/camel-k/v2/pkg/cmd/run.go:1365: isJar 0.0% -github.com/apache/camel-k/v2/pkg/cmd/run.go:1369: getFileRelativePathAndExtension 0.0% -github.com/apache/camel-k/v2/pkg/cmd/run.go:1378: getDirName 0.0% -github.com/apache/camel-k/v2/pkg/cmd/run.go:1390: contains 0.0% +github.com/apache/camel-k/v2/pkg/cmd/root.go:56: NewKamelCommand 87.5% +github.com/apache/camel-k/v2/pkg/cmd/root.go:77: kamelPreAddCommandInit 100.0% +github.com/apache/camel-k/v2/pkg/cmd/root.go:97: kamelPostAddCommandInit 88.9% +github.com/apache/camel-k/v2/pkg/cmd/root.go:135: addKamelSubcommands 100.0% +github.com/apache/camel-k/v2/pkg/cmd/root.go:158: addHelpSubCommands 90.0% +github.com/apache/camel-k/v2/pkg/cmd/root.go:177: preRun 82.4% +github.com/apache/camel-k/v2/pkg/cmd/root.go:211: checkAndShowCompatibilityWarning 71.4% +github.com/apache/camel-k/v2/pkg/cmd/root.go:227: GetCmdClient 100.0% +github.com/apache/camel-k/v2/pkg/cmd/root.go:238: GetCamelCmdClient 0.0% +github.com/apache/camel-k/v2/pkg/cmd/root.go:247: NewCmdClient 100.0% +github.com/apache/camel-k/v2/pkg/cmd/root.go:251: PrintVerboseOut 0.0% +github.com/apache/camel-k/v2/pkg/cmd/root.go:257: PrintfVerboseOutf 0.0% +github.com/apache/camel-k/v2/pkg/cmd/root.go:262: PrintfVerboseErrf 0.0% +github.com/apache/camel-k/v2/pkg/cmd/root.go:268: wrappedFlagUsages 0.0% +github.com/apache/camel-k/v2/pkg/cmd/run.go:79: newCmdRun 100.0% +github.com/apache/camel-k/v2/pkg/cmd/run.go:171: decode 87.0% +github.com/apache/camel-k/v2/pkg/cmd/run.go:239: validateArgs 100.0% +github.com/apache/camel-k/v2/pkg/cmd/run.go:247: validate 80.6% +github.com/apache/camel-k/v2/pkg/cmd/run.go:303: filterBuildPropertyFiles 100.0% +github.com/apache/camel-k/v2/pkg/cmd/run.go:314: run 28.3% +github.com/apache/camel-k/v2/pkg/cmd/run.go:404: postRun 18.2% +github.com/apache/camel-k/v2/pkg/cmd/run.go:425: waitForIntegrationReady 0.0% +github.com/apache/camel-k/v2/pkg/cmd/run.go:444: syncIntegration 0.0% +github.com/apache/camel-k/v2/pkg/cmd/run.go:505: createOrUpdateIntegration 75.5% +github.com/apache/camel-k/v2/pkg/cmd/run.go:604: showIntegrationOutput 100.0% +github.com/apache/camel-k/v2/pkg/cmd/run.go:612: getIntegration 88.9% +github.com/apache/camel-k/v2/pkg/cmd/run.go:640: applyLabels 16.7% +github.com/apache/camel-k/v2/pkg/cmd/run.go:652: applyAnnotations 42.1% +github.com/apache/camel-k/v2/pkg/cmd/run.go:691: resolveSources 85.7% +github.com/apache/camel-k/v2/pkg/cmd/run.go:722: convertOptionsToTraits 50.0% +github.com/apache/camel-k/v2/pkg/cmd/run.go:760: parseAndConvertToTrait 22.2% +github.com/apache/camel-k/v2/pkg/cmd/run.go:781: convertToTrait 0.0% +github.com/apache/camel-k/v2/pkg/cmd/run.go:785: applyProperties 84.6% +github.com/apache/camel-k/v2/pkg/cmd/run.go:806: convertToTraitParameter 78.6% +github.com/apache/camel-k/v2/pkg/cmd/run.go:829: applyDependencies 21.1% +github.com/apache/camel-k/v2/pkg/cmd/run.go:866: getPlatform 0.0% +github.com/apache/camel-k/v2/pkg/cmd/run.go:889: GetIntegrationName 100.0% +github.com/apache/camel-k/v2/pkg/cmd/run.go:904: mergePropertiesWithPrecedence 92.9% +github.com/apache/camel-k/v2/pkg/cmd/run.go:930: extractProperties 60.0% +github.com/apache/camel-k/v2/pkg/cmd/run.go:944: loadPropertyFile 71.4% +github.com/apache/camel-k/v2/pkg/cmd/run.go:956: resolvePodTemplate 73.3% +github.com/apache/camel-k/v2/pkg/cmd/run.go:987: parseFileURI 0.0% +github.com/apache/camel-k/v2/pkg/cmd/run.go:1001: getRegistry 0.0% +github.com/apache/camel-k/v2/pkg/cmd/run.go:1009: skipChecksums 0.0% +github.com/apache/camel-k/v2/pkg/cmd/run.go:1013: skipPom 0.0% +github.com/apache/camel-k/v2/pkg/cmd/run.go:1017: classpath 0.0% +github.com/apache/camel-k/v2/pkg/cmd/run.go:1021: getTargetPath 0.0% +github.com/apache/camel-k/v2/pkg/cmd/run.go:1026: uploadDependency 0.0% +github.com/apache/camel-k/v2/pkg/cmd/run.go:1106: getMountPath 0.0% +github.com/apache/camel-k/v2/pkg/cmd/run.go:1120: uploadPomFromJar 0.0% +github.com/apache/camel-k/v2/pkg/cmd/run.go:1162: extractFromZip 0.0% +github.com/apache/camel-k/v2/pkg/cmd/run.go:1179: extractGav 0.0% +github.com/apache/camel-k/v2/pkg/cmd/run.go:1219: uploadAsMavenArtifact 0.0% +github.com/apache/camel-k/v2/pkg/cmd/run.go:1237: extractGavFromPom 0.0% +github.com/apache/camel-k/v2/pkg/cmd/run.go:1262: uploadChecksumFiles 0.0% +github.com/apache/camel-k/v2/pkg/cmd/run.go:1273: uploadChecksumFile 0.0% +github.com/apache/camel-k/v2/pkg/cmd/run.go:1295: writeChecksumToFile 0.0% +github.com/apache/camel-k/v2/pkg/cmd/run.go:1306: getSpectrumOptions 0.0% +github.com/apache/camel-k/v2/pkg/cmd/run.go:1325: getArtifactHTTPPath 0.0% +github.com/apache/camel-k/v2/pkg/cmd/run.go:1339: createDefaultGav 0.0% +github.com/apache/camel-k/v2/pkg/cmd/run.go:1360: isPom 0.0% +github.com/apache/camel-k/v2/pkg/cmd/run.go:1364: isJar 0.0% +github.com/apache/camel-k/v2/pkg/cmd/run.go:1368: getFileRelativePathAndExtension 0.0% +github.com/apache/camel-k/v2/pkg/cmd/run.go:1377: getDirName 0.0% +github.com/apache/camel-k/v2/pkg/cmd/run.go:1389: contains 0.0% github.com/apache/camel-k/v2/pkg/cmd/run_support.go:43: addDependency 0.0% github.com/apache/camel-k/v2/pkg/cmd/run_support.go:49: parseConfig 0.0% github.com/apache/camel-k/v2/pkg/cmd/run_support.go:71: filterFileLocation 100.0% @@ -1005,40 +1010,40 @@ github.com/apache/camel-k/v2/pkg/cmd/trait_support.go:52: configureTraits github.com/apache/camel-k/v2/pkg/cmd/trait_support.go:99: optionsToMap 68.0% github.com/apache/camel-k/v2/pkg/cmd/trait_support.go:147: configureAddons 0.0% github.com/apache/camel-k/v2/pkg/cmd/trait_support.go:181: configureAddon 0.0% -github.com/apache/camel-k/v2/pkg/cmd/uninstall.go:45: newCmdUninstall 100.0% -github.com/apache/camel-k/v2/pkg/cmd/uninstall.go:108: decode 85.7% -github.com/apache/camel-k/v2/pkg/cmd/uninstall.go:121: uninstall 0.0% -github.com/apache/camel-k/v2/pkg/cmd/uninstall.go:200: uninstallOperator 0.0% -github.com/apache/camel-k/v2/pkg/cmd/uninstall.go:218: uninstallClusterWideResources 0.0% -github.com/apache/camel-k/v2/pkg/cmd/uninstall.go:261: uninstallNamespaceRoles 0.0% -github.com/apache/camel-k/v2/pkg/cmd/uninstall.go:292: uninstallNamespaceResources 0.0% -github.com/apache/camel-k/v2/pkg/cmd/uninstall.go:324: uninstallCrd 0.0% -github.com/apache/camel-k/v2/pkg/cmd/uninstall.go:349: uninstallRoles 0.0% -github.com/apache/camel-k/v2/pkg/cmd/uninstall.go:367: uninstallRoleBindings 0.0% -github.com/apache/camel-k/v2/pkg/cmd/uninstall.go:385: uninstallKEP1755RoleBindings 0.0% -github.com/apache/camel-k/v2/pkg/cmd/uninstall.go:403: uninstallClusterRoles 0.0% -github.com/apache/camel-k/v2/pkg/cmd/uninstall.go:421: removeSubjectFromClusterRoleBindings 0.0% -github.com/apache/camel-k/v2/pkg/cmd/uninstall.go:446: uninstallClusterRoleBindings 0.0% -github.com/apache/camel-k/v2/pkg/cmd/uninstall.go:464: uninstallServiceAccounts 0.0% -github.com/apache/camel-k/v2/pkg/cmd/uninstall.go:482: uninstallIntegrationPlatform 0.0% -github.com/apache/camel-k/v2/pkg/cmd/uninstall.go:498: uninstallIntegrationProfile 0.0% -github.com/apache/camel-k/v2/pkg/cmd/uninstall.go:514: uninstallConfigMaps 0.0% -github.com/apache/camel-k/v2/pkg/cmd/uninstall.go:532: uninstallRegistrySecret 0.0% -github.com/apache/camel-k/v2/pkg/cmd/uninstall.go:550: uninstallKamelets 0.0% -github.com/apache/camel-k/v2/pkg/cmd/uninstall.go:569: uninstallCamelCatalogs 0.0% -github.com/apache/camel-k/v2/pkg/cmd/uninstall.go:585: createActionNotAuthorizedError 0.0% +github.com/apache/camel-k/v2/pkg/cmd/uninstall.go:43: newCmdUninstall 100.0% +github.com/apache/camel-k/v2/pkg/cmd/uninstall.go:106: decode 85.7% +github.com/apache/camel-k/v2/pkg/cmd/uninstall.go:120: uninstall 0.0% +github.com/apache/camel-k/v2/pkg/cmd/uninstall.go:199: uninstallOperator 0.0% +github.com/apache/camel-k/v2/pkg/cmd/uninstall.go:217: uninstallClusterWideResources 0.0% +github.com/apache/camel-k/v2/pkg/cmd/uninstall.go:260: uninstallNamespaceRoles 0.0% +github.com/apache/camel-k/v2/pkg/cmd/uninstall.go:291: uninstallNamespaceResources 0.0% +github.com/apache/camel-k/v2/pkg/cmd/uninstall.go:323: uninstallCrd 0.0% +github.com/apache/camel-k/v2/pkg/cmd/uninstall.go:348: uninstallRoles 0.0% +github.com/apache/camel-k/v2/pkg/cmd/uninstall.go:366: uninstallRoleBindings 0.0% +github.com/apache/camel-k/v2/pkg/cmd/uninstall.go:384: uninstallKEP1755RoleBindings 0.0% +github.com/apache/camel-k/v2/pkg/cmd/uninstall.go:402: uninstallClusterRoles 0.0% +github.com/apache/camel-k/v2/pkg/cmd/uninstall.go:420: removeSubjectFromClusterRoleBindings 0.0% +github.com/apache/camel-k/v2/pkg/cmd/uninstall.go:445: uninstallClusterRoleBindings 0.0% +github.com/apache/camel-k/v2/pkg/cmd/uninstall.go:463: uninstallServiceAccounts 0.0% +github.com/apache/camel-k/v2/pkg/cmd/uninstall.go:481: uninstallIntegrationPlatform 0.0% +github.com/apache/camel-k/v2/pkg/cmd/uninstall.go:497: uninstallIntegrationProfile 0.0% +github.com/apache/camel-k/v2/pkg/cmd/uninstall.go:513: uninstallConfigMaps 0.0% +github.com/apache/camel-k/v2/pkg/cmd/uninstall.go:531: uninstallRegistrySecret 0.0% +github.com/apache/camel-k/v2/pkg/cmd/uninstall.go:549: uninstallKamelets 0.0% +github.com/apache/camel-k/v2/pkg/cmd/uninstall.go:568: uninstallCamelCatalogs 0.0% +github.com/apache/camel-k/v2/pkg/cmd/uninstall.go:584: createActionNotAuthorizedError 0.0% github.com/apache/camel-k/v2/pkg/cmd/util.go:48: DeleteIntegration 0.0% github.com/apache/camel-k/v2/pkg/cmd/util.go:62: bindPFlagsHierarchy 66.7% github.com/apache/camel-k/v2/pkg/cmd/util.go:76: bindPFlags 84.6% github.com/apache/camel-k/v2/pkg/cmd/util.go:103: pathToRoot 100.0% -github.com/apache/camel-k/v2/pkg/cmd/util.go:116: decodeKey 82.4% -github.com/apache/camel-k/v2/pkg/cmd/util.go:157: decode 80.0% -github.com/apache/camel-k/v2/pkg/cmd/util.go:168: stringToSliceHookFunc 86.7% -github.com/apache/camel-k/v2/pkg/cmd/util.go:194: cmdOnly 100.0% -github.com/apache/camel-k/v2/pkg/cmd/util.go:198: isOfflineCommand 100.0% -github.com/apache/camel-k/v2/pkg/cmd/util.go:202: clone 63.6% -github.com/apache/camel-k/v2/pkg/cmd/util.go:222: fieldByMapstructureTagName 90.9% -github.com/apache/camel-k/v2/pkg/cmd/util.go:243: verifyOperatorID 42.9% +github.com/apache/camel-k/v2/pkg/cmd/util.go:116: decodeKey 81.2% +github.com/apache/camel-k/v2/pkg/cmd/util.go:156: decode 80.0% +github.com/apache/camel-k/v2/pkg/cmd/util.go:167: stringToSliceHookFunc 86.7% +github.com/apache/camel-k/v2/pkg/cmd/util.go:193: cmdOnly 100.0% +github.com/apache/camel-k/v2/pkg/cmd/util.go:197: isOfflineCommand 100.0% +github.com/apache/camel-k/v2/pkg/cmd/util.go:201: clone 63.6% +github.com/apache/camel-k/v2/pkg/cmd/util.go:221: fieldByMapstructureTagName 90.9% +github.com/apache/camel-k/v2/pkg/cmd/util.go:242: verifyOperatorID 42.9% github.com/apache/camel-k/v2/pkg/cmd/util_config.go:56: LoadConfiguration 0.0% github.com/apache/camel-k/v2/pkg/cmd/util_config.go:61: LoadConfigurationFrom 100.0% github.com/apache/camel-k/v2/pkg/cmd/util_config.go:65: loadConfiguration 75.0% @@ -1146,48 +1151,46 @@ github.com/apache/camel-k/v2/pkg/controller/integration/initialize.go:49: Can github.com/apache/camel-k/v2/pkg/controller/integration/initialize.go:54: Handle 11.5% github.com/apache/camel-k/v2/pkg/controller/integration/initialize.go:100: importFromExternalApp 100.0% github.com/apache/camel-k/v2/pkg/controller/integration/initialize.go:123: getCamelAppImportingCondition 100.0% -github.com/apache/camel-k/v2/pkg/controller/integration/integration_controller.go:58: Add 0.0% -github.com/apache/camel-k/v2/pkg/controller/integration/integration_controller.go:72: newReconciler 0.0% -github.com/apache/camel-k/v2/pkg/controller/integration/integration_controller.go:87: integrationUpdateFunc 0.0% -github.com/apache/camel-k/v2/pkg/controller/integration/integration_controller.go:117: isIntegrationUpdated 0.0% -github.com/apache/camel-k/v2/pkg/controller/integration/integration_controller.go:127: integrationKitEnqueueRequestsFromMapFunc 0.0% -github.com/apache/camel-k/v2/pkg/controller/integration/integration_controller.go:174: configmapEnqueueRequestsFromMapFunc 0.0% -github.com/apache/camel-k/v2/pkg/controller/integration/integration_controller.go:224: secretEnqueueRequestsFromMapFunc 0.0% -github.com/apache/camel-k/v2/pkg/controller/integration/integration_controller.go:274: integrationProfileEnqueueRequestsFromMapFunc 0.0% -github.com/apache/camel-k/v2/pkg/controller/integration/integration_controller.go:310: integrationPlatformEnqueueRequestsFromMapFunc 0.0% -github.com/apache/camel-k/v2/pkg/controller/integration/integration_controller.go:343: add 0.0% -github.com/apache/camel-k/v2/pkg/controller/integration/integration_controller.go:384: watchIntegrationResources 0.0% -github.com/apache/camel-k/v2/pkg/controller/integration/integration_controller.go:469: watchCronJobResources 0.0% -github.com/apache/camel-k/v2/pkg/controller/integration/integration_controller.go:474: watchKnativeResources 0.0% -github.com/apache/camel-k/v2/pkg/controller/integration/integration_controller.go:516: Reconcile 0.0% -github.com/apache/camel-k/v2/pkg/controller/integration/integration_controller.go:597: update 0.0% -github.com/apache/camel-k/v2/pkg/controller/integration/kits.go:40: lookupKitsForIntegration 81.0% -github.com/apache/camel-k/v2/pkg/controller/integration/kits.go:88: sameOrMatch 0.0% -github.com/apache/camel-k/v2/pkg/controller/integration/kits.go:99: integrationMatches 65.4% -github.com/apache/camel-k/v2/pkg/controller/integration/kits.go:154: statusMatches 41.7% -github.com/apache/camel-k/v2/pkg/controller/integration/kits.go:175: kitMatches 0.0% -github.com/apache/camel-k/v2/pkg/controller/integration/kits.go:208: hasMatchingTraits 81.2% -github.com/apache/camel-k/v2/pkg/controller/integration/kits.go:241: matchesComparableTrait 0.0% -github.com/apache/camel-k/v2/pkg/controller/integration/kits.go:264: matchesTrait 100.0% -github.com/apache/camel-k/v2/pkg/controller/integration/kits.go:269: hasMatchingSourcesForNative 100.0% -github.com/apache/camel-k/v2/pkg/controller/integration/metrics.go:42: init 100.0% -github.com/apache/camel-k/v2/pkg/controller/integration/monitor.go:47: NewMonitorAction 0.0% -github.com/apache/camel-k/v2/pkg/controller/integration/monitor.go:55: Name 0.0% -github.com/apache/camel-k/v2/pkg/controller/integration/monitor.go:59: CanHandle 100.0% -github.com/apache/camel-k/v2/pkg/controller/integration/monitor.go:65: Handle 0.0% -github.com/apache/camel-k/v2/pkg/controller/integration/monitor.go:132: monitorPods 77.8% -github.com/apache/camel-k/v2/pkg/controller/integration/monitor.go:205: isInInitializationFailed 0.0% -github.com/apache/camel-k/v2/pkg/controller/integration/monitor.go:219: isInIntegrationKitFailed 0.0% -github.com/apache/camel-k/v2/pkg/controller/integration/monitor.go:230: checkDigestAndRebuild 0.0% +github.com/apache/camel-k/v2/pkg/controller/integration/integration_controller.go:59: Add 0.0% +github.com/apache/camel-k/v2/pkg/controller/integration/integration_controller.go:73: newReconciler 0.0% +github.com/apache/camel-k/v2/pkg/controller/integration/integration_controller.go:88: integrationUpdateFunc 0.0% +github.com/apache/camel-k/v2/pkg/controller/integration/integration_controller.go:119: isIntegrationUpdated 0.0% +github.com/apache/camel-k/v2/pkg/controller/integration/integration_controller.go:129: integrationKitEnqueueRequestsFromMapFunc 0.0% +github.com/apache/camel-k/v2/pkg/controller/integration/integration_controller.go:176: configmapEnqueueRequestsFromMapFunc 0.0% +github.com/apache/camel-k/v2/pkg/controller/integration/integration_controller.go:226: secretEnqueueRequestsFromMapFunc 0.0% +github.com/apache/camel-k/v2/pkg/controller/integration/integration_controller.go:276: integrationProfileEnqueueRequestsFromMapFunc 0.0% +github.com/apache/camel-k/v2/pkg/controller/integration/integration_controller.go:312: integrationPlatformEnqueueRequestsFromMapFunc 0.0% +github.com/apache/camel-k/v2/pkg/controller/integration/integration_controller.go:345: add 0.0% +github.com/apache/camel-k/v2/pkg/controller/integration/integration_controller.go:386: watchIntegrationResources 0.0% +github.com/apache/camel-k/v2/pkg/controller/integration/integration_controller.go:471: watchCronJobResources 0.0% +github.com/apache/camel-k/v2/pkg/controller/integration/integration_controller.go:476: watchKnativeResources 0.0% +github.com/apache/camel-k/v2/pkg/controller/integration/integration_controller.go:518: Reconcile 0.0% +github.com/apache/camel-k/v2/pkg/controller/integration/integration_controller.go:599: update 0.0% +github.com/apache/camel-k/v2/pkg/controller/integration/kits.go:38: lookupKitsForIntegration 81.0% +github.com/apache/camel-k/v2/pkg/controller/integration/kits.go:86: sameOrMatch 0.0% +github.com/apache/camel-k/v2/pkg/controller/integration/kits.go:97: integrationMatches 65.4% +github.com/apache/camel-k/v2/pkg/controller/integration/kits.go:152: statusMatches 41.7% +github.com/apache/camel-k/v2/pkg/controller/integration/kits.go:173: kitMatches 0.0% +github.com/apache/camel-k/v2/pkg/controller/integration/kits.go:206: hasMatchingSourcesForNative 100.0% +github.com/apache/camel-k/v2/pkg/controller/integration/metrics.go:55: init 100.0% +github.com/apache/camel-k/v2/pkg/controller/integration/metrics.go:60: updateIntegrationPhase 100.0% +github.com/apache/camel-k/v2/pkg/controller/integration/monitor.go:49: NewMonitorAction 0.0% +github.com/apache/camel-k/v2/pkg/controller/integration/monitor.go:57: Name 0.0% +github.com/apache/camel-k/v2/pkg/controller/integration/monitor.go:61: CanHandle 100.0% +github.com/apache/camel-k/v2/pkg/controller/integration/monitor.go:67: Handle 0.0% +github.com/apache/camel-k/v2/pkg/controller/integration/monitor.go:134: monitorPods 77.8% +github.com/apache/camel-k/v2/pkg/controller/integration/monitor.go:207: isInInitializationFailed 0.0% +github.com/apache/camel-k/v2/pkg/controller/integration/monitor.go:221: isInIntegrationKitFailed 0.0% +github.com/apache/camel-k/v2/pkg/controller/integration/monitor.go:232: checkDigestAndRebuild 0.0% github.com/apache/camel-k/v2/pkg/controller/integration/monitor.go:253: isIntegrationKitResetRequired 0.0% -github.com/apache/camel-k/v2/pkg/controller/integration/monitor.go:282: getIntegrationSecretsAndConfigmaps 0.0% -github.com/apache/camel-k/v2/pkg/controller/integration/monitor.go:320: newController 77.3% -github.com/apache/camel-k/v2/pkg/controller/integration/monitor.go:367: getUpdatedController 100.0% -github.com/apache/camel-k/v2/pkg/controller/integration/monitor.go:373: updateIntegrationPhaseAndReadyCondition 53.3% -github.com/apache/camel-k/v2/pkg/controller/integration/monitor.go:402: arePodsFailingStatuses 30.0% -github.com/apache/camel-k/v2/pkg/controller/integration/monitor.go:456: probeReadiness 35.2% -github.com/apache/camel-k/v2/pkg/controller/integration/monitor.go:580: findHighestPriorityReadyKit 0.0% -github.com/apache/camel-k/v2/pkg/controller/integration/monitor.go:602: getIntegrationContainer 0.0% +github.com/apache/camel-k/v2/pkg/controller/integration/monitor.go:283: getIntegrationSecretAndConfigmapResourceVersions 100.0% +github.com/apache/camel-k/v2/pkg/controller/integration/monitor.go:331: newController 77.3% +github.com/apache/camel-k/v2/pkg/controller/integration/monitor.go:378: getUpdatedController 100.0% +github.com/apache/camel-k/v2/pkg/controller/integration/monitor.go:384: updateIntegrationPhaseAndReadyCondition 53.3% +github.com/apache/camel-k/v2/pkg/controller/integration/monitor.go:413: arePodsFailingStatuses 30.0% +github.com/apache/camel-k/v2/pkg/controller/integration/monitor.go:467: probeReadiness 35.2% +github.com/apache/camel-k/v2/pkg/controller/integration/monitor.go:591: findHighestPriorityReadyKit 0.0% +github.com/apache/camel-k/v2/pkg/controller/integration/monitor.go:613: getIntegrationContainer 0.0% github.com/apache/camel-k/v2/pkg/controller/integration/monitor_cronjob.go:43: checkReadyCondition 12.5% github.com/apache/camel-k/v2/pkg/controller/integration/monitor_cronjob.go:76: getPodSpec 0.0% github.com/apache/camel-k/v2/pkg/controller/integration/monitor_cronjob.go:80: updateReadyCondition 25.0% @@ -1260,9 +1263,9 @@ github.com/apache/camel-k/v2/pkg/controller/kameletbinding/monitor.go:55: Han github.com/apache/camel-k/v2/pkg/controller/kameletbinding/monitor.go:162: setKameletBindingReadyCondition 0.0% github.com/apache/camel-k/v2/pkg/controller/pipe/action.go:48: InjectClient 0.0% github.com/apache/camel-k/v2/pkg/controller/pipe/action.go:52: InjectLogger 0.0% -github.com/apache/camel-k/v2/pkg/controller/pipe/error_handler.go:29: maybeErrorHandler 20.0% +github.com/apache/camel-k/v2/pkg/controller/pipe/error_handler.go:29: maybeErrorHandler 80.0% github.com/apache/camel-k/v2/pkg/controller/pipe/error_handler.go:59: parseErrorHandler 73.7% -github.com/apache/camel-k/v2/pkg/controller/pipe/error_handler.go:95: setErrorHandlerConfiguration 0.0% +github.com/apache/camel-k/v2/pkg/controller/pipe/error_handler.go:95: setErrorHandlerConfiguration 90.0% github.com/apache/camel-k/v2/pkg/controller/pipe/initialize.go:38: NewInitializeAction 0.0% github.com/apache/camel-k/v2/pkg/controller/pipe/initialize.go:46: Name 0.0% github.com/apache/camel-k/v2/pkg/controller/pipe/initialize.go:50: CanHandle 0.0% @@ -1271,7 +1274,7 @@ github.com/apache/camel-k/v2/pkg/controller/pipe/initialize.go:86: propagate github.com/apache/camel-k/v2/pkg/controller/pipe/initialize.go:117: findIcon 0.0% github.com/apache/camel-k/v2/pkg/controller/pipe/integration.go:46: CreateIntegrationFor 64.4% github.com/apache/camel-k/v2/pkg/controller/pipe/integration.go:213: configureBinding 81.8% -github.com/apache/camel-k/v2/pkg/controller/pipe/integration.go:238: determineTraitProfile 36.8% +github.com/apache/camel-k/v2/pkg/controller/pipe/integration.go:235: determineTraitProfile 36.8% github.com/apache/camel-k/v2/pkg/controller/pipe/monitor.go:35: NewMonitorAction 0.0% github.com/apache/camel-k/v2/pkg/controller/pipe/monitor.go:43: Name 0.0% github.com/apache/camel-k/v2/pkg/controller/pipe/monitor.go:47: CanHandle 0.0% @@ -1423,61 +1426,61 @@ github.com/apache/camel-k/v2/pkg/trait/affinity.go:120: addPodAffinity github.com/apache/camel-k/v2/pkg/trait/affinity.go:171: addPodAntiAffinity 89.5% github.com/apache/camel-k/v2/pkg/trait/affinity.go:222: operatorToNodeSelectorOperator 25.0% github.com/apache/camel-k/v2/pkg/trait/affinity.go:240: operatorToLabelSelectorOperator 50.0% -github.com/apache/camel-k/v2/pkg/trait/builder.go:48: newBuilderTrait 100.0% -github.com/apache/camel-k/v2/pkg/trait/builder.go:55: InfluencesKit 100.0% -github.com/apache/camel-k/v2/pkg/trait/builder.go:60: InfluencesBuild 0.0% -github.com/apache/camel-k/v2/pkg/trait/builder.go:64: Configure 44.4% -github.com/apache/camel-k/v2/pkg/trait/builder.go:109: existsTaskRequest 100.0% -github.com/apache/camel-k/v2/pkg/trait/builder.go:119: adaptDeprecatedFields 95.8% -github.com/apache/camel-k/v2/pkg/trait/builder.go:152: newOrAppend 100.0% -github.com/apache/camel-k/v2/pkg/trait/builder.go:162: Apply 88.1% -github.com/apache/camel-k/v2/pkg/trait/builder.go:288: failIntegrationKit 80.0% -github.com/apache/camel-k/v2/pkg/trait/builder.go:297: builderTask 66.7% -github.com/apache/camel-k/v2/pkg/trait/builder.go:410: getImageName 100.0% -github.com/apache/camel-k/v2/pkg/trait/builder.go:418: getBaseImage 100.0% -github.com/apache/camel-k/v2/pkg/trait/builder.go:427: customTasks 91.7% -github.com/apache/camel-k/v2/pkg/trait/builder.go:457: taskConfOrDefault 66.7% -github.com/apache/camel-k/v2/pkg/trait/builder.go:465: parseTasksConf 92.1% -github.com/apache/camel-k/v2/pkg/trait/builder.go:526: splitContainerCommand 100.0% -github.com/apache/camel-k/v2/pkg/trait/builder.go:540: filter 81.8% -github.com/apache/camel-k/v2/pkg/trait/builder.go:581: publishingOrUserTask 80.0% +github.com/apache/camel-k/v2/pkg/trait/builder.go:49: newBuilderTrait 100.0% +github.com/apache/camel-k/v2/pkg/trait/builder.go:56: InfluencesKit 100.0% +github.com/apache/camel-k/v2/pkg/trait/builder.go:60: Matches 90.0% +github.com/apache/camel-k/v2/pkg/trait/builder.go:89: Configure 44.4% +github.com/apache/camel-k/v2/pkg/trait/builder.go:134: existsTaskRequest 100.0% +github.com/apache/camel-k/v2/pkg/trait/builder.go:144: adaptDeprecatedFields 95.8% +github.com/apache/camel-k/v2/pkg/trait/builder.go:177: newOrAppend 100.0% +github.com/apache/camel-k/v2/pkg/trait/builder.go:187: Apply 88.9% +github.com/apache/camel-k/v2/pkg/trait/builder.go:317: failIntegrationKit 80.0% +github.com/apache/camel-k/v2/pkg/trait/builder.go:326: builderTask 66.7% +github.com/apache/camel-k/v2/pkg/trait/builder.go:439: getImageName 100.0% +github.com/apache/camel-k/v2/pkg/trait/builder.go:447: getBaseImage 100.0% +github.com/apache/camel-k/v2/pkg/trait/builder.go:456: customTasks 91.7% +github.com/apache/camel-k/v2/pkg/trait/builder.go:486: taskConfOrDefault 66.7% +github.com/apache/camel-k/v2/pkg/trait/builder.go:494: parseTasksConf 92.1% +github.com/apache/camel-k/v2/pkg/trait/builder.go:555: splitContainerCommand 100.0% +github.com/apache/camel-k/v2/pkg/trait/builder.go:569: filter 81.8% +github.com/apache/camel-k/v2/pkg/trait/builder.go:610: publishingOrUserTask 80.0% github.com/apache/camel-k/v2/pkg/trait/camel.go:45: newCamelTrait 100.0% github.com/apache/camel-k/v2/pkg/trait/camel.go:52: InfluencesKit 100.0% -github.com/apache/camel-k/v2/pkg/trait/camel.go:57: InfluencesBuild 0.0% -github.com/apache/camel-k/v2/pkg/trait/camel.go:61: Configure 80.0% -github.com/apache/camel-k/v2/pkg/trait/camel.go:74: Apply 93.8% -github.com/apache/camel-k/v2/pkg/trait/camel.go:105: loadOrCreateCatalog 56.2% -github.com/apache/camel-k/v2/pkg/trait/camel.go:144: computeConfigMaps 100.0% -github.com/apache/camel-k/v2/pkg/trait/camel.go:225: determineRuntimeVersion 66.7% +github.com/apache/camel-k/v2/pkg/trait/camel.go:56: Matches 75.0% +github.com/apache/camel-k/v2/pkg/trait/camel.go:65: Configure 80.0% +github.com/apache/camel-k/v2/pkg/trait/camel.go:78: Apply 93.8% +github.com/apache/camel-k/v2/pkg/trait/camel.go:109: loadOrCreateCatalog 56.2% +github.com/apache/camel-k/v2/pkg/trait/camel.go:148: computeConfigMaps 100.0% +github.com/apache/camel-k/v2/pkg/trait/camel.go:229: determineRuntimeVersion 66.7% github.com/apache/camel-k/v2/pkg/trait/container.go:58: newContainerTrait 100.0% github.com/apache/camel-k/v2/pkg/trait/container.go:70: Configure 80.0% -github.com/apache/camel-k/v2/pkg/trait/container.go:113: isValidPullPolicy 100.0% -github.com/apache/camel-k/v2/pkg/trait/container.go:117: Apply 100.0% -github.com/apache/camel-k/v2/pkg/trait/container.go:124: configureImageIntegrationKit 71.4% -github.com/apache/camel-k/v2/pkg/trait/container.go:174: configureContainer 86.3% -github.com/apache/camel-k/v2/pkg/trait/container.go:273: configureService 91.7% -github.com/apache/camel-k/v2/pkg/trait/container.go:315: configureResources 81.0% -github.com/apache/camel-k/v2/pkg/trait/container.go:347: configureCapabilities 50.0% -github.com/apache/camel-k/v2/pkg/trait/container.go:353: configureSecurityContext 100.0% +github.com/apache/camel-k/v2/pkg/trait/container.go:114: isValidPullPolicy 100.0% +github.com/apache/camel-k/v2/pkg/trait/container.go:118: Apply 100.0% +github.com/apache/camel-k/v2/pkg/trait/container.go:125: configureImageIntegrationKit 71.4% +github.com/apache/camel-k/v2/pkg/trait/container.go:175: configureContainer 86.3% +github.com/apache/camel-k/v2/pkg/trait/container.go:274: configureService 91.7% +github.com/apache/camel-k/v2/pkg/trait/container.go:316: configureResources 81.0% +github.com/apache/camel-k/v2/pkg/trait/container.go:348: configureCapabilities 50.0% +github.com/apache/camel-k/v2/pkg/trait/container.go:354: configureSecurityContext 100.0% github.com/apache/camel-k/v2/pkg/trait/cron.go:70: newCronTrait 100.0% -github.com/apache/camel-k/v2/pkg/trait/cron.go:76: Configure 73.2% -github.com/apache/camel-k/v2/pkg/trait/cron.go:169: Apply 94.4% -github.com/apache/camel-k/v2/pkg/trait/cron.go:205: getCronJobFor 83.3% -github.com/apache/camel-k/v2/pkg/trait/cron.go:265: SelectControllerStrategy 80.0% -github.com/apache/camel-k/v2/pkg/trait/cron.go:282: ControllerStrategySelectorOrder 100.0% -github.com/apache/camel-k/v2/pkg/trait/cron.go:288: newCronInfo 100.0% -github.com/apache/camel-k/v2/pkg/trait/cron.go:292: withComponents 100.0% -github.com/apache/camel-k/v2/pkg/trait/cron.go:299: withSchedule 100.0% -github.com/apache/camel-k/v2/pkg/trait/cron.go:304: getGlobalCron 94.1% -github.com/apache/camel-k/v2/pkg/trait/cron.go:332: getSourcesFromURIs 75.0% -github.com/apache/camel-k/v2/pkg/trait/cron.go:346: getCronForURIs 100.0% -github.com/apache/camel-k/v2/pkg/trait/cron.go:365: getCronForURI 100.0% -github.com/apache/camel-k/v2/pkg/trait/cron.go:375: timerToCronInfo 100.0% -github.com/apache/camel-k/v2/pkg/trait/cron.go:411: quartzToCronInfo 100.0% -github.com/apache/camel-k/v2/pkg/trait/cron.go:428: cronToCronInfo 100.0% -github.com/apache/camel-k/v2/pkg/trait/cron.go:441: cronEquivalent 100.0% -github.com/apache/camel-k/v2/pkg/trait/cron.go:448: toKubernetesCronSchedule 100.0% -github.com/apache/camel-k/v2/pkg/trait/cron.go:471: checkedStringToUint64 75.0% +github.com/apache/camel-k/v2/pkg/trait/cron.go:76: Configure 78.0% +github.com/apache/camel-k/v2/pkg/trait/cron.go:173: Apply 94.4% +github.com/apache/camel-k/v2/pkg/trait/cron.go:209: getCronJobFor 83.3% +github.com/apache/camel-k/v2/pkg/trait/cron.go:269: SelectControllerStrategy 80.0% +github.com/apache/camel-k/v2/pkg/trait/cron.go:286: ControllerStrategySelectorOrder 100.0% +github.com/apache/camel-k/v2/pkg/trait/cron.go:292: newCronInfo 100.0% +github.com/apache/camel-k/v2/pkg/trait/cron.go:296: withComponents 100.0% +github.com/apache/camel-k/v2/pkg/trait/cron.go:303: withSchedule 100.0% +github.com/apache/camel-k/v2/pkg/trait/cron.go:308: getGlobalCron 94.1% +github.com/apache/camel-k/v2/pkg/trait/cron.go:336: getSourcesFromURIs 75.0% +github.com/apache/camel-k/v2/pkg/trait/cron.go:350: getCronForURIs 100.0% +github.com/apache/camel-k/v2/pkg/trait/cron.go:369: getCronForURI 100.0% +github.com/apache/camel-k/v2/pkg/trait/cron.go:379: timerToCronInfo 100.0% +github.com/apache/camel-k/v2/pkg/trait/cron.go:415: quartzToCronInfo 100.0% +github.com/apache/camel-k/v2/pkg/trait/cron.go:432: cronToCronInfo 100.0% +github.com/apache/camel-k/v2/pkg/trait/cron.go:445: cronEquivalent 100.0% +github.com/apache/camel-k/v2/pkg/trait/cron.go:452: toKubernetesCronSchedule 100.0% +github.com/apache/camel-k/v2/pkg/trait/cron.go:475: checkedStringToUint64 75.0% github.com/apache/camel-k/v2/pkg/trait/dependencies.go:35: newDependenciesTrait 100.0% github.com/apache/camel-k/v2/pkg/trait/dependencies.go:41: Configure 66.7% github.com/apache/camel-k/v2/pkg/trait/dependencies.go:49: Apply 85.2% @@ -1493,18 +1496,18 @@ github.com/apache/camel-k/v2/pkg/trait/deployer.go:166: ControllerStrategy github.com/apache/camel-k/v2/pkg/trait/deployer.go:171: RequiresIntegrationPlatform 100.0% github.com/apache/camel-k/v2/pkg/trait/deployment.go:40: newDeploymentTrait 100.0% github.com/apache/camel-k/v2/pkg/trait/deployment.go:46: Configure 90.9% -github.com/apache/camel-k/v2/pkg/trait/deployment.go:79: SelectControllerStrategy 100.0% -github.com/apache/camel-k/v2/pkg/trait/deployment.go:84: ControllerStrategySelectorOrder 100.0% -github.com/apache/camel-k/v2/pkg/trait/deployment.go:88: Apply 100.0% -github.com/apache/camel-k/v2/pkg/trait/deployment.go:102: getDeploymentFor 100.0% +github.com/apache/camel-k/v2/pkg/trait/deployment.go:81: SelectControllerStrategy 100.0% +github.com/apache/camel-k/v2/pkg/trait/deployment.go:86: ControllerStrategySelectorOrder 100.0% +github.com/apache/camel-k/v2/pkg/trait/deployment.go:90: Apply 100.0% +github.com/apache/camel-k/v2/pkg/trait/deployment.go:104: getDeploymentFor 100.0% github.com/apache/camel-k/v2/pkg/trait/environment.go:55: newEnvironmentTrait 100.0% github.com/apache/camel-k/v2/pkg/trait/environment.go:64: Configure 66.7% github.com/apache/camel-k/v2/pkg/trait/environment.go:72: Apply 86.4% -github.com/apache/camel-k/v2/pkg/trait/error_handler.go:37: newErrorHandlerTrait 100.0% -github.com/apache/camel-k/v2/pkg/trait/error_handler.go:44: Configure 85.7% -github.com/apache/camel-k/v2/pkg/trait/error_handler.go:60: Apply 83.3% -github.com/apache/camel-k/v2/pkg/trait/error_handler.go:75: addErrorHandlerDependencies 83.3% -github.com/apache/camel-k/v2/pkg/trait/error_handler.go:87: addErrorHandlerAsSource 85.7% +github.com/apache/camel-k/v2/pkg/trait/error_handler.go:36: newErrorHandlerTrait 100.0% +github.com/apache/camel-k/v2/pkg/trait/error_handler.go:43: Configure 85.7% +github.com/apache/camel-k/v2/pkg/trait/error_handler.go:59: Apply 83.3% +github.com/apache/camel-k/v2/pkg/trait/error_handler.go:74: addErrorHandlerDependencies 83.3% +github.com/apache/camel-k/v2/pkg/trait/error_handler.go:86: addGlobalErrorHandlerAsSource 85.7% github.com/apache/camel-k/v2/pkg/trait/gc.go:58: newGCTrait 100.0% github.com/apache/camel-k/v2/pkg/trait/gc.go:64: Configure 80.0% github.com/apache/camel-k/v2/pkg/trait/gc.go:75: Apply 91.7% @@ -1521,7 +1524,7 @@ github.com/apache/camel-k/v2/pkg/trait/health.go:156: newStartupProbe github.com/apache/camel-k/v2/pkg/trait/ingress.go:38: newIngressTrait 100.0% github.com/apache/camel-k/v2/pkg/trait/ingress.go:51: IsAllowedInProfile 100.0% github.com/apache/camel-k/v2/pkg/trait/ingress.go:55: Configure 90.0% -github.com/apache/camel-k/v2/pkg/trait/ingress.go:80: Apply 100.0% +github.com/apache/camel-k/v2/pkg/trait/ingress.go:81: Apply 100.0% github.com/apache/camel-k/v2/pkg/trait/init.go:39: NewInitTrait 100.0% github.com/apache/camel-k/v2/pkg/trait/init.go:45: Configure 66.7% github.com/apache/camel-k/v2/pkg/trait/init.go:53: Apply 71.4% @@ -1537,18 +1540,18 @@ github.com/apache/camel-k/v2/pkg/trait/jolokia.go:170: addToJolokiaOptions github.com/apache/camel-k/v2/pkg/trait/jvm.go:48: newJvmTrait 100.0% github.com/apache/camel-k/v2/pkg/trait/jvm.go:58: Configure 91.7% github.com/apache/camel-k/v2/pkg/trait/jvm.go:85: Apply 50.0% -github.com/apache/camel-k/v2/pkg/trait/kamelets.go:56: newConfigurationKey 100.0% -github.com/apache/camel-k/v2/pkg/trait/kamelets.go:68: newKameletsTrait 100.0% -github.com/apache/camel-k/v2/pkg/trait/kamelets.go:74: Configure 75.0% -github.com/apache/camel-k/v2/pkg/trait/kamelets.go:104: Apply 83.3% -github.com/apache/camel-k/v2/pkg/trait/kamelets.go:117: collectKamelets 90.9% -github.com/apache/camel-k/v2/pkg/trait/kamelets.go:170: addKamelets 88.5% -github.com/apache/camel-k/v2/pkg/trait/kamelets.go:215: addKameletAsSource 80.0% -github.com/apache/camel-k/v2/pkg/trait/kamelets.go:264: addConfigurationSecrets 91.7% -github.com/apache/camel-k/v2/pkg/trait/kamelets.go:291: getKameletKeys 100.0% -github.com/apache/camel-k/v2/pkg/trait/kamelets.go:306: getConfigurationKeys 90.0% -github.com/apache/camel-k/v2/pkg/trait/kamelets.go:336: integrationSourceFromKameletSource 86.7% -github.com/apache/camel-k/v2/pkg/trait/kamelets.go:363: initializeConfigmapKameletSource 100.0% +github.com/apache/camel-k/v2/pkg/trait/kamelets.go:57: newConfigurationKey 100.0% +github.com/apache/camel-k/v2/pkg/trait/kamelets.go:69: newKameletsTrait 100.0% +github.com/apache/camel-k/v2/pkg/trait/kamelets.go:75: Configure 75.0% +github.com/apache/camel-k/v2/pkg/trait/kamelets.go:105: Apply 100.0% +github.com/apache/camel-k/v2/pkg/trait/kamelets.go:114: collectKamelets 90.9% +github.com/apache/camel-k/v2/pkg/trait/kamelets.go:167: addKamelets 88.5% +github.com/apache/camel-k/v2/pkg/trait/kamelets.go:212: addKameletAsSource 80.0% +github.com/apache/camel-k/v2/pkg/trait/kamelets.go:262: listConfigurationSecrets 92.3% +github.com/apache/camel-k/v2/pkg/trait/kamelets.go:285: getKameletKeys 100.0% +github.com/apache/camel-k/v2/pkg/trait/kamelets.go:300: getConfigurationKeys 90.0% +github.com/apache/camel-k/v2/pkg/trait/kamelets.go:330: integrationSourceFromKameletSource 86.7% +github.com/apache/camel-k/v2/pkg/trait/kamelets.go:357: initializeConfigmapKameletSource 100.0% github.com/apache/camel-k/v2/pkg/trait/kamelets_support.go:36: newKameletBundle 100.0% github.com/apache/camel-k/v2/pkg/trait/kamelets_support.go:42: add 100.0% github.com/apache/camel-k/v2/pkg/trait/kamelets_support.go:47: toConfigmaps 94.1% @@ -1557,33 +1560,34 @@ github.com/apache/camel-k/v2/pkg/trait/knative.go:56: newKnativeTrait github.com/apache/camel-k/v2/pkg/trait/knative.go:65: IsAllowedInProfile 100.0% github.com/apache/camel-k/v2/pkg/trait/knative.go:69: Configure 78.3% github.com/apache/camel-k/v2/pkg/trait/knative.go:139: filterMetaItems 91.7% -github.com/apache/camel-k/v2/pkg/trait/knative.go:158: Apply 77.8% -github.com/apache/camel-k/v2/pkg/trait/knative.go:206: configureChannels 74.1% -github.com/apache/camel-k/v2/pkg/trait/knative.go:264: createSubscription 80.0% -github.com/apache/camel-k/v2/pkg/trait/knative.go:273: configureEndpoints 76.2% -github.com/apache/camel-k/v2/pkg/trait/knative.go:321: configureEvents 84.0% -github.com/apache/camel-k/v2/pkg/trait/knative.go:378: isSinkBindingAllowed 77.8% -github.com/apache/camel-k/v2/pkg/trait/knative.go:395: configureSinkBinding 88.1% -github.com/apache/camel-k/v2/pkg/trait/knative.go:476: createTrigger 71.4% -github.com/apache/camel-k/v2/pkg/trait/knative.go:492: ifServiceMissingDo 100.0% -github.com/apache/camel-k/v2/pkg/trait/knative.go:502: withServiceDo 76.0% -github.com/apache/camel-k/v2/pkg/trait/knative.go:549: extractServices 100.0% +github.com/apache/camel-k/v2/pkg/trait/knative.go:158: Apply 75.0% +github.com/apache/camel-k/v2/pkg/trait/knative.go:200: configureChannels 74.1% +github.com/apache/camel-k/v2/pkg/trait/knative.go:258: createSubscription 80.0% +github.com/apache/camel-k/v2/pkg/trait/knative.go:267: configureEndpoints 76.2% +github.com/apache/camel-k/v2/pkg/trait/knative.go:315: configureEvents 84.0% +github.com/apache/camel-k/v2/pkg/trait/knative.go:372: isSinkBindingAllowed 77.8% +github.com/apache/camel-k/v2/pkg/trait/knative.go:389: configureSinkBinding 88.1% +github.com/apache/camel-k/v2/pkg/trait/knative.go:470: createTrigger 71.4% +github.com/apache/camel-k/v2/pkg/trait/knative.go:486: ifServiceMissingDo 100.0% +github.com/apache/camel-k/v2/pkg/trait/knative.go:496: withServiceDo 76.0% +github.com/apache/camel-k/v2/pkg/trait/knative.go:543: extractServices 100.0% github.com/apache/camel-k/v2/pkg/trait/knative_service.go:58: newKnativeServiceTrait 100.0% github.com/apache/camel-k/v2/pkg/trait/knative_service.go:68: IsAllowedInProfile 100.0% github.com/apache/camel-k/v2/pkg/trait/knative_service.go:72: Configure 70.6% -github.com/apache/camel-k/v2/pkg/trait/knative_service.go:125: Apply 83.3% -github.com/apache/camel-k/v2/pkg/trait/knative_service.go:142: SelectControllerStrategy 84.6% -github.com/apache/camel-k/v2/pkg/trait/knative_service.go:165: ControllerStrategySelectorOrder 100.0% -github.com/apache/camel-k/v2/pkg/trait/knative_service.go:169: getServiceFor 47.5% +github.com/apache/camel-k/v2/pkg/trait/knative_service.go:129: Apply 83.3% +github.com/apache/camel-k/v2/pkg/trait/knative_service.go:146: SelectControllerStrategy 84.6% +github.com/apache/camel-k/v2/pkg/trait/knative_service.go:169: ControllerStrategySelectorOrder 100.0% +github.com/apache/camel-k/v2/pkg/trait/knative_service.go:173: getServiceFor 47.5% github.com/apache/camel-k/v2/pkg/trait/logging.go:42: newLoggingTraitTrait 100.0% github.com/apache/camel-k/v2/pkg/trait/logging.go:51: Configure 60.0% github.com/apache/camel-k/v2/pkg/trait/logging.go:63: Apply 90.9% -github.com/apache/camel-k/v2/pkg/trait/mount.go:41: newMountTrait 100.0% -github.com/apache/camel-k/v2/pkg/trait/mount.go:48: Configure 80.0% -github.com/apache/camel-k/v2/pkg/trait/mount.go:74: Apply 80.8% -github.com/apache/camel-k/v2/pkg/trait/mount.go:123: configureVolumesAndMounts 76.9% -github.com/apache/camel-k/v2/pkg/trait/mount.go:149: mountResource 93.3% -github.com/apache/camel-k/v2/pkg/trait/mount.go:172: addServiceBindingSecret 33.3% +github.com/apache/camel-k/v2/pkg/trait/mount.go:43: newMountTrait 100.0% +github.com/apache/camel-k/v2/pkg/trait/mount.go:50: Configure 81.8% +github.com/apache/camel-k/v2/pkg/trait/mount.go:79: Apply 80.8% +github.com/apache/camel-k/v2/pkg/trait/mount.go:128: configureVolumesAndMounts 76.9% +github.com/apache/camel-k/v2/pkg/trait/mount.go:154: mountResource 93.3% +github.com/apache/camel-k/v2/pkg/trait/mount.go:177: addServiceBindingSecret 33.3% +github.com/apache/camel-k/v2/pkg/trait/mount.go:187: addImplicitKameletsSecrets 62.5% github.com/apache/camel-k/v2/pkg/trait/openapi.go:52: newOpenAPITrait 100.0% github.com/apache/camel-k/v2/pkg/trait/openapi.go:58: Configure 85.7% github.com/apache/camel-k/v2/pkg/trait/openapi.go:75: Apply 0.0% @@ -1612,60 +1616,58 @@ github.com/apache/camel-k/v2/pkg/trait/pod.go:61: Apply 52.4% github.com/apache/camel-k/v2/pkg/trait/pod.go:103: applyChangesTo 75.0% github.com/apache/camel-k/v2/pkg/trait/prometheus.go:39: newPrometheusTrait 100.0% github.com/apache/camel-k/v2/pkg/trait/prometheus.go:48: Configure 100.0% -github.com/apache/camel-k/v2/pkg/trait/prometheus.go:56: Apply 73.3% -github.com/apache/camel-k/v2/pkg/trait/prometheus.go:122: getContainerPort 100.0% -github.com/apache/camel-k/v2/pkg/trait/prometheus.go:145: getPodMonitorFor 83.3% +github.com/apache/camel-k/v2/pkg/trait/prometheus.go:56: Apply 81.5% +github.com/apache/camel-k/v2/pkg/trait/prometheus.go:117: getContainerPort 100.0% +github.com/apache/camel-k/v2/pkg/trait/prometheus.go:140: getPodMonitorFor 83.3% github.com/apache/camel-k/v2/pkg/trait/pull_secret.go:41: newPullSecretTrait 100.0% github.com/apache/camel-k/v2/pkg/trait/pull_secret.go:47: Configure 67.9% github.com/apache/camel-k/v2/pkg/trait/pull_secret.go:91: Apply 85.7% github.com/apache/camel-k/v2/pkg/trait/pull_secret.go:108: delegateImagePuller 75.0% github.com/apache/camel-k/v2/pkg/trait/pull_secret.go:118: newImagePullerRoleBinding 70.0% -github.com/apache/camel-k/v2/pkg/trait/quarkus.go:75: getLanguageSettings 100.0% -github.com/apache/camel-k/v2/pkg/trait/quarkus.go:93: getLegacyLanguageSettings 100.0% -github.com/apache/camel-k/v2/pkg/trait/quarkus.go:102: newQuarkusTrait 100.0% -github.com/apache/camel-k/v2/pkg/trait/quarkus.go:109: InfluencesKit 100.0% -github.com/apache/camel-k/v2/pkg/trait/quarkus.go:114: InfluencesBuild 0.0% -github.com/apache/camel-k/v2/pkg/trait/quarkus.go:120: Matches 0.0% -github.com/apache/camel-k/v2/pkg/trait/quarkus.go:143: Configure 100.0% -github.com/apache/camel-k/v2/pkg/trait/quarkus.go:152: adaptDeprecatedFields 18.2% -github.com/apache/camel-k/v2/pkg/trait/quarkus.go:171: Apply 77.8% -github.com/apache/camel-k/v2/pkg/trait/quarkus.go:193: applyWhileBuildingKit 81.2% -github.com/apache/camel-k/v2/pkg/trait/quarkus.go:228: validateNativeSupport 42.9% -github.com/apache/camel-k/v2/pkg/trait/quarkus.go:246: newIntegrationKit 70.0% -github.com/apache/camel-k/v2/pkg/trait/quarkus.go:301: propagateKitTraits 85.7% -github.com/apache/camel-k/v2/pkg/trait/quarkus.go:317: propagate 33.3% -github.com/apache/camel-k/v2/pkg/trait/quarkus.go:343: applyWhenBuildSubmitted 62.8% -github.com/apache/camel-k/v2/pkg/trait/quarkus.go:419: isNativeKit 50.0% -github.com/apache/camel-k/v2/pkg/trait/quarkus.go:430: isIncrementalImageBuild 75.0% -github.com/apache/camel-k/v2/pkg/trait/quarkus.go:441: applyWhenKitReady 28.6% -github.com/apache/camel-k/v2/pkg/trait/quarkus.go:455: isNativeIntegration 100.0% -github.com/apache/camel-k/v2/pkg/trait/quarkus.go:461: isEmbedded 66.7% -github.com/apache/camel-k/v2/pkg/trait/quarkus.go:471: containsMode 100.0% -github.com/apache/camel-k/v2/pkg/trait/quarkus.go:480: packageType 80.0% -github.com/apache/camel-k/v2/pkg/trait/quarkus.go:492: sourcesRequiredAtBuildTime 100.0% -github.com/apache/camel-k/v2/pkg/trait/quarkus.go:498: propagateSourcesRequiredAtBuildTime 80.0% +github.com/apache/camel-k/v2/pkg/trait/quarkus.go:74: getLanguageSettings 100.0% +github.com/apache/camel-k/v2/pkg/trait/quarkus.go:92: getLegacyLanguageSettings 100.0% +github.com/apache/camel-k/v2/pkg/trait/quarkus.go:101: newQuarkusTrait 100.0% +github.com/apache/camel-k/v2/pkg/trait/quarkus.go:108: InfluencesKit 100.0% +github.com/apache/camel-k/v2/pkg/trait/quarkus.go:112: Matches 88.9% +github.com/apache/camel-k/v2/pkg/trait/quarkus.go:142: Configure 100.0% +github.com/apache/camel-k/v2/pkg/trait/quarkus.go:151: adaptDeprecatedFields 18.2% +github.com/apache/camel-k/v2/pkg/trait/quarkus.go:170: Apply 77.8% +github.com/apache/camel-k/v2/pkg/trait/quarkus.go:192: applyWhileBuildingKit 81.2% +github.com/apache/camel-k/v2/pkg/trait/quarkus.go:227: validateNativeSupport 42.9% +github.com/apache/camel-k/v2/pkg/trait/quarkus.go:245: newIntegrationKit 68.2% +github.com/apache/camel-k/v2/pkg/trait/quarkus.go:299: propagateKitTraits 85.7% +github.com/apache/camel-k/v2/pkg/trait/quarkus.go:315: propagate 33.3% +github.com/apache/camel-k/v2/pkg/trait/quarkus.go:342: applyWhenBuildSubmitted 62.8% +github.com/apache/camel-k/v2/pkg/trait/quarkus.go:418: isNativeKit 50.0% +github.com/apache/camel-k/v2/pkg/trait/quarkus.go:429: isIncrementalImageBuild 75.0% +github.com/apache/camel-k/v2/pkg/trait/quarkus.go:440: applyWhenKitReady 28.6% +github.com/apache/camel-k/v2/pkg/trait/quarkus.go:454: isNativeIntegration 100.0% +github.com/apache/camel-k/v2/pkg/trait/quarkus.go:460: isEmbedded 66.7% +github.com/apache/camel-k/v2/pkg/trait/quarkus.go:470: containsMode 100.0% +github.com/apache/camel-k/v2/pkg/trait/quarkus.go:479: packageType 80.0% +github.com/apache/camel-k/v2/pkg/trait/quarkus.go:491: sourcesRequiredAtBuildTime 100.0% +github.com/apache/camel-k/v2/pkg/trait/quarkus.go:497: propagateSourcesRequiredAtBuildTime 80.0% github.com/apache/camel-k/v2/pkg/trait/registry.go:46: newRegistryTrait 100.0% github.com/apache/camel-k/v2/pkg/trait/registry.go:53: InfluencesKit 100.0% -github.com/apache/camel-k/v2/pkg/trait/registry.go:58: InfluencesBuild 0.0% -github.com/apache/camel-k/v2/pkg/trait/registry.go:62: Configure 66.7% -github.com/apache/camel-k/v2/pkg/trait/registry.go:71: Apply 0.0% -github.com/apache/camel-k/v2/pkg/trait/registry.go:115: addRegistryAndExtensionToMaven 0.0% -github.com/apache/camel-k/v2/pkg/trait/registry.go:140: getOpenShiftRegistrySecret 0.0% -github.com/apache/camel-k/v2/pkg/trait/registry.go:164: extractMavenServerCredentialsFromSecret 0.0% -github.com/apache/camel-k/v2/pkg/trait/registry.go:213: getDockerConfig 0.0% -github.com/apache/camel-k/v2/pkg/trait/registry.go:232: getOpenShiftImageRegistryCA 0.0% -github.com/apache/camel-k/v2/pkg/trait/registry.go:255: addImageRegistryCaToMavenBuild 0.0% -github.com/apache/camel-k/v2/pkg/trait/registry.go:272: decodeSecretKeySelector 0.0% +github.com/apache/camel-k/v2/pkg/trait/registry.go:57: Configure 28.6% +github.com/apache/camel-k/v2/pkg/trait/registry.go:76: Apply 0.0% +github.com/apache/camel-k/v2/pkg/trait/registry.go:120: addRegistryAndExtensionToMaven 0.0% +github.com/apache/camel-k/v2/pkg/trait/registry.go:145: getOpenShiftRegistrySecret 0.0% +github.com/apache/camel-k/v2/pkg/trait/registry.go:169: extractMavenServerCredentialsFromSecret 0.0% +github.com/apache/camel-k/v2/pkg/trait/registry.go:218: getDockerConfig 0.0% +github.com/apache/camel-k/v2/pkg/trait/registry.go:237: getOpenShiftImageRegistryCA 0.0% +github.com/apache/camel-k/v2/pkg/trait/registry.go:260: addImageRegistryCaToMavenBuild 0.0% +github.com/apache/camel-k/v2/pkg/trait/registry.go:277: decodeSecretKeySelector 0.0% github.com/apache/camel-k/v2/pkg/trait/route.go:43: newRouteTrait 100.0% github.com/apache/camel-k/v2/pkg/trait/route.go:53: IsAllowedInProfile 100.0% github.com/apache/camel-k/v2/pkg/trait/route.go:57: Configure 100.0% -github.com/apache/camel-k/v2/pkg/trait/route.go:81: Apply 100.0% -github.com/apache/camel-k/v2/pkg/trait/route.go:146: getTLSConfig 92.0% -github.com/apache/camel-k/v2/pkg/trait/route.go:196: readContentIfExists 95.0% +github.com/apache/camel-k/v2/pkg/trait/route.go:82: Apply 100.0% +github.com/apache/camel-k/v2/pkg/trait/route.go:147: getTLSConfig 92.0% +github.com/apache/camel-k/v2/pkg/trait/route.go:197: readContentIfExists 95.0% github.com/apache/camel-k/v2/pkg/trait/service.go:40: newServiceTrait 100.0% github.com/apache/camel-k/v2/pkg/trait/service.go:46: Configure 81.8% -github.com/apache/camel-k/v2/pkg/trait/service.go:96: Apply 68.8% -github.com/apache/camel-k/v2/pkg/trait/service.go:124: getServiceFor 100.0% +github.com/apache/camel-k/v2/pkg/trait/service.go:98: Apply 68.8% +github.com/apache/camel-k/v2/pkg/trait/service.go:126: getServiceFor 100.0% github.com/apache/camel-k/v2/pkg/trait/service_binding.go:60: newServiceBindingTrait 100.0% github.com/apache/camel-k/v2/pkg/trait/service_binding.go:66: Configure 71.4% github.com/apache/camel-k/v2/pkg/trait/service_binding.go:80: Apply 63.6% @@ -1674,31 +1676,32 @@ github.com/apache/camel-k/v2/pkg/trait/service_binding.go:117: parseService github.com/apache/camel-k/v2/pkg/trait/service_binding.go:145: process 42.9% github.com/apache/camel-k/v2/pkg/trait/service_binding.go:158: createServiceBinding 100.0% github.com/apache/camel-k/v2/pkg/trait/service_binding.go:180: createSecret 83.3% -github.com/apache/camel-k/v2/pkg/trait/test_support.go:38: createNominalDeploymentTraitTest 100.0% -github.com/apache/camel-k/v2/pkg/trait/test_support.go:63: createNominalMissingDeploymentTraitTest 100.0% -github.com/apache/camel-k/v2/pkg/trait/test_support.go:79: createNominalKnativeServiceTraitTest 100.0% -github.com/apache/camel-k/v2/pkg/trait/test_support.go:102: createNominalCronJobTraitTest 100.0% -github.com/apache/camel-k/v2/pkg/trait/test_support.go:125: traitToMap 100.0% -github.com/apache/camel-k/v2/pkg/trait/test_support.go:139: ToAddonTrait 100.0% +github.com/apache/camel-k/v2/pkg/trait/test_support.go:37: createNominalDeploymentTraitTest 100.0% +github.com/apache/camel-k/v2/pkg/trait/test_support.go:62: createNominalMissingDeploymentTraitTest 100.0% +github.com/apache/camel-k/v2/pkg/trait/test_support.go:78: createNominalKnativeServiceTraitTest 100.0% +github.com/apache/camel-k/v2/pkg/trait/test_support.go:101: createNominalCronJobTraitTest 100.0% +github.com/apache/camel-k/v2/pkg/trait/test_support.go:124: traitToMap 100.0% +github.com/apache/camel-k/v2/pkg/trait/test_support.go:138: ToAddonTrait 100.0% github.com/apache/camel-k/v2/pkg/trait/toleration.go:35: newTolerationTrait 100.0% github.com/apache/camel-k/v2/pkg/trait/toleration.go:41: Configure 80.0% github.com/apache/camel-k/v2/pkg/trait/toleration.go:53: Apply 100.0% github.com/apache/camel-k/v2/pkg/trait/trait.go:38: Apply 0.0% -github.com/apache/camel-k/v2/pkg/trait/trait.go:103: newEnvironment 0.0% -github.com/apache/camel-k/v2/pkg/trait/trait.go:154: NewSyntheticEnvironment 0.0% -github.com/apache/camel-k/v2/pkg/trait/trait.go:199: getCamelAppObject 0.0% -github.com/apache/camel-k/v2/pkg/trait/trait_catalog.go:38: NewCatalog 100.0% -github.com/apache/camel-k/v2/pkg/trait/trait_catalog.go:63: AllTraits 100.0% -github.com/apache/camel-k/v2/pkg/trait/trait_catalog.go:69: traitsFor 100.0% -github.com/apache/camel-k/v2/pkg/trait/trait_catalog.go:78: TraitsForProfile 100.0% -github.com/apache/camel-k/v2/pkg/trait/trait_catalog.go:88: apply 81.1% -github.com/apache/camel-k/v2/pkg/trait/trait_catalog.go:152: GetTrait 100.0% -github.com/apache/camel-k/v2/pkg/trait/trait_condition_types.go:45: NewIntegrationCondition 100.0% -github.com/apache/camel-k/v2/pkg/trait/trait_condition_types.go:54: NewIntegrationConditionUserDisabled 100.0% -github.com/apache/camel-k/v2/pkg/trait/trait_condition_types.go:58: NewIntegrationConditionUserEnabledWithMessage 100.0% -github.com/apache/camel-k/v2/pkg/trait/trait_condition_types.go:62: newIntegrationConditionPlatformDisabledWithMessage 100.0% -github.com/apache/camel-k/v2/pkg/trait/trait_condition_types.go:66: integrationCondition 0.0% -github.com/apache/camel-k/v2/pkg/trait/trait_condition_types.go:70: integrationKitCondition 0.0% +github.com/apache/camel-k/v2/pkg/trait/trait.go:97: newEnvironment 0.0% +github.com/apache/camel-k/v2/pkg/trait/trait.go:148: NewSyntheticEnvironment 0.0% +github.com/apache/camel-k/v2/pkg/trait/trait.go:193: getCamelAppObject 0.0% +github.com/apache/camel-k/v2/pkg/trait/trait_catalog.go:39: NewCatalog 100.0% +github.com/apache/camel-k/v2/pkg/trait/trait_catalog.go:64: AllTraits 100.0% +github.com/apache/camel-k/v2/pkg/trait/trait_catalog.go:70: traitsFor 100.0% +github.com/apache/camel-k/v2/pkg/trait/trait_catalog.go:79: TraitsForProfile 100.0% +github.com/apache/camel-k/v2/pkg/trait/trait_catalog.go:89: apply 78.8% +github.com/apache/camel-k/v2/pkg/trait/trait_catalog.go:144: executedTraitCondition 100.0% +github.com/apache/camel-k/v2/pkg/trait/trait_catalog.go:156: GetTrait 100.0% +github.com/apache/camel-k/v2/pkg/trait/trait_condition_types.go:46: NewIntegrationCondition 100.0% +github.com/apache/camel-k/v2/pkg/trait/trait_condition_types.go:56: NewIntegrationConditionUserDisabled 100.0% +github.com/apache/camel-k/v2/pkg/trait/trait_condition_types.go:60: NewIntegrationConditionUserEnabledWithMessage 100.0% +github.com/apache/camel-k/v2/pkg/trait/trait_condition_types.go:64: newIntegrationConditionPlatformDisabledWithMessage 100.0% +github.com/apache/camel-k/v2/pkg/trait/trait_condition_types.go:68: integrationCondition 0.0% +github.com/apache/camel-k/v2/pkg/trait/trait_condition_types.go:75: integrationKitCondition 0.0% github.com/apache/camel-k/v2/pkg/trait/trait_configure.go:34: Configure 63.2% github.com/apache/camel-k/v2/pkg/trait/trait_configure.go:68: configureTraits 53.8% github.com/apache/camel-k/v2/pkg/trait/trait_configure.go:96: configureTrait 75.0% @@ -1713,39 +1716,39 @@ github.com/apache/camel-k/v2/pkg/trait/trait_types.go:124: NewBasePlatformT github.com/apache/camel-k/v2/pkg/trait/trait_types.go:143: ID 100.0% github.com/apache/camel-k/v2/pkg/trait/trait_types.go:148: InjectClient 100.0% github.com/apache/camel-k/v2/pkg/trait/trait_types.go:153: InfluencesKit 100.0% -github.com/apache/camel-k/v2/pkg/trait/trait_types.go:159: InfluencesBuild 0.0% -github.com/apache/camel-k/v2/pkg/trait/trait_types.go:164: IsPlatformTrait 100.0% -github.com/apache/camel-k/v2/pkg/trait/trait_types.go:169: RequiresIntegrationPlatform 100.0% -github.com/apache/camel-k/v2/pkg/trait/trait_types.go:175: IsAllowedInProfile 100.0% -github.com/apache/camel-k/v2/pkg/trait/trait_types.go:180: Order 100.0% -github.com/apache/camel-k/v2/pkg/trait/trait_types.go:190: IsPlatformTrait 100.0% -github.com/apache/camel-k/v2/pkg/trait/trait_types.go:247: GetTrait 100.0% -github.com/apache/camel-k/v2/pkg/trait/trait_types.go:257: IntegrationInPhase 100.0% -github.com/apache/camel-k/v2/pkg/trait/trait_types.go:271: IntegrationInRunningPhases 100.0% -github.com/apache/camel-k/v2/pkg/trait/trait_types.go:275: IntegrationKitInPhase 100.0% -github.com/apache/camel-k/v2/pkg/trait/trait_types.go:289: PlatformInPhase 66.7% -github.com/apache/camel-k/v2/pkg/trait/trait_types.go:303: InPhase 0.0% -github.com/apache/camel-k/v2/pkg/trait/trait_types.go:311: DetermineProfile 80.0% -github.com/apache/camel-k/v2/pkg/trait/trait_types.go:333: DetermineControllerStrategy 85.7% -github.com/apache/camel-k/v2/pkg/trait/trait_types.go:346: getControllerStrategyChoosers 100.0% -github.com/apache/camel-k/v2/pkg/trait/trait_types.go:360: GetIntegrationPodSpec 100.0% -github.com/apache/camel-k/v2/pkg/trait/trait_types.go:388: DetermineCatalogNamespace 18.2% -github.com/apache/camel-k/v2/pkg/trait/trait_types.go:408: computeApplicationProperties 83.3% -github.com/apache/camel-k/v2/pkg/trait/trait_types.go:439: addSourcesProperties 80.6% -github.com/apache/camel-k/v2/pkg/trait/trait_types.go:490: configureVolumesAndMounts 89.2% -github.com/apache/camel-k/v2/pkg/trait/trait_types.go:600: getVolume 100.0% -github.com/apache/camel-k/v2/pkg/trait/trait_types.go:628: getMount 100.0% -github.com/apache/camel-k/v2/pkg/trait/trait_types.go:641: convertToKeyToPath 100.0% -github.com/apache/camel-k/v2/pkg/trait/trait_types.go:658: getMountPoint 100.0% -github.com/apache/camel-k/v2/pkg/trait/trait_types.go:673: collectConfigurationValues 100.0% -github.com/apache/camel-k/v2/pkg/trait/trait_types.go:681: collectConfigurationPairs 100.0% -github.com/apache/camel-k/v2/pkg/trait/trait_types.go:685: collectConfigurations 100.0% -github.com/apache/camel-k/v2/pkg/trait/trait_types.go:689: GetIntegrationContainerName 100.0% -github.com/apache/camel-k/v2/pkg/trait/trait_types.go:701: isEmbedded 100.0% -github.com/apache/camel-k/v2/pkg/trait/trait_types.go:710: GetIntegrationContainer 100.0% -github.com/apache/camel-k/v2/pkg/trait/trait_types.go:715: getIntegrationContainerPort 76.9% +github.com/apache/camel-k/v2/pkg/trait/trait_types.go:158: IsPlatformTrait 100.0% +github.com/apache/camel-k/v2/pkg/trait/trait_types.go:163: RequiresIntegrationPlatform 100.0% +github.com/apache/camel-k/v2/pkg/trait/trait_types.go:169: IsAllowedInProfile 100.0% +github.com/apache/camel-k/v2/pkg/trait/trait_types.go:174: Order 100.0% +github.com/apache/camel-k/v2/pkg/trait/trait_types.go:184: IsPlatformTrait 100.0% +github.com/apache/camel-k/v2/pkg/trait/trait_types.go:241: GetTrait 100.0% +github.com/apache/camel-k/v2/pkg/trait/trait_types.go:251: IntegrationInPhase 100.0% +github.com/apache/camel-k/v2/pkg/trait/trait_types.go:265: IntegrationInRunningPhases 100.0% +github.com/apache/camel-k/v2/pkg/trait/trait_types.go:269: IntegrationKitInPhase 100.0% +github.com/apache/camel-k/v2/pkg/trait/trait_types.go:283: PlatformInPhase 66.7% +github.com/apache/camel-k/v2/pkg/trait/trait_types.go:297: InPhase 0.0% +github.com/apache/camel-k/v2/pkg/trait/trait_types.go:305: DetermineProfile 80.0% +github.com/apache/camel-k/v2/pkg/trait/trait_types.go:327: DetermineControllerStrategy 85.7% +github.com/apache/camel-k/v2/pkg/trait/trait_types.go:340: getControllerStrategyChoosers 100.0% +github.com/apache/camel-k/v2/pkg/trait/trait_types.go:354: GetIntegrationPodSpec 100.0% +github.com/apache/camel-k/v2/pkg/trait/trait_types.go:382: DetermineCatalogNamespace 18.2% +github.com/apache/camel-k/v2/pkg/trait/trait_types.go:402: computeApplicationProperties 83.3% +github.com/apache/camel-k/v2/pkg/trait/trait_types.go:433: addSourcesProperties 80.6% +github.com/apache/camel-k/v2/pkg/trait/trait_types.go:484: configureVolumesAndMounts 89.2% +github.com/apache/camel-k/v2/pkg/trait/trait_types.go:594: getVolume 100.0% +github.com/apache/camel-k/v2/pkg/trait/trait_types.go:622: getMount 100.0% +github.com/apache/camel-k/v2/pkg/trait/trait_types.go:635: convertToKeyToPath 100.0% +github.com/apache/camel-k/v2/pkg/trait/trait_types.go:652: getMountPoint 100.0% +github.com/apache/camel-k/v2/pkg/trait/trait_types.go:667: collectConfigurationValues 100.0% +github.com/apache/camel-k/v2/pkg/trait/trait_types.go:675: collectConfigurationPairs 100.0% +github.com/apache/camel-k/v2/pkg/trait/trait_types.go:679: collectConfigurations 100.0% +github.com/apache/camel-k/v2/pkg/trait/trait_types.go:683: GetIntegrationContainerName 100.0% +github.com/apache/camel-k/v2/pkg/trait/trait_types.go:695: isEmbedded 100.0% +github.com/apache/camel-k/v2/pkg/trait/trait_types.go:704: GetIntegrationContainer 100.0% +github.com/apache/camel-k/v2/pkg/trait/trait_types.go:709: getIntegrationContainerPort 76.9% +github.com/apache/camel-k/v2/pkg/trait/trait_types.go:736: CapabilityPropertyKey 83.3% github.com/apache/camel-k/v2/pkg/trait/util.go:46: ptrFrom 100.0% -github.com/apache/camel-k/v2/pkg/trait/util.go:52: Get 0.0% +github.com/apache/camel-k/v2/pkg/trait/util.go:52: Get 57.1% github.com/apache/camel-k/v2/pkg/trait/util.go:71: getIntegrationKit 0.0% github.com/apache/camel-k/v2/pkg/trait/util.go:80: collectConfigurationValues 100.0% github.com/apache/camel-k/v2/pkg/trait/util.go:107: collectConfigurations 100.0% @@ -1770,12 +1773,15 @@ github.com/apache/camel-k/v2/pkg/trait/util.go:440: newTraitsOptions 8 github.com/apache/camel-k/v2/pkg/trait/util.go:453: NewSpecTraitsOptionsForIntegrationAndPlatform 0.0% github.com/apache/camel-k/v2/pkg/trait/util.go:477: NewSpecTraitsOptionsForIntegration 0.0% github.com/apache/camel-k/v2/pkg/trait/util.go:486: newTraitsOptionsForIntegrationKit 0.0% -github.com/apache/camel-k/v2/pkg/trait/util.go:495: NewStatusTraitsOptionsForIntegrationKit 0.0% -github.com/apache/camel-k/v2/pkg/trait/util.go:499: NewSpecTraitsOptionsForIntegrationKit 0.0% -github.com/apache/camel-k/v2/pkg/trait/util.go:503: NewTraitsOptionsForPipe 87.5% -github.com/apache/camel-k/v2/pkg/trait/util.go:521: NewTraitsOptionsForKameletBinding 0.0% -github.com/apache/camel-k/v2/pkg/trait/util.go:538: FromAnnotations 68.2% -github.com/apache/camel-k/v2/pkg/trait/util.go:577: containsEndpoint 86.7% +github.com/apache/camel-k/v2/pkg/trait/util.go:495: NewSpecTraitsOptionsForIntegrationKit 0.0% +github.com/apache/camel-k/v2/pkg/trait/util.go:499: NewTraitsOptionsForPipe 87.5% +github.com/apache/camel-k/v2/pkg/trait/util.go:517: NewTraitsOptionsForKameletBinding 0.0% +github.com/apache/camel-k/v2/pkg/trait/util.go:534: FromAnnotations 92.3% +github.com/apache/camel-k/v2/pkg/trait/util.go:558: stringOrSlice 100.0% +github.com/apache/camel-k/v2/pkg/trait/util.go:575: containsEndpoint 86.7% +github.com/apache/camel-k/v2/pkg/trait/util.go:600: HasMatchingTraits 92.3% +github.com/apache/camel-k/v2/pkg/trait/util.go:626: matchesComparableTrait 69.2% +github.com/apache/camel-k/v2/pkg/trait/util.go:647: matchesTrait 100.0% github.com/apache/camel-k/v2/pkg/util/bindings/api_support.go:24: AsYamlDSL 0.0% github.com/apache/camel-k/v2/pkg/util/bindings/api_support.go:36: GenerateID 100.0% github.com/apache/camel-k/v2/pkg/util/bindings/api_support.go:46: GenerateID 0.0% @@ -1818,24 +1824,24 @@ github.com/apache/camel-k/v2/pkg/util/bindings/knative_uri.go:171: Order github.com/apache/camel-k/v2/pkg/util/bindings/knative_uri.go:175: init 100.0% github.com/apache/camel-k/v2/pkg/util/bindings/test_support.go:28: asEndpointProperties 75.0% github.com/apache/camel-k/v2/pkg/util/bindings/test_support.go:38: asKnativeConfig 75.0% -github.com/apache/camel-k/v2/pkg/util/camel/camel_dependencies.go:35: NormalizeDependency 100.0% -github.com/apache/camel-k/v2/pkg/util/camel/camel_dependencies.go:55: ValidateDependency 100.0% -github.com/apache/camel-k/v2/pkg/util/camel/camel_dependencies.go:74: ValidateDependencyE 100.0% -github.com/apache/camel-k/v2/pkg/util/camel/camel_dependencies.go:98: ValidateDependenciesE 0.0% -github.com/apache/camel-k/v2/pkg/util/camel/camel_dependencies.go:109: ManageIntegrationDependencies 80.0% -github.com/apache/camel-k/v2/pkg/util/camel/camel_dependencies.go:122: addDependencies 61.5% -github.com/apache/camel-k/v2/pkg/util/camel/camel_dependencies.go:151: addBOM 0.0% -github.com/apache/camel-k/v2/pkg/util/camel/camel_dependencies.go:169: addCamelComponent 62.5% -github.com/apache/camel-k/v2/pkg/util/camel/camel_dependencies.go:184: addCamelKComponent 100.0% -github.com/apache/camel-k/v2/pkg/util/camel/camel_dependencies.go:192: addCamelQuarkusComponent 100.0% -github.com/apache/camel-k/v2/pkg/util/camel/camel_dependencies.go:200: addMavenDependency 100.0% -github.com/apache/camel-k/v2/pkg/util/camel/camel_dependencies.go:205: addRegistryMavenDependency 0.0% -github.com/apache/camel-k/v2/pkg/util/camel/camel_dependencies.go:241: getOrCreateBuildPlugin 0.0% -github.com/apache/camel-k/v2/pkg/util/camel/camel_dependencies.go:258: addJitPack 66.7% -github.com/apache/camel-k/v2/pkg/util/camel/camel_dependencies.go:291: addDependenciesFromCatalog 50.0% -github.com/apache/camel-k/v2/pkg/util/camel/camel_dependencies.go:320: postProcessDependencies 75.0% -github.com/apache/camel-k/v2/pkg/util/camel/camel_dependencies.go:344: SanitizeIntegrationDependencies 0.0% -github.com/apache/camel-k/v2/pkg/util/camel/camel_runtime.go:36: CreateCatalog 0.0% +github.com/apache/camel-k/v2/pkg/util/camel/camel_dependencies.go:36: NormalizeDependency 100.0% +github.com/apache/camel-k/v2/pkg/util/camel/camel_dependencies.go:56: ValidateDependency 100.0% +github.com/apache/camel-k/v2/pkg/util/camel/camel_dependencies.go:75: ValidateDependencyE 100.0% +github.com/apache/camel-k/v2/pkg/util/camel/camel_dependencies.go:99: ValidateDependenciesE 0.0% +github.com/apache/camel-k/v2/pkg/util/camel/camel_dependencies.go:110: ManageIntegrationDependencies 80.0% +github.com/apache/camel-k/v2/pkg/util/camel/camel_dependencies.go:123: addDependencies 61.5% +github.com/apache/camel-k/v2/pkg/util/camel/camel_dependencies.go:152: addBOM 0.0% +github.com/apache/camel-k/v2/pkg/util/camel/camel_dependencies.go:170: addCamelComponent 62.5% +github.com/apache/camel-k/v2/pkg/util/camel/camel_dependencies.go:185: addCamelKComponent 100.0% +github.com/apache/camel-k/v2/pkg/util/camel/camel_dependencies.go:193: addCamelQuarkusComponent 100.0% +github.com/apache/camel-k/v2/pkg/util/camel/camel_dependencies.go:201: addMavenDependency 100.0% +github.com/apache/camel-k/v2/pkg/util/camel/camel_dependencies.go:206: addRegistryMavenDependency 0.0% +github.com/apache/camel-k/v2/pkg/util/camel/camel_dependencies.go:242: getOrCreateBuildPlugin 0.0% +github.com/apache/camel-k/v2/pkg/util/camel/camel_dependencies.go:259: addJitPack 66.7% +github.com/apache/camel-k/v2/pkg/util/camel/camel_dependencies.go:292: addDependenciesFromCatalog 50.0% +github.com/apache/camel-k/v2/pkg/util/camel/camel_dependencies.go:321: postProcessDependencies 75.0% +github.com/apache/camel-k/v2/pkg/util/camel/camel_dependencies.go:345: SanitizeIntegrationDependencies 0.0% +github.com/apache/camel-k/v2/pkg/util/camel/camel_runtime.go:36: CreateCatalog 68.2% github.com/apache/camel-k/v2/pkg/util/camel/camel_runtime.go:92: LoadCatalog 0.0% github.com/apache/camel-k/v2/pkg/util/camel/camel_runtime_catalog.go:27: NewRuntimeCatalog 93.1% github.com/apache/camel-k/v2/pkg/util/camel/camel_runtime_catalog.go:92: HasArtifact 85.7% @@ -1860,8 +1866,8 @@ github.com/apache/camel-k/v2/pkg/util/camel/camel_util.go:104: getDependenc github.com/apache/camel-k/v2/pkg/util/camel/catalog.go:37: DefaultCatalog 100.0% github.com/apache/camel-k/v2/pkg/util/camel/catalog.go:41: QuarkusCatalog 100.0% github.com/apache/camel-k/v2/pkg/util/camel/catalog.go:45: catalogForRuntimeProvider 76.9% -github.com/apache/camel-k/v2/pkg/util/camel/catalog.go:75: GenerateCatalog 0.0% -github.com/apache/camel-k/v2/pkg/util/camel/catalog.go:107: GenerateCatalogCommon 0.0% +github.com/apache/camel-k/v2/pkg/util/camel/catalog.go:75: GenerateCatalog 60.0% +github.com/apache/camel-k/v2/pkg/util/camel/catalog.go:107: GenerateCatalogCommon 69.2% github.com/apache/camel-k/v2/pkg/util/camel/catalog.go:162: generateMavenProject 100.0% github.com/apache/camel-k/v2/pkg/util/command.go:32: RunAndLog 76.9% github.com/apache/camel-k/v2/pkg/util/command.go:72: scan 100.0% @@ -1873,17 +1879,17 @@ github.com/apache/camel-k/v2/pkg/util/defaults/defaults_support.go:40: Insta github.com/apache/camel-k/v2/pkg/util/defaults/defaults_support.go:44: OperatorID 100.0% github.com/apache/camel-k/v2/pkg/util/defaults/defaults_support.go:48: boolEnvOrDefault 100.0% github.com/apache/camel-k/v2/pkg/util/defaults/defaults_support.go:58: envOrDefault 100.0% -github.com/apache/camel-k/v2/pkg/util/digest/digest.go:50: ComputeForIntegration 58.9% -github.com/apache/camel-k/v2/pkg/util/digest/digest.go:201: computeForTraits 46.2% -github.com/apache/camel-k/v2/pkg/util/digest/digest.go:226: computeForTrait 41.7% -github.com/apache/camel-k/v2/pkg/util/digest/digest.go:249: computeForTraitProps 80.0% -github.com/apache/camel-k/v2/pkg/util/digest/digest.go:260: toMap 71.4% -github.com/apache/camel-k/v2/pkg/util/digest/digest.go:275: ComputeForIntegrationKit 0.0% -github.com/apache/camel-k/v2/pkg/util/digest/digest.go:303: ComputeForResource 0.0% -github.com/apache/camel-k/v2/pkg/util/digest/digest.go:332: ComputeForSource 0.0% -github.com/apache/camel-k/v2/pkg/util/digest/digest.go:375: sortedTraitsMapKeys 100.0% -github.com/apache/camel-k/v2/pkg/util/digest/digest.go:386: sortedTraitAnnotationsKeys 100.0% -github.com/apache/camel-k/v2/pkg/util/digest/digest.go:397: ComputeSHA1 77.8% +github.com/apache/camel-k/v2/pkg/util/digest/digest.go:49: ComputeForIntegration 50.0% +github.com/apache/camel-k/v2/pkg/util/digest/digest.go:153: computeForTraits 46.2% +github.com/apache/camel-k/v2/pkg/util/digest/digest.go:178: computeForTrait 41.7% +github.com/apache/camel-k/v2/pkg/util/digest/digest.go:201: computeForTraitProps 80.0% +github.com/apache/camel-k/v2/pkg/util/digest/digest.go:212: toMap 71.4% +github.com/apache/camel-k/v2/pkg/util/digest/digest.go:227: ComputeForIntegrationKit 0.0% +github.com/apache/camel-k/v2/pkg/util/digest/digest.go:255: ComputeForResource 0.0% +github.com/apache/camel-k/v2/pkg/util/digest/digest.go:284: ComputeForSource 0.0% +github.com/apache/camel-k/v2/pkg/util/digest/digest.go:327: sortedTraitsMapKeys 100.0% +github.com/apache/camel-k/v2/pkg/util/digest/digest.go:338: sortedTraitAnnotationsKeys 100.0% +github.com/apache/camel-k/v2/pkg/util/digest/digest.go:349: ComputeSHA1 77.8% github.com/apache/camel-k/v2/pkg/util/docker/docker.go:31: CreateBaseImageDockerFile 85.7% github.com/apache/camel-k/v2/pkg/util/docker/docker.go:50: CreateIntegrationImageDockerFile 95.5% github.com/apache/camel-k/v2/pkg/util/docker/docker.go:97: BuildBaseImageArgs 0.0% @@ -1931,8 +1937,8 @@ github.com/apache/camel-k/v2/pkg/util/gzip/compress.go:30: Compress 62 github.com/apache/camel-k/v2/pkg/util/gzip/compress.go:47: CompressBase64 75.0% github.com/apache/camel-k/v2/pkg/util/gzip/compress.go:58: Uncompress 61.5% github.com/apache/camel-k/v2/pkg/util/gzip/compress.go:81: UncompressBase64 75.0% -github.com/apache/camel-k/v2/pkg/util/jib/configuration.go:58: CreateProfileConfigmap 87.5% -github.com/apache/camel-k/v2/pkg/util/jib/configuration.go:97: JibMavenProfile 91.7% +github.com/apache/camel-k/v2/pkg/util/jib/configuration.go:59: CreateProfileConfigmap 87.5% +github.com/apache/camel-k/v2/pkg/util/jib/configuration.go:98: JibMavenProfile 91.7% github.com/apache/camel-k/v2/pkg/util/jitpack/jitpack.go:34: ToDependency 95.2% github.com/apache/camel-k/v2/pkg/util/jvm/keystore.go:40: GenerateKeystore 94.4% github.com/apache/camel-k/v2/pkg/util/jvm/keystore.go:77: NewKeystorePassword 100.0% @@ -2036,9 +2042,10 @@ github.com/apache/camel-k/v2/pkg/util/kubernetes/loader.go:33: LoadResource github.com/apache/camel-k/v2/pkg/util/kubernetes/loader.go:57: LoadUnstructuredFromYaml 0.0% github.com/apache/camel-k/v2/pkg/util/kubernetes/loader.go:71: runtimeObjectFromUnstructured 0.0% github.com/apache/camel-k/v2/pkg/util/kubernetes/lookup.go:32: LookupConfigmap 0.0% -github.com/apache/camel-k/v2/pkg/util/kubernetes/lookup.go:56: LookupSecret 0.0% -github.com/apache/camel-k/v2/pkg/util/kubernetes/lookup.go:80: LookupPersistentVolumeClaim 0.0% -github.com/apache/camel-k/v2/pkg/util/kubernetes/lookup.go:104: LookupDefaultStorageClass 0.0% +github.com/apache/camel-k/v2/pkg/util/kubernetes/lookup.go:57: LookupResourceVersion 0.0% +github.com/apache/camel-k/v2/pkg/util/kubernetes/lookup.go:65: LookupSecret 0.0% +github.com/apache/camel-k/v2/pkg/util/kubernetes/lookup.go:89: LookupPersistentVolumeClaim 0.0% +github.com/apache/camel-k/v2/pkg/util/kubernetes/lookup.go:113: LookupDefaultStorageClass 0.0% github.com/apache/camel-k/v2/pkg/util/kubernetes/permission.go:32: CheckPermission 0.0% github.com/apache/camel-k/v2/pkg/util/kubernetes/portforward.go:38: PortForward 0.0% github.com/apache/camel-k/v2/pkg/util/kubernetes/portforward.go:122: portFowardPod 0.0% @@ -2095,12 +2102,12 @@ github.com/apache/camel-k/v2/pkg/util/maven/maven_project.go:178: NewReposit github.com/apache/camel-k/v2/pkg/util/maven/maven_project.go:214: NewMirror 88.9% github.com/apache/camel-k/v2/pkg/util/maven/maven_proxies.go:30: apply 0.0% github.com/apache/camel-k/v2/pkg/util/maven/maven_proxies.go:52: parseProxyFromEnvVar 0.0% -github.com/apache/camel-k/v2/pkg/util/maven/maven_repositories.go:31: apply 100.0% -github.com/apache/camel-k/v2/pkg/util/maven/maven_repositories.go:39: defaultMavenRepositories 100.0% -github.com/apache/camel-k/v2/pkg/util/maven/maven_repositories.go:48: Repositories 100.0% -github.com/apache/camel-k/v2/pkg/util/maven/maven_repositories.go:58: apply 83.3% -github.com/apache/camel-k/v2/pkg/util/maven/maven_repositories.go:78: upsertRepository 60.0% -github.com/apache/camel-k/v2/pkg/util/maven/maven_repositories.go:88: upsertMirror 40.0% +github.com/apache/camel-k/v2/pkg/util/maven/maven_repositories.go:32: apply 100.0% +github.com/apache/camel-k/v2/pkg/util/maven/maven_repositories.go:40: defaultMavenRepositories 100.0% +github.com/apache/camel-k/v2/pkg/util/maven/maven_repositories.go:49: Repositories 100.0% +github.com/apache/camel-k/v2/pkg/util/maven/maven_repositories.go:59: apply 83.3% +github.com/apache/camel-k/v2/pkg/util/maven/maven_repositories.go:79: upsertRepository 60.0% +github.com/apache/camel-k/v2/pkg/util/maven/maven_repositories.go:89: upsertMirror 40.0% github.com/apache/camel-k/v2/pkg/util/maven/maven_settings.go:30: MarshalBytes 0.0% github.com/apache/camel-k/v2/pkg/util/maven/maven_settings.go:38: NewSettings 83.3% github.com/apache/camel-k/v2/pkg/util/modeline/parser.go:36: Parse 87.5% @@ -2257,4 +2264,4 @@ github.com/apache/camel-k/v2/pkg/util/util.go:649: WithTempDir 0.0% github.com/apache/camel-k/v2/pkg/util/util.go:664: ConfigTreePropertySplit 0.0% github.com/apache/camel-k/v2/pkg/util/util.go:685: trimQuotes 0.0% github.com/apache/camel-k/v2/pkg/util/util.go:696: NavigateConfigTree 0.0% -total: (statements) 36.2% +total: (statements) 37.2% diff --git a/docs/modules/ROOT/pages/architecture/traits.adoc b/docs/modules/ROOT/pages/architecture/traits.adoc index fc56b11928..dee146ccb3 100644 --- a/docs/modules/ROOT/pages/architecture/traits.adoc +++ b/docs/modules/ROOT/pages/architecture/traits.adoc @@ -49,6 +49,15 @@ type Trait interface { IsAllowedInProfile(v1.TraitProfile) bool Order() int } + +type Comparable interface { + Matches(trait Trait) bool +} + +type ComparableTrait interface { + Trait + Comparable +} ---- Each trait will implement this interface. The most important methods that will be invoked by the xref:architecture/operator.adoc[Operator] are `Configure()` and `Apply()`. Basically, the `Configure()` method will set those inputs aforementioned (each trait has its own). The method is in charge to verify also the correctness of those expected parameters, where it makes sense (i.e., a well expected `Kubernetes` resource name). The function can return a `TraitCondition` object containing any informative or warning condition to be attached to the resulting Integration (for instance, traits forcefully altered by the platform, or deprecation notices). @@ -59,6 +68,6 @@ The `Order()` method helps in resolving the order of execution of different trai The `InfluencesKit()`, `IsPlatformTrait()` and `RequiresIntegrationPlatform()` methods are easy to understand. They are used to determine if a trait has to influence an `IntegrationKit` build/initialization, if it's a platform trait (ie, needed by the platform itself) or are requiring the presence of an `IntegrationPlatform`. -The presence of `InfluencesBuild()` will let specify the level of granularity of a trait down to its properties for a rebuild. So, if you need, you can compare the traits properties coming from the `prev` (previous) Integration to decide if it is worth to rebuild an Integration or the trait can reuse the one already provided in `this` version. +For those traits that `InfluencesKit()` you may need to provide a `Matches(trait Trait)` func in order to specify those trait parameters that influences a build. This is required by the platform to decide if it is worth to rebuild an Integration or the trait can reuse the one already provided. Finally, through the `IsAllowedInProfile()` method we can override the default behavior (allow the trait for any profile). We must specify the profile we expect for this trait to be executed properly. diff --git a/docs/modules/ROOT/pages/cli/cli.adoc b/docs/modules/ROOT/pages/cli/cli.adoc index d34a73d86c..a84664c6fd 100644 --- a/docs/modules/ROOT/pages/cli/cli.adoc +++ b/docs/modules/ROOT/pages/cli/cli.adoc @@ -124,17 +124,3 @@ $ kamel --help Some command options in the CLI can be also specified as modeline in the source file, take a look at the xref:cli/modeline.adoc[Modeline] section for more information. - -[[image-registry]] -== Image Registry - -The CLI can be used to xref:configuration/dependencies.adoc#local-remote-dependencies[upload] Maven dependencies and user data to the Image Registry. To do so, the CLI and the Operator have to be configured correctly. - -For the Operator part, have a look at the xref:installation/registry/registry.adoc[installation] documentation. - -For the CLI, in most cases, executing `docker login REGISTRY_URL` successfully will suffice. -If the Image Registry uses a custom certificate authority then it needs to be trusted, see -link:https://go.dev/src/crypto/x509/root_unix.go[SSL_CERT_FILE]. - - - diff --git a/docs/modules/ROOT/pages/configuration/dependencies.adoc b/docs/modules/ROOT/pages/configuration/dependencies.adoc index 5edff4a4ce..0393577889 100644 --- a/docs/modules/ROOT/pages/configuration/dependencies.adoc +++ b/docs/modules/ROOT/pages/configuration/dependencies.adoc @@ -74,37 +74,6 @@ kamel run -d mvn:com.google.guava:guava:26.0-jre Integration.java ``` Note that if your dependencies belong to a private repository, this repository needs to be defined. See xref:installation/advanced/maven.adoc[Configure maven]. -[[local-remote-dependencies]] -=== Local and remote dependencies - -*Local dependencies* can be added using the `-d` flag and the `file://` prefix: -``` -kamel run -d file://path/to/integration-dep.jar Integration.java -``` - -You can also specify data files and directories which will be mounted in the running container relative to the working directory: - -``` -kamel run -d file://path/to/data.csv?targetPath=/in/container/data.csv Integration.java -``` - -If the data files needs to be present at build time, you can also set `classpath` option to `true`: - -``` -kamel run -d file://path/to/data.csv?targetPath=/in/container/data.csv&classpath=true Integration.java -``` - -Similarly, *remote dependencies* can be added with the `http(s)://` prefix: - -``` -kamel run -d https://raw.githubusercontent.com/example/data.csv|targetPath=/tmp/foo&classpath=true Integration.java -``` - -For a full list of options checkout `kamel run --help`. - - -*Important note*: this will upload the dependencies and data files to the Image Registry. The CLI and Operator need to be setup xref:cli/cli.adoc[correctly], especially if authentication or custom certificates are required. - [[dependencies-kind-jitpack]] === Jitpack dependencies diff --git a/docs/modules/ROOT/pages/contributing/developers.adoc b/docs/modules/ROOT/pages/contributing/developers.adoc index 8d662ba3b1..6f699cc821 100644 --- a/docs/modules/ROOT/pages/contributing/developers.adoc +++ b/docs/modules/ROOT/pages/contributing/developers.adoc @@ -96,11 +96,11 @@ After a successful build, if you're connected to a Docker daemon, you can build make images ---- -The above command produces a `camel-k` image with the name `docker.io/apache/camel-k`. Sometimes you might need to produce `camel-k` images that need to be pushed to the custom repository e.g. `docker.io/myrepo/camel-k`, to do that you can pass a parameter `STAGING_IMAGE_NAME` to `make` as shown below: +The above command produces a `camel-k` image with the name `docker.io/apache/camel-k`. Sometimes you might need to produce `camel-k` images that need to be pushed to the custom repository e.g. `docker.io/myrepo/camel-k`, to do that you can pass a parameter `STAGING_IMAGE` to `make` as shown below: [source] ---- -make STAGING_IMAGE_NAME='docker.io/myrepo/camel-k' images-push-staging +make STAGING_IMAGE='docker.io/myrepo/camel-k' images-push-staging ---- [[testing]] diff --git a/docs/modules/ROOT/pages/installation/advanced/multi-architecture.adoc b/docs/modules/ROOT/pages/installation/advanced/multi-architecture.adoc index 5a167ea22e..d082b32d12 100644 --- a/docs/modules/ROOT/pages/installation/advanced/multi-architecture.adoc +++ b/docs/modules/ROOT/pages/installation/advanced/multi-architecture.adoc @@ -3,37 +3,12 @@ NOTE: this part is evolving quickly during development of version 2 so it may be slightly inaccurate. -Since version 2, Camel K is publishing an ARM64 architecture beside the default AMD64 architecture. You need to reference this as `apache/camel-k:-arm64`. You can build your particular architecture from source, following the guidelines in xref:contributing/local-development.adoc[Local development]. +Since version 2, Camel K is publishing an ARM64 architecture beside the default AMD64 architecture. You can build your particular architecture from source as well, following the guidelines in xref:contributing/local-development.adoc[Local development]. [[multi-architecture-install]] == Install Camel K ARM64 operator -The default configured base image defaults to the AMD64 architecture manifest, it does not automatically look for the AMR64 architecture manifest reference. To ensure your integrations work correctly, you must specifically reference the ARM64 architecture as your base image. - -Proceed with installation of Camel K inside kubernetes cluster with the below command: - -[source,shell] ----- -kamel install --operator-image apache/camel-k:-arm64 --base-image --registry ... ----- - -=== Example - -On Camel K 2.1.0, the default base image is : `eclipse-temurin:17`. - -Look through the manifest to find the digest of a valid image containing `"architecture": "arm64"`: - -[source,shell] ----- -docker manifest inspect eclipse-temurin:17 ----- - -Proceed with installation of Camel K inside kubernetes cluster with the valid image reference: - -[source,shell] ----- -kamel install --operator-image apache/camel-k:2.1.0-arm64 --base-image eclipse-temurin:17@sha256:bbc153da9e6041c65f0d4cdc7ef03eec174c9a74c8852c838582b579081c99c1 --registry ... ----- +From version 2.3 onward, the ARM64 architecture is published beside the AMD64 in a Docker manifest. Your platform should be able to pick up the platform target architecture accordingly using the usual installation procedure. The logs should indicate the architecture at the start of the operator pod: @@ -44,24 +19,16 @@ The logs should indicate the architecture at the start of the operator pod: {"level":"info","ts":"2023-12-19T16:40:31Z","logger":"camel-k.cmd","msg":"Camel K Operator Version: 2.1.0"} ---- +=== Example -[[multi-architecture-use]] -== Test an integration +Once you've installed the operator you will need to specify the platform target you whish to use. This is required as each of the different publishing tasks may need to know how to create a manifest accordingly. You can use `builder.platforms` trait option to control this behavior. -Build and run an integration - -[source,groovy] -.hello.groovy ----- -from('timer:tick?period=3000') - .setBody().constant('Hello world from Camel K') - .to('log:info') ----- +NOTE: you can set the property at IntegrationPlatform level to have it for all Integrations. Send the groovy file to kamel operator to build, publish and run it [source,shell] ---- -kamel run hello.groovy +kamel run hello.groovy -t builder.platforms=linux/arm64 -t builder.platforms=linux/amd64 ---- You should observe base image in the logs of the operator pod: @@ -71,3 +38,5 @@ You should observe base image in the logs of the operator pod: {"level":"info","ts":"2023-12-19T17:10:05Z","logger":"camel-k","msg":"spectrum - 2023/12/19 17:10:05 Pulling base image eclipse-temurin:17@sha256:bbc153da9e6041c65f0d4cdc7ef03eec174c9a74c8852c838582b579081c99c1 (insecure=false)..."} ... ---- + +WARNING: you may need to start a new platform image from scratch disabling incremental image in order to avoid using a base image which was built against a different set of platforms. \ No newline at end of file diff --git a/docs/modules/ROOT/pages/running/camel-runtimes.adoc b/docs/modules/ROOT/pages/running/camel-runtimes.adoc index 393e69e0de..db1fdb2352 100644 --- a/docs/modules/ROOT/pages/running/camel-runtimes.adoc +++ b/docs/modules/ROOT/pages/running/camel-runtimes.adoc @@ -20,3 +20,265 @@ At this stage we do have a container image with our Camel application. We can us NOTE: Jvm trait won't be available when running an application built externally. If all is good, in a few seconds (there is no build involved) you should have your application up and running and you can monitor and operate with Camel K as usual. + +[[traits-and-dependencies]] +== Traits and dependencies + +Certain Camel K operational aspect may be driven by traits. When you're building the application outside the operator, some of those traits may not be executed as they are executed during the building phase that we are skipping when running **sourceless Integrations**. Here we provided a list of those traits that may not work when building the application outside the Camel K operator. + +NOTE: this is a best effort analysis taking as reference the work available in version 2.3. + +* Build column show those traits that affects the build (will be skipped for sourceless Integrations). +* Dependencies column show those traits that will add some dependency (you may need to manually add those dependencies). +* Runtime column show those traits that will influence the runtime, mostly via properties (you may need to manually add those properties to the bundled `application.properties`). +* Deployment column show those traits that will be executed for the deployment (nothing should be required). + +[cols="1,1,1,1,1"] +|=== +|Trait +|Build +|Dependencies +|Runtime +|Deployment + +|Affinity +|x +|x +|x +|v + +|Builder +|v +|x +|x +|x + +|Camel +|x +|x +|v +|x + +|Container +|x +|x +|x +|v + +|Cron +|x +|v +|v +|x + +|Dependencies +|v +|v +|x +|x + +|Deployer +|x +|x +|x +|v + +|Deployment +|x +|x +|x +|v + +|Environment +|x +|x +|x +|v + +|Affinity +|x +|x +|x +|v + +|Error Handler +|x +|v +|x +|x + +|GC (Garbage Collector) +|x +|x +|x +|v + +|Health +|x +|v +|v +|v + +|Ingress +|x +|x +|x +|v + +|Istio +|x +|x +|x +|v + +|Jolokia +|x +|v +|v +|v + +|JVM +|x +|x +|v +|v + +|Kamelets +|x +|x +|v +|x + +|KNative Service +|v +|x +|x +|x + +|KNative +|x +|v +|x +|x + +|Logging +|x +|x +|v +|v + +|Mount +|x +|x +|x +|v + +|Openapi +|x +|v +|v +|v + +|Owner +|x +|x +|x +|v + +|PDB +|x +|x +|x +|v + +|Platform +|x +|x +|x +|v + +|Pod +|x +|x +|x +|v + +|Prometheus +|v +|v +|x +|x + +|Pull Secret +|x +|x +|x +|v + +|Quarkus +|v +|x +|x +|x + +|Service +|x +|x +|x +|v + +|Service Binding +|x +|x +|v +|v + +|Toleration +|x +|x +|x +|v + +|Keda +|x +|x +|x +|v + +|Master +|v +|v +|v +|x + +|Resume +|v +|v +|x +|x + +|Strimzi +|x +|x +|x +|v + +|Telemetry +|x +|x +|v +|x + +|Three Scale +|x +|x +|x +|v + +|Vaults +|x +|v +|v +|x + +|=== diff --git a/docs/modules/ROOT/partials/apis/camel-k-crds.adoc b/docs/modules/ROOT/partials/apis/camel-k-crds.adoc index 497284dc12..ad9272dd25 100644 --- a/docs/modules/ROOT/partials/apis/camel-k-crds.adoc +++ b/docs/modules/ROOT/partials/apis/camel-k-crds.adoc @@ -658,6 +658,13 @@ map[string]string Annotation to use for the builder pod. Only used for `pod` strategy +|`platforms` + +[]string +| + + +The list of platforms used in order to build a container image. + |=== @@ -1315,6 +1322,37 @@ map[string]string the metadata of the loader +|=== + +[#_camel_apache_org_v1_CamelProperty] +=== CamelProperty + +*Appears on:* + +* <<#_camel_apache_org_v1_Capability, Capability>> + +CamelProperty represents a Camel property that may end up in an application.properties file. + +[cols="2,2a",options="header"] +|=== +|Field +|Description + +|`key` + +string +| + + + + +|`value` + +string +| + + + + + |=== [#_camel_apache_org_v1_CamelScheme] @@ -1400,7 +1438,7 @@ list of dependencies needed for this scope * <<#_camel_apache_org_v1_RuntimeSpec, RuntimeSpec>> -Capability is a particular feature which requires a well known set of dependencies +Capability is a particular feature which requires a well known set of dependencies and other properties which are specified in the runtime catalog. [cols="2,2a",options="header"] @@ -1413,7 +1451,28 @@ which are specified in the runtime catalog. | +List of required Maven dependencies + +|`runtimeProperties` + +*xref:#_camel_apache_org_v1_CamelProperty[[\]CamelProperty]* +| + + +Set of required Camel runtime properties + +|`buildTimeProperties` + +*xref:#_camel_apache_org_v1_CamelProperty[[\]CamelProperty]* +| + + +Set of required Camel build time properties + +|`metadata` + +map[string]string +| + +Set of generic metadata |=== @@ -2494,6 +2553,13 @@ Maven repositories that can be used by the kit the sources to add at build time +|`capabilities` + +[]string +| + + +features offered by the IntegrationKit + |=== @@ -2602,13 +2668,6 @@ the Camel K operator version for which this kit was configured a list of conditions which happened for the events related the kit -|`traits` + -*xref:#_camel_apache_org_v1_IntegrationKitTraits[IntegrationKitTraits]* -| - - -generated traits executed by the kit - |=== @@ -2618,7 +2677,6 @@ generated traits executed by the kit *Appears on:* * <<#_camel_apache_org_v1_IntegrationKitSpec, IntegrationKitSpec>> -* <<#_camel_apache_org_v1_IntegrationKitStatus, IntegrationKitStatus>> IntegrationKitTraits defines traits assigned to an `IntegrationKit`. @@ -2656,6 +2714,7 @@ NOTE: Compiling to a native executable, requires at least 4GiB of memory, so the The Registry trait sets up Maven to use the Image registry as a Maven repository. +Deprecated: use jvm trait or read documentation. |`addons` + *xref:#_camel_apache_org_v1_AddonTrait[map[string\]github.com/apache/camel-k/v2/pkg/apis/camel/v1.AddonTrait]* @@ -3505,13 +3564,6 @@ label selector features offered by the Integration -|`traits` + -*xref:#_camel_apache_org_v1_Traits[Traits]* -| - - -the traits generated and executed for this Integration - |`lastInitTimestamp` + *https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.27/#time-v1-meta[Kubernetes meta/v1.Time]* | @@ -5666,7 +5718,6 @@ TraitConfiguration parameters configuration * <<#_camel_apache_org_v1_IntegrationPlatformSpec, IntegrationPlatformSpec>> * <<#_camel_apache_org_v1_IntegrationProfileSpec, IntegrationProfileSpec>> * <<#_camel_apache_org_v1_IntegrationSpec, IntegrationSpec>> -* <<#_camel_apache_org_v1_IntegrationStatus, IntegrationStatus>> Traits represents the collection of trait configurations. @@ -5884,6 +5935,7 @@ The configuration of Quarkus trait The configuration of Registry trait +Deprecated: use jvm trait or read documentation. |`route` + *xref:#_camel_apache_org_v1_trait_RouteTrait[RouteTrait]* @@ -6286,6 +6338,13 @@ map[string]string When using `pod` strategy, annotation to use for the builder pod. +|`platforms` + +[]string +| + + +The list of manifest platforms to use to build a container image (default `linux/amd64`). + |=== @@ -6488,7 +6547,7 @@ require to be activated at specific hours of the day or with a periodic delay of For such tasks, the cron trait can materialize the integration as a Kubernetes CronJob instead of a standard deployment, in order to save resources when the integration does not need to be executed. -Integrations that start from the following components are evaluated by the cron trait: `timer`, `cron`, `quartz`. +Integrations that start from the following components are evaluated by the cron trait: `timer`, `cron`, `quartz`. The trait does support multiple evaluated components only if they have the same schedule, else it will fallback to Camel implementation instead of instanciating a Kubernetes CronJob. WARNING: In case of native build-mode defined in xref:traits:quarkus.adoc[quarkus] trait, the component can't be customized. @@ -6696,7 +6755,7 @@ is considered to be failed. It defaults to `60s`. The deployment strategy to use to replace existing pods with new ones. |`rollingUpdateMaxUnavailable` + -int +k8s.io/apimachinery/pkg/util/intstr.IntOrString | @@ -6707,7 +6766,7 @@ This can not be 0 if MaxSurge is 0. Defaults to `25%`. |`rollingUpdateMaxSurge` + -int +k8s.io/apimachinery/pkg/util/intstr.IntOrString | @@ -7713,7 +7772,18 @@ bool Enable "hot reload" when a secret/configmap mounted is edited (default `false`). The configmap/secret must be -marked with `camel.apache.org/integration` label to be taken in account. +marked with `camel.apache.org/integration` label to be taken in account. The resource will be watched for any kind change, also for +changes in metadata. + +|`scanKameletsImplicitLabelSecrets` + +bool +| + + +Deprecated: include your properties in an explicit property file backed by a secret. +Let the operator to scan for secret labeled with `camel.apache.org/kamelet` and `camel.apache.org/kamelet.configuration`. +These secrets are mounted to the application and treated as plain properties file with their key/value list +(ie .spec.data["camel.my-property"] = my-value) (default `true`). |=== @@ -8172,6 +8242,8 @@ Deprecated: for backward compatibility. * <<#_camel_apache_org_v1_IntegrationKitTraits, IntegrationKitTraits>> * <<#_camel_apache_org_v1_Traits, Traits>> +WARNING: The Registry trait is **deprecated** and will removed in future release versions. + The Registry trait sets up Maven to use the Image registry as a Maven repository. diff --git a/docs/modules/traits/pages/azure-key-vault.adoc b/docs/modules/traits/pages/azure-key-vault.adoc index a5d8ffc69c..6ff6e162d9 100644 --- a/docs/modules/traits/pages/azure-key-vault.adoc +++ b/docs/modules/traits/pages/azure-key-vault.adoc @@ -13,7 +13,7 @@ the following trait options: To enable the automatic context reload on secrets updates you should define the following trait options: --t azure-key-vault.enabled=true -t azure-key-vault.tenant-id="tenant-id" -t azure-key-vault.client-id="client-id" -t azure-key-vault.client-secret="client-secret" -t azure-key-vault.vault-name="vault-name" -t azure-key-vault.context-reload-enabled="true" -t azure-key-vault.refresh-enabled="true" -t azure-key-vault.refresh-period="30000" -t azure-key-vault.secrets="test*" -t azure-key-vault.eventhub-connection-string="connection-string" -t azure-key-vault.blob-account-name="account-name" -t azure-key-vault.blob-container-name="container-name" -t azure-key-vault.blob-access-key="account-name" +-t azure-key-vault.enabled=true -t azure-key-vault.tenant-id="tenant-id" -t azure-key-vault.client-id="client-id" -t azure-key-vault.client-secret="client-secret" -t azure-key-vault.vault-name="vault-name" -t azure-key-vault.context-reload-enabled="true" -t azure-key-vault.refresh-enabled="true" -t azure-key-vault.refresh-period="30000" -t azure-key-vault.secrets="test*" -t azure-key-vault.eventhub-connection-string="connection-string" -t azure-key-vault.blob-account-name="account-name" -t azure-key-vault.blob-container-name="container-name" -t azure-key-vault.blob-access-key="account-name" -t azure-key-vault.azure-identity-enabled="true" This trait is available in the following profiles: **Kubernetes, Knative, OpenShift**. @@ -67,6 +67,10 @@ Syntax: [configmap\|secret]:name[/key], where name represents the resource name, | bool | Define if we want to use the Refresh Feature for secrets +| azure-key-vault.azure-identity-enabled +| bool +| Whether the Azure Identity Authentication should be used or not + | azure-key-vault.refresh-period | string | If Refresh is enabled, this defines the interval to check the refresh event diff --git a/docs/modules/traits/pages/builder.adoc b/docs/modules/traits/pages/builder.adoc index deb3481a88..e637badbc0 100755 --- a/docs/modules/traits/pages/builder.adoc +++ b/docs/modules/traits/pages/builder.adoc @@ -113,6 +113,10 @@ if you need to execute them. Useful only with `pod` strategy. | map[string]string | When using `pod` strategy, annotation to use for the builder pod. +| builder.platforms +| []string +| The list of manifest platforms to use to build a container image (default `linux/amd64`). + |=== // End of autogenerated code - DO NOT EDIT! (configuration) diff --git a/docs/modules/traits/pages/cron.adoc b/docs/modules/traits/pages/cron.adoc index 2250e33057..6b5cbb0980 100755 --- a/docs/modules/traits/pages/cron.adoc +++ b/docs/modules/traits/pages/cron.adoc @@ -8,7 +8,7 @@ require to be activated at specific hours of the day or with a periodic delay of For such tasks, the cron trait can materialize the integration as a Kubernetes CronJob instead of a standard deployment, in order to save resources when the integration does not need to be executed. -Integrations that start from the following components are evaluated by the cron trait: `timer`, `cron`, `quartz`. +Integrations that start from the following components are evaluated by the cron trait: `timer`, `cron`, `quartz`. The trait does support multiple evaluated components only if they have the same schedule, else it will fallback to Camel implementation instead of instanciating a Kubernetes CronJob. WARNING: In case of native build-mode defined in xref:traits:quarkus.adoc[quarkus] trait, the component can't be customized. diff --git a/docs/modules/traits/pages/deployment.adoc b/docs/modules/traits/pages/deployment.adoc index fbae7fc2e3..b7177b3998 100755 --- a/docs/modules/traits/pages/deployment.adoc +++ b/docs/modules/traits/pages/deployment.adoc @@ -38,7 +38,7 @@ is considered to be failed. It defaults to `60s`. | The deployment strategy to use to replace existing pods with new ones. | deployment.rolling-update-max-unavailable -| int +| k8s.io/apimachinery/pkg/util/intstr.IntOrString | The maximum number of pods that can be unavailable during the update. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). Absolute number is calculated from percentage by rounding down. @@ -46,7 +46,7 @@ This can not be 0 if MaxSurge is 0. Defaults to `25%`. | deployment.rolling-update-max-surge -| int +| k8s.io/apimachinery/pkg/util/intstr.IntOrString | The maximum number of pods that can be scheduled above the desired number of pods. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). diff --git a/docs/modules/traits/pages/mount.adoc b/docs/modules/traits/pages/mount.adoc index 1077b8e48e..523408287a 100644 --- a/docs/modules/traits/pages/mount.adoc +++ b/docs/modules/traits/pages/mount.adoc @@ -48,7 +48,15 @@ Syntax: [configmap\|secret]:name[/key][@path], where name represents the resourc | mount.hot-reload | bool | Enable "hot reload" when a secret/configmap mounted is edited (default `false`). The configmap/secret must be -marked with `camel.apache.org/integration` label to be taken in account. +marked with `camel.apache.org/integration` label to be taken in account. The resource will be watched for any kind change, also for +changes in metadata. + +| mount.scan-kamelets-implicit-label-secrets +| bool +| Deprecated: include your properties in an explicit property file backed by a secret. +Let the operator to scan for secret labeled with `camel.apache.org/kamelet` and `camel.apache.org/kamelet.configuration`. +These secrets are mounted to the application and treated as plain properties file with their key/value list +(ie .spec.data["camel.my-property"] = my-value) (default `true`). |=== diff --git a/docs/modules/traits/pages/registry.adoc b/docs/modules/traits/pages/registry.adoc index 6decb9efbb..e7bcf958da 100644 --- a/docs/modules/traits/pages/registry.adoc +++ b/docs/modules/traits/pages/registry.adoc @@ -1,6 +1,8 @@ = Registry Trait // Start of autogenerated code - DO NOT EDIT! (description) +WARNING: The Registry trait is **deprecated** and will removed in future release versions. + The Registry trait sets up Maven to use the Image registry as a Maven repository. diff --git a/e2e/advanced/build_order_strategy_test.go b/e2e/advanced/build_order_strategy_test.go index 1f5debb4c4..666b774c70 100644 --- a/e2e/advanced/build_order_strategy_test.go +++ b/e2e/advanced/build_order_strategy_test.go @@ -23,6 +23,7 @@ limitations under the License. package advanced import ( + "context" "testing" . "github.com/onsi/gomega" @@ -35,147 +36,138 @@ import ( ) func TestRunBuildOrderStrategyMatchingDependencies(t *testing.T) { - WithNewTestNamespace(t, func(ns string) { + t.Parallel() + + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { operatorID := "camel-k-build-order-deps" - Expect(CopyCamelCatalog(ns, operatorID)).To(Succeed()) - Expect(KamelInstallWithID(operatorID, ns, - "--max-running-pipelines", "4", - "--build-order-strategy", string(v1.BuildOrderStrategyDependencies)).Execute()).To(Succeed()) - Eventually(PlatformPhase(ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns, "--max-running-pipelines", "4", "--build-order-strategy", string(v1.BuildOrderStrategyDependencies))).To(Succeed()) + g.Eventually(PlatformPhase(t, ctx, ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) - Expect(CreateTimerKamelet(ns, "timer-source")()).To(Succeed()) + g.Expect(CreateTimerKamelet(t, ctx, operatorID, ns, "timer-source")()).To(Succeed()) integrationA := RandomizedSuffixName("java-a") - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", - "--name", integrationA, - ).Execute()).To(Succeed()) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", integrationA).Execute()).To(Succeed()) - Eventually(IntegrationKit(ns, integrationA), TestTimeoutMedium).ShouldNot(BeEmpty()) - integrationKitNameA := IntegrationKit(ns, integrationA)() - Eventually(Build(ns, integrationKitNameA), TestTimeoutMedium).ShouldNot(BeNil()) + g.Eventually(IntegrationKit(t, ctx, ns, integrationA), TestTimeoutMedium).ShouldNot(BeEmpty()) + integrationKitNameA := IntegrationKit(t, ctx, ns, integrationA)() + g.Eventually(Build(t, ctx, ns, integrationKitNameA), TestTimeoutMedium).ShouldNot(BeNil()) integrationB := RandomizedSuffixName("java-b") - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", - "--name", integrationB, - "-d", "camel:cron", - ).Execute()).To(Succeed()) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", integrationB, "-d", "camel:cron").Execute()).To(Succeed()) integrationC := RandomizedSuffixName("java-c") - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", - "--name", integrationC, - "-d", "camel:cron", - "-d", "camel:zipfile", - ).Execute()).To(Succeed()) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", integrationC, "-d", "camel:cron", "-d", "camel:zipfile").Execute()).To(Succeed()) integrationZ := RandomizedSuffixName("groovy-z") - Expect(KamelRunWithID(operatorID, ns, "files/timer-source.groovy", - "--name", integrationZ, - ).Execute()).To(Succeed()) - - Eventually(IntegrationKit(ns, integrationB), TestTimeoutMedium).ShouldNot(BeEmpty()) - Eventually(IntegrationKit(ns, integrationC), TestTimeoutMedium).ShouldNot(BeEmpty()) - Eventually(IntegrationKit(ns, integrationZ), TestTimeoutMedium).ShouldNot(BeEmpty()) - - integrationKitNameB := IntegrationKit(ns, integrationB)() - integrationKitNameC := IntegrationKit(ns, integrationC)() - integrationKitNameZ := IntegrationKit(ns, integrationZ)() - - Eventually(BuildPhase(ns, integrationKitNameA), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded)) - Eventually(IntegrationPodPhase(ns, integrationA), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, integrationA, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, integrationA), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - Eventually(Kit(ns, integrationKitNameA)().Status.BaseImage).Should(Equal(defaults.BaseImage())) - - Eventually(BuildPhase(ns, integrationKitNameB), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded)) - Eventually(IntegrationPodPhase(ns, integrationB), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, integrationB, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, integrationB), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - Eventually(Kit(ns, integrationKitNameB)().Status.BaseImage).Should(ContainSubstring(integrationKitNameA)) - - Eventually(BuildPhase(ns, integrationKitNameC), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded)) - Eventually(IntegrationPodPhase(ns, integrationC), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, integrationC, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, integrationC), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - Eventually(Kit(ns, integrationKitNameC)().Status.BaseImage).Should(ContainSubstring(integrationKitNameB)) - - Eventually(BuildPhase(ns, integrationKitNameZ), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded)) - Eventually(IntegrationPodPhase(ns, integrationZ), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, integrationZ, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, integrationZ), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - Eventually(Kit(ns, integrationKitNameZ)().Status.BaseImage).Should(Equal(defaults.BaseImage())) - - buildA := Build(ns, integrationKitNameA)() - buildB := Build(ns, integrationKitNameB)() - buildC := Build(ns, integrationKitNameC)() - buildZ := Build(ns, integrationKitNameZ)() - - Expect(buildA.Status.StartedAt.Before(buildB.Status.StartedAt)).Should(BeTrue()) - Expect(buildA.Status.StartedAt.Before(buildC.Status.StartedAt)).Should(BeTrue()) - Expect(buildB.Status.StartedAt.Before(buildC.Status.StartedAt)).Should(BeTrue()) - Expect(buildZ.Status.StartedAt.Before(buildB.Status.StartedAt)).Should(BeTrue()) - Expect(buildZ.Status.StartedAt.Before(buildC.Status.StartedAt)).Should(BeTrue()) - - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/timer-source.groovy", "--name", integrationZ).Execute()).To(Succeed()) + + g.Eventually(IntegrationKit(t, ctx, ns, integrationB), TestTimeoutMedium).ShouldNot(BeEmpty()) + g.Eventually(IntegrationKit(t, ctx, ns, integrationC), TestTimeoutMedium).ShouldNot(BeEmpty()) + g.Eventually(IntegrationKit(t, ctx, ns, integrationZ), TestTimeoutMedium).ShouldNot(BeEmpty()) + + integrationKitNameB := IntegrationKit(t, ctx, ns, integrationB)() + integrationKitNameC := IntegrationKit(t, ctx, ns, integrationC)() + integrationKitNameZ := IntegrationKit(t, ctx, ns, integrationZ)() + + g.Eventually(BuildPhase(t, ctx, ns, integrationKitNameA), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded)) + g.Eventually(IntegrationPodPhase(t, ctx, ns, integrationA), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, integrationA, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, integrationA), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + g.Eventually(Kit(t, ctx, ns, integrationKitNameA)().Status.BaseImage).Should(Equal(defaults.BaseImage())) + + g.Eventually(BuildPhase(t, ctx, ns, integrationKitNameB), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded)) + g.Eventually(IntegrationPodPhase(t, ctx, ns, integrationB), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, integrationB, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, integrationB), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + g.Eventually(Kit(t, ctx, ns, integrationKitNameB)().Status.BaseImage).Should(ContainSubstring(integrationKitNameA)) + + g.Eventually(BuildPhase(t, ctx, ns, integrationKitNameC), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded)) + g.Eventually(IntegrationPodPhase(t, ctx, ns, integrationC), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, integrationC, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, integrationC), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + g.Eventually(Kit(t, ctx, ns, integrationKitNameC)().Status.BaseImage).Should(ContainSubstring(integrationKitNameB)) + + g.Eventually(BuildPhase(t, ctx, ns, integrationKitNameZ), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded)) + g.Eventually(IntegrationPodPhase(t, ctx, ns, integrationZ), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, integrationZ, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, integrationZ), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + g.Eventually(Kit(t, ctx, ns, integrationKitNameZ)().Status.BaseImage).Should(Equal(defaults.BaseImage())) + + buildA := Build(t, ctx, ns, integrationKitNameA)() + buildB := Build(t, ctx, ns, integrationKitNameB)() + buildC := Build(t, ctx, ns, integrationKitNameC)() + buildZ := Build(t, ctx, ns, integrationKitNameZ)() + + g.Expect(buildA.Status.StartedAt.Before(buildB.Status.StartedAt)).Should(BeTrue()) + g.Expect(buildA.Status.StartedAt.Before(buildC.Status.StartedAt)).Should(BeTrue()) + g.Expect(buildB.Status.StartedAt.Before(buildC.Status.StartedAt)).Should(BeTrue()) + g.Expect(buildZ.Status.StartedAt.Before(buildB.Status.StartedAt)).Should(BeTrue()) + g.Expect(buildZ.Status.StartedAt.Before(buildC.Status.StartedAt)).Should(BeTrue()) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) } /* func TestRunBuildOrderStrategyFIFO(t *testing.T) { - WithNewTestNamespace(t, func(ns string) { + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) {x operatorID := "camel-k-build-order-fifo" - Expect(CopyCamelCatalog(ns, operatorID)).To(Succeed()) - Expect(KamelInstallWithID(operatorID, ns, "--build-order-strategy", string(v1.BuildOrderStrategyFIFO)).Execute()).To(Succeed()) - Eventually(PlatformPhase(ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns, "--build-order-strategy", string(v1.BuildOrderStrategyFIFO)).Execute()).To(Succeed()) + g.Eventually(PlatformPhase(t, ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) - Expect(CreateTimerKamelet(ns, "timer-source")()).To(Succeed()) + g.Expect(CreateTimerKamelet(t, ctx, ns, "timer-source")()).To(Succeed()) integrationA := RandomizedSuffixName("java-a") - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", integrationA, ).Execute()).To(Succeed()) - Eventually(IntegrationPhase(ns, integrationA)).Should(Equal(v1.IntegrationPhaseBuildingKit)) + g.Eventually(IntegrationPhase(t, ctx, ns, integrationA)).Should(Equal(v1.IntegrationPhaseBuildingKit)) integrationB := RandomizedSuffixName("java-b") - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", integrationB, "-d", "camel:joor", ).Execute()).To(Succeed()) integrationZ := RandomizedSuffixName("groovy-z") - Expect(KamelRunWithID(operatorID, ns, "files/timer-source.groovy", + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/timer-source.groovy", "--name", integrationZ, ).Execute()).To(Succeed()) - integrationKitNameA := IntegrationKit(ns, integrationA)() - Eventually(BuildPhase(ns, integrationKitNameA), TestTimeoutShort).Should(Equal(v1.BuildPhaseRunning)) + integrationKitNameA := IntegrationKit(t, ctx, ns, integrationA)() + g.Eventually(BuildPhase(t, ctx, ns, integrationKitNameA), TestTimeoutShort).Should(Equal(v1.BuildPhaseRunning)) - Eventually(IntegrationPhase(ns, integrationB)).Should(Equal(v1.IntegrationPhaseBuildingKit)) - integrationKitNameB := IntegrationKit(ns, integrationB)() - Eventually(BuildPhase(ns, integrationKitNameB), TestTimeoutShort).Should(Equal(v1.BuildPhaseRunning)) + g.Eventually(IntegrationPhase(t, ctx, ns, integrationB)).Should(Equal(v1.IntegrationPhaseBuildingKit)) + integrationKitNameB := IntegrationKit(t, ctx, ns, integrationB)() + g.Eventually(BuildPhase(t, ctx, ns, integrationKitNameB), TestTimeoutShort).Should(Equal(v1.BuildPhaseRunning)) - Eventually(IntegrationPhase(ns, integrationZ)).Should(Equal(v1.IntegrationPhaseBuildingKit)) - integrationKitNameZ := IntegrationKit(ns, integrationZ)() - Eventually(BuildPhase(ns, integrationKitNameZ), TestTimeoutShort).Should(Equal(v1.BuildPhaseRunning)) + g.Eventually(IntegrationPhase(t, ctx, ns, integrationZ)).Should(Equal(v1.IntegrationPhaseBuildingKit)) + integrationKitNameZ := IntegrationKit(t, ctx, ns, integrationZ)() + g.Eventually(BuildPhase(t, ctx, ns, integrationKitNameZ), TestTimeoutShort).Should(Equal(v1.BuildPhaseRunning)) - Eventually(BuildPhase(ns, integrationKitNameA), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded)) - Eventually(IntegrationPodPhase(ns, integrationA), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, integrationA, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, integrationA), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - Eventually(Kit(ns, integrationKitNameA)().Status.BaseImage).Should(Equal(defaults.BaseImage())) + g.Eventually(BuildPhase(t, ctx, ns, integrationKitNameA), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded)) + g.Eventually(IntegrationPodPhase(t, ctx, ns, integrationA), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, integrationA, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, integrationA), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + g.Eventually(Kit(t, ctx, ns, integrationKitNameA)().Status.BaseImage).Should(Equal(defaults.BaseImage())) - Eventually(BuildPhase(ns, integrationKitNameB), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded)) - Eventually(IntegrationPodPhase(ns, integrationB), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, integrationB, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, integrationB), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - Eventually(Kit(ns, integrationKitNameB)().Status.BaseImage).Should(Equal(defaults.BaseImage())) + g.Eventually(BuildPhase(t, ctx, ns, integrationKitNameB), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded)) + g.Eventually(IntegrationPodPhase(t, ctx, ns, integrationB), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, integrationB, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, integrationB), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + g.Eventually(Kit(t, ctx, ns, integrationKitNameB)().Status.BaseImage).Should(Equal(defaults.BaseImage())) - Eventually(BuildPhase(ns, integrationKitNameZ), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded)) - Eventually(IntegrationPodPhase(ns, integrationZ), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, integrationZ, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, integrationZ), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - Eventually(Kit(ns, integrationKitNameZ)().Status.BaseImage).Should(Equal(defaults.BaseImage())) + g.Eventually(BuildPhase(t, ctx, ns, integrationKitNameZ), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded)) + g.Eventually(IntegrationPodPhase(t, ctx, ns, integrationZ), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, integrationZ, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, integrationZ), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + g.Eventually(Kit(t, ctx, ns, integrationKitNameZ)().Status.BaseImage).Should(Equal(defaults.BaseImage())) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + g.Expect(Kamel(t, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) } */ diff --git a/e2e/advanced/builder_test.go b/e2e/advanced/builder_test.go index b79651cfde..c5a0919aca 100644 --- a/e2e/advanced/builder_test.go +++ b/e2e/advanced/builder_test.go @@ -23,6 +23,7 @@ limitations under the License. package advanced import ( + "context" "fmt" "testing" "time" @@ -36,49 +37,50 @@ import ( ) func TestBuilderTimeout(t *testing.T) { - WithNewTestNamespace(t, func(ns string) { + t.Parallel() + + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { operatorID := fmt.Sprintf("camel-k-%s", ns) - Expect(CopyCamelCatalog(ns, operatorID)).To(Succeed()) - Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed()) - Eventually(OperatorPod(ns)).ShouldNot(BeNil()) - Eventually(Platform(ns)).ShouldNot(BeNil()) - Eventually(PlatformConditionStatus(ns, v1.IntegrationPlatformConditionTypeCreated), TestTimeoutShort). + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + g.Eventually(OperatorPod(t, ctx, ns)).ShouldNot(BeNil()) + g.Eventually(Platform(t, ctx, ns)).ShouldNot(BeNil()) + g.Eventually(PlatformConditionStatus(t, ctx, ns, v1.IntegrationPlatformConditionTypeCreated), TestTimeoutShort). Should(Equal(corev1.ConditionTrue)) - pl := Platform(ns)() + pl := Platform(t, ctx, ns)() // set a short timeout to simulate the build timeout pl.Spec.Build.Timeout = &metav1.Duration{ Duration: 10 * time.Second, } - TestClient().Update(TestContext, pl) - Eventually(Platform(ns)).ShouldNot(BeNil()) - Eventually(PlatformTimeout(ns)).Should(Equal( + TestClient(t).Update(ctx, pl) + g.Eventually(Platform(t, ctx, ns)).ShouldNot(BeNil()) + g.Eventually(PlatformTimeout(t, ctx, ns)).Should(Equal( &metav1.Duration{ Duration: 10 * time.Second, }, )) - operatorPod := OperatorPod(ns)() + operatorPod := OperatorPod(t, ctx, ns)() operatorPodImage := operatorPod.Spec.Containers[0].Image t.Run("run yaml", func(t *testing.T) { name := RandomizedSuffixName("yaml") - Expect(KamelRunWithID(operatorID, ns, "files/yaml.yaml", - "--name", name, - "-t", "builder.strategy=pod").Execute()).To(Succeed()) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/yaml.yaml", "--name", name, "-t", "builder.strategy=pod").Execute()).To(Succeed()) // As the build hits timeout, it keeps trying building - Eventually(IntegrationPhase(ns, name)).Should(Equal(v1.IntegrationPhaseBuildingKit)) - integrationKitName := IntegrationKit(ns, name)() + g.Eventually(IntegrationPhase(t, ctx, ns, name)).Should(Equal(v1.IntegrationPhaseBuildingKit)) + integrationKitName := IntegrationKit(t, ctx, ns, name)() builderKitName := fmt.Sprintf("camel-k-%s-builder", integrationKitName) - Eventually(BuilderPodPhase(ns, builderKitName)).Should(Equal(corev1.PodPending)) - Eventually(BuildPhase(ns, integrationKitName)).Should(Equal(v1.BuildPhaseRunning)) - Eventually(BuilderPod(ns, builderKitName)().Spec.InitContainers[0].Name).Should(Equal("builder")) - Eventually(BuilderPod(ns, builderKitName)().Spec.InitContainers[0].Image).Should(Equal(operatorPodImage)) + g.Eventually(BuilderPodPhase(t, ctx, ns, builderKitName)).Should(Equal(corev1.PodPending)) + g.Eventually(BuildPhase(t, ctx, ns, integrationKitName)).Should(Equal(v1.BuildPhaseRunning)) + g.Eventually(BuilderPod(t, ctx, ns, builderKitName)().Spec.InitContainers[0].Name).Should(Equal("builder")) + g.Eventually(BuilderPod(t, ctx, ns, builderKitName)().Spec.InitContainers[0].Image).Should(Equal(operatorPodImage)) // After a few minutes (5 max retries), this has to be in error state - Eventually(BuildPhase(ns, integrationKitName), TestTimeoutMedium).Should(Equal(v1.BuildPhaseError)) - Eventually(IntegrationPhase(ns, name), TestTimeoutMedium).Should(Equal(v1.IntegrationPhaseError)) - Eventually(BuildFailureRecovery(ns, integrationKitName), TestTimeoutMedium).Should(Equal(5)) - Eventually(BuilderPodPhase(ns, builderKitName), TestTimeoutMedium).Should(Equal(corev1.PodFailed)) + g.Eventually(BuildPhase(t, ctx, ns, integrationKitName), TestTimeoutMedium).Should(Equal(v1.BuildPhaseError)) + g.Eventually(IntegrationPhase(t, ctx, ns, name), TestTimeoutMedium).Should(Equal(v1.IntegrationPhaseError)) + g.Eventually(BuildFailureRecovery(t, ctx, ns, integrationKitName), TestTimeoutMedium).Should(Equal(5)) + g.Eventually(BuilderPodPhase(t, ctx, ns, builderKitName), TestTimeoutMedium).Should(Equal(corev1.PodFailed)) }) }) } diff --git a/e2e/advanced/catalog_builder_test.go b/e2e/advanced/catalog_builder_test.go index 2917b10304..7b85e0ef59 100644 --- a/e2e/advanced/catalog_builder_test.go +++ b/e2e/advanced/catalog_builder_test.go @@ -23,6 +23,7 @@ limitations under the License. package advanced import ( + "context" "fmt" "strings" "testing" @@ -36,18 +37,20 @@ import ( ) func TestCamelCatalogBuilder(t *testing.T) { + t.Parallel() - WithNewTestNamespace(t, func(ns string) { + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { operatorID := fmt.Sprintf("camel-k-%s", ns) - Expect(CopyCamelCatalog(ns, operatorID)).To(Succeed()) - Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed()) - Eventually(OperatorPod(ns)).ShouldNot(BeNil()) - Eventually(Platform(ns)).ShouldNot(BeNil()) - Eventually(PlatformConditionStatus(ns, v1.IntegrationPlatformConditionTypeCreated), TestTimeoutShort). + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + g.Eventually(OperatorPod(t, ctx, ns)).ShouldNot(BeNil()) + g.Eventually(Platform(t, ctx, ns)).ShouldNot(BeNil()) + g.Eventually(PlatformConditionStatus(t, ctx, ns, v1.IntegrationPlatformConditionTypeCreated), TestTimeoutShort). Should(Equal(corev1.ConditionTrue)) catalogName := fmt.Sprintf("camel-catalog-%s", strings.ToLower(defaults.DefaultRuntimeVersion)) - Eventually(CamelCatalog(ns, catalogName)).ShouldNot(BeNil()) - Eventually(CamelCatalogPhase(ns, catalogName), TestTimeoutMedium).Should(Equal(v1.CamelCatalogPhaseReady)) + g.Eventually(CamelCatalog(t, ctx, ns, catalogName)).ShouldNot(BeNil()) + g.Eventually(CamelCatalogPhase(t, ctx, ns, catalogName), TestTimeoutMedium).Should(Equal(v1.CamelCatalogPhaseReady)) // Run an integration with a catalog not compatible // The operator should create the catalog, but fail on reconciliation as it is not compatible @@ -55,24 +58,22 @@ func TestCamelCatalogBuilder(t *testing.T) { t.Run("Run catalog not compatible", func(t *testing.T) { name := RandomizedSuffixName("java-1-15") nonCompatibleCatalogName := "camel-catalog-1.15.0" - Expect( - KamelRunWithID(operatorID, ns, "files/Java.java", "--name", name, - "-t", "camel.runtime-version=1.15.0", - ).Execute()).To(Succeed()) - - Eventually(CamelCatalog(ns, nonCompatibleCatalogName)).ShouldNot(BeNil()) - Eventually(CamelCatalogPhase(ns, nonCompatibleCatalogName)).Should(Equal(v1.CamelCatalogPhaseError)) - Eventually(CamelCatalogCondition(ns, nonCompatibleCatalogName, v1.CamelCatalogConditionReady)().Message).Should(ContainSubstring("Container image tool missing in catalog")) - - Eventually(IntegrationKit(ns, name)).ShouldNot(Equal("")) - kitName := IntegrationKit(ns, name)() - Eventually(KitPhase(ns, kitName)).Should(Equal(v1.IntegrationKitPhaseError)) - Eventually(KitCondition(ns, kitName, v1.IntegrationKitConditionCatalogAvailable)().Reason).Should(Equal("Camel Catalog 1.15.0 error")) - Eventually(IntegrationPhase(ns, name)).Should(Equal(v1.IntegrationPhaseError)) - Eventually(IntegrationCondition(ns, name, v1.IntegrationConditionKitAvailable)().Status).Should(Equal(corev1.ConditionFalse)) + g.Expect( + KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", name, "-t", "camel.runtime-version=1.15.0").Execute()).To(Succeed()) + + g.Eventually(CamelCatalog(t, ctx, ns, nonCompatibleCatalogName)).ShouldNot(BeNil()) + g.Eventually(CamelCatalogPhase(t, ctx, ns, nonCompatibleCatalogName)).Should(Equal(v1.CamelCatalogPhaseError)) + g.Eventually(CamelCatalogCondition(t, ctx, ns, nonCompatibleCatalogName, v1.CamelCatalogConditionReady)().Message).Should(ContainSubstring("Container image tool missing in catalog")) + + g.Eventually(IntegrationKit(t, ctx, ns, name)).ShouldNot(Equal("")) + kitName := IntegrationKit(t, ctx, ns, name)() + g.Eventually(KitPhase(t, ctx, ns, kitName)).Should(Equal(v1.IntegrationKitPhaseError)) + g.Eventually(KitCondition(t, ctx, ns, kitName, v1.IntegrationKitConditionCatalogAvailable)().Reason).Should(Equal("Camel Catalog 1.15.0 error")) + g.Eventually(IntegrationPhase(t, ctx, ns, name)).Should(Equal(v1.IntegrationPhaseError)) + g.Eventually(IntegrationCondition(t, ctx, ns, name, v1.IntegrationConditionKitAvailable)().Status).Should(Equal(corev1.ConditionFalse)) // Clean up - Eventually(DeleteIntegrations(ns)).Should(Equal(0)) + g.Eventually(DeleteIntegrations(t, ctx, ns)).Should(Equal(0)) }) // Run an integration with a compatible catalog @@ -83,24 +84,22 @@ func TestCamelCatalogBuilder(t *testing.T) { compatibleCatalogName := "camel-catalog-" + strings.ToLower(compatibleVersion) // First of all we delete the catalog, if by any chance it was created previously - Expect(DeleteCamelCatalog(ns, compatibleCatalogName)()).Should(BeTrue()) - Eventually(CamelCatalog(ns, compatibleCatalogName)).Should(BeNil()) - - Expect( - KamelRunWithID(operatorID, ns, "files/Java.java", "--name", name, - "-t", "camel.runtime-version="+compatibleVersion, - ).Execute()).To(Succeed()) - - Eventually(CamelCatalog(ns, compatibleCatalogName)).ShouldNot(BeNil()) - Eventually(CamelCatalogPhase(ns, compatibleCatalogName)).Should(Equal(v1.CamelCatalogPhaseReady)) - Eventually(CamelCatalogCondition(ns, compatibleCatalogName, v1.CamelCatalogConditionReady)().Message).Should(Equal("Container image tool found in catalog")) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutMedium). + g.Expect(DeleteCamelCatalog(t, ctx, ns, compatibleCatalogName)()).Should(BeTrue()) + g.Eventually(CamelCatalog(t, ctx, ns, compatibleCatalogName)).Should(BeNil()) + + g.Expect( + KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", name, "-t", "camel.runtime-version="+compatibleVersion).Execute()).To(Succeed()) + + g.Eventually(CamelCatalog(t, ctx, ns, compatibleCatalogName)).ShouldNot(BeNil()) + g.Eventually(CamelCatalogPhase(t, ctx, ns, compatibleCatalogName)).Should(Equal(v1.CamelCatalogPhaseReady)) + g.Eventually(CamelCatalogCondition(t, ctx, ns, compatibleCatalogName, v1.CamelCatalogConditionReady)().Message).Should(Equal("Container image tool found in catalog")) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutMedium). Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutMedium).Should(ContainSubstring("Magicstring!")) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutMedium).Should(ContainSubstring("Magicstring!")) // Clean up - Eventually(DeleteIntegrations(ns)).Should(Equal(0)) + g.Eventually(DeleteIntegrations(t, ctx, ns)).Should(Equal(0)) }) t.Run("Run catalog container exists", func(t *testing.T) { @@ -109,32 +108,30 @@ func TestCamelCatalogBuilder(t *testing.T) { compatibleCatalogName := "camel-catalog-" + strings.ToLower(compatibleVersion) // First of all we delete the catalog, if by any chance it was created previously - Expect(DeleteCamelCatalog(ns, compatibleCatalogName)()).Should(BeTrue()) - Eventually(CamelCatalog(ns, compatibleCatalogName)).Should(BeNil()) + g.Expect(DeleteCamelCatalog(t, ctx, ns, compatibleCatalogName)()).Should(BeTrue()) + g.Eventually(CamelCatalog(t, ctx, ns, compatibleCatalogName)).Should(BeNil()) - Expect( - KamelRunWithID(operatorID, ns, "files/Java.java", "--name", name, - "-t", "camel.runtime-version="+compatibleVersion, - ).Execute()).To(Succeed()) + g.Expect( + KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", name, "-t", "camel.runtime-version="+compatibleVersion).Execute()).To(Succeed()) - Eventually(CamelCatalog(ns, compatibleCatalogName)).ShouldNot(BeNil()) - Eventually(CamelCatalogPhase(ns, compatibleCatalogName)).Should(Equal(v1.CamelCatalogPhaseReady)) - Eventually(CamelCatalogCondition(ns, compatibleCatalogName, v1.CamelCatalogConditionReady)().Message).Should( + g.Eventually(CamelCatalog(t, ctx, ns, compatibleCatalogName)).ShouldNot(BeNil()) + g.Eventually(CamelCatalogPhase(t, ctx, ns, compatibleCatalogName)).Should(Equal(v1.CamelCatalogPhaseReady)) + g.Eventually(CamelCatalogCondition(t, ctx, ns, compatibleCatalogName, v1.CamelCatalogConditionReady)().Message).Should( Equal("Container image tool found in catalog"), ) - Eventually(IntegrationKit(ns, name)).ShouldNot(Equal("")) - kitName := IntegrationKit(ns, name)() - Eventually(KitPhase(ns, kitName)).Should(Equal(v1.IntegrationKitPhaseReady)) - Eventually(IntegrationPodPhase(ns, name)).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort). + g.Eventually(IntegrationKit(t, ctx, ns, name)).ShouldNot(Equal("")) + kitName := IntegrationKit(t, ctx, ns, name)() + g.Eventually(KitPhase(t, ctx, ns, kitName)).Should(Equal(v1.IntegrationKitPhaseReady)) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name)).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort). Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) // Clean up - Eventually(DeleteIntegrations(ns)).Should(Equal(0)) + g.Eventually(DeleteIntegrations(t, ctx, ns)).Should(Equal(0)) }) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) } diff --git a/e2e/advanced/debug_test.go b/e2e/advanced/debug_test.go index 1a0fb8bc89..6806e57d55 100644 --- a/e2e/advanced/debug_test.go +++ b/e2e/advanced/debug_test.go @@ -37,69 +37,70 @@ import ( ) func TestKamelCLIDebug(t *testing.T) { - RegisterTestingT(t) + t.Parallel() - WithNewTestNamespace(t, func(ns string) { + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { operatorID := fmt.Sprintf("camel-k-%s", ns) - Expect(CopyCamelCatalog(ns, operatorID)).To(Succeed()) - Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed()) + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) - Eventually(SelectedPlatformPhase(ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) t.Run("debug local default port check", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "files/yaml.yaml").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "yaml"), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) - Expect(portIsInUse("127.0.0.1", "5005")()).To(BeFalse()) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/yaml.yaml").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "yaml"), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) + g.Expect(portIsInUse("127.0.0.1", "5005")()).To(BeFalse()) - debugTestContext, cancel := context.WithCancel(TestContext) + debugTestContext, cancel := context.WithCancel(ctx) defer cancelAndWait(cancel) - go KamelWithContext(debugTestContext, "debug", "yaml", "-n", ns).ExecuteContext(debugTestContext) + go KamelWithContext(t, debugTestContext, "debug", "yaml", "-n", ns).ExecuteContext(debugTestContext) - Eventually(portIsInUse("127.0.0.1", "5005"), TestTimeoutMedium, 5*time.Second).Should(BeTrue()) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + g.Eventually(portIsInUse("127.0.0.1", "5005"), TestTimeoutMedium, 5*time.Second).Should(BeTrue()) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) t.Run("debug local port check", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "files/yaml.yaml").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "yaml"), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) - Expect(portIsInUse("127.0.0.1", "5006")()).To(BeFalse()) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/yaml.yaml").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "yaml"), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) + g.Expect(portIsInUse("127.0.0.1", "5006")()).To(BeFalse()) - debugTestContext, cancel := context.WithCancel(TestContext) + debugTestContext, cancel := context.WithCancel(ctx) defer cancelAndWait(cancel) - go KamelWithContext(debugTestContext, "debug", "yaml", "--port", "5006", "-n", ns).ExecuteContext(debugTestContext) + go KamelWithContext(t, debugTestContext, "debug", "yaml", "--port", "5006", "-n", ns).ExecuteContext(debugTestContext) - Eventually(portIsInUse("127.0.0.1", "5006"), TestTimeoutMedium, 5*time.Second).Should(BeTrue()) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + g.Eventually(portIsInUse("127.0.0.1", "5006"), TestTimeoutMedium, 5*time.Second).Should(BeTrue()) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) t.Run("debug logs check", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "files/yaml.yaml").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "yaml"), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/yaml.yaml").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "yaml"), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) - debugTestContext, cancel := context.WithCancel(TestContext) + debugTestContext, cancel := context.WithCancel(ctx) defer cancelAndWait(cancel) - go KamelWithContext(debugTestContext, "debug", "yaml", "-n", ns).ExecuteContext(debugTestContext) + go KamelWithContext(t, debugTestContext, "debug", "yaml", "-n", ns).ExecuteContext(debugTestContext) - Eventually(IntegrationLogs(ns, "yaml"), TestTimeoutMedium).Should(ContainSubstring("Listening for transport dt_socket at address: 5005")) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + g.Eventually(IntegrationLogs(t, ctx, ns, "yaml"), TestTimeoutMedium).Should(ContainSubstring("Listening for transport dt_socket at address: 5005")) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) t.Run("Pod config test", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "files/yaml.yaml").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "yaml"), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/yaml.yaml").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "yaml"), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) - debugTestContext, cancel := context.WithCancel(TestContext) + debugTestContext, cancel := context.WithCancel(ctx) defer cancelAndWait(cancel) - go KamelWithContext(debugTestContext, "debug", "yaml", "-n", ns).ExecuteContext(debugTestContext) + go KamelWithContext(t, debugTestContext, "debug", "yaml", "-n", ns).ExecuteContext(debugTestContext) - Eventually(func() string { - return IntegrationPod(ns, "yaml")().Spec.Containers[0].Args[0] + g.Eventually(func() string { + return IntegrationPod(t, ctx, ns, "yaml")().Spec.Containers[0].Args[0] }).Should(ContainSubstring("-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5005")) - Expect(IntegrationPod(ns, "yaml")().GetLabels()["camel.apache.org/debug"]).To(Not(BeNil())) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + g.Expect(IntegrationPod(t, ctx, ns, "yaml")().GetLabels()["camel.apache.org/debug"]).To(Not(BeNil())) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) } diff --git a/e2e/advanced/deployment_test.go b/e2e/advanced/deployment_test.go index cd8acc44d3..ba3b931926 100644 --- a/e2e/advanced/deployment_test.go +++ b/e2e/advanced/deployment_test.go @@ -23,6 +23,7 @@ limitations under the License. package advanced import ( + "context" "testing" . "github.com/onsi/gomega" @@ -34,13 +35,16 @@ import ( ) func TestDeploymentFailureShouldReportIntegrationCondition(t *testing.T) { - WithNewTestNamespace(t, func(ns string) { + t.Parallel() + + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { operatorID := "camel-k-failing-deploy" nsRestr := "restr" - Expect(CopyCamelCatalog(ns, operatorID)).To(Succeed()) - Expect(KamelInstallWithID(operatorID, ns, "--global", "--force").Execute()).To(Succeed()) + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns, "--global", "--force")).To(Succeed()) // Create restricted namespace - ExpectExecSucceed(t, + ExpectExecSucceed(t, g, exec.Command( "kubectl", "create", @@ -48,7 +52,7 @@ func TestDeploymentFailureShouldReportIntegrationCondition(t *testing.T) { nsRestr, ), ) - ExpectExecSucceed(t, + ExpectExecSucceed(t, g, exec.Command( "kubectl", "label", @@ -65,14 +69,14 @@ func TestDeploymentFailureShouldReportIntegrationCondition(t *testing.T) { ) // Create an Integration into a restricted namespace name := RandomizedSuffixName("java-fail") - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", "--name", name, "-n", nsRestr).Execute()).To(Succeed()) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", name, "-n", nsRestr).Execute()).To(Succeed()) // Check the error is reported into the Integration - Eventually(IntegrationPhase(nsRestr, name), TestTimeoutMedium).Should(Equal(v1.IntegrationPhaseError)) - Eventually(IntegrationCondition(nsRestr, name, v1.IntegrationConditionReady)().Status). + g.Eventually(IntegrationPhase(t, ctx, nsRestr, name), TestTimeoutMedium).Should(Equal(v1.IntegrationPhaseError)) + g.Eventually(IntegrationCondition(t, ctx, nsRestr, name, v1.IntegrationConditionReady)().Status). Should(Equal(corev1.ConditionFalse)) - Eventually(IntegrationCondition(nsRestr, name, v1.IntegrationConditionReady)().Message). + g.Eventually(IntegrationCondition(t, ctx, nsRestr, name, v1.IntegrationConditionReady)().Message). Should(ContainSubstring("is forbidden: violates PodSecurity")) // Clean up - Eventually(DeleteIntegrations(nsRestr)).Should(Equal(0)) + g.Eventually(DeleteIntegrations(t, ctx, nsRestr)).Should(Equal(0)) }) } diff --git a/e2e/advanced/dump_test.go b/e2e/advanced/dump_test.go index 587c8116d8..37b5e0bcc7 100644 --- a/e2e/advanced/dump_test.go +++ b/e2e/advanced/dump_test.go @@ -23,6 +23,7 @@ limitations under the License. package advanced import ( + "context" "fmt" v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" "testing" @@ -35,31 +36,32 @@ import ( ) func TestKamelCLIDump(t *testing.T) { - RegisterTestingT(t) + t.Parallel() - WithNewTestNamespace(t, func(ns string) { + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { t.Run("dump empty namespace", func(t *testing.T) { - dump := GetOutputString(Kamel("dump", "-n", ns)) + dump := GetOutputString(Kamel(t, ctx, "dump", "-n", ns)) - Expect(dump).To(ContainSubstring("Found 0 integrations:")) - Expect(dump).To(ContainSubstring("Found 0 deployments:")) + g.Expect(dump).To(ContainSubstring("Found 0 integrations:")) + g.Expect(dump).To(ContainSubstring("Found 0 deployments:")) }) t.Run("dump non-empty namespace", func(t *testing.T) { operatorID := fmt.Sprintf("camel-k-%s", ns) - Expect(CopyCamelCatalog(ns, operatorID)).To(Succeed()) - Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed()) - Eventually(SelectedPlatformPhase(ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) - Expect(KamelRunWithID(operatorID, ns, "files/yaml.yaml").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "yaml"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns, "yaml")).Should(ContainSubstring("Magicstring!")) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/yaml.yaml").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "yaml"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, "yaml")).Should(ContainSubstring("Magicstring!")) - dump := GetOutputString(Kamel("dump", "-n", ns)) - Expect(dump).To(ContainSubstring("Found 1 platforms")) - Expect(dump).To(ContainSubstring("Found 1 integrations")) - Expect(dump).To(ContainSubstring("name: yaml")) - Expect(dump).To(ContainSubstring("Magicstring!")) + dump := GetOutputString(Kamel(t, ctx, "dump", "-n", ns)) + g.Expect(dump).To(ContainSubstring("Found 1 platforms")) + g.Expect(dump).To(ContainSubstring("Found 1 integrations")) + g.Expect(dump).To(ContainSubstring("name: yaml")) + g.Expect(dump).To(ContainSubstring("Magicstring!")) }) }) } diff --git a/e2e/advanced/environment_test.go b/e2e/advanced/environment_test.go index 4bfffb4290..eadde81f63 100644 --- a/e2e/advanced/environment_test.go +++ b/e2e/advanced/environment_test.go @@ -23,6 +23,7 @@ limitations under the License. package advanced import ( + "context" "fmt" "os" "strings" @@ -39,7 +40,9 @@ import ( ) func TestEnvironmentTrait(t *testing.T) { - WithNewTestNamespace(t, func(ns string) { + t.Parallel() + + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { // HTTP proxy configuration httpProxy := "http://proxy" noProxy := []string{ @@ -50,37 +53,35 @@ func TestEnvironmentTrait(t *testing.T) { } // Retrieve the Kubernetes Service ClusterIPs to populate the NO_PROXY environment variable - svc := Service("default", "kubernetes")() - Expect(svc).NotTo(BeNil()) + svc := Service(t, ctx, TestDefaultNamespace, "kubernetes")() + g.Expect(svc).NotTo(BeNil()) noProxy = append(noProxy, svc.Spec.ClusterIPs...) // Retrieve the internal container registry to populate the NO_PROXY environment variable if registry, ok := os.LookupEnv("KAMEL_INSTALL_REGISTRY"); ok { domain := RegistryRegexp.FindString(registry) - Expect(domain).NotTo(BeNil()) + g.Expect(domain).NotTo(BeNil()) domain = strings.Split(domain, ":")[0] noProxy = append(noProxy, domain) } // Install Camel K with the HTTP proxy environment variable operatorID := "camel-k-trait-environment" - Expect(CopyCamelCatalog(ns, operatorID)).To(Succeed()) - Expect(KamelInstallWithID(operatorID, ns, - "--operator-env-vars", fmt.Sprintf("HTTP_PROXY=%s", httpProxy), - "--operator-env-vars", "NO_PROXY="+strings.Join(noProxy, ","), - ).Execute()).To(Succeed()) + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns, "--operator-env-vars", fmt.Sprintf("HTTP_PROXY=%s", httpProxy), "--operator-env-vars", "NO_PROXY="+strings.Join(noProxy, ","))).To(Succeed()) - Eventually(SelectedPlatformPhase(ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) t.Run("Run integration with default environment", func(t *testing.T) { name := RandomizedSuffixName("java-default") - Expect(KamelRunWithID(operatorID, ns, "--name", name, "files/Java.java").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "--name", name, "files/Java.java").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - Expect(IntegrationPod(ns, name)()).To(WithTransform(podEnvVars, And( + g.Expect(IntegrationPod(t, ctx, ns, name)()).To(WithTransform(podEnvVars, And( ContainElement(corev1.EnvVar{Name: "CAMEL_K_VERSION", Value: defaults.Version}), ContainElement(corev1.EnvVar{Name: "NAMESPACE", ValueFrom: &corev1.EnvVarSource{ FieldRef: &corev1.ObjectFieldSelector{ @@ -101,15 +102,12 @@ func TestEnvironmentTrait(t *testing.T) { t.Run("Run integration with custom environment", func(t *testing.T) { name := RandomizedSuffixName("java-custom-proxy") - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", - "--name", name, - "-t", "environment.vars=HTTP_PROXY=http://custom.proxy", - ).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - - Expect(IntegrationPod(ns, name)()).To(WithTransform(podEnvVars, And( + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", name, "-t", "environment.vars=HTTP_PROXY=http://custom.proxy").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + + g.Expect(IntegrationPod(t, ctx, ns, name)()).To(WithTransform(podEnvVars, And( ContainElement(corev1.EnvVar{Name: "CAMEL_K_VERSION", Value: defaults.Version}), ContainElement(corev1.EnvVar{Name: "NAMESPACE", ValueFrom: &corev1.EnvVarSource{ FieldRef: &corev1.ObjectFieldSelector{ @@ -130,15 +128,12 @@ func TestEnvironmentTrait(t *testing.T) { t.Run("Run integration without default HTTP proxy environment", func(t *testing.T) { name := RandomizedSuffixName("java-no-proxy") - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", - "--name", name, - "-t", "environment.http-proxy=false", - ).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - - Expect(IntegrationPod(ns, name)()).To(WithTransform(podEnvVars, And( + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", name, "-t", "environment.http-proxy=false").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + + g.Expect(IntegrationPod(t, ctx, ns, name)()).To(WithTransform(podEnvVars, And( ContainElement(corev1.EnvVar{Name: "CAMEL_K_VERSION", Value: defaults.Version}), ContainElement(corev1.EnvVar{Name: "NAMESPACE", ValueFrom: &corev1.EnvVarSource{ FieldRef: &corev1.ObjectFieldSelector{ @@ -157,15 +152,15 @@ func TestEnvironmentTrait(t *testing.T) { ))) // check integration schema does not contains unwanted default trait value. - Eventually(UnstructuredIntegration(ns, name)).ShouldNot(BeNil()) - unstructuredIntegration := UnstructuredIntegration(ns, name)() + g.Eventually(UnstructuredIntegration(t, ctx, ns, name)).ShouldNot(BeNil()) + unstructuredIntegration := UnstructuredIntegration(t, ctx, ns, name)() envTrait, _, _ := unstructured.NestedMap(unstructuredIntegration.Object, "spec", "traits", "environment") - Expect(envTrait).ToNot(BeNil()) - Expect(len(envTrait)).To(Equal(1)) - Expect(envTrait["httpProxy"]).To(Equal(false)) + g.Expect(envTrait).ToNot(BeNil()) + g.Expect(len(envTrait)).To(Equal(1)) + g.Expect(envTrait["httpProxy"]).To(Equal(false)) }) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) } diff --git a/e2e/advanced/incremental_build_test.go b/e2e/advanced/incremental_build_test.go index dc7bcf16e7..cdb1ba38ce 100644 --- a/e2e/advanced/incremental_build_test.go +++ b/e2e/advanced/incremental_build_test.go @@ -23,6 +23,7 @@ limitations under the License. package advanced import ( + "context" "fmt" "testing" @@ -36,217 +37,194 @@ import ( ) func TestRunIncrementalBuildRoutine(t *testing.T) { - WithNewTestNamespace(t, func(ns string) { - operatorID := "camel-k-incremental-build" - Expect(CopyCamelCatalog(ns, operatorID)).To(Succeed()) - Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed()) - Eventually(SelectedPlatformPhase(ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + t.Parallel() + + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-incremental-build-routine" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) name := RandomizedSuffixName("java") - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", - "--name", name, - ).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - integrationKitName := IntegrationKit(ns, name)() - Eventually(Kit(ns, integrationKitName)().Status.BaseImage).Should(Equal(defaults.BaseImage())) - Eventually(Kit(ns, integrationKitName)().Status.RootImage).Should(Equal(defaults.BaseImage())) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", name).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + integrationKitName := IntegrationKit(t, ctx, ns, name)() + g.Eventually(Kit(t, ctx, ns, integrationKitName)().Status.BaseImage).Should(Equal(defaults.BaseImage())) + g.Eventually(Kit(t, ctx, ns, integrationKitName)().Status.RootImage).Should(Equal(defaults.BaseImage())) t.Run("Reuse previous kit", func(t *testing.T) { nameClone := "java-clone" - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", - "--name", nameClone, - ).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, nameClone), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, nameClone, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, nameClone), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - integrationCloneKitName := IntegrationKit(ns, nameClone)() - Eventually(integrationCloneKitName).Should(Equal(integrationKitName)) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", nameClone).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, nameClone), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, nameClone, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, nameClone), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + integrationCloneKitName := IntegrationKit(t, ctx, ns, nameClone)() + g.Eventually(integrationCloneKitName).Should(Equal(integrationKitName)) }) t.Run("Create incremental kit", func(t *testing.T) { // Another integration that should be built on top of the previous IntegrationKit // just add a new random dependency nameIncremental := RandomizedSuffixName("java-incremental") - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", - "--name", nameIncremental, - "-d", "camel:zipfile", - ).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, nameIncremental), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, nameIncremental, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, nameIncremental), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - integrationIncrementalKitName := IntegrationKit(ns, nameIncremental)() + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", nameIncremental, "-d", "camel:zipfile").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, nameIncremental), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, nameIncremental, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, nameIncremental), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + integrationIncrementalKitName := IntegrationKit(t, ctx, ns, nameIncremental)() // the container comes in a format like // 10.108.177.66/test-d7cad110-bb1d-4e79-8a0e-ebd44f6fe5d4/camel-k-kit-c8357r4k5tp6fn1idm60@sha256:d49716f0429ad8b23a1b8d20a357d64b1aa42a67c1a2a534ebd4c54cd598a18d - // we should be save just to check the substring is contained - Eventually(Kit(ns, integrationIncrementalKitName)().Status.BaseImage).Should(ContainSubstring(integrationKitName)) - Eventually(Kit(ns, integrationIncrementalKitName)().Status.RootImage).Should(Equal(defaults.BaseImage())) + // we should be saving just to check the substring is contained + g.Eventually(Kit(t, ctx, ns, integrationIncrementalKitName)().Status.BaseImage).Should(ContainSubstring(integrationKitName)) + g.Eventually(Kit(t, ctx, ns, integrationIncrementalKitName)().Status.RootImage).Should(Equal(defaults.BaseImage())) }) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) } func TestRunIncrementalBuildPod(t *testing.T) { - WithNewTestNamespace(t, func(ns string) { - operatorID := "camel-k-incremental-build" - Expect(CopyCamelCatalog(ns, operatorID)).To(Succeed()) - Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed()) + t.Parallel() + + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-incremental-build-pod" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) name := RandomizedSuffixName("java") - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", - "--name", name, - "-t", "builder.strategy=pod", - ).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - integrationKitName := IntegrationKit(ns, name)() - Eventually(Kit(ns, integrationKitName)().Status.BaseImage).Should(Equal(defaults.BaseImage())) - Eventually(Kit(ns, integrationKitName)().Status.RootImage).Should(Equal(defaults.BaseImage())) - Eventually(BuilderPodsCount(ns)).Should(Equal(1)) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", name, "-t", "builder.strategy=pod").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + integrationKitName := IntegrationKit(t, ctx, ns, name)() + g.Eventually(Kit(t, ctx, ns, integrationKitName)().Status.BaseImage).Should(Equal(defaults.BaseImage())) + g.Eventually(Kit(t, ctx, ns, integrationKitName)().Status.RootImage).Should(Equal(defaults.BaseImage())) + g.Eventually(BuilderPodsCount(t, ctx, ns)).Should(Equal(1)) t.Run("Reuse previous kit", func(t *testing.T) { nameClone := RandomizedSuffixName("java-clone") - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", - "--name", nameClone, - "-t", "builder.strategy=pod", - ).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, nameClone), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, nameClone, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, nameClone), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - integrationCloneKitName := IntegrationKit(ns, nameClone)() - Eventually(integrationCloneKitName).Should(Equal(integrationKitName)) - Eventually(BuilderPodsCount(ns)).Should(Equal(1)) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", nameClone, "-t", "builder.strategy=pod").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, nameClone), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, nameClone, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, nameClone), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + integrationCloneKitName := IntegrationKit(t, ctx, ns, nameClone)() + g.Eventually(integrationCloneKitName).Should(Equal(integrationKitName)) + g.Eventually(BuilderPodsCount(t, ctx, ns)).Should(Equal(1)) }) t.Run("Create incremental kit", func(t *testing.T) { // Another integration that should be built on top of the previous IntegrationKit // just add a new random dependency nameIncremental := RandomizedSuffixName("java-incremental") - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", - "--name", nameIncremental, - "-d", "camel:zipfile", - "-t", "builder.strategy=pod", - ).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, nameIncremental), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, nameIncremental, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, nameIncremental), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - integrationIncrementalKitName := IntegrationKit(ns, nameIncremental)() + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", nameIncremental, "-d", "camel:zipfile", "-t", "builder.strategy=pod").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, nameIncremental), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, nameIncremental, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, nameIncremental), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + integrationIncrementalKitName := IntegrationKit(t, ctx, ns, nameIncremental)() // the container comes in a format like // 10.108.177.66/test-d7cad110-bb1d-4e79-8a0e-ebd44f6fe5d4/camel-k-kit-c8357r4k5tp6fn1idm60@sha256:d49716f0429ad8b23a1b8d20a357d64b1aa42a67c1a2a534ebd4c54cd598a18d - // we should be save just to check the substring is contained - Eventually(Kit(ns, integrationIncrementalKitName)().Status.BaseImage).Should(ContainSubstring(integrationKitName)) - Eventually(Kit(ns, integrationIncrementalKitName)().Status.RootImage).Should(Equal(defaults.BaseImage())) - Eventually(BuilderPodsCount(ns)).Should(Equal(2)) + // we should be saving just to check the substring is contained + g.Eventually(Kit(t, ctx, ns, integrationIncrementalKitName)().Status.BaseImage).Should(ContainSubstring(integrationKitName)) + g.Eventually(Kit(t, ctx, ns, integrationIncrementalKitName)().Status.RootImage).Should(Equal(defaults.BaseImage())) + g.Eventually(BuilderPodsCount(t, ctx, ns)).Should(Equal(2)) }) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) } func TestRunIncrementalBuildOff(t *testing.T) { - WithNewTestNamespace(t, func(ns string) { + t.Parallel() + + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { operatorID := "camel-k-standard-build" - Expect(CopyCamelCatalog(ns, operatorID)).To(Succeed()) - Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed()) + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) name := RandomizedSuffixName("java") - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", - "--name", name, - ).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - integrationKitName := IntegrationKit(ns, name)() - Eventually(Kit(ns, integrationKitName)().Status.BaseImage).Should(Equal(defaults.BaseImage())) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", name).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + integrationKitName := IntegrationKit(t, ctx, ns, name)() + g.Eventually(Kit(t, ctx, ns, integrationKitName)().Status.BaseImage).Should(Equal(defaults.BaseImage())) t.Run("Don't reuse previous kit", func(t *testing.T) { nameClone := RandomizedSuffixName("java-clone") - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", - "--name", nameClone, - "-t", "builder.incremental-image-build=false", - ).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, nameClone), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, nameClone, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, nameClone), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - integrationCloneKitName := IntegrationKit(ns, nameClone)() - Eventually(Kit(ns, integrationCloneKitName)().Status.BaseImage).Should(Equal(defaults.BaseImage())) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", nameClone, "-t", "builder.incremental-image-build=false").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, nameClone), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, nameClone, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, nameClone), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + integrationCloneKitName := IntegrationKit(t, ctx, ns, nameClone)() + g.Eventually(Kit(t, ctx, ns, integrationCloneKitName)().Status.BaseImage).Should(Equal(defaults.BaseImage())) }) t.Run("Don't create incremental kit", func(t *testing.T) { // Another integration that should be built on top of the previous IntegrationKit // just add a new random dependency nameIncremental := RandomizedSuffixName("java-incremental") - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", - "--name", nameIncremental, - "-d", "camel:zipfile", - "-t", "builder.incremental-image-build=false", - ).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, nameIncremental), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, nameIncremental, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, nameIncremental), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - integrationIncrementalKitName := IntegrationKit(ns, nameIncremental)() - Eventually(Kit(ns, integrationIncrementalKitName)().Status.BaseImage).Should(Equal(defaults.BaseImage())) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", nameIncremental, "-d", "camel:zipfile", "-t", "builder.incremental-image-build=false").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, nameIncremental), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, nameIncremental, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, nameIncremental), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + integrationIncrementalKitName := IntegrationKit(t, ctx, ns, nameIncremental)() + g.Eventually(Kit(t, ctx, ns, integrationIncrementalKitName)().Status.BaseImage).Should(Equal(defaults.BaseImage())) }) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) } func TestRunIncrementalBuildWithDifferentBaseImages(t *testing.T) { - WithNewTestNamespace(t, func(ns string) { - operatorID := "camel-k-standard-build" - Expect(CopyCamelCatalog(ns, operatorID)).To(Succeed()) - Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed()) + t.Parallel() + + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-incremental-different-base" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) name := RandomizedSuffixName("java") - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", - "--name", name, - ).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - integrationKitName := IntegrationKit(ns, name)() - Eventually(Kit(ns, integrationKitName)().Status.BaseImage).Should(Equal(defaults.BaseImage())) - Eventually(Kit(ns, integrationKitName)().Status.RootImage).Should(Equal(defaults.BaseImage())) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", name).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + integrationKitName := IntegrationKit(t, ctx, ns, name)() + g.Eventually(Kit(t, ctx, ns, integrationKitName)().Status.BaseImage).Should(Equal(defaults.BaseImage())) + g.Eventually(Kit(t, ctx, ns, integrationKitName)().Status.RootImage).Should(Equal(defaults.BaseImage())) t.Run("Create incremental kit", func(t *testing.T) { // Another integration that should be built on top of the previous IntegrationKit // just add a new random dependency nameIncremental := RandomizedSuffixName("java-incremental") - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", - "--name", nameIncremental, - "-d", "camel:zipfile", - ).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, nameIncremental), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, nameIncremental, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, nameIncremental), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - integrationIncrementalKitName := IntegrationKit(ns, nameIncremental)() + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", nameIncremental, "-d", "camel:zipfile").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, nameIncremental), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, nameIncremental, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, nameIncremental), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + integrationIncrementalKitName := IntegrationKit(t, ctx, ns, nameIncremental)() // the container comes in a format like // 10.108.177.66/test-d7cad110-bb1d-4e79-8a0e-ebd44f6fe5d4/camel-k-kit-c8357r4k5tp6fn1idm60@sha256:d49716f0429ad8b23a1b8d20a357d64b1aa42a67c1a2a534ebd4c54cd598a18d // we should be save just to check the substring is contained - Eventually(Kit(ns, integrationIncrementalKitName)().Status.BaseImage).Should(ContainSubstring(integrationKitName)) - Eventually(Kit(ns, integrationIncrementalKitName)().Status.RootImage).Should(Equal(defaults.BaseImage())) + g.Eventually(Kit(t, ctx, ns, integrationIncrementalKitName)().Status.BaseImage).Should(ContainSubstring(integrationKitName)) + g.Eventually(Kit(t, ctx, ns, integrationIncrementalKitName)().Status.RootImage).Should(Equal(defaults.BaseImage())) }) t.Run("Create new hierarchy kit", func(t *testing.T) { // We should spin off a new hierarchy of builds newBaseImage := "eclipse-temurin:17.0.8.1_1-jdk-ubi9-minimal" name = RandomizedSuffixName("java-new") - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", - "--name", name, - "-d", "camel:mongodb", - "-t", fmt.Sprintf("builder.base-image=%s", newBaseImage), - ).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - integrationKitName = IntegrationKit(ns, name)() - Eventually(Kit(ns, integrationKitName)().Status.BaseImage).Should(Equal(newBaseImage)) - Eventually(Kit(ns, integrationKitName)().Status.RootImage).Should(Equal(newBaseImage)) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", name, "-d", "camel:mongodb", "-t", fmt.Sprintf("builder.base-image=%s", newBaseImage)).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + integrationKitName = IntegrationKit(t, ctx, ns, name)() + g.Eventually(Kit(t, ctx, ns, integrationKitName)().Status.BaseImage).Should(Equal(newBaseImage)) + g.Eventually(Kit(t, ctx, ns, integrationKitName)().Status.RootImage).Should(Equal(newBaseImage)) }) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) } diff --git a/e2e/advanced/integration_profile_test.go b/e2e/advanced/integration_profile_test.go index b4475fb0f2..0a14026e23 100644 --- a/e2e/advanced/integration_profile_test.go +++ b/e2e/advanced/integration_profile_test.go @@ -23,6 +23,7 @@ limitations under the License. package advanced import ( + "context" "testing" "github.com/apache/camel-k/v2/pkg/util/defaults" @@ -36,10 +37,12 @@ import ( ) func TestIntegrationProfile(t *testing.T) { - WithNewTestNamespace(t, func(ns string) { + t.Parallel() + + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { operatorID := "camel-k-integration-profile" - Expect(KamelInstallWithID(operatorID, ns, "--global", "--force").Execute()).To(Succeed()) - Eventually(PlatformPhase(ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns, "--global", "--force")).To(Succeed()) + g.Eventually(PlatformPhase(t, ctx, ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) integrationProfile := v1.NewIntegrationProfile(ns, "ipr-global") integrationProfile.SetOperatorID(operatorID) @@ -48,44 +51,44 @@ func TestIntegrationProfile(t *testing.T) { LimitCPU: "0.2", } - Expect(CreateIntegrationProfile(&integrationProfile)).To(Succeed()) - Eventually(SelectedIntegrationProfilePhase(ns, "ipr-global"), TestTimeoutMedium).Should(Equal(v1.IntegrationProfilePhaseReady)) + g.Expect(CreateIntegrationProfile(t, ctx, &integrationProfile)).To(Succeed()) + g.Eventually(SelectedIntegrationProfilePhase(t, ctx, ns, "ipr-global"), TestTimeoutMedium).Should(Equal(v1.IntegrationProfilePhaseReady)) - WithNewTestNamespace(t, func(ns1 string) { + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns1 string) { integrationProfile := v1.NewIntegrationProfile(ns1, "ipr-local") integrationProfile.SetOperatorID(operatorID) integrationProfile.Spec.Traits.Container = &traitv1.ContainerTrait{ LimitCPU: "0.1", } - Expect(CreateIntegrationProfile(&integrationProfile)).To(Succeed()) - Eventually(SelectedIntegrationProfilePhase(ns1, "ipr-local"), TestTimeoutMedium).Should(Equal(v1.IntegrationProfilePhaseReady)) + g.Expect(CreateIntegrationProfile(t, ctx, &integrationProfile)).To(Succeed()) + g.Eventually(SelectedIntegrationProfilePhase(t, ctx, ns1, "ipr-local"), TestTimeoutMedium).Should(Equal(v1.IntegrationProfilePhaseReady)) t.Run("Run integration with global integration profile", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns1, "--name", "limited", "--integration-profile", "ipr-global", "files/yaml.yaml").Execute()).To(Succeed()) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns1, "--name", "limited", "--integration-profile", "ipr-global", "files/yaml.yaml").Execute()).To(Succeed()) - Eventually(IntegrationPod(ns1, "limited"), TestTimeoutMedium).Should(Not(BeNil())) - Eventually(IntegrationPodHas(ns1, "limited", func(pod *corev1.Pod) bool { + g.Eventually(IntegrationPod(t, ctx, ns1, "limited"), TestTimeoutMedium).Should(Not(BeNil())) + g.Eventually(IntegrationPodHas(t, ctx, ns1, "limited", func(pod *corev1.Pod) bool { if len(pod.Spec.Containers) != 1 { return false } containerName := pod.Spec.Containers[0].Name return containerName == "ck-integration-global" }), TestTimeoutShort).Should(BeTrue()) - Eventually(IntegrationPodHas(ns1, "limited", func(pod *corev1.Pod) bool { + g.Eventually(IntegrationPodHas(t, ctx, ns1, "limited", func(pod *corev1.Pod) bool { if len(pod.Spec.Containers) != 1 { return false } cpuLimits := pod.Spec.Containers[0].Resources.Limits.Cpu() return cpuLimits != nil && cpuLimits.AsApproximateFloat64() > 0 }), TestTimeoutShort).Should(BeTrue()) - Expect(Kamel("delete", "limited", "-n", ns1).Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "delete", "limited", "-n", ns1).Execute()).To(Succeed()) }) t.Run("Run integration with namespace local integration profile", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns1, "--name", "limited", "--integration-profile", "ipr-local", "files/yaml.yaml").Execute()).To(Succeed()) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns1, "--name", "limited", "--integration-profile", "ipr-local", "files/yaml.yaml").Execute()).To(Succeed()) - Eventually(IntegrationPod(ns1, "limited"), TestTimeoutMedium).Should(Not(BeNil())) - Eventually(IntegrationPodHas(ns1, "limited", func(pod *corev1.Pod) bool { + g.Eventually(IntegrationPod(t, ctx, ns1, "limited"), TestTimeoutMedium).Should(Not(BeNil())) + g.Eventually(IntegrationPodHas(t, ctx, ns1, "limited", func(pod *corev1.Pod) bool { if len(pod.Spec.Containers) != 1 { return false } @@ -93,20 +96,20 @@ func TestIntegrationProfile(t *testing.T) { return containerName == "integration" }), TestTimeoutShort).Should(BeTrue()) - Eventually(IntegrationPodHas(ns1, "limited", func(pod *corev1.Pod) bool { + g.Eventually(IntegrationPodHas(t, ctx, ns1, "limited", func(pod *corev1.Pod) bool { if len(pod.Spec.Containers) != 1 { return false } cpuLimits := pod.Spec.Containers[0].Resources.Limits.Cpu() return cpuLimits != nil && cpuLimits.AsApproximateFloat64() > 0 }), TestTimeoutShort).Should(BeTrue()) - Expect(Kamel("delete", "limited", "-n", ns1).Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "delete", "limited", "-n", ns1).Execute()).To(Succeed()) }) t.Run("Run integration without integration profile", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns1, "--name", "normal", "files/yaml.yaml").Execute()).To(Succeed()) - Eventually(IntegrationPod(ns1, "normal"), TestTimeoutShort).Should(Not(BeNil())) - Eventually(IntegrationPodHas(ns1, "normal", func(pod *corev1.Pod) bool { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns1, "--name", "normal", "files/yaml.yaml").Execute()).To(Succeed()) + g.Eventually(IntegrationPod(t, ctx, ns1, "normal"), TestTimeoutShort).Should(Not(BeNil())) + g.Eventually(IntegrationPodHas(t, ctx, ns1, "normal", func(pod *corev1.Pod) bool { if len(pod.Spec.Containers) != 1 { return false } @@ -116,16 +119,18 @@ func TestIntegrationProfile(t *testing.T) { }) // Clean up - Expect(Kamel("delete", "--all", "-n", ns1).Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns1).Execute()).To(Succeed()) }) }) } func TestIntegrationProfileInfluencesKit(t *testing.T) { - WithNewTestNamespace(t, func(ns string) { + t.Parallel() + + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { operatorID := "camel-k-ipr-kit" - Expect(KamelInstallWithID(operatorID, ns, "--global", "--force").Execute()).To(Succeed()) - Eventually(PlatformPhase(ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns, "--global", "--force")).To(Succeed()) + g.Eventually(PlatformPhase(t, ctx, ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) integrationProfile := v1.NewIntegrationProfile(ns, "ipr-global") integrationProfile.SetOperatorID(operatorID) @@ -133,42 +138,44 @@ func TestIntegrationProfileInfluencesKit(t *testing.T) { Properties: []string{"b1=foo"}, } - Expect(CreateIntegrationProfile(&integrationProfile)).To(Succeed()) - Eventually(SelectedIntegrationProfilePhase(ns, "ipr-global"), TestTimeoutMedium).Should(Equal(v1.IntegrationProfilePhaseReady)) + g.Expect(CreateIntegrationProfile(t, ctx, &integrationProfile)).To(Succeed()) + g.Eventually(SelectedIntegrationProfilePhase(t, ctx, ns, "ipr-global"), TestTimeoutMedium).Should(Equal(v1.IntegrationProfilePhaseReady)) - Expect(KamelRunWithID(operatorID, ns, "--name", "normal", "files/yaml.yaml").Execute()).To(Succeed()) - Eventually(IntegrationPod(ns, "normal"), TestTimeoutMedium).Should(Not(BeNil())) - Eventually(IntegrationPodPhase(ns, "normal"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "normal", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "normal"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "--name", "normal", "files/yaml.yaml").Execute()).To(Succeed()) + g.Eventually(IntegrationPod(t, ctx, ns, "normal"), TestTimeoutMedium).Should(Not(BeNil())) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "normal"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "normal", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "normal"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) // Verify that a new kit has been built based on the default base image - integrationKitName := IntegrationKit(ns, "normal")() - Eventually(Kit(ns, integrationKitName)().Status.BaseImage).Should(Equal(defaults.BaseImage())) - Eventually(Kit(ns, integrationKitName)().Status.RootImage).Should(Equal(defaults.BaseImage())) + integrationKitName := IntegrationKit(t, ctx, ns, "normal")() + g.Eventually(Kit(t, ctx, ns, integrationKitName)().Status.BaseImage).Should(Equal(defaults.BaseImage())) + g.Eventually(Kit(t, ctx, ns, integrationKitName)().Status.RootImage).Should(Equal(defaults.BaseImage())) - Expect(KamelRunWithID(operatorID, ns, "--name", "simple", "--integration-profile", "ipr-global", "files/yaml.yaml").Execute()).To(Succeed()) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "--name", "simple", "--integration-profile", "ipr-global", "files/yaml.yaml").Execute()).To(Succeed()) - Eventually(IntegrationPod(ns, "simple"), TestTimeoutMedium).Should(Not(BeNil())) - Eventually(IntegrationPodPhase(ns, "simple"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "simple", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "simple"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + g.Eventually(IntegrationPod(t, ctx, ns, "simple"), TestTimeoutMedium).Should(Not(BeNil())) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "simple"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "simple", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "simple"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) // Verify that a new kit has been built based on the previous kit - integrationKitNameWithProfile := IntegrationKit(ns, "simple")() - Eventually(integrationKitNameWithProfile).ShouldNot(Equal(integrationKitName)) - Eventually(Kit(ns, integrationKitNameWithProfile)().Status.BaseImage).Should(ContainSubstring(integrationKitName)) - Eventually(Kit(ns, integrationKitNameWithProfile)().Status.RootImage).Should(Equal(defaults.BaseImage())) + integrationKitNameWithProfile := IntegrationKit(t, ctx, ns, "simple")() + g.Eventually(integrationKitNameWithProfile).ShouldNot(Equal(integrationKitName)) + g.Eventually(Kit(t, ctx, ns, integrationKitNameWithProfile)().Status.BaseImage).Should(ContainSubstring(integrationKitName)) + g.Eventually(Kit(t, ctx, ns, integrationKitNameWithProfile)().Status.RootImage).Should(Equal(defaults.BaseImage())) // Clean up - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) } func TestPropagateIntegrationProfileChanges(t *testing.T) { - WithNewTestNamespace(t, func(ns string) { + t.Parallel() + + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { operatorID := "camel-k-ipr-changes" - Expect(KamelInstallWithID(operatorID, ns, "--global", "--force").Execute()).To(Succeed()) - Eventually(PlatformPhase(ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns, "--global", "--force")).To(Succeed()) + g.Eventually(PlatformPhase(t, ctx, ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) integrationProfile := v1.NewIntegrationProfile(ns, "debug-profile") integrationProfile.SetOperatorID(operatorID) @@ -179,13 +186,13 @@ func TestPropagateIntegrationProfileChanges(t *testing.T) { Level: "DEBUG", } - Expect(CreateIntegrationProfile(&integrationProfile)).To(Succeed()) - Eventually(SelectedIntegrationProfilePhase(ns, "debug-profile"), TestTimeoutMedium).Should(Equal(v1.IntegrationProfilePhaseReady)) + g.Expect(CreateIntegrationProfile(t, ctx, &integrationProfile)).To(Succeed()) + g.Eventually(SelectedIntegrationProfilePhase(t, ctx, ns, "debug-profile"), TestTimeoutMedium).Should(Equal(v1.IntegrationProfilePhaseReady)) - Expect(KamelRunWithID(operatorID, ns, "--name", "simple", "--integration-profile", "debug-profile", "files/yaml.yaml").Execute()).To(Succeed()) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "--name", "simple", "--integration-profile", "debug-profile", "files/yaml.yaml").Execute()).To(Succeed()) - Eventually(IntegrationPod(ns, "simple"), TestTimeoutMedium).Should(Not(BeNil())) - Eventually(IntegrationPodHas(ns, "simple", func(pod *corev1.Pod) bool { + g.Eventually(IntegrationPod(t, ctx, ns, "simple"), TestTimeoutMedium).Should(Not(BeNil())) + g.Eventually(IntegrationPodHas(t, ctx, ns, "simple", func(pod *corev1.Pod) bool { if len(pod.Spec.Containers) != 1 { return false } @@ -193,13 +200,13 @@ func TestPropagateIntegrationProfileChanges(t *testing.T) { return containerName == "ck-ipr" }), TestTimeoutShort).Should(BeTrue()) - Expect(UpdateIntegrationProfile(ns, func(ipr *v1.IntegrationProfile) { + g.Expect(UpdateIntegrationProfile(t, ctx, ns, func(ipr *v1.IntegrationProfile) { ipr.Spec.Traits.Container = &traitv1.ContainerTrait{ Name: "ck-ipr-new", } })).To(Succeed()) - Eventually(IntegrationPodHas(ns, "simple", func(pod *corev1.Pod) bool { + g.Eventually(IntegrationPodHas(t, ctx, ns, "simple", func(pod *corev1.Pod) bool { if len(pod.Spec.Containers) != 1 { return false } @@ -208,6 +215,6 @@ func TestPropagateIntegrationProfileChanges(t *testing.T) { }), TestTimeoutShort).Should(BeTrue()) // Clean up - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) } diff --git a/e2e/advanced/kamelet_repo_test.go b/e2e/advanced/kamelet_repo_test.go index 04ee0be25e..d85a2c2bb4 100644 --- a/e2e/advanced/kamelet_repo_test.go +++ b/e2e/advanced/kamelet_repo_test.go @@ -23,6 +23,7 @@ limitations under the License. package advanced import ( + "context" "fmt" "testing" @@ -34,38 +35,33 @@ import ( ) func TestKameletFromCustomRepository(t *testing.T) { - RegisterTestingT(t) + t.Parallel() - WithNewTestNamespace(t, func(ns string) { + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { operatorID := fmt.Sprintf("camel-k-%s", ns) - Expect(CopyCamelCatalog(ns, operatorID)).To(Succeed()) - Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed()) - Eventually(PlatformPhase(ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + g.Eventually(PlatformPhase(t, ctx, ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) kameletName := "timer-custom-source" - removeKamelet(kameletName, ns) + removeKamelet(t, ctx, kameletName, ns) - Eventually(Kamelet(kameletName, ns)).Should(BeNil()) + g.Eventually(Kamelet(t, ctx, kameletName, ns)).Should(BeNil()) // Add the custom repository - Expect(Kamel("kamelet", "add-repo", - "github:squakez/ck-kamelet-test-repo/kamelets", - "-n", ns, - "-x", operatorID).Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "kamelet", "add-repo", "github:squakez/ck-kamelet-test-repo/kamelets", "-n", ns, "-x", operatorID).Execute()).To(Succeed()) - Expect(KamelRunWithID(operatorID, ns, "files/TimerCustomKameletIntegration.java").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "timer-custom-kamelet-integration"), TestTimeoutLong). + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/TimerCustomKameletIntegration.java").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "timer-custom-kamelet-integration"), TestTimeoutLong). Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns, "timer-custom-kamelet-integration")).Should(ContainSubstring("hello world")) + g.Eventually(IntegrationLogs(t, ctx, ns, "timer-custom-kamelet-integration")).Should(ContainSubstring("hello world")) // Remove the custom repository - Expect(Kamel("kamelet", "remove-repo", - "github:squakez/ck-kamelet-test-repo/kamelets", - "-n", ns, - "-x", operatorID).Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "kamelet", "remove-repo", "github:squakez/ck-kamelet-test-repo/kamelets", "-n", ns, "-x", operatorID).Execute()).To(Succeed()) }) } -func removeKamelet(name string, ns string) { - kamelet := Kamelet(name, ns)() - TestClient().Delete(TestContext, kamelet) +func removeKamelet(t *testing.T, ctx context.Context, name string, ns string) { + kamelet := Kamelet(t, ctx, name, ns)() + TestClient(t).Delete(ctx, kamelet) } diff --git a/e2e/advanced/local_platform_test.go b/e2e/advanced/local_platform_test.go index e896dcaaad..ec03d1317a 100644 --- a/e2e/advanced/local_platform_test.go +++ b/e2e/advanced/local_platform_test.go @@ -23,6 +23,7 @@ limitations under the License. package advanced import ( + "context" "testing" . "github.com/onsi/gomega" @@ -34,66 +35,64 @@ import ( ) func TestLocalPlatform(t *testing.T) { - WithNewTestNamespace(t, func(ns string) { + t.Parallel() + + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { operatorID := "camel-k-platform-local" - Expect(CopyCamelCatalog(ns, operatorID)).To(Succeed()) - Expect(KamelInstallWithID(operatorID, ns, "--global", "--force").Execute()).To(Succeed()) - Eventually(PlatformPhase(ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) - - pl := Platform(ns)() - pl.Spec.Build.Maven.Properties = make(map[string]string) - pl.Spec.Build.Maven.Properties["build-global-prop1"] = "build-global-value1" - // set maximum number of running builds - pl.Spec.Build.MaxRunningBuilds = 1 - if err := TestClient().Update(TestContext, pl); err != nil { - t.Error(err) - t.FailNow() - } - - Eventually(PlatformHas(ns, func(pl *v1.IntegrationPlatform) bool { + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns, "--global", "--force")).To(Succeed()) + g.Eventually(PlatformPhase(t, ctx, ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + + g.Expect(UpdatePlatform(t, ctx, ns, operatorID, func(pl *v1.IntegrationPlatform) { + pl.Spec.Build.Maven.Properties = make(map[string]string) + pl.Spec.Build.Maven.Properties["build-global-prop1"] = "build-global-value1" + // set maximum number of running builds + pl.Spec.Build.MaxRunningBuilds = 1 + })).To(Succeed()) + + g.Eventually(PlatformHas(t, ctx, ns, func(pl *v1.IntegrationPlatform) bool { return pl.Status.Build.MaxRunningBuilds == 1 }), TestTimeoutMedium).Should(BeTrue()) - WithNewTestNamespace(t, func(ns1 string) { + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns1 string) { // Install platform (use the installer to get staging if present) - Expect(KamelInstallWithID("local-platform", ns1, "--skip-operator-setup").Execute()).To(Succeed()) - - localPlatform := Platform(ns1)() - localPlatform.Spec.Build.Maven.Properties = make(map[string]string) - localPlatform.Spec.Build.Maven.Properties["build-local-prop1"] = "build-local-value1" - localPlatform.SetOperatorID(operatorID) - - localPlatform.Spec.Traits.Container = &traitv1.ContainerTrait{ - LimitCPU: "0.1", - } - - if err := TestClient().Update(TestContext, localPlatform); err != nil { - t.Error(err) - t.FailNow() - } - Eventually(PlatformPhase(ns1), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) - Eventually(PlatformHas(ns1, func(pl *v1.IntegrationPlatform) bool { + g.Expect(KamelInstallWithID(t, ctx, "local-platform", ns1, "--skip-operator-setup")).To(Succeed()) + + g.Expect(UpdatePlatform(t, ctx, ns1, "local-platform", func(pl *v1.IntegrationPlatform) { + pl.Spec.Build.Maven.Properties = make(map[string]string) + pl.Spec.Build.Maven.Properties["build-local-prop1"] = "build-local-value1" + pl.SetOperatorID(operatorID) + + pl.Spec.Traits.Container = &traitv1.ContainerTrait{ + LimitCPU: "0.1", + } + })).To(Succeed()) + + g.Eventually(PlatformPhase(t, ctx, ns1), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + g.Eventually(PlatformHas(t, ctx, ns1, func(pl *v1.IntegrationPlatform) bool { return pl.Status.Cluster != "" }), TestTimeoutShort).Should(BeTrue()) - Eventually(PlatformHas(ns1, func(pl *v1.IntegrationPlatform) bool { + g.Eventually(PlatformHas(t, ctx, ns1, func(pl *v1.IntegrationPlatform) bool { return pl.Status.Build.MaxRunningBuilds == 1 }), TestTimeoutShort).Should(BeTrue()) - local := Platform(ns1)() - Expect(local.Status.Build.PublishStrategy).To(Equal(pl.Status.Build.PublishStrategy)) - Expect(local.Status.Build.BuildConfiguration.Strategy).To(Equal(pl.Status.Build.BuildConfiguration.Strategy)) - Expect(local.Status.Build.BuildConfiguration.OrderStrategy).To(Equal(pl.Status.Build.BuildConfiguration.OrderStrategy)) - Expect(local.Status.Build.Maven.LocalRepository).To(Equal(pl.Status.Build.Maven.LocalRepository)) - Expect(local.Status.Build.Maven.CLIOptions).To(ContainElements(pl.Status.Build.Maven.CLIOptions)) - Expect(local.Status.Build.Maven.Extension).To(BeEmpty()) - Expect(local.Status.Build.Maven.Properties).To(HaveLen(2)) - Expect(local.Status.Build.Maven.Properties["build-global-prop1"]).To(Equal("build-global-value1")) - Expect(local.Status.Build.Maven.Properties["build-local-prop1"]).To(Equal("build-local-value1")) - - Expect(KamelRunWithID(operatorID, ns1, "--name", "local-integration", "files/yaml.yaml").Execute()).To(Succeed()) - Eventually(IntegrationPod(ns1, "local-integration"), TestTimeoutMedium).Should(Not(BeNil())) - Eventually(IntegrationPodHas(ns1, "local-integration", func(pod *corev1.Pod) bool { + pl := PlatformByName(t, ctx, ns, operatorID)() + local := Platform(t, ctx, ns1)() + g.Expect(local.Status.Build.PublishStrategy).To(Equal(pl.Status.Build.PublishStrategy)) + g.Expect(local.Status.Build.BuildConfiguration.Strategy).To(Equal(pl.Status.Build.BuildConfiguration.Strategy)) + g.Expect(local.Status.Build.BuildConfiguration.OrderStrategy).To(Equal(pl.Status.Build.BuildConfiguration.OrderStrategy)) + g.Expect(local.Status.Build.Maven.LocalRepository).To(Equal(pl.Status.Build.Maven.LocalRepository)) + g.Expect(local.Status.Build.Maven.CLIOptions).To(ContainElements(pl.Status.Build.Maven.CLIOptions)) + g.Expect(local.Status.Build.Maven.Extension).To(BeEmpty()) + g.Expect(local.Status.Build.Maven.Properties).To(HaveLen(2)) + g.Expect(local.Status.Build.Maven.Properties["build-global-prop1"]).To(Equal("build-global-value1")) + g.Expect(local.Status.Build.Maven.Properties["build-local-prop1"]).To(Equal("build-local-value1")) + + g.Expect(KamelRunWithID(t, ctx, operatorID, ns1, "--name", "local-integration", "files/yaml.yaml").Execute()).To(Succeed()) + g.Eventually(IntegrationPod(t, ctx, ns1, "local-integration"), TestTimeoutMedium).Should(Not(BeNil())) + g.Eventually(IntegrationPodHas(t, ctx, ns1, "local-integration", func(pod *corev1.Pod) bool { if len(pod.Spec.Containers) != 1 { return false } @@ -102,7 +101,7 @@ func TestLocalPlatform(t *testing.T) { }), TestTimeoutShort).Should(BeTrue()) // Clean up - Expect(Kamel("delete", "--all", "-n", ns1).Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns1).Execute()).To(Succeed()) }) }) } diff --git a/e2e/advanced/main_test.go b/e2e/advanced/main_test.go new file mode 100644 index 0000000000..dd14d866d6 --- /dev/null +++ b/e2e/advanced/main_test.go @@ -0,0 +1,74 @@ +//go:build integration +// +build integration + +// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration" + +/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package advanced + +import ( + "fmt" + "os" + "testing" + + . "github.com/onsi/gomega" + + . "github.com/apache/camel-k/v2/e2e/support" + v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" + "github.com/apache/camel-k/v2/pkg/platform" + + corev1 "k8s.io/api/core/v1" +) + +func TestMain(m *testing.M) { + justCompile := GetEnvOrDefault("CAMEL_K_E2E_JUST_COMPILE", "false") + if justCompile == "true" { + os.Exit(m.Run()) + } + + fastSetup := GetEnvOrDefault("CAMEL_K_E2E_FAST_SETUP", "false") + if fastSetup == "true" { + operatorID := platform.DefaultPlatformName + ns := GetEnvOrDefault("CAMEL_K_GLOBAL_OPERATOR_NS", TestDefaultNamespace) + + g := NewGomega(func(message string, callerSkip ...int) { + fmt.Printf("Test fast setup failed! - %s\n", message) + }) + + var t *testing.T + g.Expect(TestClient(t)).ShouldNot(BeNil()) + ctx := TestContext() + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "java"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "java", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "java"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/yaml.yaml").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "yaml"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "yaml", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "yaml"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/timer-source.groovy").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "timer-source"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "timer-source", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "timer-source"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + } + + os.Exit(m.Run()) +} diff --git a/e2e/advanced/maven_http_proxy_test.go b/e2e/advanced/maven_http_proxy_test.go index ef092942d6..4dd7a8af2c 100644 --- a/e2e/advanced/maven_http_proxy_test.go +++ b/e2e/advanced/maven_http_proxy_test.go @@ -23,6 +23,7 @@ limitations under the License. package advanced import ( + "context" "crypto/rand" "crypto/rsa" "crypto/x509" @@ -58,7 +59,9 @@ import ( var httpdTlsMountPath = "/etc/tls/private" func TestMavenProxy(t *testing.T) { - WithNewTestNamespace(t, func(ns string) { + t.Parallel() + + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { hostname := fmt.Sprintf("%s.%s.svc", "proxy", ns) // Generate the TLS certificate @@ -78,7 +81,7 @@ func TestMavenProxy(t *testing.T) { // generate the certificate private key certPrivateKey, err := rsa.GenerateKey(rand.Reader, 2048) - Expect(err).To(BeNil()) + g.Expect(err).To(BeNil()) privateKeyBytes := x509.MarshalPKCS1PrivateKey(certPrivateKey) // encode for storing into a Secret @@ -89,7 +92,7 @@ func TestMavenProxy(t *testing.T) { }, ) certBytes, err := x509.CreateCertificate(rand.Reader, cert, cert, &certPrivateKey.PublicKey, certPrivateKey) - Expect(err).To(BeNil()) + g.Expect(err).To(BeNil()) // encode for storing into a Secret certPem := pem.EncodeToMemory(&pem.Block{ @@ -112,21 +115,21 @@ func TestMavenProxy(t *testing.T) { corev1.TLSPrivateKeyKey: privateKeyPem, }, } - Expect(TestClient().Create(TestContext, secret)).To(Succeed()) + g.Expect(TestClient(t).Create(ctx, secret)).To(Succeed()) // HTTPD ConfigMap config := newHTTPDConfigMap(ns, hostname) - Expect(TestClient().Create(TestContext, config)).To(Succeed()) + g.Expect(TestClient(t).Create(ctx, config)).To(Succeed()) // HTTPD Deployment deployment := newHTTPDDeployment(ns, config.Name, secret.Name) - Expect(TestClient().Create(TestContext, deployment)).To(Succeed()) + g.Expect(TestClient(t).Create(ctx, deployment)).To(Succeed()) service := newHTTPDService(deployment) - Expect(TestClient().Create(TestContext, service)).To(Succeed()) + g.Expect(TestClient(t).Create(ctx, service)).To(Succeed()) // Wait for the Deployment to become ready - Eventually(Deployment(ns, deployment.Name), TestTimeoutMedium).Should(PointTo(MatchFields(IgnoreExtras, + g.Eventually(Deployment(t, ctx, ns, deployment.Name), TestTimeoutMedium).Should(PointTo(MatchFields(IgnoreExtras, Fields{ "Status": MatchFields(IgnoreExtras, Fields{ @@ -135,8 +138,8 @@ func TestMavenProxy(t *testing.T) { }), )) - svc := Service("default", "kubernetes")() - Expect(svc).NotTo(BeNil()) + svc := Service(t, ctx, TestDefaultNamespace, "kubernetes")() + g.Expect(svc).NotTo(BeNil()) // It may be needed to populate the values from the cluster, machine and service network CIDRs noProxy := []string{ @@ -148,10 +151,11 @@ func TestMavenProxy(t *testing.T) { // Install Camel K with the HTTP proxy operatorID := "camel-k-maven-proxy" - Expect(CopyCamelCatalog(ns, operatorID)).To(Succeed()) - olm, olmErr := olm.IsAPIAvailable(TestContext, TestClient(), ns) - installed, inErr := kubernetes.IsAPIResourceInstalled(TestClient(), configv1.GroupVersion.String(), reflect.TypeOf(configv1.Proxy{}).Name()) - permission, pErr := kubernetes.CheckPermission(TestContext, TestClient(), configv1.GroupName, reflect.TypeOf(configv1.Proxy{}).Name(), "", "cluster", "edit") + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + olm, olmErr := olm.IsAPIAvailable(TestClient(t)) + installed, inErr := kubernetes.IsAPIResourceInstalled(TestClient(t), configv1.GroupVersion.String(), reflect.TypeOf(configv1.Proxy{}).Name()) + permission, pErr := kubernetes.CheckPermission(ctx, TestClient(t), configv1.GroupName, reflect.TypeOf(configv1.Proxy{}).Name(), "", "cluster", "edit") olmInstall := pErr == nil && olmErr == nil && inErr == nil && olm && installed && permission var defaultProxy configv1.Proxy if olmInstall { @@ -160,12 +164,12 @@ func TestMavenProxy(t *testing.T) { key := ctrl.ObjectKey{ Name: "cluster", } - Expect(TestClient().Get(TestContext, key, &defaultProxy)).To(Succeed()) + g.Expect(TestClient(t).Get(ctx, key, &defaultProxy)).To(Succeed()) newProxy := defaultProxy.DeepCopy() newProxy.Spec.HTTPProxy = fmt.Sprintf("http://%s", hostname) newProxy.Spec.NoProxy = strings.Join(noProxy, ",") - Expect(TestClient().Update(TestContext, newProxy)) + g.Expect(TestClient(t).Update(ctx, newProxy)) defer func() { // @@ -174,30 +178,24 @@ func TestMavenProxy(t *testing.T) { // does not work on some platforms, eg. OCP4 // patch := []byte(`[{"op": "replace","path": "/spec","value": {}},{"op": "replace","path": "/status","value": {}}]`) - TestClient().Patch(TestContext, &defaultProxy, ctrl.RawPatch(types.JSONPatchType, patch)) + TestClient(t).Patch(ctx, &defaultProxy, ctrl.RawPatch(types.JSONPatchType, patch)) }() // ENV values should be injected by the OLM - Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) } else { - Expect(KamelInstallWithID(operatorID, ns, - "--operator-env-vars", fmt.Sprintf("HTTP_PROXY=http://%s", hostname), - // TODO: enable TLS for the HTTPS proxy when Maven supports it - // "--operator-env-vars", fmt.Sprintf("HTTPS_PROXY=https://%s", hostname), - // "--maven-ca-secret", secret.Name+"/"+corev1.TLSCertKey, - "--operator-env-vars", "NO_PROXY="+strings.Join(noProxy, ","), - ).Execute()).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns, "--operator-env-vars", fmt.Sprintf("HTTP_PROXY=http://%s", hostname), "--operator-env-vars", "NO_PROXY="+strings.Join(noProxy, ","))).To(Succeed()) } - Eventually(PlatformPhase(ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + g.Eventually(PlatformPhase(t, ctx, ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) // Run the Integration name := RandomizedSuffixName("java") - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", "--name", name).Execute()).To(Succeed()) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", name).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) proxies := corev1.PodList{ TypeMeta: metav1.TypeMeta{ @@ -205,23 +203,23 @@ func TestMavenProxy(t *testing.T) { APIVersion: corev1.SchemeGroupVersion.String(), }, } - err = TestClient().List(TestContext, &proxies, + err = TestClient(t).List(ctx, &proxies, ctrl.InNamespace(ns), ctrl.MatchingLabels(deployment.Spec.Selector.MatchLabels), ) - Expect(err).To(Succeed()) - Expect(proxies.Items).To(HaveLen(1)) + g.Expect(err).To(Succeed()) + g.Expect(proxies.Items).To(HaveLen(1)) - logs := Logs(ns, proxies.Items[0].Name, corev1.PodLogOptions{})() - Expect(logs).NotTo(BeEmpty()) - Expect(logs).To(ContainSubstring("\"CONNECT repo.maven.apache.org:443 HTTP/1.1\" 200")) + logs := Logs(t, ctx, ns, proxies.Items[0].Name, corev1.PodLogOptions{})() + g.Expect(logs).NotTo(BeEmpty()) + g.Expect(logs).To(ContainSubstring("\"CONNECT repo.maven.apache.org:443 HTTP/1.1\" 200")) // Clean up - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) - Expect(TestClient().Delete(TestContext, deployment)).To(Succeed()) - Expect(TestClient().Delete(TestContext, service)).To(Succeed()) - Expect(TestClient().Delete(TestContext, secret)).To(Succeed()) - Expect(TestClient().Delete(TestContext, config)).To(Succeed()) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + g.Expect(TestClient(t).Delete(ctx, deployment)).To(Succeed()) + g.Expect(TestClient(t).Delete(ctx, service)).To(Succeed()) + g.Expect(TestClient(t).Delete(ctx, secret)).To(Succeed()) + g.Expect(TestClient(t).Delete(ctx, config)).To(Succeed()) }) } diff --git a/e2e/advanced/operator_id_filtering_test.go b/e2e/advanced/operator_id_filtering_test.go index 5305722cac..390d010c83 100644 --- a/e2e/advanced/operator_id_filtering_test.go +++ b/e2e/advanced/operator_id_filtering_test.go @@ -23,6 +23,7 @@ limitations under the License. package advanced import ( + "context" "fmt" "testing" "time" @@ -35,89 +36,91 @@ import ( ) func TestOperatorIDCamelCatalogReconciliation(t *testing.T) { - WithNewTestNamespace(t, func(ns string) { + t.Parallel() + + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { operatorID := fmt.Sprintf("camel-k-%s", ns) - Expect(KamelInstallWithID(operatorID, ns, "--global", "--force").Execute()).To(Succeed()) - Eventually(PlatformPhase(ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) - Eventually(DefaultCamelCatalogPhase(ns), TestTimeoutMedium).Should(Equal(v1.CamelCatalogPhaseReady)) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns, "--global", "--force")).To(Succeed()) + g.Eventually(PlatformPhase(t, ctx, ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + g.Eventually(DefaultCamelCatalogPhase(t, ctx, ns), TestTimeoutMedium).Should(Equal(v1.CamelCatalogPhaseReady)) }) } func TestOperatorIDFiltering(t *testing.T) { - RegisterTestingT(t) + t.Parallel() - WithNewTestNamespace(t, func(ns string) { - WithNewTestNamespace(t, func(nsop1 string) { + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, nsop1 string) { operator1 := "operator-1" - Expect(CopyCamelCatalog(nsop1, operator1)).To(Succeed()) - Expect(KamelInstallWithIDAndKameletCatalog(operator1, nsop1, "--global", "--force").Execute()).To(Succeed()) - Eventually(PlatformPhase(nsop1), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + g.Expect(CopyCamelCatalog(t, ctx, nsop1, operator1)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, nsop1, operator1)).To(Succeed()) + g.Expect(KamelInstallWithIDAndKameletCatalog(t, ctx, operator1, nsop1, "--global", "--force")).To(Succeed()) + g.Eventually(PlatformPhase(t, ctx, nsop1), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) - WithNewTestNamespace(t, func(nsop2 string) { + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, nsop2 string) { operator2 := "operator-2" - Expect(CopyCamelCatalog(nsop2, operator2)).To(Succeed()) - Expect(KamelInstallWithIDAndKameletCatalog(operator2, nsop2, "--global", "--force").Execute()).To(Succeed()) - Eventually(PlatformPhase(nsop2), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + g.Expect(CopyCamelCatalog(t, ctx, nsop2, operator2)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, nsop2, operator2)).To(Succeed()) + g.Expect(KamelInstallWithIDAndKameletCatalog(t, ctx, operator2, nsop2, "--global", "--force")).To(Succeed()) + g.Eventually(PlatformPhase(t, ctx, nsop2), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) t.Run("Operators ignore non-scoped integrations", func(t *testing.T) { - Expect(KamelRunWithID("operator-x", ns, "files/yaml.yaml", "--name", "untouched", "--force").Execute()).To(Succeed()) - Consistently(IntegrationPhase(ns, "untouched"), 10*time.Second).Should(BeEmpty()) + g.Expect(KamelRunWithID(t, ctx, "operator-x", ns, "files/yaml.yaml", "--name", "untouched", "--force").Execute()).To(Succeed()) + g.Consistently(IntegrationPhase(t, ctx, ns, "untouched"), 10*time.Second).Should(BeEmpty()) }) t.Run("Operators run scoped integrations", func(t *testing.T) { - Expect(KamelRunWithID("operator-x", ns, "files/yaml.yaml", "--name", "moving", "--force").Execute()).To(Succeed()) - Expect(AssignIntegrationToOperator(ns, "moving", operator1)).To(Succeed()) - Eventually(IntegrationPhase(ns, "moving"), TestTimeoutMedium).Should(Equal(v1.IntegrationPhaseRunning)) - Eventually(IntegrationPodPhase(ns, "moving"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns, "moving"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + g.Expect(KamelRunWithID(t, ctx, "operator-x", ns, "files/yaml.yaml", "--name", "moving", "--force").Execute()).To(Succeed()) + g.Expect(AssignIntegrationToOperator(t, ctx, ns, "moving", operator1)).To(Succeed()) + g.Eventually(IntegrationPhase(t, ctx, ns, "moving"), TestTimeoutMedium).Should(Equal(v1.IntegrationPhaseRunning)) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "moving"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, "moving"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) }) t.Run("Operators can handoff scoped integrations", func(t *testing.T) { - Expect(AssignIntegrationToOperator(ns, "moving", operator2)).To(Succeed()) - Eventually(IntegrationPhase(ns, "moving"), TestTimeoutMedium).Should(Equal(v1.IntegrationPhaseBuildingKit)) - Eventually(IntegrationPhase(ns, "moving"), TestTimeoutMedium).Should(Equal(v1.IntegrationPhaseRunning)) - Eventually(IntegrationPodPhase(ns, "moving"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns, "moving"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + g.Expect(AssignIntegrationToOperator(t, ctx, ns, "moving", operator2)).To(Succeed()) + g.Eventually(IntegrationPhase(t, ctx, ns, "moving"), TestTimeoutMedium).Should(Equal(v1.IntegrationPhaseBuildingKit)) + g.Eventually(IntegrationPhase(t, ctx, ns, "moving"), TestTimeoutMedium).Should(Equal(v1.IntegrationPhaseRunning)) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "moving"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, "moving"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) }) t.Run("Operators can be deactivated after completely handing off scoped integrations", func(t *testing.T) { - Expect(ScaleOperator(nsop1, 0)).To(Succeed()) - Expect(Kamel("rebuild", "-n", ns, "moving").Execute()).To(Succeed()) - Eventually(IntegrationPhase(ns, "moving"), TestTimeoutMedium).Should(Equal(v1.IntegrationPhaseRunning)) - Eventually(IntegrationPodPhase(ns, "moving"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns, "moving"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - Expect(ScaleOperator(nsop1, 1)).To(Succeed()) + g.Expect(ScaleOperator(t, ctx, nsop1, 0)).To(Succeed()) + g.Expect(Kamel(t, ctx, "rebuild", "-n", ns, "moving").Execute()).To(Succeed()) + g.Eventually(IntegrationPhase(t, ctx, ns, "moving"), TestTimeoutMedium).Should(Equal(v1.IntegrationPhaseRunning)) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "moving"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, "moving"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + g.Expect(ScaleOperator(t, ctx, nsop1, 1)).To(Succeed()) }) t.Run("Operators can run scoped integrations with fixed image", func(t *testing.T) { - image := IntegrationPodImage(ns, "moving")() - Expect(image).NotTo(BeEmpty()) + image := IntegrationPodImage(t, ctx, ns, "moving")() + g.Expect(image).NotTo(BeEmpty()) // Save resources by deleting "moving" integration - Expect(Kamel("delete", "moving", "-n", ns).Execute()).To(Succeed()) - - Expect(KamelRunWithID("operator-x", ns, "files/yaml.yaml", "--name", "pre-built", "--force", - "-t", fmt.Sprintf("container.image=%s", image), "-t", "jvm.enabled=true").Execute()).To(Succeed()) - Consistently(IntegrationPhase(ns, "pre-built"), 10*time.Second).Should(BeEmpty()) - Expect(AssignIntegrationToOperator(ns, "pre-built", operator2)).To(Succeed()) - Eventually(IntegrationPhase(ns, "pre-built"), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseRunning)) - Eventually(IntegrationPodPhase(ns, "pre-built"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns, "pre-built"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - Expect(Kamel("delete", "pre-built", "-n", ns).Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "delete", "moving", "-n", ns).Execute()).To(Succeed()) + + g.Expect(KamelRunWithID(t, ctx, "operator-x", ns, "files/yaml.yaml", "--name", "pre-built", "--force", "-t", fmt.Sprintf("container.image=%s", image), "-t", "jvm.enabled=true").Execute()).To(Succeed()) + g.Consistently(IntegrationPhase(t, ctx, ns, "pre-built"), 10*time.Second).Should(BeEmpty()) + g.Expect(AssignIntegrationToOperator(t, ctx, ns, "pre-built", operator2)).To(Succeed()) + g.Eventually(IntegrationPhase(t, ctx, ns, "pre-built"), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseRunning)) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "pre-built"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, "pre-built"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + g.Expect(Kamel(t, ctx, "delete", "pre-built", "-n", ns).Execute()).To(Succeed()) }) t.Run("Operators can run scoped Pipes", func(t *testing.T) { - Expect(KamelBindWithID("operator-x", ns, "timer-source?message=Hello", "log-sink", - "--name", "klb", "--force").Execute()).To(Succeed()) - Consistently(Integration(ns, "klb"), 10*time.Second).Should(BeNil()) - - Expect(AssignPipeToOperator(ns, "klb", operator1)).To(Succeed()) - Eventually(Integration(ns, "klb"), TestTimeoutShort).ShouldNot(BeNil()) - Eventually(IntegrationPhase(ns, "klb"), TestTimeoutMedium).Should(Equal(v1.IntegrationPhaseRunning)) - Eventually(IntegrationPodPhase(ns, "klb"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Expect(KamelBindWithID(t, ctx, "operator-x", ns, "timer-source?message=Hello", "log-sink", "--name", "klb", "--force").Execute()).To(Succeed()) + g.Consistently(Integration(t, ctx, ns, "klb"), 10*time.Second).Should(BeNil()) + + g.Expect(AssignPipeToOperator(t, ctx, ns, "klb", operator1)).To(Succeed()) + g.Eventually(Integration(t, ctx, ns, "klb"), TestTimeoutShort).ShouldNot(BeNil()) + g.Eventually(IntegrationPhase(t, ctx, ns, "klb"), TestTimeoutMedium).Should(Equal(v1.IntegrationPhaseRunning)) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "klb"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) }) }) }) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) } diff --git a/e2e/advanced/operator_metrics_test.go b/e2e/advanced/operator_metrics_test.go index 1828125771..376aeb0cc1 100644 --- a/e2e/advanced/operator_metrics_test.go +++ b/e2e/advanced/operator_metrics_test.go @@ -24,6 +24,7 @@ package advanced import ( "bytes" + "context" "fmt" "math" "os" @@ -52,56 +53,52 @@ import ( * Adding CAMEL_K_TEST_SKIP_PROBLEMATIC env var for the moment. */ func TestMetrics(t *testing.T) { + t.Parallel() + if os.Getenv("CAMEL_K_TEST_SKIP_PROBLEMATIC") == "true" { t.Skip("WARNING: Test marked as problematic ... skipping") } - RegisterTestingT(t) - - WithNewTestNamespace(t, func(ns string) { + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { name := RandomizedSuffixName("java") operatorID := "camel-k-metrics" - Expect(CopyCamelCatalog(ns, operatorID)).To(Succeed()) - Expect(KamelInstallWithID(operatorID, ns, "--log-level", "debug").Execute()).To(Succeed()) - Eventually(SelectedPlatformPhase(ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) - - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", - "--name", name, - "-t", "prometheus.enabled=true", - "-t", "prometheus.pod-monitor=false", - ).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort). + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns, "--log-level", "debug")).To(Succeed()) + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", name, "-t", "prometheus.enabled=true", "-t", "prometheus.pod-monitor=false").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort). Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - pod := OperatorPod(ns)() - Expect(pod).NotTo(BeNil()) + pod := OperatorPod(t, ctx, ns)() + g.Expect(pod).NotTo(BeNil()) // pod.Namespace could be different from ns if using global operator fmt.Printf("Fetching logs for operator pod %s in namespace %s", pod.Name, pod.Namespace) logOptions := &corev1.PodLogOptions{ Container: "camel-k-operator", } - logs, err := StructuredLogs(pod.Namespace, pod.Name, logOptions, false) - Expect(err).To(BeNil()) - Expect(logs).NotTo(BeEmpty()) + logs, err := StructuredLogs(t, ctx, pod.Namespace, pod.Name, logOptions, false) + g.Expect(err).To(BeNil()) + g.Expect(logs).NotTo(BeEmpty()) - response, err := TestClient().CoreV1().RESTClient().Get(). - AbsPath(fmt.Sprintf("/api/v1/namespaces/%s/pods/%s/proxy/metrics", pod.Namespace, pod.Name)).DoRaw(TestContext) - Expect(err).To(BeNil()) + response, err := TestClient(t).CoreV1().RESTClient().Get(). + AbsPath(fmt.Sprintf("/api/v1/namespaces/%s/pods/%s/proxy/metrics", pod.Namespace, pod.Name)).DoRaw(ctx) + g.Expect(err).To(BeNil()) metrics, err := parsePrometheusData(response) - Expect(err).To(BeNil()) + g.Expect(err).To(BeNil()) - it := Integration(ns, name)() - Expect(it).NotTo(BeNil()) - build := Build(ns, it.Status.IntegrationKit.Name)() - Expect(build).NotTo(BeNil()) + it := Integration(t, ctx, ns, name)() + g.Expect(it).NotTo(BeNil()) + build := Build(t, ctx, ns, it.Status.IntegrationKit.Name)() + g.Expect(build).NotTo(BeNil()) t.Run("Build duration metric", func(t *testing.T) { // Get the duration from the Build status duration, err := time.ParseDuration(build.Status.Duration) - Expect(err).To(BeNil()) + g.Expect(err).To(BeNil()) // Check it's consistent with the duration observed from logs var ts1, ts2 time.Time @@ -125,18 +122,18 @@ func TestMetrics(t *testing.T) { "RequestName": Equal(build.Name), }), func(l *LogEntry) { ts2 = l.Timestamp }). Walk() - Expect(err).To(BeNil()) - Expect(ts1).NotTo(BeZero()) - Expect(ts2).NotTo(BeZero()) - Expect(ts2).To(BeTemporally(">", ts1)) + g.Expect(err).To(BeNil()) + g.Expect(ts1).NotTo(BeZero()) + g.Expect(ts2).NotTo(BeZero()) + g.Expect(ts2).To(BeTemporally(">", ts1)) durationFromLogs := ts2.Sub(ts1) // With a build strategy there could be a little variance (less than 10 seconds should be enough) - Expect(math.Abs((durationFromLogs - duration).Seconds())).To(BeNumerically("<", 10)) + g.Expect(math.Abs((durationFromLogs - duration).Seconds())).To(BeNumerically("<", 10)) // Check the duration is observed in the corresponding metric - Expect(metrics).To(HaveKey("camel_k_build_duration_seconds")) - Expect(metrics["camel_k_build_duration_seconds"]).To(EqualP( + g.Expect(metrics).To(HaveKey("camel_k_build_duration_seconds")) + g.Expect(metrics["camel_k_build_duration_seconds"]).To(EqualP( prometheus.MetricFamily{ Name: stringP("camel_k_build_duration_seconds"), Help: stringP("Camel K build duration"), @@ -160,7 +157,7 @@ func TestMetrics(t *testing.T) { t.Run("Build recovery attempts metric", func(t *testing.T) { // Check there are no failures reported in the Build status - Expect(build.Status.Failure).To(BeNil()) + g.Expect(build.Status.Failure).To(BeNil()) // Check no recovery attempts are reported in the logs recoveryAttempts, err := NewLogCounter(&logs).Count(MatchFields(IgnoreExtras, Fields{ @@ -169,12 +166,12 @@ func TestMetrics(t *testing.T) { "Kind": Equal("Build"), "RequestName": Equal(build.Name), })) - Expect(err).To(BeNil()) - Expect(recoveryAttempts).To(BeNumerically("==", 0)) + g.Expect(err).To(BeNil()) + g.Expect(recoveryAttempts).To(BeNumerically("==", 0)) // Check no recovery attempts are observed in the corresponding metric - Expect(metrics).To(HaveKey("camel_k_build_recovery_attempts")) - Expect(metrics["camel_k_build_recovery_attempts"]).To(EqualP( + g.Expect(metrics).To(HaveKey("camel_k_build_recovery_attempts")) + g.Expect(metrics["camel_k_build_recovery_attempts"]).To(EqualP( prometheus.MetricFamily{ Name: stringP("camel_k_build_recovery_attempts"), Help: stringP("Camel K build recovery attempts"), @@ -197,8 +194,8 @@ func TestMetrics(t *testing.T) { }) t.Run("reconciliation duration metric", func(t *testing.T) { - Expect(metrics).To(HaveKey("camel_k_reconciliation_duration_seconds")) - Expect(metrics["camel_k_reconciliation_duration_seconds"]).To(PointTo(MatchFields(IgnoreExtras, + g.Expect(metrics).To(HaveKey("camel_k_reconciliation_duration_seconds")) + g.Expect(metrics["camel_k_reconciliation_duration_seconds"]).To(PointTo(MatchFields(IgnoreExtras, Fields{ "Name": EqualP("camel_k_reconciliation_duration_seconds"), "Help": EqualP("Camel K reconciliation loop duration"), @@ -215,7 +212,7 @@ func TestMetrics(t *testing.T) { "RequestNamespace": Equal(ns), "RequestName": Equal(operatorID), })) - Expect(err).To(BeNil()) + g.Expect(err).To(BeNil()) // Check it matches the observation in the corresponding metric platformReconciled := getMetric(metrics["camel_k_reconciliation_duration_seconds"], @@ -229,9 +226,9 @@ func TestMetrics(t *testing.T) { label("tag", ""), ), })) - Expect(platformReconciled).NotTo(BeNil()) + g.Expect(platformReconciled).NotTo(BeNil()) platformReconciledCount := *platformReconciled.Histogram.SampleCount - Expect(platformReconciledCount).To(BeNumerically(">", 0)) + g.Expect(platformReconciledCount).To(BeNumerically(">", 0)) platformRequeued := getMetric(metrics["camel_k_reconciliation_duration_seconds"], MatchFieldsP(IgnoreExtras, Fields{ @@ -265,7 +262,7 @@ func TestMetrics(t *testing.T) { platformErroredCount = *platformErrored.Histogram.SampleCount } - Expect(platformReconciliations).To(BeNumerically("==", platformReconciledCount+platformRequeuedCount+platformErroredCount)) + g.Expect(platformReconciliations).To(BeNumerically("==", platformReconciledCount+platformRequeuedCount+platformErroredCount)) // Count the number of Integration reconciliations integrationReconciliations, err := counter.Count(MatchFields(IgnoreExtras, Fields{ @@ -274,8 +271,8 @@ func TestMetrics(t *testing.T) { "RequestNamespace": Equal(it.Namespace), "RequestName": Equal(it.Name), })) - Expect(err).To(BeNil()) - Expect(integrationReconciliations).To(BeNumerically(">", 0)) + g.Expect(err).To(BeNil()) + g.Expect(integrationReconciliations).To(BeNumerically(">", 0)) // Check it matches the observation in the corresponding metric integrationReconciled := getMetric(metrics["camel_k_reconciliation_duration_seconds"], @@ -289,9 +286,9 @@ func TestMetrics(t *testing.T) { label("tag", ""), ), })) - Expect(integrationReconciled).NotTo(BeNil()) + g.Expect(integrationReconciled).NotTo(BeNil()) integrationReconciledCount := *integrationReconciled.Histogram.SampleCount - Expect(integrationReconciledCount).To(BeNumerically(">", 0)) + g.Expect(integrationReconciledCount).To(BeNumerically(">", 0)) integrationRequeued := getMetric(metrics["camel_k_reconciliation_duration_seconds"], MatchFieldsP(IgnoreExtras, Fields{ @@ -325,7 +322,7 @@ func TestMetrics(t *testing.T) { integrationErroredCount = *integrationErrored.Histogram.SampleCount } - Expect(integrationReconciliations).To(BeNumerically("==", integrationReconciledCount+integrationRequeuedCount+integrationErroredCount)) + g.Expect(integrationReconciliations).To(BeNumerically("==", integrationReconciledCount+integrationRequeuedCount+integrationErroredCount)) // Count the number of IntegrationKit reconciliations integrationKitReconciliations, err := counter.Count(MatchFields(IgnoreExtras, Fields{ @@ -334,8 +331,8 @@ func TestMetrics(t *testing.T) { "RequestNamespace": Equal(it.Status.IntegrationKit.Namespace), "RequestName": Equal(it.Status.IntegrationKit.Name), })) - Expect(err).To(BeNil()) - Expect(integrationKitReconciliations).To(BeNumerically(">", 0)) + g.Expect(err).To(BeNil()) + g.Expect(integrationKitReconciliations).To(BeNumerically(">", 0)) // Check it matches the observation in the corresponding metric integrationKitReconciled := getMetric(metrics["camel_k_reconciliation_duration_seconds"], @@ -349,9 +346,9 @@ func TestMetrics(t *testing.T) { label("tag", ""), ), })) - Expect(integrationKitReconciled).NotTo(BeNil()) + g.Expect(integrationKitReconciled).NotTo(BeNil()) integrationKitReconciledCount := *integrationKitReconciled.Histogram.SampleCount - Expect(integrationKitReconciledCount).To(BeNumerically(">", 0)) + g.Expect(integrationKitReconciledCount).To(BeNumerically(">", 0)) // Kit can be requeued, above all when a catalog needs to be built integrationKitRequeued := getMetric(metrics["camel_k_reconciliation_duration_seconds"], @@ -371,7 +368,7 @@ func TestMetrics(t *testing.T) { integrationKitRequeuedCount = *integrationKitRequeued.Histogram.SampleCount } - Expect(integrationKitReconciliations).To(BeNumerically("==", integrationKitReconciledCount+integrationKitRequeuedCount)) + g.Expect(integrationKitReconciliations).To(BeNumerically("==", integrationKitReconciledCount+integrationKitRequeuedCount)) // Count the number of Build reconciliations buildReconciliations, err := counter.Count(MatchFields(IgnoreExtras, Fields{ @@ -380,7 +377,7 @@ func TestMetrics(t *testing.T) { "RequestNamespace": Equal(build.Namespace), "RequestName": Equal(build.Name), })) - Expect(err).To(BeNil()) + g.Expect(err).To(BeNil()) // Check it matches the observation in the corresponding metric buildReconciled := getMetric(metrics["camel_k_reconciliation_duration_seconds"], @@ -394,9 +391,9 @@ func TestMetrics(t *testing.T) { label("tag", ""), ), })) - Expect(buildReconciled).NotTo(BeNil()) + g.Expect(buildReconciled).NotTo(BeNil()) buildReconciledCount := *buildReconciled.Histogram.SampleCount - Expect(buildReconciledCount).To(BeNumerically(">", 0)) + g.Expect(buildReconciledCount).To(BeNumerically(">", 0)) buildRequeued := getMetric(metrics["camel_k_reconciliation_duration_seconds"], MatchFieldsP(IgnoreExtras, Fields{ @@ -414,7 +411,7 @@ func TestMetrics(t *testing.T) { buildRequeuedCount = *buildRequeued.Histogram.SampleCount } - Expect(buildReconciliations).To(BeNumerically("==", buildReconciledCount+buildRequeuedCount)) + g.Expect(buildReconciliations).To(BeNumerically("==", buildReconciledCount+buildRequeuedCount)) }) t.Run("Build queue duration metric", func(t *testing.T) { @@ -432,27 +429,27 @@ func TestMetrics(t *testing.T) { "RequestName": Equal(build.Name), }), func(l *LogEntry) { ts2 = l.Timestamp }). Walk() - Expect(err).To(BeNil()) - Expect(ts1).NotTo(BeZero()) - Expect(ts2).NotTo(BeZero()) + g.Expect(err).To(BeNil()) + g.Expect(ts1).NotTo(BeZero()) + g.Expect(ts2).NotTo(BeZero()) durationFromLogs := ts2.Sub(ts1) // Retrieve the queuing duration from the metric - Expect(metrics).To(HaveKey("camel_k_build_queue_duration_seconds")) + g.Expect(metrics).To(HaveKey("camel_k_build_queue_duration_seconds")) metric := metrics["camel_k_build_queue_duration_seconds"].Metric - Expect(metric).To(HaveLen(1)) + g.Expect(metric).To(HaveLen(1)) histogram := metric[0].Histogram - Expect(histogram).NotTo(BeNil()) - Expect(histogram.SampleSum).NotTo(BeNil()) + g.Expect(histogram).NotTo(BeNil()) + g.Expect(histogram.SampleSum).NotTo(BeNil()) duration := *histogram.SampleSum // Check both durations match - Expect(math.Abs(durationFromLogs.Seconds() - duration)).To(BeNumerically("<", 1)) + g.Expect(math.Abs(durationFromLogs.Seconds() - duration)).To(BeNumerically("<", 1)) // Check the queuing duration is correctly observed in the corresponding metric - Expect(metrics["camel_k_build_queue_duration_seconds"]).To(EqualP( + g.Expect(metrics["camel_k_build_queue_duration_seconds"]).To(EqualP( prometheus.MetricFamily{ Name: stringP("camel_k_build_queue_duration_seconds"), Help: stringP("Camel K build queue duration"), @@ -478,10 +475,10 @@ func TestMetrics(t *testing.T) { // The start time is taken from the Integration status initialization timestamp ts1 = it.Status.InitializationTimestamp.Time - Expect(ts1).NotTo(BeZero()) + g.Expect(ts1).NotTo(BeZero()) // The end time is reported into the ready condition first truthy time ts2 = it.Status.GetCondition(v1.IntegrationConditionReady).FirstTruthyTime.Time - Expect(ts2).NotTo(BeZero()) + g.Expect(ts2).NotTo(BeZero()) duration := ts2.Sub(ts1) @@ -500,29 +497,29 @@ func TestMetrics(t *testing.T) { "RequestName": Equal(it.Name), }), func(l *LogEntry) { ts2 = l.Timestamp }). Walk() - Expect(err).To(BeNil()) - Expect(ts1).NotTo(BeZero()) - Expect(ts2).NotTo(BeZero()) - Expect(ts2).To(BeTemporally(">", ts1)) + g.Expect(err).To(BeNil()) + g.Expect(ts1).NotTo(BeZero()) + g.Expect(ts2).NotTo(BeZero()) + g.Expect(ts2).To(BeTemporally(">", ts1)) durationFromLogs := ts2.Sub(ts1) // Check both durations match - Expect(math.Abs((durationFromLogs - duration).Seconds())).To(BeNumerically("<=", 1)) + g.Expect(math.Abs((durationFromLogs - duration).Seconds())).To(BeNumerically("<=", 1)) // Retrieve the first readiness duration from the metric - Expect(metrics).To(HaveKey("camel_k_integration_first_readiness_seconds")) + g.Expect(metrics).To(HaveKey("camel_k_integration_first_readiness_seconds")) metric := metrics["camel_k_integration_first_readiness_seconds"].Metric - Expect(metric).To(HaveLen(1)) + g.Expect(metric).To(HaveLen(1)) histogram := metric[0].Histogram - Expect(histogram).NotTo(BeNil()) + g.Expect(histogram).NotTo(BeNil()) // Check both durations match d := duration.Seconds() - Expect(math.Abs(*histogram.SampleSum - d)).To(BeNumerically("<=", 1)) + g.Expect(math.Abs(*histogram.SampleSum - d)).To(BeNumerically("<=", 1)) // Check the duration is correctly observed in the corresponding metric - Expect(metrics).To(HaveKey("camel_k_integration_first_readiness_seconds")) - Expect(metrics["camel_k_integration_first_readiness_seconds"]).To(EqualP( + g.Expect(metrics).To(HaveKey("camel_k_integration_first_readiness_seconds")) + g.Expect(metrics["camel_k_integration_first_readiness_seconds"]).To(EqualP( prometheus.MetricFamily{ Name: stringP("camel_k_integration_first_readiness_seconds"), Help: stringP("Camel K integration time to first readiness"), @@ -541,7 +538,7 @@ func TestMetrics(t *testing.T) { }) // Clean up - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) } diff --git a/e2e/advanced/platform_traits_test.go b/e2e/advanced/platform_traits_test.go index ca5d1a9206..662d1f4e18 100644 --- a/e2e/advanced/platform_traits_test.go +++ b/e2e/advanced/platform_traits_test.go @@ -23,6 +23,7 @@ limitations under the License. package advanced import ( + "context" "testing" "github.com/apache/camel-k/v2/pkg/apis/camel/v1/trait" @@ -36,45 +37,43 @@ import ( ) func TestTraitOnIntegrationPlatform(t *testing.T) { - WithNewTestNamespace(t, func(ns string) { + t.Parallel() + + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { operatorID := "camel-k-platform-trait-test" - Expect(CopyCamelCatalog(ns, operatorID)).To(Succeed()) - Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed()) + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) containerTestName := "testname" - Eventually(PlatformPhase(ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) - ip := Platform(ns)() - ip.Spec.Traits = v1.Traits{Logging: &trait.LoggingTrait{Level: "DEBUG"}, Container: &trait.ContainerTrait{Name: containerTestName}} - - if err := TestClient().Update(TestContext, ip); err != nil { - t.Fatal("Can't create IntegrationPlatform", err) - } - Eventually(PlatformPhase(ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + g.Eventually(PlatformPhase(t, ctx, ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + g.Expect(UpdatePlatform(t, ctx, ns, operatorID, func(ip *v1.IntegrationPlatform) { + ip.Spec.Traits = v1.Traits{Logging: &trait.LoggingTrait{Level: "DEBUG"}, Container: &trait.ContainerTrait{Name: containerTestName}} + })).To(Succeed()) + g.Eventually(PlatformPhase(t, ctx, ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) name := RandomizedSuffixName("java") t.Run("Run integration with platform traits", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", - "--name", name, - ).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", name).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - Expect(IntegrationPod(ns, name)().Spec.Containers[0].Name).To(BeEquivalentTo(containerTestName)) + g.Expect(IntegrationPod(t, ctx, ns, name)().Spec.Containers[0].Name).To(BeEquivalentTo(containerTestName)) found := false - for _, env := range IntegrationPod(ns, name)().Spec.Containers[0].Env { + for _, env := range IntegrationPod(t, ctx, ns, name)().Spec.Containers[0].Env { if env.Name == "QUARKUS_LOG_LEVEL" { - Expect(env.Value).To(BeEquivalentTo("DEBUG")) + g.Expect(env.Value).To(BeEquivalentTo("DEBUG")) found = true break } } - Expect(found).To(BeTrue(), "Can't find QUARKUS_LOG_LEVEL ENV variable") - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("DEBUG")) + g.Expect(found).To(BeTrue(), "Can't find QUARKUS_LOG_LEVEL ENV variable") + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("DEBUG")) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) }) } diff --git a/e2e/advanced/promote_test.go b/e2e/advanced/promote_test.go index 15580920a2..6491908554 100644 --- a/e2e/advanced/promote_test.go +++ b/e2e/advanced/promote_test.go @@ -23,6 +23,7 @@ limitations under the License. package advanced import ( + "context" "testing" corev1 "k8s.io/api/core/v1" @@ -34,142 +35,142 @@ import ( ) func TestKamelCLIPromote(t *testing.T) { + t.Parallel() + one := int64(1) two := int64(2) // Dev environment namespace - WithNewTestNamespace(t, func(nsDev string) { + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, nsDev string) { operatorDevID := "camel-k-cli-promote-dev" - Expect(CopyCamelCatalog(nsDev, operatorDevID)).To(Succeed()) - Expect(KamelInstallWithID(operatorDevID, nsDev).Execute()).To(Succeed()) - Eventually(SelectedPlatformPhase(nsDev, operatorDevID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + g.Expect(CopyCamelCatalog(t, ctx, nsDev, operatorDevID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, nsDev, operatorDevID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorDevID, nsDev)).To(Succeed()) + g.Eventually(SelectedPlatformPhase(t, ctx, nsDev, operatorDevID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) // Dev content configmap var cmData = make(map[string]string) cmData["my-configmap-key"] = "I am development configmap!" - CreatePlainTextConfigmap(nsDev, "my-cm-promote", cmData) + CreatePlainTextConfigmap(t, ctx, nsDev, "my-cm-promote", cmData) // Dev secret var secData = make(map[string]string) secData["my-secret-key"] = "very top secret development" - CreatePlainTextSecret(nsDev, "my-sec-promote", secData) + CreatePlainTextSecret(t, ctx, nsDev, "my-sec-promote", secData) t.Run("plain integration dev", func(t *testing.T) { - Expect(KamelRunWithID(operatorDevID, nsDev, "./files/promote-route.groovy", - "--config", "configmap:my-cm-promote", - "--config", "secret:my-sec-promote", - ).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(nsDev, "promote-route"), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationObservedGeneration(nsDev, "promote-route")).Should(Equal(&one)) - //Eventually(IntegrationConditionStatus(nsDev, "promote-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(nsDev, "promote-route"), TestTimeoutShort).Should(ContainSubstring("I am development configmap!")) - Eventually(IntegrationLogs(nsDev, "promote-route"), TestTimeoutShort).Should(ContainSubstring("very top secret development")) + g.Expect(KamelRunWithID(t, ctx, operatorDevID, nsDev, "./files/promote-route.groovy", "--config", "configmap:my-cm-promote", "--config", "secret:my-sec-promote").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, nsDev, "promote-route"), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationObservedGeneration(t, ctx, nsDev, "promote-route")).Should(Equal(&one)) + //g.Eventually(IntegrationConditionStatus(t, nsDev, "promote-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, nsDev, "promote-route"), TestTimeoutShort).Should(ContainSubstring("I am development configmap!")) + g.Eventually(IntegrationLogs(t, ctx, nsDev, "promote-route"), TestTimeoutShort).Should(ContainSubstring("very top secret development")) }) t.Run("kamelet integration dev", func(t *testing.T) { - Expect(CreateTimerKamelet(nsDev, "my-own-timer-source")()).To(Succeed()) - Expect(KamelRunWithID(operatorDevID, nsDev, "./files/timer-kamelet-usage.groovy").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(nsDev, "timer-kamelet-usage"), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(nsDev, "timer-kamelet-usage"), TestTimeoutShort).Should(ContainSubstring("Hello world")) + g.Expect(CreateTimerKamelet(t, ctx, operatorDevID, nsDev, "my-own-timer-source")()).To(Succeed()) + g.Expect(KamelRunWithID(t, ctx, operatorDevID, nsDev, "./files/timer-kamelet-usage.groovy").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, nsDev, "timer-kamelet-usage"), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, nsDev, "timer-kamelet-usage"), TestTimeoutShort).Should(ContainSubstring("Hello world")) }) t.Run("binding dev", func(t *testing.T) { - Expect(CreateTimerKamelet(nsDev, "kb-timer-source")()).To(Succeed()) - Expect(KamelBindWithID(operatorDevID, nsDev, "kb-timer-source", "log:info", "-p", "source.message=my-kamelet-binding-rocks").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(nsDev, "kb-timer-source-to-log"), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(nsDev, "kb-timer-source-to-log"), TestTimeoutShort).Should(ContainSubstring("my-kamelet-binding-rocks")) + g.Expect(CreateTimerKamelet(t, ctx, operatorDevID, nsDev, "kb-timer-source")()).To(Succeed()) + g.Expect(KamelBindWithID(t, ctx, operatorDevID, nsDev, "kb-timer-source", "log:info", "-p", "source.message=my-kamelet-binding-rocks").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, nsDev, "kb-timer-source-to-log"), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, nsDev, "kb-timer-source-to-log"), TestTimeoutShort).Should(ContainSubstring("my-kamelet-binding-rocks")) }) // Prod environment namespace - WithNewTestNamespace(t, func(nsProd string) { + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, nsProd string) { operatorProdID := "camel-k-cli-promote-prod" - Expect(CopyCamelCatalog(nsProd, operatorProdID)).To(Succeed()) - Expect(KamelInstallWithID(operatorProdID, nsProd).Execute()).To(Succeed()) - Eventually(PlatformPhase(nsProd), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + g.Expect(CopyCamelCatalog(t, ctx, nsProd, operatorProdID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, nsProd, operatorProdID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorProdID, nsProd)).To(Succeed()) + g.Eventually(PlatformPhase(t, ctx, nsProd), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) t.Run("no configmap in destination", func(t *testing.T) { - Expect(Kamel("promote", "-n", nsDev, "promote-route", "--to", nsProd).Execute()).NotTo(Succeed()) + g.Expect(Kamel(t, ctx, "promote", "-n", nsDev, "promote-route", "--to", nsProd).Execute()).NotTo(Succeed()) }) // Prod content configmap var cmData = make(map[string]string) cmData["my-configmap-key"] = "I am production!" - CreatePlainTextConfigmap(nsProd, "my-cm-promote", cmData) + CreatePlainTextConfigmap(t, ctx, nsProd, "my-cm-promote", cmData) t.Run("no secret in destination", func(t *testing.T) { - Expect(Kamel("promote", "-n", nsDev, "promote-route", "--to", nsProd).Execute()).NotTo(Succeed()) + g.Expect(Kamel(t, ctx, "promote", "-n", nsDev, "promote-route", "--to", nsProd).Execute()).NotTo(Succeed()) }) // Prod secret var secData = make(map[string]string) secData["my-secret-key"] = "very top secret production" - CreatePlainTextSecret(nsProd, "my-sec-promote", secData) + CreatePlainTextSecret(t, ctx, nsProd, "my-sec-promote", secData) t.Run("plain integration promotion", func(t *testing.T) { - Expect(Kamel("promote", "-n", nsDev, "promote-route", "--to", nsProd).Execute()).To(Succeed()) - Eventually(IntegrationObservedGeneration(nsProd, "promote-route")).Should(Equal(&one)) - Eventually(IntegrationPodPhase(nsProd, "promote-route"), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(nsProd, "promote-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(nsProd, "promote-route"), TestTimeoutShort).Should(ContainSubstring("I am production!")) - Eventually(IntegrationLogs(nsProd, "promote-route"), TestTimeoutShort).Should(ContainSubstring("very top secret production")) + g.Expect(Kamel(t, ctx, "promote", "-n", nsDev, "promote-route", "--to", nsProd).Execute()).To(Succeed()) + g.Eventually(IntegrationObservedGeneration(t, ctx, nsProd, "promote-route")).Should(Equal(&one)) + g.Eventually(IntegrationPodPhase(t, ctx, nsProd, "promote-route"), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, nsProd, "promote-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, nsProd, "promote-route"), TestTimeoutShort).Should(ContainSubstring("I am production!")) + g.Eventually(IntegrationLogs(t, ctx, nsProd, "promote-route"), TestTimeoutShort).Should(ContainSubstring("very top secret production")) // They must use the same image - Expect(IntegrationPodImage(nsProd, "promote-route")()).Should(Equal(IntegrationPodImage(nsDev, "promote-route")())) + g.Expect(IntegrationPodImage(t, ctx, nsProd, "promote-route")()).Should(Equal(IntegrationPodImage(t, ctx, nsDev, "promote-route")())) }) t.Run("plain integration promotion update", func(t *testing.T) { // We need to update the Integration CR in order the operator to restart it both in dev and prod envs - Expect(KamelRunWithID(operatorDevID, nsDev, "./files/promote-route-edited.groovy", "--name", "promote-route", - "--config", "configmap:my-cm-promote").Execute()).To(Succeed()) + g.Expect(KamelRunWithID(t, ctx, operatorDevID, nsDev, "./files/promote-route-edited.groovy", "--name", "promote-route", "--config", "configmap:my-cm-promote").Execute()).To(Succeed()) // The generation has to be incremented - Eventually(IntegrationObservedGeneration(nsDev, "promote-route")).Should(Equal(&two)) - Eventually(IntegrationPodPhase(nsDev, "promote-route"), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(nsDev, "promote-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(nsDev, "promote-route"), TestTimeoutShort).Should(ContainSubstring("I am development configmap!")) + g.Eventually(IntegrationObservedGeneration(t, ctx, nsDev, "promote-route")).Should(Equal(&two)) + g.Eventually(IntegrationPodPhase(t, ctx, nsDev, "promote-route"), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, nsDev, "promote-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, nsDev, "promote-route"), TestTimeoutShort).Should(ContainSubstring("I am development configmap!")) // Update the configmap only in prod var cmData = make(map[string]string) cmData["my-configmap-key"] = "I am production, but I was updated!" - UpdatePlainTextConfigmap(nsProd, "my-cm-promote", cmData) + UpdatePlainTextConfigmap(t, ctx, nsProd, "my-cm-promote", cmData) // Promote the edited Integration - Expect(Kamel("promote", "-n", nsDev, "promote-route", "--to", nsProd).Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "promote", "-n", nsDev, "promote-route", "--to", nsProd).Execute()).To(Succeed()) // The generation has to be incremented also in prod - Eventually(IntegrationObservedGeneration(nsDev, "promote-route")).Should(Equal(&two)) - Eventually(IntegrationPodPhase(nsProd, "promote-route"), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(nsProd, "promote-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(nsProd, "promote-route"), TestTimeoutShort).Should(ContainSubstring("I am production, but I was updated!")) + g.Eventually(IntegrationObservedGeneration(t, ctx, nsDev, "promote-route")).Should(Equal(&two)) + g.Eventually(IntegrationPodPhase(t, ctx, nsProd, "promote-route"), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, nsProd, "promote-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, nsProd, "promote-route"), TestTimeoutShort).Should(ContainSubstring("I am production, but I was updated!")) // They must use the same image - Expect(IntegrationPodImage(nsProd, "promote-route")()).Should(Equal(IntegrationPodImage(nsDev, "promote-route")())) + g.Expect(IntegrationPodImage(t, ctx, nsProd, "promote-route")()).Should(Equal(IntegrationPodImage(t, ctx, nsDev, "promote-route")())) }) t.Run("no kamelet in destination", func(t *testing.T) { - Expect(Kamel("promote", "-n", nsDev, "timer-kamelet-usage", "--to", nsProd).Execute()).NotTo(Succeed()) + g.Expect(Kamel(t, ctx, "promote", "-n", nsDev, "timer-kamelet-usage", "--to", nsProd).Execute()).NotTo(Succeed()) }) t.Run("kamelet integration promotion", func(t *testing.T) { - Expect(CreateTimerKamelet(nsProd, "my-own-timer-source")()).To(Succeed()) - Expect(Kamel("promote", "-n", nsDev, "timer-kamelet-usage", "--to", nsProd).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(nsProd, "timer-kamelet-usage"), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(nsProd, "timer-kamelet-usage"), TestTimeoutShort).Should(ContainSubstring("Hello world")) + g.Expect(CreateTimerKamelet(t, ctx, operatorProdID, nsProd, "my-own-timer-source")()).To(Succeed()) + g.Expect(Kamel(t, ctx, "promote", "-n", nsDev, "timer-kamelet-usage", "--to", nsProd).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, nsProd, "timer-kamelet-usage"), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, nsProd, "timer-kamelet-usage"), TestTimeoutShort).Should(ContainSubstring("Hello world")) // They must use the same image - Expect(IntegrationPodImage(nsProd, "timer-kamelet-usage")()).Should(Equal(IntegrationPodImage(nsDev, "timer-kamelet-usage")())) + g.Expect(IntegrationPodImage(t, ctx, nsProd, "timer-kamelet-usage")()).Should(Equal(IntegrationPodImage(t, ctx, nsDev, "timer-kamelet-usage")())) }) t.Run("no kamelet for binding in destination", func(t *testing.T) { - Expect(Kamel("promote", "-n", nsDev, "kb-timer-source-to-log", "--to", nsProd).Execute()).NotTo(Succeed()) + g.Expect(Kamel(t, ctx, "promote", "-n", nsDev, "kb-timer-source-to-log", "--to", nsProd).Execute()).NotTo(Succeed()) }) t.Run("binding promotion", func(t *testing.T) { - Expect(CreateTimerKamelet(nsProd, "kb-timer-source")()).To(Succeed()) - Expect(Kamel("promote", "-n", nsDev, "kb-timer-source-to-log", "--to", nsProd).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(nsProd, "kb-timer-source-to-log"), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(nsProd, "kb-timer-source-to-log"), TestTimeoutShort).Should(ContainSubstring("my-kamelet-binding-rocks")) + g.Expect(CreateTimerKamelet(t, ctx, operatorProdID, nsProd, "kb-timer-source")()).To(Succeed()) + g.Expect(Kamel(t, ctx, "promote", "-n", nsDev, "kb-timer-source-to-log", "--to", nsProd).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, nsProd, "kb-timer-source-to-log"), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, nsProd, "kb-timer-source-to-log"), TestTimeoutShort).Should(ContainSubstring("my-kamelet-binding-rocks")) // They must use the same image - Expect(IntegrationPodImage(nsProd, "kb-timer-source-to-log")()).Should(Equal(IntegrationPodImage(nsDev, "kb-timer-source-to-log")())) + g.Expect(IntegrationPodImage(t, ctx, nsProd, "kb-timer-source-to-log")()).Should(Equal(IntegrationPodImage(t, ctx, nsDev, "kb-timer-source-to-log")())) //Binding update - Expect(KamelBindWithID(operatorDevID, nsDev, "kb-timer-source", "log:info", "-p", "source.message=my-kamelet-binding-rocks-again").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(nsDev, "kb-timer-source-to-log"), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(nsDev, "kb-timer-source-to-log"), TestTimeoutShort).Should(ContainSubstring("my-kamelet-binding-rocks-again")) - Expect(Kamel("promote", "-n", nsDev, "kb-timer-source-to-log", "--to", nsProd).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(nsProd, "kb-timer-source-to-log"), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(nsProd, "kb-timer-source-to-log"), TestTimeoutShort).Should(ContainSubstring("my-kamelet-binding-rocks-again")) + g.Expect(KamelBindWithID(t, ctx, operatorDevID, nsDev, "kb-timer-source", "log:info", "-p", "source.message=my-kamelet-binding-rocks-again").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, nsDev, "kb-timer-source-to-log"), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, nsDev, "kb-timer-source-to-log"), TestTimeoutShort).Should(ContainSubstring("my-kamelet-binding-rocks-again")) + g.Expect(Kamel(t, ctx, "promote", "-n", nsDev, "kb-timer-source-to-log", "--to", nsProd).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, nsProd, "kb-timer-source-to-log"), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, nsProd, "kb-timer-source-to-log"), TestTimeoutShort).Should(ContainSubstring("my-kamelet-binding-rocks-again")) }) }) }) diff --git a/e2e/advanced/reset_test.go b/e2e/advanced/reset_test.go index 3ab3674101..8724addcdb 100644 --- a/e2e/advanced/reset_test.go +++ b/e2e/advanced/reset_test.go @@ -23,6 +23,7 @@ limitations under the License. package advanced import ( + "context" "testing" . "github.com/onsi/gomega" @@ -33,59 +34,62 @@ import ( ) func TestKamelReset(t *testing.T) { - WithNewTestNamespace(t, func(ns string) { + t.Parallel() + + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { operatorID := "camel-k-cli-reset" - Expect(CopyCamelCatalog(ns, operatorID)).To(Succeed()) - Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed()) + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) - Eventually(SelectedPlatformPhase(ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) t.Run("Reset the whole platform", func(t *testing.T) { name := RandomizedSuffixName("yaml1") - Expect(KamelRunWithID(operatorID, ns, "files/yaml.yaml", "--name", name).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/yaml.yaml", "--name", name).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - Eventually(Kit(ns, IntegrationKit(ns, name)())).Should(Not(BeNil())) - Eventually(Integration(ns, name)).Should(Not(BeNil())) + g.Eventually(Kit(t, ctx, ns, IntegrationKit(t, ctx, ns, name)())).Should(Not(BeNil())) + g.Eventually(Integration(t, ctx, ns, name)).Should(Not(BeNil())) - Expect(Kamel("reset", "-n", ns).Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "reset", "-n", ns).Execute()).To(Succeed()) - Expect(Integration(ns, name)()).To(BeNil()) - Expect(Kits(ns)()).To(HaveLen(0)) + g.Expect(Integration(t, ctx, ns, name)()).To(BeNil()) + g.Expect(Kits(t, ctx, ns)()).To(HaveLen(0)) }) t.Run("Reset skip-integrations", func(t *testing.T) { name := RandomizedSuffixName("yaml2") - Expect(KamelRunWithID(operatorID, ns, "files/yaml.yaml", "--name", name).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/yaml.yaml", "--name", name).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - Eventually(Kit(ns, IntegrationKit(ns, name)())).Should(Not(BeNil())) - Eventually(Integration(ns, name)).Should(Not(BeNil())) + g.Eventually(Kit(t, ctx, ns, IntegrationKit(t, ctx, ns, name)())).Should(Not(BeNil())) + g.Eventually(Integration(t, ctx, ns, name)).Should(Not(BeNil())) - Expect(Kamel("reset", "-n", ns, "--skip-integrations").Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "reset", "-n", ns, "--skip-integrations").Execute()).To(Succeed()) - Expect(Integration(ns, name)()).To(Not(BeNil())) - Expect(Kits(ns)()).To(HaveLen(0)) + g.Expect(Integration(t, ctx, ns, name)()).To(Not(BeNil())) + g.Expect(Kits(t, ctx, ns)()).To(HaveLen(0)) }) t.Run("Reset skip-kits", func(t *testing.T) { name := RandomizedSuffixName("yaml3") - Expect(KamelRunWithID(operatorID, ns, "files/yaml.yaml", "--name", name).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/yaml.yaml", "--name", name).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - kitName := IntegrationKit(ns, name)() - Eventually(Kit(ns, kitName)).Should(Not(BeNil())) - Eventually(Integration(ns, name)).Should(Not(BeNil())) + kitName := IntegrationKit(t, ctx, ns, name)() + g.Eventually(Kit(t, ctx, ns, kitName)).Should(Not(BeNil())) + g.Eventually(Integration(t, ctx, ns, name)).Should(Not(BeNil())) - Expect(Kamel("reset", "-n", ns, "--skip-kits").Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "reset", "-n", ns, "--skip-kits").Execute()).To(Succeed()) - Expect(Integration(ns, name)()).To(BeNil()) - Expect(Kit(ns, kitName)()).To(Not(BeNil())) + g.Expect(Integration(t, ctx, ns, name)()).To(BeNil()) + g.Expect(Kit(t, ctx, ns, kitName)()).To(Not(BeNil())) }) // Clean up - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) } diff --git a/e2e/advanced/synthetic_test.go b/e2e/advanced/synthetic_test.go index 67539964f7..4ed0d84134 100644 --- a/e2e/advanced/synthetic_test.go +++ b/e2e/advanced/synthetic_test.go @@ -23,6 +23,7 @@ limitations under the License. package advanced import ( + "context" "testing" . "github.com/onsi/gomega" @@ -35,88 +36,92 @@ import ( ) func TestSyntheticIntegrationOff(t *testing.T) { - RegisterTestingT(t) - WithNewTestNamespace(t, func(ns string) { + t.Parallel() + + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { // Install Camel K without synthetic Integration feature variable (default) operatorID := "camel-k-synthetic-env-off" - Expect(CopyCamelCatalog(ns, operatorID)).To(Succeed()) - Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed()) - Eventually(SelectedPlatformPhase(ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) // Run the external deployment - ExpectExecSucceed(t, Kubectl("apply", "-f", "files/deploy.yaml", "-n", ns)) - Eventually(DeploymentCondition(ns, "my-camel-sb-svc", appsv1.DeploymentProgressing), TestTimeoutShort). + ExpectExecSucceed(t, g, Kubectl("apply", "-f", "files/deploy.yaml", "-n", ns)) + g.Eventually(DeploymentCondition(t, ctx, ns, "my-camel-sb-svc", appsv1.DeploymentProgressing), TestTimeoutShort). Should(MatchFields(IgnoreExtras, Fields{ "Status": Equal(corev1.ConditionTrue), "Reason": Equal("NewReplicaSetAvailable"), })) // Label the deployment --> Verify the Integration is not created - ExpectExecSucceed(t, Kubectl("label", "deploy", "my-camel-sb-svc", "camel.apache.org/integration=my-it", "-n", ns)) - Eventually(Integration(ns, "my-it"), TestTimeoutShort).Should(BeNil()) + ExpectExecSucceed(t, g, Kubectl("label", "deploy", "my-camel-sb-svc", "camel.apache.org/integration=my-it", "-n", ns)) + g.Eventually(Integration(t, ctx, ns, "my-it"), TestTimeoutShort).Should(BeNil()) }) } func TestSyntheticIntegrationFromDeployment(t *testing.T) { - RegisterTestingT(t) - WithNewTestNamespace(t, func(ns string) { + t.Parallel() + + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { // Install Camel K with the synthetic Integration feature variable operatorID := "camel-k-synthetic-env" - Expect(CopyCamelCatalog(ns, operatorID)).To(Succeed()) - Expect(KamelInstallWithID(operatorID, ns, + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns, "--operator-env-vars", "CAMEL_K_SYNTHETIC_INTEGRATIONS=true", - ).Execute()).To(Succeed()) + )).To(Succeed()) // Run the external deployment - ExpectExecSucceed(t, Kubectl("apply", "-f", "files/deploy.yaml", "-n", ns)) - Eventually(DeploymentCondition(ns, "my-camel-sb-svc", appsv1.DeploymentProgressing), TestTimeoutShort). + ExpectExecSucceed(t, g, Kubectl("apply", "-f", "files/deploy.yaml", "-n", ns)) + g.Eventually(DeploymentCondition(t, ctx, ns, "my-camel-sb-svc", appsv1.DeploymentProgressing), TestTimeoutShort). Should(MatchFields(IgnoreExtras, Fields{ "Status": Equal(corev1.ConditionTrue), "Reason": Equal("NewReplicaSetAvailable"), })) // Label the deployment --> Verify the Integration is created (cannot still monitor) - ExpectExecSucceed(t, Kubectl("label", "deploy", "my-camel-sb-svc", "camel.apache.org/integration=my-it", "-n", ns)) - Eventually(IntegrationPhase(ns, "my-it"), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseRunning)) - Eventually(IntegrationConditionStatus(ns, "my-it", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionFalse)) - Eventually(IntegrationCondition(ns, "my-it", v1.IntegrationConditionReady), TestTimeoutShort).Should( + ExpectExecSucceed(t, g, Kubectl("label", "deploy", "my-camel-sb-svc", "camel.apache.org/integration=my-it", "-n", ns)) + g.Eventually(IntegrationPhase(t, ctx, ns, "my-it"), TestTimeoutMedium).Should(Equal(v1.IntegrationPhaseRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "my-it", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionFalse)) + g.Eventually(IntegrationCondition(t, ctx, ns, "my-it", v1.IntegrationConditionReady), TestTimeoutShort).Should( WithTransform(IntegrationConditionReason, Equal(v1.IntegrationConditionMonitoringPodsAvailableReason))) // Label the deployment template --> Verify the Integration is monitored - ExpectExecSucceed(t, Kubectl("patch", "deployment", "my-camel-sb-svc", "--patch", `{"spec": {"template": {"metadata": {"labels": {"camel.apache.org/integration": "my-it"}}}}}`, "-n", ns)) - Eventually(IntegrationPhase(ns, "my-it"), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseRunning)) - Eventually(IntegrationConditionStatus(ns, "my-it", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + ExpectExecSucceed(t, g, Kubectl("patch", "deployment", "my-camel-sb-svc", "--patch", `{"spec": {"template": {"metadata": {"labels": {"camel.apache.org/integration": "my-it"}}}}}`, "-n", ns)) + g.Eventually(IntegrationPhase(t, ctx, ns, "my-it"), TestTimeoutMedium).Should(Equal(v1.IntegrationPhaseRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "my-it", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) one := int32(1) - Eventually(IntegrationStatusReplicas(ns, "my-it"), TestTimeoutShort).Should(Equal(&one)) + g.Eventually(IntegrationStatusReplicas(t, ctx, ns, "my-it"), TestTimeoutShort).Should(Equal(&one)) // Delete the deployment --> Verify the Integration is eventually garbage collected - ExpectExecSucceed(t, Kubectl("delete", "deploy", "my-camel-sb-svc", "-n", ns)) - Eventually(Integration(ns, "my-it"), TestTimeoutShort).Should(BeNil()) + ExpectExecSucceed(t, g, Kubectl("delete", "deploy", "my-camel-sb-svc", "-n", ns)) + g.Eventually(Integration(t, ctx, ns, "my-it"), TestTimeoutShort).Should(BeNil()) // Recreate the deployment and label --> Verify the Integration is monitored - ExpectExecSucceed(t, Kubectl("apply", "-f", "files/deploy.yaml", "-n", ns)) - ExpectExecSucceed(t, Kubectl("label", "deploy", "my-camel-sb-svc", "camel.apache.org/integration=my-it", "-n", ns)) - ExpectExecSucceed(t, Kubectl("patch", "deployment", "my-camel-sb-svc", "--patch", `{"spec": {"template": {"metadata": {"labels": {"camel.apache.org/integration": "my-it"}}}}}`, "-n", ns)) - Eventually(IntegrationPhase(ns, "my-it"), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseRunning)) - Eventually(IntegrationConditionStatus(ns, "my-it", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationStatusReplicas(ns, "my-it"), TestTimeoutShort).Should(Equal(&one)) + ExpectExecSucceed(t, g, Kubectl("apply", "-f", "files/deploy.yaml", "-n", ns)) + ExpectExecSucceed(t, g, Kubectl("label", "deploy", "my-camel-sb-svc", "camel.apache.org/integration=my-it", "-n", ns)) + ExpectExecSucceed(t, g, Kubectl("patch", "deployment", "my-camel-sb-svc", "--patch", `{"spec": {"template": {"metadata": {"labels": {"camel.apache.org/integration": "my-it"}}}}}`, "-n", ns)) + g.Eventually(IntegrationPhase(t, ctx, ns, "my-it"), TestTimeoutMedium).Should(Equal(v1.IntegrationPhaseRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "my-it", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationStatusReplicas(t, ctx, ns, "my-it"), TestTimeoutShort).Should(Equal(&one)) // Remove label from the deployment --> Verify the Integration is deleted - ExpectExecSucceed(t, Kubectl("label", "deploy", "my-camel-sb-svc", "camel.apache.org/integration-", "-n", ns)) - Eventually(Integration(ns, "my-it"), TestTimeoutShort).Should(BeNil()) + ExpectExecSucceed(t, g, Kubectl("label", "deploy", "my-camel-sb-svc", "camel.apache.org/integration-", "-n", ns)) + g.Eventually(Integration(t, ctx, ns, "my-it"), TestTimeoutShort).Should(BeNil()) // Add label back to the deployment --> Verify the Integration is created - ExpectExecSucceed(t, Kubectl("label", "deploy", "my-camel-sb-svc", "camel.apache.org/integration=my-it", "-n", ns)) - Eventually(IntegrationPhase(ns, "my-it"), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseRunning)) - Eventually(IntegrationConditionStatus(ns, "my-it", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationStatusReplicas(ns, "my-it"), TestTimeoutShort).Should(Equal(&one)) + ExpectExecSucceed(t, g, Kubectl("label", "deploy", "my-camel-sb-svc", "camel.apache.org/integration=my-it", "-n", ns)) + g.Eventually(IntegrationPhase(t, ctx, ns, "my-it"), TestTimeoutMedium).Should(Equal(v1.IntegrationPhaseRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "my-it", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationStatusReplicas(t, ctx, ns, "my-it"), TestTimeoutShort).Should(Equal(&one)) // Scale the deployment --> verify replicas are correctly set - ExpectExecSucceed(t, Kubectl("scale", "deploy", "my-camel-sb-svc", "--replicas", "2", "-n", ns)) + ExpectExecSucceed(t, g, Kubectl("scale", "deploy", "my-camel-sb-svc", "--replicas", "2", "-n", ns)) two := int32(2) - Eventually(IntegrationStatusReplicas(ns, "my-it"), TestTimeoutShort).Should(Equal(&two)) + g.Eventually(IntegrationStatusReplicas(t, ctx, ns, "my-it"), TestTimeoutShort).Should(Equal(&two)) // Delete Integration and deployments --> verify no Integration exists any longer - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) - ExpectExecSucceed(t, Kubectl("delete", "deploy", "my-camel-sb-svc", "-n", ns)) - Eventually(Integration(ns, "my-it"), TestTimeoutShort).Should(BeNil()) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + ExpectExecSucceed(t, g, Kubectl("delete", "deploy", "my-camel-sb-svc", "-n", ns)) + g.Eventually(Integration(t, ctx, ns, "my-it"), TestTimeoutShort).Should(BeNil()) }) } diff --git a/e2e/advanced/tekton_test.go b/e2e/advanced/tekton_test.go index f9e84e2999..6edb89744c 100644 --- a/e2e/advanced/tekton_test.go +++ b/e2e/advanced/tekton_test.go @@ -23,6 +23,7 @@ limitations under the License. package advanced import ( + "context" "testing" . "github.com/onsi/gomega" @@ -33,16 +34,16 @@ import ( // TestTektonLikeBehavior verifies that the kamel binary can be invoked from within the Camel K image. // This feature is used in Tekton pipelines. func TestTektonLikeBehavior(t *testing.T) { - RegisterTestingT(t) + t.Parallel() - WithNewTestNamespace(t, func(ns string) { - Expect(CreateOperatorServiceAccount(ns)).To(Succeed()) - Expect(CreateOperatorRole(ns)).To(Succeed()) - Expect(CreateOperatorRoleBinding(ns)).To(Succeed()) + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + g.Expect(CreateOperatorServiceAccount(t, ctx, ns)).To(Succeed()) + g.Expect(CreateOperatorRole(t, ctx, ns)).To(Succeed()) + g.Expect(CreateOperatorRoleBinding(t, ctx, ns)).To(Succeed()) - Eventually(OperatorPod(ns)).Should(BeNil()) - Expect(CreateKamelPod(ns, "tekton-task", "install", "--skip-cluster-setup", "--force")).To(Succeed()) + g.Eventually(OperatorPod(t, ctx, ns)).Should(BeNil()) + g.Expect(CreateKamelPod(t, ctx, ns, "tekton-task", "install", "--skip-cluster-setup", "--force")).To(Succeed()) - Eventually(OperatorPod(ns)).ShouldNot(BeNil()) + g.Eventually(OperatorPod(t, ctx, ns)).ShouldNot(BeNil()) }) } diff --git a/e2e/builder/build_test.go b/e2e/builder/build_test.go index c90f91f3d1..0ed06c7e07 100644 --- a/e2e/builder/build_test.go +++ b/e2e/builder/build_test.go @@ -23,6 +23,7 @@ limitations under the License. package builder import ( + "context" "errors" "fmt" "testing" @@ -42,14 +43,14 @@ type kitOptions struct { } func TestKitMaxBuildLimit(t *testing.T) { - WithNewTestNamespace(t, func(ns string) { - createOperator(ns, "8m0s", "--global", "--force") + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + createOperator(t, ctx, g, ns, "8m0s", "--global", "--force") - pl := Platform(ns)() + pl := Platform(t, ctx, ns)() // set maximum number of running builds and order strategy pl.Spec.Build.MaxRunningBuilds = 2 pl.Spec.Build.BuildConfiguration.OrderStrategy = v1.BuildOrderStrategySequential - if err := TestClient().Update(TestContext, pl); err != nil { + if err := TestClient(t).Update(ctx, pl); err != nil { t.Error(err) t.FailNow() } @@ -58,31 +59,31 @@ func TestKitMaxBuildLimit(t *testing.T) { buildB := "integration-b" buildC := "integration-c" - WithNewTestNamespace(t, func(ns1 string) { - WithNewTestNamespace(t, func(ns2 string) { + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns1 string) { + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns2 string) { pl1 := v1.NewIntegrationPlatform(ns1, fmt.Sprintf("camel-k-%s", ns)) pl.Spec.DeepCopyInto(&pl1.Spec) pl1.Spec.Build.Maven.Settings = v1.ValueSource{} pl1.SetOperatorID(fmt.Sprintf("camel-k-%s", ns)) - if err := TestClient().Create(TestContext, &pl1); err != nil { + if err := TestClient(t).Create(ctx, &pl1); err != nil { t.Error(err) t.FailNow() } - Eventually(PlatformPhase(ns1), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + g.Eventually(PlatformPhase(t, ctx, ns1), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) pl2 := v1.NewIntegrationPlatform(ns2, fmt.Sprintf("camel-k-%s", ns)) pl.Spec.DeepCopyInto(&pl2.Spec) pl2.Spec.Build.Maven.Settings = v1.ValueSource{} pl2.SetOperatorID(fmt.Sprintf("camel-k-%s", ns)) - if err := TestClient().Create(TestContext, &pl2); err != nil { + if err := TestClient(t).Create(ctx, &pl2); err != nil { t.Error(err) t.FailNow() } - Eventually(PlatformPhase(ns2), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + g.Eventually(PlatformPhase(t, ctx, ns2), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) - doKitBuildInNamespace(buildA, ns, TestTimeoutShort, kitOptions{ + doKitBuildInNamespace(t, ctx, g, buildA, ns, TestTimeoutShort, kitOptions{ operatorID: fmt.Sprintf("camel-k-%s", ns), dependencies: []string{ "camel:timer", "camel:log", @@ -92,7 +93,7 @@ func TestKitMaxBuildLimit(t *testing.T) { }, }, v1.BuildPhaseRunning, v1.IntegrationKitPhaseBuildRunning) - doKitBuildInNamespace(buildB, ns1, TestTimeoutShort, kitOptions{ + doKitBuildInNamespace(t, ctx, g, buildB, ns1, TestTimeoutShort, kitOptions{ operatorID: fmt.Sprintf("camel-k-%s", ns), dependencies: []string{ "camel:timer", "camel:log", @@ -102,7 +103,7 @@ func TestKitMaxBuildLimit(t *testing.T) { }, }, v1.BuildPhaseRunning, v1.IntegrationKitPhaseBuildRunning) - doKitBuildInNamespace(buildC, ns2, TestTimeoutShort, kitOptions{ + doKitBuildInNamespace(t, ctx, g, buildC, ns2, TestTimeoutShort, kitOptions{ operatorID: fmt.Sprintf("camel-k-%s", ns), dependencies: []string{ "camel:timer", "camel:log", @@ -117,41 +118,41 @@ func TestKitMaxBuildLimit(t *testing.T) { } limit := 0 - for limit < 5 && BuildPhase(ns, buildA)() == v1.BuildPhaseRunning { + for limit < 5 && BuildPhase(t, ctx, ns, buildA)() == v1.BuildPhaseRunning { // verify that number of running builds does not exceed max build limit - Consistently(BuildsRunning(BuildPhase(ns, buildA), BuildPhase(ns1, buildB), BuildPhase(ns2, buildC)), TestTimeoutShort, 10*time.Second).Should(Satisfy(notExceedsMaxBuildLimit)) + g.Consistently(BuildsRunning(BuildPhase(t, ctx, ns, buildA), BuildPhase(t, ctx, ns1, buildB), BuildPhase(t, ctx, ns2, buildC)), TestTimeoutShort, 10*time.Second).Should(Satisfy(notExceedsMaxBuildLimit)) limit++ } // make sure we have verified max build limit at least once if limit == 0 { - t.Error(errors.New(fmt.Sprintf("Unexpected build phase '%s' for %s - not able to verify max builds limit", BuildPhase(ns, buildA)(), buildA))) + t.Error(errors.New(fmt.Sprintf("Unexpected build phase '%s' for %s - not able to verify max builds limit", BuildPhase(t, ctx, ns, buildA)(), buildA))) t.FailNow() } // verify that all builds are successful - Eventually(BuildPhase(ns, buildA), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded)) - Eventually(KitPhase(ns, buildA), TestTimeoutLong).Should(Equal(v1.IntegrationKitPhaseReady)) + g.Eventually(BuildPhase(t, ctx, ns, buildA), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded)) + g.Eventually(KitPhase(t, ctx, ns, buildA), TestTimeoutLong).Should(Equal(v1.IntegrationKitPhaseReady)) - Eventually(BuildPhase(ns1, buildB), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded)) - Eventually(KitPhase(ns1, buildB), TestTimeoutLong).Should(Equal(v1.IntegrationKitPhaseReady)) + g.Eventually(BuildPhase(t, ctx, ns1, buildB), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded)) + g.Eventually(KitPhase(t, ctx, ns1, buildB), TestTimeoutLong).Should(Equal(v1.IntegrationKitPhaseReady)) - Eventually(BuildPhase(ns2, buildC), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded)) - Eventually(KitPhase(ns2, buildC), TestTimeoutLong).Should(Equal(v1.IntegrationKitPhaseReady)) + g.Eventually(BuildPhase(t, ctx, ns2, buildC), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded)) + g.Eventually(KitPhase(t, ctx, ns2, buildC), TestTimeoutLong).Should(Equal(v1.IntegrationKitPhaseReady)) }) }) }) } func TestKitMaxBuildLimitFIFOStrategy(t *testing.T) { - WithNewTestNamespace(t, func(ns string) { - createOperator(ns, "8m0s", "--global", "--force") + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + createOperator(t, ctx, g, ns, "8m0s", "--global", "--force") - pl := Platform(ns)() + pl := Platform(t, ctx, ns)() // set maximum number of running builds and order strategy pl.Spec.Build.MaxRunningBuilds = 2 pl.Spec.Build.BuildConfiguration.OrderStrategy = v1.BuildOrderStrategyFIFO - if err := TestClient().Update(TestContext, pl); err != nil { + if err := TestClient(t).Update(ctx, pl); err != nil { t.Error(err) t.FailNow() } @@ -160,7 +161,7 @@ func TestKitMaxBuildLimitFIFOStrategy(t *testing.T) { buildB := "integration-b" buildC := "integration-c" - doKitBuildInNamespace(buildA, ns, TestTimeoutShort, kitOptions{ + doKitBuildInNamespace(t, ctx, g, buildA, ns, TestTimeoutShort, kitOptions{ operatorID: fmt.Sprintf("camel-k-%s", ns), dependencies: []string{ "camel:timer", "camel:log", @@ -170,7 +171,7 @@ func TestKitMaxBuildLimitFIFOStrategy(t *testing.T) { }, }, v1.BuildPhaseRunning, v1.IntegrationKitPhaseBuildRunning) - doKitBuildInNamespace(buildB, ns, TestTimeoutShort, kitOptions{ + doKitBuildInNamespace(t, ctx, g, buildB, ns, TestTimeoutShort, kitOptions{ operatorID: fmt.Sprintf("camel-k-%s", ns), dependencies: []string{ "camel:timer", "camel:log", @@ -180,7 +181,7 @@ func TestKitMaxBuildLimitFIFOStrategy(t *testing.T) { }, }, v1.BuildPhaseRunning, v1.IntegrationKitPhaseBuildRunning) - doKitBuildInNamespace(buildC, ns, TestTimeoutShort, kitOptions{ + doKitBuildInNamespace(t, ctx, g, buildC, ns, TestTimeoutShort, kitOptions{ operatorID: fmt.Sprintf("camel-k-%s", ns), dependencies: []string{ "camel:timer", "camel:log", @@ -195,37 +196,37 @@ func TestKitMaxBuildLimitFIFOStrategy(t *testing.T) { } limit := 0 - for limit < 5 && BuildPhase(ns, buildA)() == v1.BuildPhaseRunning { + for limit < 5 && BuildPhase(t, ctx, ns, buildA)() == v1.BuildPhaseRunning { // verify that number of running builds does not exceed max build limit - Consistently(BuildsRunning(BuildPhase(ns, buildA), BuildPhase(ns, buildB), BuildPhase(ns, buildC)), TestTimeoutShort, 10*time.Second).Should(Satisfy(notExceedsMaxBuildLimit)) + g.Consistently(BuildsRunning(BuildPhase(t, ctx, ns, buildA), BuildPhase(t, ctx, ns, buildB), BuildPhase(t, ctx, ns, buildC)), TestTimeoutShort, 10*time.Second).Should(Satisfy(notExceedsMaxBuildLimit)) limit++ } // make sure we have verified max build limit at least once if limit == 0 { - t.Error(errors.New(fmt.Sprintf("Unexpected build phase '%s' for %s - not able to verify max builds limit", BuildPhase(ns, buildA)(), buildA))) + t.Error(errors.New(fmt.Sprintf("Unexpected build phase '%s' for %s - not able to verify max builds limit", BuildPhase(t, ctx, ns, buildA)(), buildA))) t.FailNow() } // verify that all builds are successful - Eventually(BuildPhase(ns, buildA), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded)) - Eventually(KitPhase(ns, buildA), TestTimeoutLong).Should(Equal(v1.IntegrationKitPhaseReady)) - Eventually(BuildPhase(ns, buildB), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded)) - Eventually(KitPhase(ns, buildB), TestTimeoutLong).Should(Equal(v1.IntegrationKitPhaseReady)) - Eventually(BuildPhase(ns, buildC), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded)) - Eventually(KitPhase(ns, buildC), TestTimeoutLong).Should(Equal(v1.IntegrationKitPhaseReady)) + g.Eventually(BuildPhase(t, ctx, ns, buildA), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded)) + g.Eventually(KitPhase(t, ctx, ns, buildA), TestTimeoutLong).Should(Equal(v1.IntegrationKitPhaseReady)) + g.Eventually(BuildPhase(t, ctx, ns, buildB), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded)) + g.Eventually(KitPhase(t, ctx, ns, buildB), TestTimeoutLong).Should(Equal(v1.IntegrationKitPhaseReady)) + g.Eventually(BuildPhase(t, ctx, ns, buildC), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded)) + g.Eventually(KitPhase(t, ctx, ns, buildC), TestTimeoutLong).Should(Equal(v1.IntegrationKitPhaseReady)) }) } func TestKitMaxBuildLimitDependencyMatchingStrategy(t *testing.T) { - WithNewTestNamespace(t, func(ns string) { - createOperator(ns, "8m0s", "--global", "--force") + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + createOperator(t, ctx, g, ns, "8m0s", "--global", "--force") - pl := Platform(ns)() + pl := Platform(t, ctx, ns)() // set maximum number of running builds and order strategy pl.Spec.Build.MaxRunningBuilds = 2 pl.Spec.Build.BuildConfiguration.OrderStrategy = v1.BuildOrderStrategyDependencies - if err := TestClient().Update(TestContext, pl); err != nil { + if err := TestClient(t).Update(ctx, pl); err != nil { t.Error(err) t.FailNow() } @@ -234,7 +235,7 @@ func TestKitMaxBuildLimitDependencyMatchingStrategy(t *testing.T) { buildB := "integration-b" buildC := "integration-c" - doKitBuildInNamespace(buildA, ns, TestTimeoutShort, kitOptions{ + doKitBuildInNamespace(t, ctx, g, buildA, ns, TestTimeoutShort, kitOptions{ operatorID: fmt.Sprintf("camel-k-%s", ns), dependencies: []string{ "camel:timer", "camel:log", @@ -244,7 +245,7 @@ func TestKitMaxBuildLimitDependencyMatchingStrategy(t *testing.T) { }, }, v1.BuildPhaseRunning, v1.IntegrationKitPhaseBuildRunning) - doKitBuildInNamespace(buildB, ns, TestTimeoutShort, kitOptions{ + doKitBuildInNamespace(t, ctx, g, buildB, ns, TestTimeoutShort, kitOptions{ operatorID: fmt.Sprintf("camel-k-%s", ns), dependencies: []string{ "camel:cron", "camel:log", "camel:joor", @@ -254,7 +255,7 @@ func TestKitMaxBuildLimitDependencyMatchingStrategy(t *testing.T) { }, }, v1.BuildPhaseRunning, v1.IntegrationKitPhaseBuildRunning) - doKitBuildInNamespace(buildC, ns, TestTimeoutShort, kitOptions{ + doKitBuildInNamespace(t, ctx, g, buildC, ns, TestTimeoutShort, kitOptions{ operatorID: fmt.Sprintf("camel-k-%s", ns), dependencies: []string{ "camel:timer", "camel:log", "camel:joor", "camel:http", @@ -269,37 +270,37 @@ func TestKitMaxBuildLimitDependencyMatchingStrategy(t *testing.T) { } limit := 0 - for limit < 5 && BuildPhase(ns, buildA)() == v1.BuildPhaseRunning { + for limit < 5 && BuildPhase(t, ctx, ns, buildA)() == v1.BuildPhaseRunning { // verify that number of running builds does not exceed max build limit - Consistently(BuildsRunning(BuildPhase(ns, buildA), BuildPhase(ns, buildB), BuildPhase(ns, buildC)), TestTimeoutShort, 10*time.Second).Should(Satisfy(notExceedsMaxBuildLimit)) + g.Consistently(BuildsRunning(BuildPhase(t, ctx, ns, buildA), BuildPhase(t, ctx, ns, buildB), BuildPhase(t, ctx, ns, buildC)), TestTimeoutShort, 10*time.Second).Should(Satisfy(notExceedsMaxBuildLimit)) limit++ } // make sure we have verified max build limit at least once if limit == 0 { - t.Error(errors.New(fmt.Sprintf("Unexpected build phase '%s' for %s - not able to verify max builds limit", BuildPhase(ns, buildA)(), buildA))) + t.Error(errors.New(fmt.Sprintf("Unexpected build phase '%s' for %s - not able to verify max builds limit", BuildPhase(t, ctx, ns, buildA)(), buildA))) t.FailNow() } // verify that all builds are successful - Eventually(BuildPhase(ns, buildA), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded)) - Eventually(KitPhase(ns, buildA), TestTimeoutLong).Should(Equal(v1.IntegrationKitPhaseReady)) - Eventually(BuildPhase(ns, buildB), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded)) - Eventually(KitPhase(ns, buildB), TestTimeoutLong).Should(Equal(v1.IntegrationKitPhaseReady)) - Eventually(BuildPhase(ns, buildC), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded)) - Eventually(KitPhase(ns, buildC), TestTimeoutLong).Should(Equal(v1.IntegrationKitPhaseReady)) + g.Eventually(BuildPhase(t, ctx, ns, buildA), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded)) + g.Eventually(KitPhase(t, ctx, ns, buildA), TestTimeoutLong).Should(Equal(v1.IntegrationKitPhaseReady)) + g.Eventually(BuildPhase(t, ctx, ns, buildB), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded)) + g.Eventually(KitPhase(t, ctx, ns, buildB), TestTimeoutLong).Should(Equal(v1.IntegrationKitPhaseReady)) + g.Eventually(BuildPhase(t, ctx, ns, buildC), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded)) + g.Eventually(KitPhase(t, ctx, ns, buildC), TestTimeoutLong).Should(Equal(v1.IntegrationKitPhaseReady)) }) } func TestMaxBuildLimitWaitingBuilds(t *testing.T) { - WithNewTestNamespace(t, func(ns string) { - createOperator(ns, "8m0s", "--global", "--force") + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + createOperator(t, ctx, g, ns, "8m0s", "--global", "--force") - pl := Platform(ns)() + pl := Platform(t, ctx, ns)() // set maximum number of running builds and order strategy pl.Spec.Build.MaxRunningBuilds = 1 pl.Spec.Build.BuildConfiguration.OrderStrategy = v1.BuildOrderStrategyFIFO - if err := TestClient().Update(TestContext, pl); err != nil { + if err := TestClient(t).Update(ctx, pl); err != nil { t.Error(err) t.FailNow() } @@ -308,7 +309,7 @@ func TestMaxBuildLimitWaitingBuilds(t *testing.T) { buildB := "integration-b" buildC := "integration-c" - doKitBuildInNamespace(buildA, ns, TestTimeoutShort, kitOptions{ + doKitBuildInNamespace(t, ctx, g, buildA, ns, TestTimeoutShort, kitOptions{ operatorID: fmt.Sprintf("camel-k-%s", ns), dependencies: []string{ "camel:timer", "camel:log", @@ -318,7 +319,7 @@ func TestMaxBuildLimitWaitingBuilds(t *testing.T) { }, }, v1.BuildPhaseRunning, v1.IntegrationKitPhaseBuildRunning) - doKitBuildInNamespace(buildB, ns, TestTimeoutShort, kitOptions{ + doKitBuildInNamespace(t, ctx, g, buildB, ns, TestTimeoutShort, kitOptions{ operatorID: fmt.Sprintf("camel-k-%s", ns), dependencies: []string{ "camel:cron", "camel:log", "camel:joor", @@ -328,7 +329,7 @@ func TestMaxBuildLimitWaitingBuilds(t *testing.T) { }, }, v1.BuildPhaseScheduling, v1.IntegrationKitPhaseNone) - doKitBuildInNamespace(buildC, ns, TestTimeoutShort, kitOptions{ + doKitBuildInNamespace(t, ctx, g, buildC, ns, TestTimeoutShort, kitOptions{ operatorID: fmt.Sprintf("camel-k-%s", ns), dependencies: []string{ "camel:timer", "camel:log", "camel:joor", "camel:http", @@ -339,24 +340,24 @@ func TestMaxBuildLimitWaitingBuilds(t *testing.T) { }, v1.BuildPhaseScheduling, v1.IntegrationKitPhaseNone) // verify that last build is waiting - Eventually(BuildConditions(ns, buildC), TestTimeoutMedium).ShouldNot(BeNil()) - Eventually( - BuildCondition(ns, buildC, v1.BuildConditionType(v1.BuildConditionScheduled))().Status, + g.Eventually(BuildConditions(t, ctx, ns, buildC), TestTimeoutMedium).ShouldNot(BeNil()) + g.Eventually( + BuildCondition(t, ctx, ns, buildC, v1.BuildConditionType(v1.BuildConditionScheduled))().Status, TestTimeoutShort).Should(Equal(corev1.ConditionFalse)) - Eventually( - BuildCondition(ns, buildC, v1.BuildConditionType(v1.BuildConditionScheduled))().Reason, + g.Eventually( + BuildCondition(t, ctx, ns, buildC, v1.BuildConditionType(v1.BuildConditionScheduled))().Reason, TestTimeoutShort).Should(Equal(v1.BuildConditionWaitingReason)) // verify that last build is scheduled - Eventually(BuildPhase(ns, buildC), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded)) - Eventually(KitPhase(ns, buildC), TestTimeoutLong).Should(Equal(v1.IntegrationKitPhaseReady)) + g.Eventually(BuildPhase(t, ctx, ns, buildC), TestTimeoutLong).Should(Equal(v1.BuildPhaseSucceeded)) + g.Eventually(KitPhase(t, ctx, ns, buildC), TestTimeoutLong).Should(Equal(v1.IntegrationKitPhaseReady)) - Eventually(BuildConditions(ns, buildC), TestTimeoutLong).ShouldNot(BeNil()) - Eventually( - BuildCondition(ns, buildC, v1.BuildConditionType(v1.BuildConditionScheduled))().Status, + g.Eventually(BuildConditions(t, ctx, ns, buildC), TestTimeoutLong).ShouldNot(BeNil()) + g.Eventually( + BuildCondition(t, ctx, ns, buildC, v1.BuildConditionType(v1.BuildConditionScheduled))().Status, TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually( - BuildCondition(ns, buildC, v1.BuildConditionType(v1.BuildConditionScheduled))().Reason, + g.Eventually( + BuildCondition(t, ctx, ns, buildC, v1.BuildConditionType(v1.BuildConditionScheduled))().Reason, TestTimeoutShort).Should(Equal(v1.BuildConditionReadyReason)) }) } @@ -392,22 +393,22 @@ func doKitFullBuild(t *testing.T, name string, buildTimeout string, testTimeout options kitOptions, buildPhase v1.BuildPhase, kitPhase v1.IntegrationKitPhase) { t.Helper() - WithNewTestNamespace(t, func(ns string) { - createOperator(ns, buildTimeout) - doKitBuildInNamespace(name, ns, testTimeout, options, buildPhase, kitPhase) + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + createOperator(t, ctx, g, ns, buildTimeout) + doKitBuildInNamespace(t, ctx, g, name, ns, testTimeout, options, buildPhase, kitPhase) }) } -func createOperator(ns string, buildTimeout string, installArgs ...string) { +func createOperator(t *testing.T, ctx context.Context, g *WithT, ns string, buildTimeout string, installArgs ...string) { args := []string{"--build-timeout", buildTimeout} args = append(args, installArgs...) operatorID := fmt.Sprintf("camel-k-%s", ns) - Expect(KamelInstallWithID(operatorID, ns, args...).Execute()).To(Succeed()) - Eventually(PlatformPhase(ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns, args...)).To(Succeed()) + g.Eventually(PlatformPhase(t, ctx, ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) } -func doKitBuildInNamespace(name string, ns string, testTimeout time.Duration, options kitOptions, buildPhase v1.BuildPhase, kitPhase v1.IntegrationKitPhase) { +func doKitBuildInNamespace(t *testing.T, ctx context.Context, g *WithT, name string, ns string, testTimeout time.Duration, options kitOptions, buildPhase v1.BuildPhase, kitPhase v1.IntegrationKitPhase) { buildKitArgs := []string{"kit", "create", name, "-n", ns} for _, dependency := range options.dependencies { @@ -423,13 +424,13 @@ func doKitBuildInNamespace(name string, ns string, testTimeout time.Duration, op buildKitArgs = append(buildKitArgs, "--operator-id", fmt.Sprintf("camel-k-%s", ns)) } - Expect(Kamel(buildKitArgs...).Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, buildKitArgs...).Execute()).To(Succeed()) - Eventually(Build(ns, name), testTimeout).ShouldNot(BeNil()) + g.Eventually(Build(t, ctx, ns, name), testTimeout).ShouldNot(BeNil()) if buildPhase != v1.BuildPhaseNone { - Eventually(BuildPhase(ns, name), testTimeout).Should(Equal(buildPhase)) + g.Eventually(BuildPhase(t, ctx, ns, name), testTimeout).Should(Equal(buildPhase)) } if kitPhase != v1.IntegrationKitPhaseNone { - Eventually(KitPhase(ns, name), testTimeout).Should(Equal(kitPhase)) + g.Eventually(KitPhase(t, ctx, ns, name), testTimeout).Should(Equal(kitPhase)) } } diff --git a/e2e/builder/registry_test.go b/e2e/builder/registry_test.go index b587e8262c..4eb413cb5b 100644 --- a/e2e/builder/registry_test.go +++ b/e2e/builder/registry_test.go @@ -23,6 +23,7 @@ limitations under the License. package builder import ( + "context" "os" "testing" @@ -41,22 +42,16 @@ func TestRunWithDockerHubRegistry(t *testing.T) { return } - WithNewTestNamespace(t, func(ns string) { + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { operatorID := "camel-k-docker-hub" - Expect(KamelInstallWithID(operatorID, ns, - "--registry", "docker.io", - "--organization", user, - "--registry-auth-username", user, - "--registry-auth-password", pass, - "--cluster-type", "kubernetes"). - Execute()).To(Succeed()) - - Expect(KamelRunWithID(operatorID, ns, "files/groovy.groovy").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "groovy"), TestTimeoutLong).Should(Equal(v1.PodRunning)) - Eventually(IntegrationLogs(ns, "groovy"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - Eventually(IntegrationPodImage(ns, "groovy"), TestTimeoutShort).Should(HavePrefix("docker.io")) - - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns, "--registry", "docker.io", "--organization", user, "--registry-auth-username", user, "--registry-auth-password", pass, "--cluster-type", "kubernetes")).To(Succeed()) + + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/groovy.groovy").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "groovy"), TestTimeoutLong).Should(Equal(v1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, "groovy"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + g.Eventually(IntegrationPodImage(t, ctx, ns, "groovy"), TestTimeoutShort).Should(HavePrefix("docker.io")) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) } @@ -69,21 +64,15 @@ func TestRunWithGithubPackagesRegistry(t *testing.T) { return } - WithNewTestNamespace(t, func(ns string) { + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { operatorID := "camel-k-github-registry" - Expect(KamelInstallWithID(operatorID, ns, - "--registry", "docker.pkg.github.com", - "--organization", repo, - "--registry-auth-username", user, - "--registry-auth-password", pass, - "--cluster-type", "kubernetes"). - Execute()).To(Succeed()) - - Expect(KamelRunWithID(operatorID, ns, "files/groovy.groovy").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "groovy"), TestTimeoutLong).Should(Equal(v1.PodRunning)) - Eventually(IntegrationLogs(ns, "groovy"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - Eventually(IntegrationPodImage(ns, "groovy"), TestTimeoutShort).Should(HavePrefix("docker.pkg.github.com")) - - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns, "--registry", "docker.pkg.github.com", "--organization", repo, "--registry-auth-username", user, "--registry-auth-password", pass, "--cluster-type", "kubernetes")).To(Succeed()) + + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/groovy.groovy").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "groovy"), TestTimeoutLong).Should(Equal(v1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, "groovy"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + g.Eventually(IntegrationPodImage(t, ctx, ns, "groovy"), TestTimeoutShort).Should(HavePrefix("docker.pkg.github.com")) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) } diff --git a/e2e/common/cli/bind_test.go b/e2e/common/cli/bind_test.go index f9a5263112..90daf7fdbd 100644 --- a/e2e/common/cli/bind_test.go +++ b/e2e/common/cli/bind_test.go @@ -23,6 +23,7 @@ limitations under the License. package cli import ( + "context" "testing" corev1 "k8s.io/api/core/v1" @@ -33,33 +34,33 @@ import ( ) func TestKamelCLIBind(t *testing.T) { - RegisterTestingT(t) - - kameletName := "test-timer-source" - Expect(CreateTimerKamelet(ns, kameletName)()).To(Succeed()) - - t.Run("bind timer to log", func(t *testing.T) { - Expect(KamelBindWithID(operatorID, ns, kameletName, "log:info", "-p", "source.message=helloTest").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "test-timer-source-to-log"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns, "test-timer-source-to-log")).Should(ContainSubstring("Body: helloTest")) - Expect(KamelBindWithID(operatorID, ns, "test-timer-source", "log:info", "-p", "source.message=newText").Execute()).To(Succeed()) - Eventually(IntegrationLogs(ns, "test-timer-source-to-log")).Should(ContainSubstring("Body: newText")) + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + kameletName := "test-timer-source" + g.Expect(CreateTimerKamelet(t, ctx, operatorID, ns, kameletName)()).To(Succeed()) + + t.Run("bind timer to log", func(t *testing.T) { + g.Expect(KamelBindWithID(t, ctx, operatorID, ns, kameletName, "log:info", "-p", "source.message=helloTest").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "test-timer-source-to-log"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, "test-timer-source-to-log")).Should(ContainSubstring("Body: helloTest")) + g.Expect(KamelBindWithID(t, ctx, operatorID, ns, "test-timer-source", "log:info", "-p", "source.message=newText").Execute()).To(Succeed()) + g.Eventually(IntegrationLogs(t, ctx, ns, "test-timer-source-to-log")).Should(ContainSubstring("Body: newText")) + }) + + t.Run("unsuccessful binding, no property", func(t *testing.T) { + g.Expect(KamelBindWithID(t, ctx, operatorID, ns, operatorNS+"/timer-source", "log:info").Execute()).NotTo(Succeed()) + }) + + t.Run("bind uris", func(t *testing.T) { + g.Expect(KamelBindWithID(t, ctx, operatorID, ns, "timer:foo", "log:bar").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "timer-to-log"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, "timer-to-log")).Should(ContainSubstring("Body is null")) + }) + + t.Run("bind with custom SA", func(t *testing.T) { + g.Expect(KamelBindWithID(t, ctx, operatorID, ns, "timer:foo", "log:bar", "--service-account", "my-service-account").Execute()).To(Succeed()) + g.Eventually(IntegrationSpecSA(t, ctx, ns, "timer-to-log")).Should(Equal("my-service-account")) + }) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) - - t.Run("unsuccessful binding, no property", func(t *testing.T) { - Expect(KamelBindWithID(operatorID, ns, "timer-source", "log:info").Execute()).NotTo(Succeed()) - }) - - t.Run("bind uris", func(t *testing.T) { - Expect(KamelBindWithID(operatorID, ns, "timer:foo", "log:bar").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "timer-to-log"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns, "timer-to-log")).Should(ContainSubstring("Body is null")) - }) - - t.Run("bind with custom SA", func(t *testing.T) { - Expect(KamelBindWithID(operatorID, ns, "timer:foo", "log:bar", "--service-account", "my-service-account").Execute()).To(Succeed()) - Eventually(IntegrationSpecSA(ns, "timer-to-log")).Should(Equal("my-service-account")) - }) - - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) } diff --git a/e2e/common/cli/config_test.go b/e2e/common/cli/config_test.go index c86228b9f3..e29297616d 100644 --- a/e2e/common/cli/config_test.go +++ b/e2e/common/cli/config_test.go @@ -23,6 +23,7 @@ limitations under the License. package cli import ( + "context" "os" "strings" "testing" @@ -31,6 +32,7 @@ import ( . "github.com/onsi/gomega" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" . "github.com/apache/camel-k/v2/e2e/support" v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" @@ -38,30 +40,30 @@ import ( ) func TestKamelCLIConfig(t *testing.T) { - RegisterTestingT(t) + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + t.Run("check default namespace", func(t *testing.T) { + _, err := os.Stat(cmd.DefaultConfigLocation) + assert.True(t, os.IsNotExist(err), "No file at "+cmd.DefaultConfigLocation+" was expected") + t.Cleanup(func() { os.Remove(cmd.DefaultConfigLocation) }) + g.Expect(Kamel(t, ctx, "config", "--default-namespace", ns).Execute()).To(Succeed()) + _, err = os.Stat(cmd.DefaultConfigLocation) + require.NoError(t, err, "A file at "+cmd.DefaultConfigLocation+" was expected") + g.Expect(Kamel(t, ctx, "run", "--operator-id", operatorID, "files/yaml.yaml").Execute()).To(Succeed()) - t.Run("check default namespace", func(t *testing.T) { - _, err := os.Stat(cmd.DefaultConfigLocation) - assert.True(t, os.IsNotExist(err), "No file at "+cmd.DefaultConfigLocation+" was expected") - t.Cleanup(func() { os.Remove(cmd.DefaultConfigLocation) }) - Expect(Kamel("config", "--default-namespace", ns).Execute()).To(Succeed()) - _, err = os.Stat(cmd.DefaultConfigLocation) - assert.Nil(t, err, "A file at "+cmd.DefaultConfigLocation+" was expected") - Expect(Kamel("run", "--operator-id", operatorID, "files/yaml.yaml").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "yaml"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "yaml", v1.IntegrationConditionReady), TestTimeoutShort). + Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "yaml"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - Eventually(IntegrationPodPhase(ns, "yaml"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "yaml", v1.IntegrationConditionReady), TestTimeoutShort). - Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "yaml"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + // first line of the integration logs + logs := strings.Split(IntegrationLogs(t, ctx, ns, "yaml")(), "\n")[0] + podName := IntegrationPod(t, ctx, ns, "yaml")().Name - // first line of the integration logs - logs := strings.Split(IntegrationLogs(ns, "yaml")(), "\n")[0] - podName := IntegrationPod(ns, "yaml")().Name + logsCLI := GetOutputStringAsync(Kamel(t, ctx, "log", "yaml")) + g.Eventually(logsCLI).Should(ContainSubstring("Monitoring pod " + podName)) + g.Eventually(logsCLI).Should(ContainSubstring(logs)) + }) - logsCLI := GetOutputStringAsync(Kamel("log", "yaml")) - Eventually(logsCLI).Should(ContainSubstring("Monitoring pod " + podName)) - Eventually(logsCLI).Should(ContainSubstring(logs)) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) - - Expect(Kamel("delete", "--all").Execute()).To(Succeed()) } diff --git a/e2e/common/cli/default.go b/e2e/common/cli/default.go index dbd4ae0b22..c6174d79c6 100644 --- a/e2e/common/cli/default.go +++ b/e2e/common/cli/default.go @@ -20,7 +20,10 @@ limitations under the License. package cli -import "github.com/apache/camel-k/v2/e2e/support" +import ( + "github.com/apache/camel-k/v2/e2e/support" + "github.com/apache/camel-k/v2/pkg/platform" +) -var ns = support.GetEnvOrDefault("CAMEL_K_TEST_NAMESPACE", support.GetCIProcessID()) -var operatorID = support.GetEnvOrDefault("CAMEL_K_OPERATOR_ID", support.GetCIProcessID()) +var operatorNS = support.TestDefaultNamespace + "-cli" +var operatorID = platform.DefaultPlatformName + "-cli" diff --git a/e2e/common/cli/delete_test.go b/e2e/common/cli/delete_test.go index ea69bde925..2ed2aba0e6 100644 --- a/e2e/common/cli/delete_test.go +++ b/e2e/common/cli/delete_test.go @@ -23,6 +23,7 @@ limitations under the License. package cli import ( + "context" "testing" corev1 "k8s.io/api/core/v1" @@ -33,47 +34,47 @@ import ( ) func TestKamelCLIDelete(t *testing.T) { - RegisterTestingT(t) + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + t.Run("delete running integration", func(t *testing.T) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/yaml.yaml").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "yaml"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Expect(Kamel(t, ctx, "delete", "yaml", "-n", ns).Execute()).To(Succeed()) + g.Eventually(Integration(t, ctx, ns, "yaml")).Should(BeNil()) + g.Eventually(IntegrationPod(t, ctx, ns, "yaml"), TestTimeoutLong).Should(BeNil()) + }) - t.Run("delete running integration", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "files/yaml.yaml").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "yaml"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Expect(Kamel("delete", "yaml", "-n", ns).Execute()).To(Succeed()) - Eventually(Integration(ns, "yaml")).Should(BeNil()) - Eventually(IntegrationPod(ns, "yaml"), TestTimeoutLong).Should(BeNil()) - }) + t.Run("delete building integration", func(t *testing.T) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/yaml.yaml").Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "delete", "yaml", "-n", ns).Execute()).To(Succeed()) + g.Eventually(Integration(t, ctx, ns, "yaml")).Should(BeNil()) + g.Eventually(IntegrationPod(t, ctx, ns, "yaml"), TestTimeoutLong).Should(BeNil()) + }) - t.Run("delete building integration", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "files/yaml.yaml").Execute()).To(Succeed()) - Expect(Kamel("delete", "yaml", "-n", ns).Execute()).To(Succeed()) - Eventually(Integration(ns, "yaml")).Should(BeNil()) - Eventually(IntegrationPod(ns, "yaml"), TestTimeoutLong).Should(BeNil()) - }) + t.Run("delete several integrations", func(t *testing.T) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/yaml.yaml").Execute()).To(Succeed()) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "yaml"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "java"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Expect(Kamel(t, ctx, "delete", "yaml", "-n", ns).Execute()).To(Succeed()) + g.Eventually(Integration(t, ctx, ns, "yaml")).Should(BeNil()) + g.Eventually(IntegrationPod(t, ctx, ns, "yaml"), TestTimeoutLong).Should(BeNil()) + g.Expect(Kamel(t, ctx, "delete", "java", "-n", ns).Execute()).To(Succeed()) + g.Eventually(Integration(t, ctx, ns, "java")).Should(BeNil()) + g.Eventually(IntegrationPod(t, ctx, ns, "java"), TestTimeoutLong).Should(BeNil()) + }) - t.Run("delete several integrations", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "files/yaml.yaml").Execute()).To(Succeed()) - Expect(KamelRunWithID(operatorID, ns, "files/Java.java").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "yaml"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationPodPhase(ns, "java"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Expect(Kamel("delete", "yaml", "-n", ns).Execute()).To(Succeed()) - Eventually(Integration(ns, "yaml")).Should(BeNil()) - Eventually(IntegrationPod(ns, "yaml"), TestTimeoutLong).Should(BeNil()) - Expect(Kamel("delete", "java", "-n", ns).Execute()).To(Succeed()) - Eventually(Integration(ns, "java")).Should(BeNil()) - Eventually(IntegrationPod(ns, "java"), TestTimeoutLong).Should(BeNil()) - }) + t.Run("delete all integrations", func(t *testing.T) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/yaml.yaml").Execute()).To(Succeed()) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "yaml"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "java"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + g.Eventually(Integration(t, ctx, ns, "yaml")).Should(BeNil()) + g.Eventually(IntegrationPod(t, ctx, ns, "yaml"), TestTimeoutLong).Should(BeNil()) + g.Eventually(Integration(t, ctx, ns, "java")).Should(BeNil()) + g.Eventually(IntegrationPod(t, ctx, ns, "java"), TestTimeoutLong).Should(BeNil()) + }) - t.Run("delete all integrations", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "files/yaml.yaml").Execute()).To(Succeed()) - Expect(KamelRunWithID(operatorID, ns, "files/Java.java").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "yaml"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationPodPhase(ns, "java"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) - Eventually(Integration(ns, "yaml")).Should(BeNil()) - Eventually(IntegrationPod(ns, "yaml"), TestTimeoutLong).Should(BeNil()) - Eventually(Integration(ns, "java")).Should(BeNil()) - Eventually(IntegrationPod(ns, "java"), TestTimeoutLong).Should(BeNil()) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) - - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) } diff --git a/e2e/common/cli/describe_test.go b/e2e/common/cli/describe_test.go index 567801a557..f4cf6ce9bb 100644 --- a/e2e/common/cli/describe_test.go +++ b/e2e/common/cli/describe_test.go @@ -23,6 +23,7 @@ limitations under the License. package cli import ( + "context" "fmt" "regexp" "testing" @@ -36,49 +37,50 @@ import ( ) func TestKamelCliDescribe(t *testing.T) { - RegisterTestingT(t) + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/yaml.yaml").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "yaml"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Expect(KamelRunWithID(operatorID, ns, "files/yaml.yaml").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "yaml"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + t.Run("Test kamel describe integration", func(t *testing.T) { + integration := GetOutputString(Kamel(t, ctx, "describe", "integration", "yaml", "-n", ns)) + r, _ := regexp.Compile("(?sm).*Name:\\s+yaml.*") + g.Expect(integration).To(MatchRegexp(r.String())) - t.Run("Test kamel describe integration", func(t *testing.T) { - integration := GetOutputString(Kamel("describe", "integration", "yaml", "-n", ns)) - r, _ := regexp.Compile("(?sm).*Name:\\s+yaml.*") - Expect(integration).To(MatchRegexp(r.String())) + r, _ = regexp.Compile("(?sm).*Phase:\\s+Running.*") + g.Expect(integration).To(MatchRegexp(r.String())) - r, _ = regexp.Compile("(?sm).*Phase:\\s+Running.*") - Expect(integration).To(MatchRegexp(r.String())) + g.Expect(integration).To(ContainSubstring("Dependencies:")) + g.Expect(integration).To(ContainSubstring("Conditions:")) + }) - Expect(integration).To(ContainSubstring("Dependencies:")) - Expect(integration).To(ContainSubstring("Conditions:")) - }) + t.Run("Test kamel describe integration kit", func(t *testing.T) { + kitName := Integration(t, ctx, ns, "yaml")().Status.IntegrationKit.Name + kitNamespace := Integration(t, ctx, ns, "yaml")().Status.IntegrationKit.Namespace + kit := GetOutputString(Kamel(t, ctx, "describe", "kit", kitName, "-n", kitNamespace)) - t.Run("Test kamel describe integration kit", func(t *testing.T) { - kitName := Integration(ns, "yaml")().Status.IntegrationKit.Name - kit := GetOutputString(Kamel("describe", "kit", kitName, "-n", ns)) + r, _ := regexp.Compile("(?sm).*Namespace:\\s+" + kitNamespace + ".*") + g.Expect(kit).To(MatchRegexp(r.String())) - r, _ := regexp.Compile("(?sm).*Namespace:\\s+" + ns + ".*") - Expect(kit).To(MatchRegexp(r.String())) + r, _ = regexp.Compile("(?sm).*Runtime Version:\\s+" + defaults.DefaultRuntimeVersion + ".*") + g.Expect(kit).To(MatchRegexp(r.String())) - r, _ = regexp.Compile("(?sm).*Runtime Version:\\s+" + defaults.DefaultRuntimeVersion + ".*") - Expect(kit).To(MatchRegexp(r.String())) + g.Expect(kit).To(ContainSubstring("camel-quarkus-core")) - Expect(kit).To(ContainSubstring("camel-quarkus-core")) + g.Expect(kit).To(ContainSubstring("Artifacts:")) + g.Expect(kit).To(ContainSubstring("Dependencies:")) + }) - Expect(kit).To(ContainSubstring("Artifacts:")) - Expect(kit).To(ContainSubstring("Dependencies:")) - }) + t.Run("Test kamel describe integration platform", func(t *testing.T) { + platform := GetOutputString(Kamel(t, ctx, "describe", "platform", operatorID, "-n", operatorNS)) + g.Expect(platform).To(ContainSubstring(fmt.Sprintf("Name: %s", operatorID))) - t.Run("Test kamel describe integration platform", func(t *testing.T) { - platform := GetOutputString(Kamel("describe", "platform", operatorID, "-n", ns)) - Expect(platform).To(ContainSubstring(fmt.Sprintf("Name: %s", operatorID))) + r, _ := regexp.Compile("(?sm).*Namespace:\\s+" + operatorNS + ".*") + g.Expect(platform).To(MatchRegexp(r.String())) - r, _ := regexp.Compile("(?sm).*Namespace:\\s+" + ns + ".*") - Expect(platform).To(MatchRegexp(r.String())) + r, _ = regexp.Compile("(?sm).*Runtime Version:\\s+" + defaults.DefaultRuntimeVersion + ".*") + g.Expect(platform).To(MatchRegexp(r.String())) + }) - r, _ = regexp.Compile("(?sm).*Runtime Version:\\s+" + defaults.DefaultRuntimeVersion + ".*") - Expect(platform).To(MatchRegexp(r.String())) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) - - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) } diff --git a/e2e/common/cli/dev_mode_test.go b/e2e/common/cli/dev_mode_test.go index f617bf7a53..0c84b46767 100644 --- a/e2e/common/cli/dev_mode_test.go +++ b/e2e/common/cli/dev_mode_test.go @@ -37,120 +37,117 @@ import ( ) func TestRunDevMode(t *testing.T) { - RegisterTestingT(t) - - /* - * TODO - * The changing of the yaml file constant from "string" to "magic" is not being - * picked up when deploying on OCP4 and so the test is failing. - * - * Adding CAMEL_K_TEST_SKIP_PROBLEMATIC env var for the moment. - */ - if os.Getenv("CAMEL_K_TEST_SKIP_PROBLEMATIC") == "true" { - t.Skip("WARNING: Test marked as problematic ... skipping") - } - - t.Run("run yaml dev mode", func(t *testing.T) { - RegisterTestingT(t) - ctx, cancel := context.WithCancel(TestContext) - defer cancel() - piper, pipew := io.Pipe() - defer pipew.Close() - defer piper.Close() - - file := util.MakeTempCopy(t, "files/yaml.yaml") - name := RandomizedSuffixName("yaml") - - kamelRun := KamelRunWithContext(ctx, operatorID, ns, file, "--name", name, "--dev") - kamelRun.SetOut(pipew) - - logScanner := util.NewLogScanner(ctx, piper, `integration "`+name+`" in phase Running`, "Magicstring!", "Magicjordan!") - - args := os.Args - defer func() { os.Args = args }() - - os.Args = []string{"kamel", "run", "-n", ns, "--operator-id", operatorID, file, "--name", name, "--dev"} - go kamelRun.Execute() - - Eventually(logScanner.IsFound(`integration "`+name+`" in phase Running`), TestTimeoutMedium).Should(BeTrue()) - Eventually(logScanner.IsFound("Magicstring!"), TestTimeoutMedium).Should(BeTrue()) - Expect(logScanner.IsFound("Magicjordan!")()).To(BeFalse()) - - util.ReplaceInFile(t, file, "string!", "jordan!") - Eventually(logScanner.IsFound("Magicjordan!"), TestTimeoutMedium).Should(BeTrue()) - }) + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + /* + * TODO + * The changing of the yaml file constant from "string" to "magic" is not being + * picked up when deploying on OCP4 and so the test is failing. + * + * Adding CAMEL_K_TEST_SKIP_PROBLEMATIC env var for the moment. + */ + if os.Getenv("CAMEL_K_TEST_SKIP_PROBLEMATIC") == "true" { + t.Skip("WARNING: Test marked as problematic ... skipping") + } - t.Run("run yaml remote dev mode", func(t *testing.T) { - RegisterTestingT(t) - ctx, cancel := context.WithCancel(TestContext) - defer cancel() - piper, pipew := io.Pipe() - defer pipew.Close() - defer piper.Close() + t.Run("run yaml dev mode", func(t *testing.T) { + ctx, cancel := context.WithCancel(ctx) + defer cancel() + piper, pipew := io.Pipe() + defer pipew.Close() + defer piper.Close() - remoteFile := "https://raw.githubusercontent.com/apache/camel-k/b29333f0a878d5d09fb3965be8fe586d77dd95d0/e2e/common/files/yaml.yaml" - name := RandomizedSuffixName("yaml") - kamelRun := KamelRunWithContext(ctx, operatorID, ns, remoteFile, "--name", name, "--dev") - kamelRun.SetOut(pipew) + file := util.MakeTempCopy(t, "files/yaml.yaml") + name := RandomizedSuffixName("yaml") - logScanner := util.NewLogScanner(ctx, piper, "Magicstring!") + kamelRun := KamelRunWithContext(t, ctx, operatorID, ns, file, "--name", name, "--dev") + kamelRun.SetOut(pipew) - args := os.Args - defer func() { os.Args = args }() + logScanner := util.NewLogScanner(ctx, piper, `integration "`+name+`" in phase Running`, "Magicstring!", "Magicjordan!") - os.Args = []string{"kamel", "run", "-n", ns, "--operator-id", operatorID, remoteFile, "--name", name, "--dev"} + args := os.Args + defer func() { os.Args = args }() - go kamelRun.Execute() + os.Args = []string{"kamel", "run", "-n", ns, "--operator-id", operatorID, file, "--name", name, "--dev"} + go kamelRun.Execute() - Eventually(logScanner.IsFound("Magicstring!"), TestTimeoutMedium).Should(BeTrue()) - }) + g.Eventually(logScanner.IsFound(`integration "`+name+`" in phase Running`), TestTimeoutMedium).Should(BeTrue()) + g.Eventually(logScanner.IsFound("Magicstring!"), TestTimeoutMedium).Should(BeTrue()) + g.Expect(logScanner.IsFound("Magicjordan!")()).To(BeFalse()) - // This test makes sure that `kamel run --dev` runs in seconds after initial build is - // already done for the same integration. - t.Run("dev mode rebuild in seconds", func(t *testing.T) { - /* - * !!! NOTE !!! - * If you find this test flaky, instead of thinking it as simply unstable, investigate - * why it does not finish in a few seconds and remove the bottlenecks which are lagging - * the integration startup. - */ - RegisterTestingT(t) - name := RandomizedSuffixName("yaml") + util.ReplaceInFile(t, file, "string!", "jordan!") + g.Eventually(logScanner.IsFound("Magicjordan!"), TestTimeoutMedium).Should(BeTrue()) + }) - // First run (warm up) - Expect(KamelRunWithID(operatorID, ns, "files/yaml.yaml", "--name", name).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - Expect(Kamel("delete", name, "-n", ns).Execute()).To(Succeed()) - Eventually(Integration(ns, name)).Should(BeNil()) - Eventually(IntegrationPod(ns, name), TestTimeoutMedium).Should(BeNil()) + t.Run("run yaml remote dev mode", func(t *testing.T) { + ctx, cancel := context.WithCancel(ctx) + defer cancel() + piper, pipew := io.Pipe() + defer pipew.Close() + defer piper.Close() - // Second run (rebuild) - ctx, cancel := context.WithCancel(TestContext) - defer cancel() - piper, pipew := io.Pipe() - defer pipew.Close() - defer piper.Close() + remoteFile := "https://raw.githubusercontent.com/apache/camel-k/b29333f0a878d5d09fb3965be8fe586d77dd95d0/e2e/common/files/yaml.yaml" + name := RandomizedSuffixName("yaml") + kamelRun := KamelRunWithContext(t, ctx, operatorID, ns, remoteFile, "--name", name, "--dev") + kamelRun.SetOut(pipew) - file := util.MakeTempCopy(t, "files/yaml.yaml") + logScanner := util.NewLogScanner(ctx, piper, "Magicstring!") - kamelRun := KamelRunWithContext(ctx, operatorID, ns, file, "--name", name, "--dev") - kamelRun.SetOut(pipew) + args := os.Args + defer func() { os.Args = args }() - logScanner := util.NewLogScanner(ctx, piper, `integration "`+name+`" in phase Running`, "Magicstring!") + os.Args = []string{"kamel", "run", "-n", ns, "--operator-id", operatorID, remoteFile, "--name", name, "--dev"} - args := os.Args - defer func() { os.Args = args }() + go kamelRun.Execute() - os.Args = []string{"kamel", "run", "-n", ns, "--operator-id", operatorID, file, "--name", name, "--dev"} + g.Eventually(logScanner.IsFound("Magicstring!"), TestTimeoutMedium).Should(BeTrue()) + }) - go kamelRun.Execute() + // This test makes sure that `kamel run --dev` runs in seconds after initial build is + // already done for the same integration. + t.Run("dev mode rebuild in seconds", func(t *testing.T) { + /* + * !!! NOTE !!! + * If you find this test flaky, instead of thinking it as simply unstable, investigate + * why it does not finish in a few seconds and remove the bottlenecks which are lagging + * the integration startup. + */ + name := RandomizedSuffixName("yaml") - // Second run should start up within a few seconds - timeout := 10 * time.Second - Eventually(logScanner.IsFound(`integration "`+name+`" in phase Running`), timeout).Should(BeTrue()) - Eventually(logScanner.IsFound("Magicstring!"), timeout).Should(BeTrue()) - }) + // First run (warm up) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/yaml.yaml", "--name", name).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + g.Expect(Kamel(t, ctx, "delete", name, "-n", ns).Execute()).To(Succeed()) + g.Eventually(Integration(t, ctx, ns, name)).Should(BeNil()) + g.Eventually(IntegrationPod(t, ctx, ns, name), TestTimeoutMedium).Should(BeNil()) + + // Second run (rebuild) + ctx, cancel := context.WithCancel(ctx) + defer cancel() + piper, pipew := io.Pipe() + defer pipew.Close() + defer piper.Close() - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + file := util.MakeTempCopy(t, "files/yaml.yaml") + + kamelRun := KamelRunWithContext(t, ctx, operatorID, ns, file, "--name", name, "--dev") + kamelRun.SetOut(pipew) + + logScanner := util.NewLogScanner(ctx, piper, `integration "`+name+`" in phase Running`, "Magicstring!") + + args := os.Args + defer func() { os.Args = args }() + + os.Args = []string{"kamel", "run", "-n", ns, "--operator-id", operatorID, file, "--name", name, "--dev"} + + go kamelRun.Execute() + + // Second run should start up within a few seconds + timeout := 20 * time.Second + g.Eventually(logScanner.IsFound(`integration "`+name+`" in phase Running`), timeout).Should(BeTrue()) + g.Eventually(logScanner.IsFound("Magicstring!"), timeout).Should(BeTrue()) + }) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) } diff --git a/e2e/common/cli/duplicate_parameters_test.go b/e2e/common/cli/duplicate_parameters_test.go index 84af397ce8..4882d96aa3 100644 --- a/e2e/common/cli/duplicate_parameters_test.go +++ b/e2e/common/cli/duplicate_parameters_test.go @@ -33,9 +33,9 @@ import ( ) func TestDuplicateParameters(t *testing.T) { - RegisterTestingT(t) + g := NewWithT(t) - ctx, cancel := context.WithCancel(TestContext) + ctx, cancel := context.WithCancel(TestContext()) defer cancel() // run kamel to output the traits/configuration structure in json format to check the processed values @@ -52,5 +52,5 @@ func TestDuplicateParameters(t *testing.T) { outParams := `"traits":{"affinity":{"enabled":true},"camel":{"properties":["prop1 = true","prop2 = true","foo = bar"]},"pull-secret":{"enabled":true},"addons":{"telemetry":{"enabled":true}}}` - Expect(commOutput).To(ContainSubstring(outParams)) + g.Expect(commOutput).To(ContainSubstring(outParams)) } diff --git a/e2e/common/cli/get_test.go b/e2e/common/cli/get_test.go index e1a461b3be..c9b0ee3511 100644 --- a/e2e/common/cli/get_test.go +++ b/e2e/common/cli/get_test.go @@ -23,6 +23,7 @@ limitations under the License. package cli import ( + "context" "fmt" "testing" @@ -34,42 +35,46 @@ import ( ) func TestKamelCLIGet(t *testing.T) { - RegisterTestingT(t) - - t.Run("get integration", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "files/yaml.yaml").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "yaml"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - // regex is used for the compatibility of tests between OC and vanilla K8 - // kamel get may have different output depending on the platform - Eventually(IntegrationKit(ns, "yaml")).ShouldNot(Equal("")) - kitName := IntegrationKit(ns, "yaml")() - regex := fmt.Sprintf("^NAME\tPHASE\tKIT\n\\s*yaml\tRunning\t(%s/%s|%s)", ns, kitName, kitName) - Expect(GetOutputString(Kamel("get", "-n", ns))).To(MatchRegexp(regex)) - - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + + t.Run("get integration", func(t *testing.T) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/yaml.yaml").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "yaml"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + // regex is used for the compatibility of tests between OC and vanilla K8 + // kamel get may have different output depending on the platform + g.Eventually(IntegrationKit(t, ctx, ns, "yaml")).ShouldNot(Equal("")) + kitName := IntegrationKit(t, ctx, ns, "yaml")() + kitNamespace := IntegrationKitNamespace(t, ctx, ns, "yaml")() + regex := fmt.Sprintf("^NAME\tPHASE\tKIT\n\\s*yaml\tRunning\t(%s/%s|%s)", kitNamespace, kitName, kitName) + g.Expect(GetOutputString(Kamel(t, ctx, "get", "-n", ns))).To(MatchRegexp(regex)) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) + + t.Run("get several integrations", func(t *testing.T) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/yaml.yaml").Execute()).To(Succeed()) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "yaml"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "java"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + + g.Eventually(IntegrationKit(t, ctx, ns, "java")).ShouldNot(Equal("")) + g.Eventually(IntegrationKit(t, ctx, ns, "yaml")).ShouldNot(Equal("")) + kitName1 := IntegrationKit(t, ctx, ns, "java")() + kitName2 := IntegrationKit(t, ctx, ns, "yaml")() + kitNamespace1 := IntegrationKitNamespace(t, ctx, ns, "java")() + kitNamespace2 := IntegrationKitNamespace(t, ctx, ns, "yaml")() + regex := fmt.Sprintf("^NAME\tPHASE\tKIT\n\\s*java\tRunning\t"+ + "(%s/%s|%s)\n\\s*yaml\tRunning\t(%s/%s|%s)\n", kitNamespace1, kitName1, kitName1, kitNamespace2, kitName2, kitName2) + g.Expect(GetOutputString(Kamel(t, ctx, "get", "-n", ns))).To(MatchRegexp(regex)) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) + + t.Run("get no integrations", func(t *testing.T) { + g.Expect(GetOutputString(Kamel(t, ctx, "get", "-n", ns))).NotTo(ContainSubstring("Running")) + g.Expect(GetOutputString(Kamel(t, ctx, "get", "-n", ns))).NotTo(ContainSubstring("Building Kit")) + }) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) - - t.Run("get several integrations", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "files/yaml.yaml").Execute()).To(Succeed()) - Expect(KamelRunWithID(operatorID, ns, "files/Java.java").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "yaml"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationPodPhase(ns, "java"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - - Eventually(IntegrationKit(ns, "java")).ShouldNot(Equal("")) - Eventually(IntegrationKit(ns, "yaml")).ShouldNot(Equal("")) - kitName1 := IntegrationKit(ns, "java")() - kitName2 := IntegrationKit(ns, "yaml")() - regex := fmt.Sprintf("^NAME\tPHASE\tKIT\n\\s*java\tRunning\t"+ - "(%s/%s|%s)\n\\s*yaml\tRunning\t(%s/%s|%s)\n", ns, kitName1, kitName1, ns, kitName2, kitName2) - Expect(GetOutputString(Kamel("get", "-n", ns))).To(MatchRegexp(regex)) - - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) - }) - - t.Run("get no integrations", func(t *testing.T) { - Expect(GetOutputString(Kamel("get", "-n", ns))).NotTo(ContainSubstring("Running")) - Expect(GetOutputString(Kamel("get", "-n", ns))).NotTo(ContainSubstring("Building Kit")) - }) - - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) } diff --git a/e2e/common/cli/help_test.go b/e2e/common/cli/help_test.go index ac54e4b168..c51dd91e45 100644 --- a/e2e/common/cli/help_test.go +++ b/e2e/common/cli/help_test.go @@ -31,27 +31,28 @@ import ( ) func TestKamelCLIHelp(t *testing.T) { - RegisterTestingT(t) + ctx := TestContext() + g := NewWithT(t) t.Run("default help message", func(t *testing.T) { - helpMsg := GetOutputString(Kamel("help")) - Expect(helpMsg).To(ContainSubstring("Apache Camel K is a lightweight integration platform, born on Kubernetes")) - Expect(helpMsg).To(ContainSubstring("Usage:")) - Expect(helpMsg).To(ContainSubstring("Available Commands:")) - Expect(helpMsg).To(ContainSubstring("Flags:")) + helpMsg := GetOutputString(Kamel(t, ctx, "help")) + g.Expect(helpMsg).To(ContainSubstring("Apache Camel K is a lightweight integration platform, born on Kubernetes")) + g.Expect(helpMsg).To(ContainSubstring("Usage:")) + g.Expect(helpMsg).To(ContainSubstring("Available Commands:")) + g.Expect(helpMsg).To(ContainSubstring("Flags:")) }) t.Run("'get' command help (short flag)", func(t *testing.T) { - helpMsg := GetOutputString(Kamel("get", "-h")) - Expect(helpMsg).To(ContainSubstring("Get the status of integrations deployed on Kubernetes")) - Expect(helpMsg).To(ContainSubstring("Usage:")) - Expect(helpMsg).To(ContainSubstring("Flags:")) + helpMsg := GetOutputString(Kamel(t, ctx, "get", "-h")) + g.Expect(helpMsg).To(ContainSubstring("Get the status of integrations deployed on Kubernetes")) + g.Expect(helpMsg).To(ContainSubstring("Usage:")) + g.Expect(helpMsg).To(ContainSubstring("Flags:")) }) t.Run("'bind' command help (long flag)", func(t *testing.T) { - helpMsg := GetOutputString(Kamel("bind", "--help")) - Expect(helpMsg).To(ContainSubstring("Bind Kubernetes resources, such as Kamelets, in an integration flow.")) - Expect(helpMsg).To(ContainSubstring("kamel bind [source] [sink] ... [flags]")) - Expect(helpMsg).To(ContainSubstring("Global Flags:")) + helpMsg := GetOutputString(Kamel(t, ctx, "bind", "--help")) + g.Expect(helpMsg).To(ContainSubstring("Bind Kubernetes resources, such as Kamelets, in an integration flow.")) + g.Expect(helpMsg).To(ContainSubstring("kamel bind [source] [sink] ... [flags]")) + g.Expect(helpMsg).To(ContainSubstring("Global Flags:")) }) } diff --git a/e2e/common/cli/log_test.go b/e2e/common/cli/log_test.go index 3396948db6..38a2d34d72 100644 --- a/e2e/common/cli/log_test.go +++ b/e2e/common/cli/log_test.go @@ -23,33 +23,37 @@ limitations under the License. package cli import ( + "context" "strings" "testing" - . "github.com/apache/camel-k/v2/e2e/support" . "github.com/onsi/gomega" corev1 "k8s.io/api/core/v1" + + . "github.com/apache/camel-k/v2/e2e/support" ) func TestKamelCLILog(t *testing.T) { - RegisterTestingT(t) - - t.Run("check integration log", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "files/yaml.yaml", "--name", "log-yaml").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "log-yaml"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - // first line of the integration logs - firstLine := strings.Split(IntegrationLogs(ns, "log-yaml")(), "\n")[0] - podName := IntegrationPod(ns, "log-yaml")().Name - - logsCLI := GetOutputStringAsync(Kamel("log", "log-yaml", "-n", ns)) - Eventually(logsCLI).Should(ContainSubstring("Monitoring pod " + podName)) - Eventually(logsCLI).Should(ContainSubstring(firstLine)) - - logs := strings.Split(IntegrationLogs(ns, "log-yaml")(), "\n") - lastLine := logs[len(logs)-1] - - logsCLI = GetOutputStringAsync(Kamel("log", "log-yaml", "-n", ns, "--tail", "5")) - Eventually(logsCLI).Should(ContainSubstring("Monitoring pod " + podName)) - Eventually(logsCLI).Should(ContainSubstring(lastLine)) + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + t.Run("check integration log", func(t *testing.T) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/yaml.yaml", "--name", "log-yaml").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "log-yaml"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + // first line of the integration logs + firstLine := strings.Split(IntegrationLogs(t, ctx, ns, "log-yaml")(), "\n")[0] + podName := IntegrationPod(t, ctx, ns, "log-yaml")().Name + + logsCLI := GetOutputStringAsync(Kamel(t, ctx, "log", "log-yaml", "-n", ns)) + g.Eventually(logsCLI).Should(ContainSubstring("Monitoring pod " + podName)) + g.Eventually(logsCLI).Should(ContainSubstring(firstLine)) + + logs := strings.Split(IntegrationLogs(t, ctx, ns, "log-yaml")(), "\n") + lastLine := logs[len(logs)-1] + + logsCLI = GetOutputStringAsync(Kamel(t, ctx, "log", "log-yaml", "-n", ns, "--tail", "5")) + g.Eventually(logsCLI).Should(ContainSubstring("Monitoring pod " + podName)) + g.Eventually(logsCLI).Should(ContainSubstring(lastLine)) + }) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) } diff --git a/e2e/common/support/startup_test.go b/e2e/common/cli/main_test.go similarity index 51% rename from e2e/common/support/startup_test.go rename to e2e/common/cli/main_test.go index 27ed31f498..fafad4f139 100644 --- a/e2e/common/support/startup_test.go +++ b/e2e/common/cli/main_test.go @@ -20,32 +20,44 @@ See the License for the specific language governing permissions and limitations under the License. */ -package support +package cli import ( + "fmt" + "os" "testing" . "github.com/onsi/gomega" - corev1 "k8s.io/api/core/v1" . "github.com/apache/camel-k/v2/e2e/support" v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" ) -func TestCommonCamelKInstallStartup(t *testing.T) { - RegisterTestingT(t) - - ns := NewTestNamespace(false) - Expect(ns).ShouldNot(BeNil()) - // the namespace is dynamic if there is some collision - // we store this value as it will be used for cleaning in the teardown process - SaveCIProcessID(ns.GetName()) - // fail fast if something did not work writing the resource - Expect(GetCIProcessID()).ShouldNot(Equal("")) - - Expect(KamelInstallWithIDAndKameletCatalog(ns.GetName(), ns.GetName()).Execute()).To(Succeed()) - Eventually(OperatorPod(ns.GetName())).ShouldNot(BeNil()) - Eventually(Platform(ns.GetName())).ShouldNot(BeNil()) - Eventually(PlatformConditionStatus(ns.GetName(), v1.IntegrationPlatformConditionTypeCreated), TestTimeoutShort). - Should(Equal(corev1.ConditionTrue)) +func TestMain(m *testing.M) { + justCompile := GetEnvOrDefault("CAMEL_K_E2E_JUST_COMPILE", "false") + if justCompile == "true" { + os.Exit(m.Run()) + } + + g := NewGomega(func(message string, callerSkip ...int) { + fmt.Printf("Test setup failed! - %s\n", message) + }) + + var t *testing.T + + g.Expect(TestClient(t)).ShouldNot(BeNil()) + ctx := TestContext() + + // Install global operator for tests in this package, all tests must use this operatorID + g.Expect(NewNamedTestNamespace(t, ctx, operatorNS, false)).ShouldNot(BeNil()) + g.Expect(CopyCamelCatalog(t, ctx, operatorNS, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithIDAndKameletCatalog(t, ctx, operatorID, operatorNS, "--global", "--force")).To(Succeed()) + g.Eventually(SelectedPlatformPhase(t, ctx, operatorNS, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + + exitCode := m.Run() + + g.Expect(UninstallFromNamespace(t, ctx, operatorNS)) + g.Expect(DeleteNamespace(t, ctx, operatorNS)).To(Succeed()) + + os.Exit(exitCode) } diff --git a/e2e/common/cli/offline_commands_test.go b/e2e/common/cli/offline_commands_test.go index 0027e8b7d3..a6d506e408 100644 --- a/e2e/common/cli/offline_commands_test.go +++ b/e2e/common/cli/offline_commands_test.go @@ -26,33 +26,30 @@ import ( "io" "testing" - "github.com/stretchr/testify/assert" - . "github.com/apache/camel-k/v2/e2e/support" . "github.com/onsi/gomega" ) func TestKamelVersionWorksOffline(t *testing.T) { - RegisterTestingT(t) - - assert.Nil(t, Kamel("version", "--kube-config", "non-existent-kubeconfig-file").Execute()) + g := NewWithT(t) + g.Expect(Kamel(t, TestContext(), "version", "--kube-config", "non-existent-kubeconfig-file").Execute()).To(Succeed()) } func TestKamelHelpOptionWorksOffline(t *testing.T) { - RegisterTestingT(t) + g := NewWithT(t) - traitCmd := Kamel("run", "Xxx.java", "--help") + traitCmd := Kamel(t, TestContext(), "run", "Xxx.java", "--help") traitCmd.SetOut(io.Discard) - assert.Nil(t, traitCmd.Execute()) + g.Expect(traitCmd.Execute()).To(Succeed()) } func TestKamelCompletionWorksOffline(t *testing.T) { - RegisterTestingT(t) + g := NewWithT(t) - bashCmd := Kamel("completion", "bash", "--kube-config", "non-existent-kubeconfig-file") + bashCmd := Kamel(t, TestContext(), "completion", "bash", "--kube-config", "non-existent-kubeconfig-file") bashCmd.SetOut(io.Discard) - zshCmd := Kamel("completion", "zsh", "--kube-config", "non-existent-kubeconfig-file") + zshCmd := Kamel(t, TestContext(), "completion", "zsh", "--kube-config", "non-existent-kubeconfig-file") zshCmd.SetOut(io.Discard) - assert.Nil(t, bashCmd.Execute()) - assert.Nil(t, zshCmd.Execute()) + g.Expect(bashCmd.Execute()).To(Succeed()) + g.Expect(zshCmd.Execute()).To(Succeed()) } diff --git a/e2e/common/cli/run_test.go b/e2e/common/cli/run_test.go index 81ccbd330a..4a1a05cd44 100644 --- a/e2e/common/cli/run_test.go +++ b/e2e/common/cli/run_test.go @@ -23,6 +23,7 @@ limitations under the License. package cli import ( + "context" "os" "testing" @@ -39,183 +40,198 @@ import ( var sampleJar = "https://raw.githubusercontent.com/apache/camel-k/main/e2e/common/traits/files/jvm/sample-1.0.jar" func TestKamelCLIRun(t *testing.T) { - RegisterTestingT(t) - - t.Run("Examples from GitHub", func(t *testing.T) { - t.Run("Java", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, - "github:apache/camel-k-examples/generic-examples/languages/Sample.java").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "sample"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "sample", v1.IntegrationConditionReady), TestTimeoutShort). - Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "sample"), TestTimeoutShort).Should(ContainSubstring("Hello Camel K!")) - Eventually(DeleteIntegrations(ns), TestTimeoutLong).Should(Equal(0)) - }) - - t.Run("Java (RAW)", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, - "https://raw.githubusercontent.com/apache/camel-k-examples/main/generic-examples/languages/Sample.java").Execute()). - To(Succeed()) - Eventually(IntegrationPodPhase(ns, "sample"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "sample", v1.IntegrationConditionReady), TestTimeoutShort). - Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "sample"), TestTimeoutShort).Should(ContainSubstring("Hello Camel K!")) - Eventually(DeleteIntegrations(ns), TestTimeoutLong).Should(Equal(0)) + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + + t.Run("Examples from GitHub", func(t *testing.T) { + t.Run("Java", func(t *testing.T) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, + "github:apache/camel-k-examples/generic-examples/languages/Sample.java").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "sample"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "sample", v1.IntegrationConditionReady), TestTimeoutShort). + Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "sample"), TestTimeoutShort).Should(ContainSubstring("Hello Camel K!")) + g.Eventually(DeleteIntegrations(t, ctx, ns), TestTimeoutLong).Should(Equal(0)) + }) + + t.Run("Java (RAW)", func(t *testing.T) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, + "https://raw.githubusercontent.com/apache/camel-k-examples/main/generic-examples/languages/Sample.java").Execute()). + To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "sample"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "sample", v1.IntegrationConditionReady), TestTimeoutShort). + Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "sample"), TestTimeoutShort).Should(ContainSubstring("Hello Camel K!")) + g.Eventually(DeleteIntegrations(t, ctx, ns), TestTimeoutLong).Should(Equal(0)) + }) + + t.Run("Java (branch)", func(t *testing.T) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, + "github:apache/camel-k-examples/generic-examples/languages/Sample.java?branch=main").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "sample"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "sample", v1.IntegrationConditionReady), TestTimeoutShort). + Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "sample"), TestTimeoutShort).Should(ContainSubstring("Hello Camel K!")) + g.Eventually(DeleteIntegrations(t, ctx, ns), TestTimeoutLong).Should(Equal(0)) + }) + + // GIST does not like GITHUB_TOKEN apparently, we must temporarily remove it + os.Setenv("GITHUB_TOKEN_TMP", os.Getenv("GITHUB_TOKEN")) + os.Unsetenv("GITHUB_TOKEN") + + t.Run("Gist (ID)", func(t *testing.T) { + name := RandomizedSuffixName("github-gist-id") + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "--name", name, + "gist:e2c3f9a5fd0d9e79b21b04809786f17a").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort). + Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Tick!")) + g.Eventually(DeleteIntegrations(t, ctx, ns), TestTimeoutLong).Should(Equal(0)) + }) + + t.Run("Gist (URL)", func(t *testing.T) { + name := RandomizedSuffixName("github-gist-url") + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "--name", name, + "https://gist.github.com/lburgazzoli/e2c3f9a5fd0d9e79b21b04809786f17a").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort). + Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Tick!")) + g.Eventually(DeleteIntegrations(t, ctx, ns), TestTimeoutLong).Should(Equal(0)) + }) + + // Revert GITHUB TOKEN + os.Setenv("GITHUB_TOKEN", os.Getenv("GITHUB_TOKEN_TMP")) + os.Unsetenv("GITHUB_TOKEN_TMP") + + // Clean up + g.Eventually(DeleteIntegrations(t, ctx, ns), TestTimeoutLong).Should(Equal(0)) }) - t.Run("Java (branch)", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, - "github:apache/camel-k-examples/generic-examples/languages/Sample.java?branch=main").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "sample"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "sample", v1.IntegrationConditionReady), TestTimeoutShort). + t.Run("Run and update", func(t *testing.T) { + name := RandomizedSuffixName("run") + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/run.yaml", "--name", name).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort). Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "sample"), TestTimeoutShort).Should(ContainSubstring("Hello Camel K!")) - Eventually(DeleteIntegrations(ns), TestTimeoutLong).Should(Equal(0)) - }) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magic default")) - // GIST does not like GITHUB_TOKEN apparently, we must temporary remove it - os.Setenv("GITHUB_TOKEN_TMP", os.Getenv("GITHUB_TOKEN")) - os.Unsetenv("GITHUB_TOKEN") + // Re-run the Integration with an updated configuration + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/run.yaml", "--name", name, "-p", "property=value").Execute()). + To(Succeed()) - t.Run("Gist (ID)", func(t *testing.T) { - name := RandomizedSuffixName("github-gist-id") - Expect(KamelRunWithID(operatorID, ns, "--name", name, - "gist:e2c3f9a5fd0d9e79b21b04809786f17a").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort). - Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Tick!")) - Eventually(DeleteIntegrations(ns), TestTimeoutLong).Should(Equal(0)) - }) + // Check the Deployment has progressed successfully + g.Eventually(DeploymentCondition(t, ctx, ns, name, appsv1.DeploymentProgressing), TestTimeoutShort). + Should(MatchFields(IgnoreExtras, Fields{ + "Status": Equal(corev1.ConditionTrue), + "Reason": Equal("NewReplicaSetAvailable"), + })) - t.Run("Gist (URL)", func(t *testing.T) { - name := RandomizedSuffixName("github-gist-url") - Expect(KamelRunWithID(operatorID, ns, "--name", name, - "https://gist.github.com/lburgazzoli/e2c3f9a5fd0d9e79b21b04809786f17a").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort). + // Check the new configuration is taken into account + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutShort).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort). Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Tick!")) - Eventually(DeleteIntegrations(ns), TestTimeoutLong).Should(Equal(0)) - }) - - // Revert GITHUB TOKEN - os.Setenv("GITHUB_TOKEN", os.Getenv("GITHUB_TOKEN_TMP")) - os.Unsetenv("GITHUB_TOKEN_TMP") + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magic value")) - // Clean up - Eventually(DeleteIntegrations(ns), TestTimeoutLong).Should(Equal(0)) - }) - - t.Run("Run and update", func(t *testing.T) { - name := RandomizedSuffixName("run") - Expect(KamelRunWithID(operatorID, ns, "files/run.yaml", "--name", name).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort). - Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magic default")) - - // Re-run the Integration with an updated configuration - Expect(KamelRunWithID(operatorID, ns, "files/run.yaml", "--name", name, "-p", "property=value").Execute()). - To(Succeed()) - - // Check the Deployment has progressed successfully - Eventually(DeploymentCondition(ns, name, appsv1.DeploymentProgressing), TestTimeoutShort). - Should(MatchFields(IgnoreExtras, Fields{ - "Status": Equal(corev1.ConditionTrue), - "Reason": Equal("NewReplicaSetAvailable"), - })) - - // Check the new configuration is taken into account - Eventually(IntegrationPodPhase(ns, name), TestTimeoutShort).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort). - Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magic value")) - - // Clean up - Eventually(DeleteIntegrations(ns), TestTimeoutLong).Should(Equal(0)) - }) - - t.Run("Run with glob patterns", func(t *testing.T) { - t.Run("YAML", func(t *testing.T) { - name := RandomizedSuffixName("run") - Expect(KamelRunWithID(operatorID, ns, "files/glob/run*", "--name", name).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort). - Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Hello run 1 default")) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Hello run 2 default")) - Eventually(DeleteIntegrations(ns), TestTimeoutLong).Should(Equal(0)) + // Clean up + g.Eventually(DeleteIntegrations(t, ctx, ns), TestTimeoutLong).Should(Equal(0)) }) - t.Run("Java", func(t *testing.T) { - name := RandomizedSuffixName("java") - Expect(KamelRunWithID(operatorID, ns, "files/glob/Java*", "--name", name).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort). - Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Hello java 1 default")) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Hello java 2 default")) - Eventually(DeleteIntegrations(ns), TestTimeoutLong).Should(Equal(0)) + t.Run("Run with glob patterns", func(t *testing.T) { + t.Run("YAML", func(t *testing.T) { + name := RandomizedSuffixName("run") + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/glob/run*", "--name", name).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort). + Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Hello run 1 default")) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Hello run 2 default")) + g.Eventually(DeleteIntegrations(t, ctx, ns), TestTimeoutLong).Should(Equal(0)) + }) + + t.Run("Java", func(t *testing.T) { + name := RandomizedSuffixName("java") + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/glob/Java*", "--name", name).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort). + Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Hello java 1 default")) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Hello java 2 default")) + g.Eventually(DeleteIntegrations(t, ctx, ns), TestTimeoutLong).Should(Equal(0)) + }) + + t.Run("All", func(t *testing.T) { + name := RandomizedSuffixName("java") + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/glob/*", "--name", name).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort). + Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Hello run 1 default")) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Hello run 2 default")) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Hello java 1 default")) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Hello java 2 default")) + g.Eventually(DeleteIntegrations(t, ctx, ns), TestTimeoutLong).Should(Equal(0)) + }) + + // Clean up + g.Eventually(DeleteIntegrations(t, ctx, ns), TestTimeoutLong).Should(Equal(0)) }) + }) - t.Run("All", func(t *testing.T) { - name := RandomizedSuffixName("java") - Expect(KamelRunWithID(operatorID, ns, "files/glob/*", "--name", name).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort). - Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Hello run 1 default")) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Hello run 2 default")) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Hello java 1 default")) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Hello java 2 default")) - Eventually(DeleteIntegrations(ns), TestTimeoutLong).Should(Equal(0)) + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + /* + * TODO + * The dependency cannot be read by maven while building. See #3708 + * + * Adding CAMEL_K_TEST_SKIP_PROBLEMATIC env var for the moment. + */ + t.Run("Run with http dependency", func(t *testing.T) { + if os.Getenv("CAMEL_K_TEST_SKIP_PROBLEMATIC") == "true" { + t.Skip("WARNING: Test marked as problematic ... skipping") + } + // Requires a local integration platform in order to resolve the insecure registry + // Install platform (use the installer to get staging if present) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns, "--skip-operator-setup")).To(Succeed()) + g.Eventually(PlatformPhase(t, ctx, ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "../traits/files/jvm/Classpath.java", + "-d", sampleJar, + ).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "classpath"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "classpath", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "classpath"), TestTimeoutShort).Should(ContainSubstring("Hello World!")) }) - // Clean up - Eventually(DeleteIntegrations(ns), TestTimeoutLong).Should(Equal(0)) + g.Eventually(DeleteIntegrations(t, ctx, ns), TestTimeoutLong).Should(Equal(0)) }) - /* - * TODO - * The dependency cannot be read by maven while building. See #3708 - * - * Adding CAMEL_K_TEST_SKIP_PROBLEMATIC env var for the moment. - */ - t.Run("Run with http dependency", func(t *testing.T) { - if os.Getenv("CAMEL_K_TEST_SKIP_PROBLEMATIC") == "true" { - t.Skip("WARNING: Test marked as problematic ... skipping") - } - Expect(KamelRunWithID(operatorID, ns, "../traits/files/jvm/Classpath.java", - "-d", sampleJar, - ).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "classpath"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "classpath", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "classpath"), TestTimeoutShort).Should(ContainSubstring("Hello World!")) - Eventually(DeleteIntegrations(ns), TestTimeoutLong).Should(Equal(0)) - }) + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + /* + * TODO + * The dependency cannot be read by maven while building. See #3708 + * + * Adding CAMEL_K_TEST_SKIP_PROBLEMATIC env var for the moment. + */ + t.Run("Run with http dependency using options", func(t *testing.T) { + if os.Getenv("CAMEL_K_TEST_SKIP_PROBLEMATIC") == "true" { + t.Skip("WARNING: Test marked as problematic ... skipping") + } + // Requires a local integration platform in order to resolve the insecure registry + // Install platform (use the installer to get staging if present) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns, "--skip-operator-setup")).To(Succeed()) + g.Eventually(PlatformPhase(t, ctx, ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "../traits/files/jvm/Classpath.java", + "-d", sampleJar, + "-d", "https://raw.githubusercontent.com/apache/camel-k-examples/main/generic-examples/languages/Sample.java|targetPath=/tmp/foo", + ).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "classpath"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "classpath", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "classpath"), TestTimeoutShort).Should(ContainSubstring("Hello World!")) + }) - /* - * TODO - * The dependency cannot be read by maven while building. See #3708 - * - * Adding CAMEL_K_TEST_SKIP_PROBLEMATIC env var for the moment. - */ - t.Run("Run with http dependency using options", func(t *testing.T) { - if os.Getenv("CAMEL_K_TEST_SKIP_PROBLEMATIC") == "true" { - t.Skip("WARNING: Test marked as problematic ... skipping") - } - Expect(KamelRunWithID(operatorID, ns, "../traits/files/jvm/Classpath.java", - "-d", sampleJar, - "-d", "https://raw.githubusercontent.com/apache/camel-k-examples/main/generic-examples/languages/Sample.java|targetPath=/tmp/foo", - ).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "classpath"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "classpath", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "classpath"), TestTimeoutShort).Should(ContainSubstring("Hello World!")) - Eventually(DeleteIntegrations(ns), TestTimeoutLong).Should(Equal(0)) + g.Eventually(DeleteIntegrations(t, ctx, ns), TestTimeoutLong).Should(Equal(0)) }) - - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) } diff --git a/e2e/common/cli/version_test.go b/e2e/common/cli/version_test.go index 202135e14d..ee9bad90d0 100644 --- a/e2e/common/cli/version_test.go +++ b/e2e/common/cli/version_test.go @@ -32,10 +32,10 @@ import ( ) func TestKamelCLIVersion(t *testing.T) { - RegisterTestingT(t) + g := NewWithT(t) t.Run("check version correctness", func(t *testing.T) { - version := GetOutputString(Kamel("version")) - Expect(version).To(ContainSubstring(defaults.Version)) + version := GetOutputString(Kamel(t, TestContext(), "version")) + g.Expect(version).To(ContainSubstring(defaults.Version)) }) } diff --git a/e2e/common/config/config_reload_test.go b/e2e/common/config/config_reload_test.go index 94a18a86b4..7b5cf9d708 100644 --- a/e2e/common/config/config_reload_test.go +++ b/e2e/common/config/config_reload_test.go @@ -23,6 +23,8 @@ limitations under the License. package config import ( + "context" + "fmt" "strconv" "testing" @@ -35,86 +37,97 @@ import ( ) func TestConfigmapHotReload(t *testing.T) { - RegisterTestingT(t) - - name := RandomizedSuffixName("config-configmap-route") - - var cmData = make(map[string]string) - cmData["my-configmap-key"] = "my configmap content" - CreatePlainTextConfigmapWithLabels(ns, "my-hot-cm", cmData, map[string]string{"camel.apache.org/integration": "test"}) - - Expect(KamelRunWithID(operatorID, ns, - "./files/config-configmap-route.groovy", - "--config", - "configmap:my-hot-cm", - "-t", - "mount.hot-reload=true", - "--name", - name, - ).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("my configmap content")) - - cmData["my-configmap-key"] = "my configmap content updated" - UpdatePlainTextConfigmapWithLabels(ns, "my-hot-cm", cmData, map[string]string{"camel.apache.org/integration": "test"}) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("my configmap content updated")) - - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + t.Parallel() + + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-config-hot-reload" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + + name := RandomizedSuffixName("config-configmap-route") + + var cmData = make(map[string]string) + cmData["my-configmap-key"] = "my configmap content" + CreatePlainTextConfigmapWithLabels(t, ctx, ns, "my-hot-cm", cmData, map[string]string{"camel.apache.org/integration": "test"}) + + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "./files/config-configmap-route.groovy", + "--config", "configmap:my-hot-cm", + "-t", "mount.hot-reload=true", + "--name", name).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("my configmap content")) + + cmData["my-configmap-key"] = "my configmap content updated" + UpdatePlainTextConfigmapWithLabels(t, ctx, ns, "my-hot-cm", cmData, map[string]string{"camel.apache.org/integration": "test"}) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("my configmap content updated")) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) } func TestConfigmapHotReloadDefault(t *testing.T) { - RegisterTestingT(t) + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-config-hot-reload-default" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) - name := RandomizedSuffixName("config-configmap-route") + name := RandomizedSuffixName("config-configmap-route") - var cmData = make(map[string]string) - cmData["my-configmap-key"] = "my configmap content" - CreatePlainTextConfigmapWithLabels(ns, "my-hot-cm-2", cmData, map[string]string{"camel.apache.org/integration": "test"}) + var cmData = make(map[string]string) + cmData["my-configmap-key"] = "my configmap content" + CreatePlainTextConfigmapWithLabels(t, ctx, ns, "my-hot-cm-2", cmData, map[string]string{"camel.apache.org/integration": "test"}) - Expect(KamelRunWithID(operatorID, ns, "./files/config-configmap-route.groovy", - "--config", - "configmap:my-hot-cm-2", - "--name", - name, - ).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("my configmap content")) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "./files/config-configmap-route.groovy", + "--config", "configmap:my-hot-cm-2", + "--name", name).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("my configmap content")) - cmData["my-configmap-key"] = "my configmap content updated" - UpdatePlainTextConfigmapWithLabels(ns, "my-hot-cm-2", cmData, map[string]string{"camel.apache.org/integration": "test"}) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(Not(ContainSubstring("my configmap content updated"))) + cmData["my-configmap-key"] = "my configmap content updated" + UpdatePlainTextConfigmapWithLabels(t, ctx, ns, "my-hot-cm-2", cmData, map[string]string{"camel.apache.org/integration": "test"}) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(Not(ContainSubstring("my configmap content updated"))) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) } func TestSecretHotReload(t *testing.T) { - RegisterTestingT(t) - - name := RandomizedSuffixName("config-secret-route") - - var secData = make(map[string]string) - secData["my-secret-key"] = "very top secret" - CreatePlainTextSecretWithLabels(ns, "my-hot-sec", secData, map[string]string{"camel.apache.org/integration": "test"}) - - Expect(KamelRunWithID(operatorID, ns, "./files/config-secret-route.groovy", - "--config", - "secret:my-hot-sec", - "-t", - "mount.hot-reload=true", - "--name", - name, - ).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("very top secret")) - - secData["my-secret-key"] = "very top secret updated" - UpdatePlainTextSecretWithLabels(ns, "my-hot-sec", secData, map[string]string{"camel.apache.org/integration": "test"}) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("very top secret updated")) - - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-secret-hot-reload" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + + name := RandomizedSuffixName("config-secret-route") + + var secData = make(map[string]string) + secData["my-secret-key"] = "very top secret" + CreatePlainTextSecretWithLabels(t, ctx, ns, "my-hot-sec", secData, map[string]string{"camel.apache.org/integration": "test"}) + + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "./files/config-secret-route.groovy", + "--config", "secret:my-hot-sec", + "-t", "mount.hot-reload=true", + "--name", name).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("very top secret")) + + secData["my-secret-key"] = "very top secret updated" + UpdatePlainTextSecretWithLabels(t, ctx, ns, "my-hot-sec", secData, map[string]string{"camel.apache.org/integration": "test"}) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("very top secret updated")) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) } func TestConfigmapWithOwnerRefHotReloadDefault(t *testing.T) { @@ -126,31 +139,34 @@ func TestConfigmapWithOwnerRefHotReload(t *testing.T) { } func CheckConfigmapWithOwnerRef(t *testing.T, hotreload bool) { - RegisterTestingT(t) - name := RandomizedSuffixName("config-configmap-route") - cmName := RandomizedSuffixName("my-hot-cm-") - Expect(KamelRunWithID(operatorID, ns, "./files/config-configmap-route.groovy", - "--config", - "configmap:"+cmName, - "--name", - name, - "-t", - "mount.hot-reload="+strconv.FormatBool(hotreload), - ).Execute()).To(Succeed()) - - Eventually(IntegrationPhase(ns, name), TestTimeoutLong).Should(Equal(v1.IntegrationPhaseError)) - var cmData = make(map[string]string) - cmData["my-configmap-key"] = "my configmap content" - CreatePlainTextConfigmapWithOwnerRefWithLabels(ns, cmName, cmData, name, Integration(ns, name)().UID, map[string]string{"camel.apache.org/integration": "test"}) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns, name), TestTimeoutLong).Should(ContainSubstring("my configmap content")) - cmData["my-configmap-key"] = "my configmap content updated" - UpdatePlainTextConfigmapWithLabels(ns, cmName, cmData, map[string]string{"camel.apache.org/integration": "test"}) - if hotreload { - Eventually(IntegrationLogs(ns, name), TestTimeoutLong).Should(ContainSubstring("my configmap content updated")) - } else { - Eventually(IntegrationLogs(ns, name), TestTimeoutLong).Should(Not(ContainSubstring("my configmap content updated"))) - } - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) - DeleteConfigmap(ns, cmName) + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := fmt.Sprintf("camel-k-config-owner-ref-%s", strconv.FormatBool(hotreload)) + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + + name := RandomizedSuffixName("config-configmap-route") + cmName := RandomizedSuffixName("my-hot-cm-") + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "./files/config-configmap-route.groovy", + "--config", "configmap:"+cmName, + "--name", name, + "-t", "mount.hot-reload="+strconv.FormatBool(hotreload)).Execute()).To(Succeed()) + + g.Eventually(IntegrationPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(v1.IntegrationPhaseError)) + var cmData = make(map[string]string) + cmData["my-configmap-key"] = "my configmap content" + CreatePlainTextConfigmapWithOwnerRefWithLabels(t, ctx, ns, cmName, cmData, name, Integration(t, ctx, ns, name)().UID, map[string]string{"camel.apache.org/integration": "test"}) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutLong).Should(ContainSubstring("my configmap content")) + cmData["my-configmap-key"] = "my configmap content updated" + UpdatePlainTextConfigmapWithLabels(t, ctx, ns, cmName, cmData, map[string]string{"camel.apache.org/integration": "test"}) + if hotreload { + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutLong).Should(ContainSubstring("my configmap content updated")) + } else { + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutLong).Should(Not(ContainSubstring("my configmap content updated"))) + } + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) } diff --git a/e2e/common/config/config_test.go b/e2e/common/config/config_test.go index ef178e3c9d..c60267d751 100644 --- a/e2e/common/config/config_test.go +++ b/e2e/common/config/config_test.go @@ -23,6 +23,7 @@ limitations under the License. package config import ( + "context" "testing" . "github.com/onsi/gomega" @@ -35,303 +36,292 @@ import ( ) func TestRunConfigExamples(t *testing.T) { - RegisterTestingT(t) - - t.Run("Simple property", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "./files/property-route.groovy", "-p", "my.message=test-property").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "property-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "property-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "property-route"), TestTimeoutShort).Should(ContainSubstring("test-property")) - Expect(Kamel("delete", "property-route", "-n", ns).Execute()).To(Succeed()) - }) - - t.Run("Property file", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "./files/property-file-route.groovy", "--property", "file:./files/my.properties").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "property-file-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "property-file-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "property-file-route"), TestTimeoutShort).Should(ContainSubstring("hello world")) - Expect(Kamel("delete", "property-file-route", "-n", ns).Execute()).To(Succeed()) - }) - - t.Run("Property precedence", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "./files/property-file-route.groovy", "-p", "my.key.2=universe", "-p", "file:./files/my.properties").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "property-file-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "property-file-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "property-file-route"), TestTimeoutShort).Should(ContainSubstring("hello universe")) - Expect(Kamel("delete", "property-file-route", "-n", ns).Execute()).To(Succeed()) - }) - - t.Run("Property from ConfigMap", func(t *testing.T) { - var cmData = make(map[string]string) - cmData["my.message"] = "my-configmap-property-value" - CreatePlainTextConfigmap(ns, "my-cm-test-property", cmData) - - Expect(KamelRunWithID(operatorID, ns, "./files/property-route.groovy", "-p", "configmap:my-cm-test-property").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "property-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "property-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "property-route"), TestTimeoutShort).Should(ContainSubstring("my-configmap-property-value")) - Expect(Kamel("delete", "property-route", "-n", ns).Execute()).To(Succeed()) - }) - - t.Run("Property from ConfigMap as property file", func(t *testing.T) { - var cmData = make(map[string]string) - cmData["my.properties"] = "my.message=my-configmap-property-entry" - CreatePlainTextConfigmap(ns, "my-cm-test-properties", cmData) - - Expect(KamelRunWithID(operatorID, ns, "./files/property-route.groovy", "-p", "configmap:my-cm-test-properties").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "property-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "property-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "property-route"), TestTimeoutShort).Should(ContainSubstring("my-configmap-property-entry")) - Expect(Kamel("delete", "property-route", "-n", ns).Execute()).To(Succeed()) - }) - - t.Run("Property from Secret", func(t *testing.T) { - var secData = make(map[string]string) - secData["my.message"] = "my-secret-property-value" - CreatePlainTextSecret(ns, "my-sec-test-property", secData) - - Expect(KamelRunWithID(operatorID, ns, "./files/property-route.groovy", "-p", "secret:my-sec-test-property").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "property-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "property-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "property-route"), TestTimeoutShort).Should(ContainSubstring("my-secret-property-value")) - Expect(Kamel("delete", "property-route", "-n", ns).Execute()).To(Succeed()) - }) - - t.Run("Property from Secret as property file", func(t *testing.T) { - var secData = make(map[string]string) - secData["my.properties"] = "my.message=my-secret-property-entry" - CreatePlainTextSecret(ns, "my-sec-test-properties", secData) - - Expect(KamelRunWithID(operatorID, ns, "./files/property-route.groovy", "-p", "secret:my-sec-test-properties").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "property-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "property-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "property-route"), TestTimeoutShort).Should(ContainSubstring("my-secret-property-entry")) - }) - - t.Run("Property from Secret inlined", func(t *testing.T) { - var secData = make(map[string]string) - secData["my-message"] = "my-secret-external-value" - CreatePlainTextSecret(ns, "my-sec-inlined", secData) - - // TODO: remove jvm.options trait as soon as CAMEL-20054 gets fixed - Expect(KamelRunWithID(operatorID, ns, "./files/property-secret-route.groovy", - "-t", "mount.configs=secret:my-sec-inlined", - "-t", "jvm.options=-Dcamel.k.mount-path.secrets=/etc/camel/conf.d/_secrets", - ).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "property-secret-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "property-secret-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "property-secret-route"), TestTimeoutShort).Should(ContainSubstring("my-secret-external-value")) - - // check integration schema does not contains unwanted default trait value. - Eventually(UnstructuredIntegration(ns, "property-secret-route")).ShouldNot(BeNil()) - unstructuredIntegration := UnstructuredIntegration(ns, "property-secret-route")() - mountTrait, _, _ := unstructured.NestedMap(unstructuredIntegration.Object, "spec", "traits", "mount") - Expect(mountTrait).ToNot(BeNil()) - Expect(len(mountTrait)).To(Equal(1)) - Expect(mountTrait["configs"]).ToNot(BeNil()) - - Expect(Kamel("delete", "property-secret-route", "-n", ns).Execute()).To(Succeed()) - - }) - - // Configmap - - // Store a configmap on the cluster - var cmData = make(map[string]string) - cmData["my-configmap-key"] = "my-configmap-content" - CreatePlainTextConfigmap(ns, "my-cm", cmData) - - // Store a configmap with multiple values - var cmDataMulti = make(map[string]string) - cmDataMulti["my-configmap-key"] = "should-not-see-it" - cmDataMulti["my-configmap-key-2"] = "my-configmap-content-2" - CreatePlainTextConfigmap(ns, "my-cm-multi", cmDataMulti) - - t.Run("Config configmap", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "./files/config-configmap-route.groovy", "--config", "configmap:my-cm").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "config-configmap-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "config-configmap-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "config-configmap-route"), TestTimeoutShort).Should(ContainSubstring(cmData["my-configmap-key"])) - }) - - t.Run("Resource configmap", func(t *testing.T) { - // We can reuse the configmap created previously - - Expect(KamelRunWithID(operatorID, ns, "./files/resource-configmap-route.groovy", "--resource", "configmap:my-cm").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "resource-configmap-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "resource-configmap-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "resource-configmap-route"), TestTimeoutShort).Should(ContainSubstring(cmData["my-configmap-key"])) - }) - - t.Run("Resource configmap with destination", func(t *testing.T) { - // We can reuse the configmap created previously - - Expect(KamelRunWithID(operatorID, ns, "./files/resource-configmap-location-route.groovy", "--resource", "configmap:my-cm@/tmp/app").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "resource-configmap-location-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "resource-configmap-location-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "resource-configmap-location-route"), TestTimeoutShort).Should(ContainSubstring(cmData["my-configmap-key"])) - }) - - t.Run("Resource configmap with filtered key and destination", func(t *testing.T) { - // We'll use the configmap contaning 2 values filtering only 1 key - - Expect(KamelRunWithID(operatorID, ns, "./files/resource-configmap-key-location-route.groovy", "--resource", "configmap:my-cm-multi/my-configmap-key-2@/tmp/app/test.txt").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "resource-configmap-key-location-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "resource-configmap-key-location-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "resource-configmap-key-location-route"), TestTimeoutShort).ShouldNot(ContainSubstring(cmDataMulti["my-configmap-key"])) - Eventually(IntegrationLogs(ns, "resource-configmap-key-location-route"), TestTimeoutShort).Should(ContainSubstring(cmDataMulti["my-configmap-key-2"])) - }) - - // Store a configmap as property file - var cmDataProps = make(map[string]string) - cmDataProps["my.properties"] = "my.key.1=hello\nmy.key.2=world" - CreatePlainTextConfigmap(ns, "my-cm-properties", cmDataProps) - - t.Run("Config configmap as property file", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "./files/config-configmap-properties-route.groovy", "--config", "configmap:my-cm-properties").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "config-configmap-properties-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "config-configmap-properties-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "config-configmap-properties-route"), TestTimeoutShort).Should(ContainSubstring("hello world")) - }) - - // Secret - - // Store a secret on the cluster - var secData = make(map[string]string) - secData["my-secret-key"] = "very top secret" - CreatePlainTextSecret(ns, "my-sec", secData) - - // Store a secret with multi values - var secDataMulti = make(map[string]string) - secDataMulti["my-secret-key"] = "very top secret" - secDataMulti["my-secret-key-2"] = "even more secret" - CreatePlainTextSecret(ns, "my-sec-multi", secDataMulti) - - t.Run("Config secret", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "./files/config-secret-route.groovy", "--config", "secret:my-sec").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "config-secret-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "config-secret-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "config-secret-route"), TestTimeoutShort).Should(ContainSubstring(secData["my-secret-key"])) - }) - - t.Run("Resource secret", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "./files/resource-secret-route.groovy", "--resource", "secret:my-sec").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "resource-secret-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "resource-secret-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "resource-secret-route"), TestTimeoutShort).Should(ContainSubstring(secData["my-secret-key"])) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) - }) - - t.Run("Secret with filtered key", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "./files/config-secret-key-route.groovy", "--config", "secret:my-sec-multi/my-secret-key-2").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "config-secret-key-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "config-secret-key-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "config-secret-key-route"), TestTimeoutShort).ShouldNot(ContainSubstring(secDataMulti["my-secret-key"])) - Eventually(IntegrationLogs(ns, "config-secret-key-route"), TestTimeoutShort).Should(ContainSubstring(secDataMulti["my-secret-key-2"])) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) - }) - - // Build-Properties - t.Run("Build time property", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "./files/build-property-route.groovy", "--build-property", "quarkus.application.name=my-super-application").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "build-property-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "build-property-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "build-property-route"), TestTimeoutShort).Should(ContainSubstring("my-super-application")) - // Don't delete - we need it for next test execution - }) - - // We need to check also that the property (which is available in the IntegrationKit) is correctly replaced and we don't reuse the same kit - t.Run("Build time property updated", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "./files/build-property-route.groovy", "--name", "build-property-route-updated", - "--build-property", "quarkus.application.name=my-super-application-updated").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "build-property-route-updated"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "build-property-route-updated", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "build-property-route-updated"), TestTimeoutShort).Should(ContainSubstring("my-super-application-updated")) - // Verify the integration kits are different - Eventually(IntegrationKit(ns, "build-property-route-updated")).ShouldNot(Equal(IntegrationKit(ns, "build-property-route")())) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) - }) - - // Build-Properties file - t.Run("Build time property file", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "./files/build-property-file-route.groovy", "--build-property", "file:./files/quarkus.properties").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "build-property-file-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "build-property-file-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "build-property-file-route"), TestTimeoutShort).Should(ContainSubstring("my-super-application")) - Expect(Kamel("delete", "build-property-file-route", "-n", ns).Execute()).To(Succeed()) - }) - - t.Run("Build time property file with precedence", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "./files/build-property-file-route.groovy", "--build-property", "quarkus.application.name=my-overridden-application", "--build-property", "file:./files/quarkus.properties").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "build-property-file-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "build-property-file-route", v1.IntegrationConditionReady), TestTimeoutMedium).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "build-property-file-route"), TestTimeoutMedium).Should(ContainSubstring("my-overridden-application")) - Expect(Kamel("delete", "build-property-file-route", "-n", ns).Execute()).To(Succeed()) - }) - - t.Run("Build time property from ConfigMap", func(t *testing.T) { + t.Parallel() + + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-config" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + + t.Run("Simple property", func(t *testing.T) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "./files/property-route.groovy", "-p", "my.message=test-property").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "property-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "property-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "property-route"), TestTimeoutShort).Should(ContainSubstring("test-property")) + g.Expect(Kamel(t, ctx, "delete", "property-route", "-n", ns).Execute()).To(Succeed()) + }) + + t.Run("Property file", func(t *testing.T) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "./files/property-file-route.groovy", "--property", "file:./files/my.properties").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "property-file-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "property-file-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "property-file-route"), TestTimeoutShort).Should(ContainSubstring("hello world")) + g.Expect(Kamel(t, ctx, "delete", "property-file-route", "-n", ns).Execute()).To(Succeed()) + }) + + t.Run("Property precedence", func(t *testing.T) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "./files/property-file-route.groovy", "-p", "my.key.2=universe", "-p", "file:./files/my.properties").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "property-file-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "property-file-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "property-file-route"), TestTimeoutShort).Should(ContainSubstring("hello universe")) + g.Expect(Kamel(t, ctx, "delete", "property-file-route", "-n", ns).Execute()).To(Succeed()) + }) + + t.Run("Property from ConfigMap", func(t *testing.T) { + var cmData = make(map[string]string) + cmData["my.message"] = "my-configmap-property-value" + CreatePlainTextConfigmap(t, ctx, ns, "my-cm-test-property", cmData) + + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "./files/property-route.groovy", "-p", "configmap:my-cm-test-property").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "property-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "property-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "property-route"), TestTimeoutShort).Should(ContainSubstring("my-configmap-property-value")) + g.Expect(Kamel(t, ctx, "delete", "property-route", "-n", ns).Execute()).To(Succeed()) + }) + + t.Run("Property from ConfigMap as property file", func(t *testing.T) { + var cmData = make(map[string]string) + cmData["my.properties"] = "my.message=my-configmap-property-entry" + CreatePlainTextConfigmap(t, ctx, ns, "my-cm-test-properties", cmData) + + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "./files/property-route.groovy", "-p", "configmap:my-cm-test-properties").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "property-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "property-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "property-route"), TestTimeoutShort).Should(ContainSubstring("my-configmap-property-entry")) + g.Expect(Kamel(t, ctx, "delete", "property-route", "-n", ns).Execute()).To(Succeed()) + }) + + t.Run("Property from Secret", func(t *testing.T) { + var secData = make(map[string]string) + secData["my.message"] = "my-secret-property-value" + CreatePlainTextSecret(t, ctx, ns, "my-sec-test-property", secData) + + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "./files/property-route.groovy", "-p", "secret:my-sec-test-property").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "property-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "property-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "property-route"), TestTimeoutShort).Should(ContainSubstring("my-secret-property-value")) + g.Expect(Kamel(t, ctx, "delete", "property-route", "-n", ns).Execute()).To(Succeed()) + }) + + t.Run("Property from Secret as property file", func(t *testing.T) { + var secData = make(map[string]string) + secData["my.properties"] = "my.message=my-secret-property-entry" + CreatePlainTextSecret(t, ctx, ns, "my-sec-test-properties", secData) + + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "./files/property-route.groovy", "--name", "property-route-secret", "-p", "secret:my-sec-test-properties").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "property-route-secret"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "property-route-secret", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "property-route-secret"), TestTimeoutShort).Should(ContainSubstring("my-secret-property-entry")) + }) + + t.Run("Property from Secret inlined", func(t *testing.T) { + var secData = make(map[string]string) + secData["my-message"] = "my-secret-external-value" + CreatePlainTextSecret(t, ctx, ns, "my-sec-inlined", secData) + + // TODO: remove jvm.options trait as soon as CAMEL-20054 gets fixed + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "./files/property-secret-route.groovy", "-t", "mount.configs=secret:my-sec-inlined", "-t", "jvm.options=-Dcamel.k.mount-path.secrets=/etc/camel/conf.d/_secrets").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "property-secret-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "property-secret-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "property-secret-route"), TestTimeoutShort).Should(ContainSubstring("my-secret-external-value")) + + // check integration schema does not contains unwanted default trait value. + g.Eventually(UnstructuredIntegration(t, ctx, ns, "property-secret-route")).ShouldNot(BeNil()) + unstructuredIntegration := UnstructuredIntegration(t, ctx, ns, "property-secret-route")() + mountTrait, _, _ := unstructured.NestedMap(unstructuredIntegration.Object, "spec", "traits", "mount") + g.Expect(mountTrait).ToNot(BeNil()) + g.Expect(len(mountTrait)).To(Equal(1)) + g.Expect(mountTrait["configs"]).ToNot(BeNil()) + + g.Expect(Kamel(t, ctx, "delete", "property-secret-route", "-n", ns).Execute()).To(Succeed()) + + }) + + // Configmap + + // Store a configmap on the cluster var cmData = make(map[string]string) - cmData["quarkus.application.name"] = "my-cool-application" - CreatePlainTextConfigmap(ns, "my-cm-test-build-property", cmData) - - Expect(KamelRunWithID(operatorID, ns, "./files/build-property-file-route.groovy", "--build-property", "configmap:my-cm-test-build-property").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "build-property-file-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "build-property-file-route", v1.IntegrationConditionReady), TestTimeoutLong).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "build-property-file-route"), TestTimeoutLong).Should(ContainSubstring("my-cool-application")) - Expect(Kamel("delete", "build-property-file-route", "-n", ns).Execute()).To(Succeed()) - }) - - t.Run("Build time property from ConfigMap as property file", func(t *testing.T) { - var cmData = make(map[string]string) - cmData["my.properties"] = "quarkus.application.name=my-super-cool-application" - CreatePlainTextConfigmap(ns, "my-cm-test-build-properties", cmData) - - Expect(KamelRunWithID(operatorID, ns, "./files/build-property-file-route.groovy", "--build-property", "configmap:my-cm-test-build-properties").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "build-property-file-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "build-property-file-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "build-property-file-route"), TestTimeoutShort).Should(ContainSubstring("my-super-cool-application")) - Expect(Kamel("delete", "build-property-file-route", "-n", ns).Execute()).To(Succeed()) - - }) - - t.Run("Build time property from Secret", func(t *testing.T) { + cmData["my-configmap-key"] = "my-configmap-content" + CreatePlainTextConfigmap(t, ctx, ns, "my-cm", cmData) + + // Store a configmap with multiple values + var cmDataMulti = make(map[string]string) + cmDataMulti["my-configmap-key"] = "should-not-see-it" + cmDataMulti["my-configmap-key-2"] = "my-configmap-content-2" + CreatePlainTextConfigmap(t, ctx, ns, "my-cm-multi", cmDataMulti) + + t.Run("Config configmap", func(t *testing.T) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "./files/config-configmap-route.groovy", "--config", "configmap:my-cm").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "config-configmap-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "config-configmap-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "config-configmap-route"), TestTimeoutShort).Should(ContainSubstring(cmData["my-configmap-key"])) + }) + + t.Run("Resource configmap", func(t *testing.T) { + // We can reuse the configmap created previously + + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "./files/resource-configmap-route.groovy", "--resource", "configmap:my-cm").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "resource-configmap-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "resource-configmap-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "resource-configmap-route"), TestTimeoutShort).Should(ContainSubstring(cmData["my-configmap-key"])) + }) + + t.Run("Resource configmap with destination", func(t *testing.T) { + // We can reuse the configmap created previously + + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "./files/resource-configmap-location-route.groovy", "--resource", "configmap:my-cm@/tmp/app").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "resource-configmap-location-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "resource-configmap-location-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "resource-configmap-location-route"), TestTimeoutShort).Should(ContainSubstring(cmData["my-configmap-key"])) + }) + + t.Run("Resource configmap with filtered key and destination", func(t *testing.T) { + // We'll use the configmap contaning 2 values filtering only 1 key + + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "./files/resource-configmap-key-location-route.groovy", "--resource", "configmap:my-cm-multi/my-configmap-key-2@/tmp/app/test.txt").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "resource-configmap-key-location-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "resource-configmap-key-location-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "resource-configmap-key-location-route"), TestTimeoutShort).ShouldNot(ContainSubstring(cmDataMulti["my-configmap-key"])) + g.Eventually(IntegrationLogs(t, ctx, ns, "resource-configmap-key-location-route"), TestTimeoutShort).Should(ContainSubstring(cmDataMulti["my-configmap-key-2"])) + }) + + t.Run("Config configmap as property file", func(t *testing.T) { + // Store a configmap as property file + var cmDataProps = make(map[string]string) + cmDataProps["my.properties"] = "my.key.1=hello\nmy.key.2=world" + CreatePlainTextConfigmap(t, ctx, ns, "my-cm-properties", cmDataProps) + + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "./files/config-configmap-properties-route.groovy", "--config", "configmap:my-cm-properties").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "config-configmap-properties-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "config-configmap-properties-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "config-configmap-properties-route"), TestTimeoutShort).Should(ContainSubstring("hello world")) + }) + + // Secret + + // Store a secret on the cluster var secData = make(map[string]string) - secData["quarkus.application.name"] = "my-great-application" - CreatePlainTextSecret(ns, "my-sec-test-build-property", secData) - - Expect(KamelRunWithID(operatorID, ns, "./files/build-property-file-route.groovy", "--build-property", "secret:my-sec-test-build-property").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "build-property-file-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "build-property-file-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "build-property-file-route"), TestTimeoutShort).Should(ContainSubstring("my-great-application")) - Expect(Kamel("delete", "build-property-file-route", "-n", ns).Execute()).To(Succeed()) - + secData["my-secret-key"] = "very top secret" + CreatePlainTextSecret(t, ctx, ns, "my-sec", secData) + + // Store a secret with multi values + var secDataMulti = make(map[string]string) + secDataMulti["my-secret-key"] = "very top secret" + secDataMulti["my-secret-key-2"] = "even more secret" + CreatePlainTextSecret(t, ctx, ns, "my-sec-multi", secDataMulti) + + t.Run("Config secret", func(t *testing.T) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "./files/config-secret-route.groovy", "--config", "secret:my-sec").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "config-secret-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "config-secret-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "config-secret-route"), TestTimeoutShort).Should(ContainSubstring(secData["my-secret-key"])) + }) + + t.Run("Resource secret", func(t *testing.T) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "./files/resource-secret-route.groovy", "--resource", "secret:my-sec").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "resource-secret-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "resource-secret-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "resource-secret-route"), TestTimeoutShort).Should(ContainSubstring(secData["my-secret-key"])) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) + + t.Run("Secret with filtered key", func(t *testing.T) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "./files/config-secret-key-route.groovy", "--config", "secret:my-sec-multi/my-secret-key-2").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "config-secret-key-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "config-secret-key-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "config-secret-key-route"), TestTimeoutShort).ShouldNot(ContainSubstring(secDataMulti["my-secret-key"])) + g.Eventually(IntegrationLogs(t, ctx, ns, "config-secret-key-route"), TestTimeoutShort).Should(ContainSubstring(secDataMulti["my-secret-key-2"])) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) + + // Build-Properties + t.Run("Build time property", func(t *testing.T) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "./files/build-property-route.groovy", "--build-property", "quarkus.application.name=my-super-application").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "build-property-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "build-property-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "build-property-route"), TestTimeoutShort).Should(ContainSubstring("my-super-application")) + // Don't delete - we need it for next test execution + }) + + // We need to check also that the property (which is available in the IntegrationKit) is correctly replaced and we don't reuse the same kit + t.Run("Build time property updated", func(t *testing.T) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "./files/build-property-route.groovy", "--name", "build-property-route-updated", "--build-property", "quarkus.application.name=my-super-application-updated").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "build-property-route-updated"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "build-property-route-updated", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "build-property-route-updated"), TestTimeoutShort).Should(ContainSubstring("my-super-application-updated")) + // Verify the integration kits are different + g.Eventually(IntegrationKit(t, ctx, ns, "build-property-route-updated")).ShouldNot(Equal(IntegrationKit(t, ctx, ns, "build-property-route")())) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) + + // Build-Properties file + t.Run("Build time property file", func(t *testing.T) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "./files/build-property-file-route.groovy", "--build-property", "file:./files/quarkus.properties").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "build-property-file-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "build-property-file-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "build-property-file-route"), TestTimeoutShort).Should(ContainSubstring("my-super-application")) + g.Expect(Kamel(t, ctx, "delete", "build-property-file-route", "-n", ns).Execute()).To(Succeed()) + }) + + t.Run("Build time property file with precedence", func(t *testing.T) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "./files/build-property-file-route.groovy", "--name", "build-property-file-route-precedence", "--build-property", "quarkus.application.name=my-overridden-application", "--build-property", "file:./files/quarkus.properties").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "build-property-file-route-precedence"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "build-property-file-route-precedence", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "build-property-file-route-precedence"), TestTimeoutShort).Should(ContainSubstring("my-overridden-application")) + g.Expect(Kamel(t, ctx, "delete", "build-property-file-route-precedence", "-n", ns).Execute()).To(Succeed()) + }) + + t.Run("Build time property from ConfigMap", func(t *testing.T) { + var cmData = make(map[string]string) + cmData["quarkus.application.name"] = "my-cool-application" + CreatePlainTextConfigmap(t, ctx, ns, "my-cm-test-build-property", cmData) + + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "./files/build-property-file-route.groovy", "--build-property", "configmap:my-cm-test-build-property").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "build-property-file-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "build-property-file-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "build-property-file-route"), TestTimeoutShort).Should(ContainSubstring("my-cool-application")) + g.Expect(Kamel(t, ctx, "delete", "build-property-file-route", "-n", ns).Execute()).To(Succeed()) + }) + + t.Run("Build time property from ConfigMap as property file", func(t *testing.T) { + var cmData = make(map[string]string) + cmData["my.properties"] = "quarkus.application.name=my-super-cool-application" + CreatePlainTextConfigmap(t, ctx, ns, "my-cm-test-build-properties", cmData) + + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "./files/build-property-file-route.groovy", "--name", "build-property-file-route-cm", "--build-property", "configmap:my-cm-test-build-properties").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "build-property-file-route-cm"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "build-property-file-route-cm", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "build-property-file-route-cm"), TestTimeoutShort).Should(ContainSubstring("my-super-cool-application")) + g.Expect(Kamel(t, ctx, "delete", "build-property-file-route-cm", "-n", ns).Execute()).To(Succeed()) + }) + + t.Run("Build time property from Secret", func(t *testing.T) { + var secData = make(map[string]string) + secData["quarkus.application.name"] = "my-great-application" + CreatePlainTextSecret(t, ctx, ns, "my-sec-test-build-property", secData) + + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "./files/build-property-file-route.groovy", "--build-property", "secret:my-sec-test-build-property").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "build-property-file-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "build-property-file-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "build-property-file-route"), TestTimeoutShort).Should(ContainSubstring("my-great-application")) + g.Expect(Kamel(t, ctx, "delete", "build-property-file-route", "-n", ns).Execute()).To(Succeed()) + }) + + t.Run("Build time property from Secret as property file", func(t *testing.T) { + var secData = make(map[string]string) + secData["my.properties"] = "quarkus.application.name=my-awsome-application" + CreatePlainTextSecret(t, ctx, ns, "my-sec-test-build-properties", secData) + + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "./files/build-property-file-route.groovy", "--name", "build-property-file-route-secret", "--build-property", "secret:my-sec-test-build-properties").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "build-property-file-route-secret"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "build-property-file-route-secret", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "build-property-file-route-secret"), TestTimeoutShort).Should(ContainSubstring("my-awsome-application")) + g.Expect(Kamel(t, ctx, "delete", "build-property-file-route-secret", "-n", ns).Execute()).To(Succeed()) + }) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) - - t.Run("Build time property from Secret as property file", func(t *testing.T) { - var secData = make(map[string]string) - secData["my.properties"] = "quarkus.application.name=my-awsome-application" - CreatePlainTextSecret(ns, "my-sec-test-build-properties", secData) - - Expect(KamelRunWithID(operatorID, ns, "./files/build-property-file-route.groovy", "--build-property", "secret:my-sec-test-build-properties").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "build-property-file-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "build-property-file-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "build-property-file-route"), TestTimeoutShort).Should(ContainSubstring("my-awsome-application")) - Expect(Kamel("delete", "build-property-file-route", "-n", ns).Execute()).To(Succeed()) - - }) - - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) - Expect(DeleteConfigmap(ns, "my-cm")).To(Succeed()) - Expect(DeleteConfigmap(ns, "my-cm-multi")).To(Succeed()) - Expect(DeleteConfigmap(ns, "my-cm-properties")).To(Succeed()) - Expect(DeleteConfigmap(ns, "my-cm-test-build-property")).To(Succeed()) - Expect(DeleteConfigmap(ns, "my-cm-test-build-properties")).To(Succeed()) - Expect(DeleteConfigmap(ns, "my-cm-test-property")).To(Succeed()) - Expect(DeleteConfigmap(ns, "my-cm-test-properties")).To(Succeed()) - Expect(DeleteSecret(ns, "my-sec-test-build-property")).To(Succeed()) - Expect(DeleteSecret(ns, "my-sec-test-build-properties")).To(Succeed()) - Expect(DeleteSecret(ns, "my-sec-test-property")).To(Succeed()) - Expect(DeleteSecret(ns, "my-sec-test-properties")).To(Succeed()) - Expect(DeleteSecret(ns, "my-sec")).To(Succeed()) - Expect(DeleteSecret(ns, "my-sec-multi")).To(Succeed()) } diff --git a/e2e/common/config/default.go b/e2e/common/config/default.go deleted file mode 100644 index 4a5ced9e02..0000000000 --- a/e2e/common/config/default.go +++ /dev/null @@ -1,26 +0,0 @@ -//go:build integration -// +build integration - -/* -Licensed to the Apache Software Foundation (ASF) under one or more -contributor license agreements. See the NOTICE file distributed with -this work for additional information regarding copyright ownership. -The ASF licenses this file to You under the Apache License, Version 2.0 -(the "License"); you may not use this file except in compliance with -the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package config - -import "github.com/apache/camel-k/v2/e2e/support" - -var ns = support.GetEnvOrDefault("CAMEL_K_TEST_NAMESPACE", support.GetCIProcessID()) -var operatorID = support.GetEnvOrDefault("CAMEL_K_OPERATOR_ID", support.GetCIProcessID()) diff --git a/e2e/common/config/kamelet_config_test.go b/e2e/common/config/kamelet_config_test.go index 0ef8ec99ef..8dcc0c2c1b 100644 --- a/e2e/common/config/kamelet_config_test.go +++ b/e2e/common/config/kamelet_config_test.go @@ -23,360 +23,324 @@ limitations under the License. package config import ( + "context" "testing" . "github.com/onsi/gomega" corev1 "k8s.io/api/core/v1" . "github.com/apache/camel-k/v2/e2e/support" + v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" ) // Tests on integrations with kamelets containing configuration from properties and secrets // // without having to change the integration code. -func TestKameletImplicitConfigDefaultUserPropery(t *testing.T) { - RegisterTestingT(t) - t.Run("run test default config using properties", func(t *testing.T) { - - Expect(CreateTimerKamelet(ns, "iconfig01-timer-source")()).To(Succeed()) - - name := RandomizedSuffixName("iconfig-test-timer-source-int01") - Expect(KamelRunWithID(operatorID, ns, "files/TimerKameletIntegrationConfiguration01.java", - "-p", "camel.kamelet.iconfig01-timer-source.message='Default message 01'", - "--name", name).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns, name)).Should(ContainSubstring("Default message 01")) - - Expect(Kamel("delete", name, "-n", ns).Execute()).To(Succeed()) - Eventually(Integration(ns, name), TestTimeoutLong).Should(BeNil()) - Expect(DeleteKamelet(ns, "iconfig01-timer-source")).To(Succeed()) - }) - - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) -} - -func TestKameletImplicitConfigDefaultMountedSecret(t *testing.T) { - RegisterTestingT(t) - - t.Run("run test default config using mounted secret", func(t *testing.T) { - - Expect(CreateTimerKamelet(ns, "iconfig03-timer-source")()).To(Succeed()) - - name := RandomizedSuffixName("iconfig-test-timer-source-int3") - secretName := "my-iconfig-int3-secret" - - var secData = make(map[string]string) - secData["camel.kamelet.iconfig03-timer-source.message"] = "very top mounted secret message" - Expect(CreatePlainTextSecret(ns, secretName, secData)).To(Succeed()) - Eventually(SecretByName(ns, secretName), TestTimeoutLong).Should(Not(BeNil())) - - Expect(KamelRunWithID(operatorID, ns, "files/TimerKameletIntegrationConfiguration03.java", - "-t", "mount.configs=secret:"+secretName, - "--name", name).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns, name)).Should(ContainSubstring("very top mounted secret message")) - - Expect(Kamel("delete", name, "-n", ns).Execute()).To(Succeed()) - Eventually(Integration(ns, name), TestTimeoutLong).Should(BeNil()) - Expect(DeleteSecret(ns, secretName)).To(Succeed()) - Eventually(SecretByName(ns, secretName), TestTimeoutLong).Should(BeNil()) - Expect(DeleteKamelet(ns, "iconfig03-timer-source")).To(Succeed()) - }) - - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) -} - -func TestKameletImplicitConfigDefaultMountedConfigmap(t *testing.T) { - RegisterTestingT(t) - - t.Run("run test default config using mounted configmap", func(t *testing.T) { - - Expect(CreateTimerKamelet(ns, "iconfig04-timer-source")()).To(Succeed()) - - name := RandomizedSuffixName("iconfig-test-timer-source-int4") - cmName := "my-iconfig-int4-configmap" - - var cmData = make(map[string]string) - cmData["camel.kamelet.iconfig04-timer-source.message"] = "very top mounted configmap message" - Expect(CreatePlainTextConfigmap(ns, cmName, cmData)).To(Succeed()) - - Expect(KamelRunWithID(operatorID, ns, "files/TimerKameletIntegrationConfiguration04.java", - "-t", "mount.configs=configmap:"+cmName, - "--name", name).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns, name)).Should(ContainSubstring("very top mounted configmap message")) - - Expect(Kamel("delete", name, "-n", ns).Execute()).To(Succeed()) - Eventually(Integration(ns, name), TestTimeoutLong).Should(BeNil()) - Expect(DeleteConfigmap(ns, cmName)).To(Succeed()) - Expect(DeleteKamelet(ns, "iconfig04-timer-source")).To(Succeed()) - }) - - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) -} - -func TestKameletImplicitConfigNamedUserPropery(t *testing.T) { - RegisterTestingT(t) - t.Run("run test named config using properties", func(t *testing.T) { - - Expect(CreateTimerKamelet(ns, "iconfig05-timer-source")()).To(Succeed()) - - name := RandomizedSuffixName("iconfig-test-timer-source-int5") - Expect(KamelRunWithID(operatorID, ns, "files/TimerKameletIntegrationNamedConfiguration05.java", - "-p", "camel.kamelet.iconfig05-timer-source.message='Default message 05'", - "-p", "camel.kamelet.iconfig05-timer-source.mynamedconfig.message='My Named Config message'", - "--name", name).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns, name)).Should(ContainSubstring("My Named Config message")) - - Expect(Kamel("delete", name, "-n", ns).Execute()).To(Succeed()) - Eventually(Integration(ns, name), TestTimeoutLong).Should(BeNil()) - Expect(DeleteKamelet(ns, "iconfig05-timer-source")).To(Succeed()) - }) - - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) -} - -func TestKameletImplicitConfigNamedLabeledSecret(t *testing.T) { - RegisterTestingT(t) - - t.Run("run test named config using labeled secret", func(t *testing.T) { - - Expect(CreateTimerKamelet(ns, "iconfig06-timer-source")()).To(Succeed()) - - name := RandomizedSuffixName("iconfig-test-timer-source-int6") - secretName := "my-iconfig-int6-secret" - - var secData = make(map[string]string) - secData["camel.kamelet.iconfig06-timer-source.mynamedconfig.message"] = "very top named secret message" - var labels = make(map[string]string) - labels["camel.apache.org/kamelet"] = "iconfig06-timer-source" - labels["camel.apache.org/kamelet.configuration"] = "mynamedconfig" - Expect(CreatePlainTextSecretWithLabels(ns, secretName, secData, labels)).To(Succeed()) - Eventually(SecretByName(ns, secretName), TestTimeoutLong).Should(Not(BeNil())) - - Expect(KamelRunWithID(operatorID, ns, "files/TimerKameletIntegrationNamedConfiguration06.java", - "-p", "camel.kamelet.iconfig06-timer-source.message='Default message 06'", - "--name", name).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns, name)).Should(ContainSubstring("very top named secret message")) - - Expect(Kamel("delete", name, "-n", ns).Execute()).To(Succeed()) - Eventually(Integration(ns, name), TestTimeoutLong).Should(BeNil()) - Expect(DeleteSecret(ns, secretName)).To(Succeed()) - Eventually(SecretByName(ns, secretName), TestTimeoutLong).Should(BeNil()) - Expect(DeleteKamelet(ns, "iconfig06-timer-source")).To(Succeed()) - }) - - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) -} +func TestKameletImplicitConfigDefaultUserProperty(t *testing.T) { + t.Parallel() -func TestKameletImplicitConfigNamedMountedSecret(t *testing.T) { - RegisterTestingT(t) + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-config-kamelet-user-property" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) - t.Run("run test named config using mounted secret", func(t *testing.T) { + t.Run("run test default config using properties", func(t *testing.T) { + + g.Expect(CreateTimerKamelet(t, ctx, operatorID, ns, "iconfig01-timer-source")()).To(Succeed()) + + name := RandomizedSuffixName("iconfig-test-timer-source-int01") + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/TimerKameletIntegrationConfiguration01.java", + "-p", "camel.kamelet.iconfig01-timer-source.message='Default message 01'", + "--name", name).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, name)).Should(ContainSubstring("Default message 01")) + + g.Expect(Kamel(t, ctx, "delete", name, "-n", ns).Execute()).To(Succeed()) + g.Eventually(Integration(t, ctx, ns, name), TestTimeoutLong).Should(BeNil()) + g.Expect(DeleteKamelet(t, ctx, ns, "iconfig01-timer-source")).To(Succeed()) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) + + t.Run("run test default config using mounted secret", func(t *testing.T) { + g.Expect(CreateTimerKamelet(t, ctx, operatorID, ns, "iconfig03-timer-source")()).To(Succeed()) + + name := RandomizedSuffixName("iconfig-test-timer-source-int3") + secretName := "my-iconfig-int3-secret" + + var secData = make(map[string]string) + secData["camel.kamelet.iconfig03-timer-source.message"] = "very top mounted secret message" + g.Expect(CreatePlainTextSecret(t, ctx, ns, secretName, secData)).To(Succeed()) + g.Eventually(SecretByName(t, ctx, ns, secretName), TestTimeoutLong).Should(Not(BeNil())) + + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/TimerKameletIntegrationConfiguration03.java", + "-t", "mount.configs=secret:"+secretName, + "--name", name).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, name)).Should(ContainSubstring("very top mounted secret message")) + + g.Expect(Kamel(t, ctx, "delete", name, "-n", ns).Execute()).To(Succeed()) + g.Eventually(Integration(t, ctx, ns, name), TestTimeoutLong).Should(BeNil()) + g.Expect(DeleteSecret(t, ctx, ns, secretName)).To(Succeed()) + g.Eventually(SecretByName(t, ctx, ns, secretName), TestTimeoutLong).Should(BeNil()) + g.Expect(DeleteKamelet(t, ctx, ns, "iconfig03-timer-source")).To(Succeed()) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) + + t.Run("run test default config using mounted configmap", func(t *testing.T) { + g.Expect(CreateTimerKamelet(t, ctx, operatorID, ns, "iconfig04-timer-source")()).To(Succeed()) + + name := RandomizedSuffixName("iconfig-test-timer-source-int4") + cmName := "my-iconfig-int4-configmap" + + var cmData = make(map[string]string) + cmData["camel.kamelet.iconfig04-timer-source.message"] = "very top mounted configmap message" + g.Expect(CreatePlainTextConfigmap(t, ctx, ns, cmName, cmData)).To(Succeed()) + + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/TimerKameletIntegrationConfiguration04.java", + "-t", "mount.configs=configmap:"+cmName, + "--name", name).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, name)).Should(ContainSubstring("very top mounted configmap message")) + + g.Expect(Kamel(t, ctx, "delete", name, "-n", ns).Execute()).To(Succeed()) + g.Eventually(Integration(t, ctx, ns, name), TestTimeoutLong).Should(BeNil()) + g.Expect(DeleteConfigmap(t, ctx, ns, cmName)).To(Succeed()) + g.Expect(DeleteKamelet(t, ctx, ns, "iconfig04-timer-source")).To(Succeed()) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) + + t.Run("run test named config using properties", func(t *testing.T) { + g.Expect(CreateTimerKamelet(t, ctx, operatorID, ns, "iconfig05-timer-source")()).To(Succeed()) + + name := RandomizedSuffixName("iconfig-test-timer-source-int5") + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/TimerKameletIntegrationNamedConfiguration05.java", + "-p", "camel.kamelet.iconfig05-timer-source.message='Default message 05'", + "-p", "camel.kamelet.iconfig05-timer-source.mynamedconfig.message='My Named Config message'", + "--name", name).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, name)).Should(ContainSubstring("My Named Config message")) + + g.Expect(Kamel(t, ctx, "delete", name, "-n", ns).Execute()).To(Succeed()) + g.Eventually(Integration(t, ctx, ns, name), TestTimeoutLong).Should(BeNil()) + g.Expect(DeleteKamelet(t, ctx, ns, "iconfig05-timer-source")).To(Succeed()) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) + + t.Run("run test named config using labeled secret", func(t *testing.T) { + g.Expect(CreateTimerKamelet(t, ctx, operatorID, ns, "iconfig06-timer-source")()).To(Succeed()) + + name := RandomizedSuffixName("iconfig-test-timer-source-int6") + secretName := "my-iconfig-int6-secret" + + var secData = make(map[string]string) + secData["camel.kamelet.iconfig06-timer-source.mynamedconfig.message"] = "very top named secret message" + var labels = make(map[string]string) + labels["camel.apache.org/kamelet"] = "iconfig06-timer-source" + labels["camel.apache.org/kamelet.configuration"] = "mynamedconfig" + g.Expect(CreatePlainTextSecretWithLabels(t, ctx, ns, secretName, secData, labels)).To(Succeed()) + g.Eventually(SecretByName(t, ctx, ns, secretName), TestTimeoutLong).Should(Not(BeNil())) + + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/TimerKameletIntegrationNamedConfiguration06.java", + "-p", "camel.kamelet.iconfig06-timer-source.message='Default message 06'", + "--name", name).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, name)).Should(ContainSubstring("very top named secret message")) + + g.Expect(Kamel(t, ctx, "delete", name, "-n", ns).Execute()).To(Succeed()) + g.Eventually(Integration(t, ctx, ns, name), TestTimeoutLong).Should(BeNil()) + g.Expect(DeleteSecret(t, ctx, ns, secretName)).To(Succeed()) + g.Eventually(SecretByName(t, ctx, ns, secretName), TestTimeoutLong).Should(BeNil()) + g.Expect(DeleteKamelet(t, ctx, ns, "iconfig06-timer-source")).To(Succeed()) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) + + t.Run("run test named config using mounted secret", func(t *testing.T) { + g.Expect(CreateTimerKamelet(t, ctx, operatorID, ns, "iconfig07-timer-source")()).To(Succeed()) + + name := RandomizedSuffixName("iconfig-test-timer-source-int7") + secretName := "my-iconfig-int7-secret" + + var secData = make(map[string]string) + secData["camel.kamelet.iconfig07-timer-source.mynamedconfig.message"] = "very top named mounted secret message" + g.Expect(CreatePlainTextSecret(t, ctx, ns, secretName, secData)).To(Succeed()) + g.Eventually(SecretByName(t, ctx, ns, secretName), TestTimeoutLong).Should(Not(BeNil())) + + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/TimerKameletIntegrationNamedConfiguration07.java", + "-p", "camel.kamelet.iconfig07-timer-source.message='Default message 07'", + "-t", "mount.configs=secret:"+secretName, + "--name", name).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, name)).Should(ContainSubstring("very top named mounted secret message")) + + g.Expect(Kamel(t, ctx, "delete", name, "-n", ns).Execute()).To(Succeed()) + g.Eventually(Integration(t, ctx, ns, name), TestTimeoutLong).Should(BeNil()) + g.Expect(DeleteSecret(t, ctx, ns, secretName)).To(Succeed()) + g.Eventually(SecretByName(t, ctx, ns, secretName), TestTimeoutLong).Should(BeNil()) + g.Expect(DeleteKamelet(t, ctx, ns, "iconfig07-timer-source")).To(Succeed()) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) + + t.Run("run test named config using mounted configmap", func(t *testing.T) { + g.Expect(CreateTimerKamelet(t, ctx, operatorID, ns, "iconfig08-timer-source")()).To(Succeed()) + + name := RandomizedSuffixName("iconfig-test-timer-source-int8") + cmName := "my-iconfig-int8-configmap" + + var cmData = make(map[string]string) + cmData["camel.kamelet.iconfig08-timer-source.mynamedconfig.message"] = "very top named mounted configmap message" + g.Expect(CreatePlainTextConfigmap(t, ctx, ns, cmName, cmData)).To(Succeed()) + + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/TimerKameletIntegrationNamedConfiguration08.java", + "-p", "camel.kamelet.iconfig08-timer-source.message='Default message 08'", + "-t", "mount.configs=configmap:"+cmName, + "--name", name).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, name)).Should(ContainSubstring("very top named mounted configmap message")) + + g.Expect(Kamel(t, ctx, "delete", name, "-n", ns).Execute()).To(Succeed()) + g.Eventually(Integration(t, ctx, ns, name), TestTimeoutLong).Should(BeNil()) + g.Expect(DeleteConfigmap(t, ctx, ns, cmName)).To(Succeed()) + g.Expect(DeleteKamelet(t, ctx, ns, "iconfig08-timer-source")).To(Succeed()) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) + + t.Run("run test default config using labeled secret", func(t *testing.T) { + g.Expect(CreateTimerKamelet(t, ctx, operatorID, ns, "iconfig09-timer-source")()).To(Succeed()) + + name := RandomizedSuffixName("iconfig-test-timer-source-int9") + secretName := "my-iconfig-int9-secret" + + var secData = make(map[string]string) + secData["camel.kamelet.iconfig09-timer-source.message"] = "very top labeled secret message" + var labels = make(map[string]string) + labels["camel.apache.org/kamelet"] = "iconfig09-timer-source" + g.Expect(CreatePlainTextSecretWithLabels(t, ctx, ns, secretName, secData, labels)).To(Succeed()) + g.Eventually(SecretByName(t, ctx, ns, secretName), TestTimeoutLong).Should(Not(BeNil())) + + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/TimerKameletIntegrationConfiguration09.java", + "--name", name).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, name)).Should(ContainSubstring("very top labeled secret message")) + + g.Expect(Kamel(t, ctx, "delete", name, "-n", ns).Execute()).To(Succeed()) + g.Eventually(Integration(t, ctx, ns, name), TestTimeoutLong).Should(BeNil()) + g.Expect(DeleteSecret(t, ctx, ns, secretName)).To(Succeed()) + g.Eventually(SecretByName(t, ctx, ns, secretName), TestTimeoutLong).Should(BeNil()) + g.Expect(DeleteKamelet(t, ctx, ns, "iconfig09-timer-source")).To(Succeed()) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) + + t.Run("run test default config inlined properties", func(t *testing.T) { + g.Expect(CreateTimerKamelet(t, ctx, operatorID, ns, "config01-timer-source")()).To(Succeed()) + g.Expect(CreateLogKamelet(t, ctx, operatorID, ns, "config01-log-sink")()).To(Succeed()) + + name := RandomizedSuffixName("config-test-timer-source-int1") + + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/timer-kamelet-integration-inlined-configuration-01.yaml", + "--name", name).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, name)).Should(ContainSubstring("important message")) + g.Eventually(IntegrationLogs(t, ctx, ns, name)).Should(ContainSubstring("integrationLogger")) + + g.Expect(Kamel(t, ctx, "delete", name, "-n", ns).Execute()).To(Succeed()) + g.Eventually(Integration(t, ctx, ns, name), TestTimeoutLong).Should(BeNil()) + g.Expect(DeleteKamelet(t, ctx, ns, "config01-timer-source")).To(Succeed()) + g.Expect(DeleteKamelet(t, ctx, ns, "config01-log-sink")).To(Succeed()) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) + + t.Run("run test default config parameters properties", func(t *testing.T) { + + g.Expect(CreateTimerKamelet(t, ctx, operatorID, ns, "config02-timer-source")()).To(Succeed()) + g.Expect(CreateLogKamelet(t, ctx, operatorID, ns, "config02-log-sink")()).To(Succeed()) + + name := RandomizedSuffixName("config-test-timer-source-int2") + + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/timer-kamelet-integration-parameters-configuration-02.yaml", + "-p", "my-message='My parameter message 02'", + "-p", "my-logger='myIntegrationLogger02'", + "--name", name).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, name)).Should(ContainSubstring("My parameter message 02")) + g.Eventually(IntegrationLogs(t, ctx, ns, name)).Should(ContainSubstring("myIntegrationLogger02")) + + g.Expect(Kamel(t, ctx, "delete", name, "-n", ns).Execute()).To(Succeed()) + g.Eventually(Integration(t, ctx, ns, name), TestTimeoutLong).Should(BeNil()) + g.Expect(DeleteKamelet(t, ctx, ns, "config02-timer-source")).To(Succeed()) + g.Expect(DeleteKamelet(t, ctx, ns, "config02-log-sink")).To(Succeed()) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) - Expect(CreateTimerKamelet(ns, "iconfig07-timer-source")()).To(Succeed()) + t.Run("run test default config secret properties", func(t *testing.T) { - name := RandomizedSuffixName("iconfig-test-timer-source-int7") - secretName := "my-iconfig-int7-secret" + g.Expect(CreateTimerKamelet(t, ctx, operatorID, ns, "config03-timer-source")()).To(Succeed()) + g.Expect(CreateLogKamelet(t, ctx, operatorID, ns, "config03-log-sink")()).To(Succeed()) - var secData = make(map[string]string) - secData["camel.kamelet.iconfig07-timer-source.mynamedconfig.message"] = "very top named mounted secret message" - Expect(CreatePlainTextSecret(ns, secretName, secData)).To(Succeed()) - Eventually(SecretByName(ns, secretName), TestTimeoutLong).Should(Not(BeNil())) + name := RandomizedSuffixName("config-test-timer-source-int3") + secretName := "my-config-int3-secret" - Expect(KamelRunWithID(operatorID, ns, "files/TimerKameletIntegrationNamedConfiguration07.java", - "-p", "camel.kamelet.iconfig07-timer-source.message='Default message 07'", - "-t", "mount.configs=secret:"+secretName, - "--name", name).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns, name)).Should(ContainSubstring("very top named mounted secret message")) + var secData = make(map[string]string) + secData["my-message"] = "My secret message 03" + secData["my-logger"] = "mySecretIntegrationLogger03" + g.Expect(CreatePlainTextSecret(t, ctx, ns, secretName, secData)).To(Succeed()) + + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/timer-kamelet-integration-parameters-configuration-03.yaml", + "-t", "mount.configs=secret:"+secretName, + "--name", name).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, name)).Should(ContainSubstring("My secret message 03")) + g.Eventually(IntegrationLogs(t, ctx, ns, name)).Should(ContainSubstring("mySecretIntegrationLogger03")) - Expect(Kamel("delete", name, "-n", ns).Execute()).To(Succeed()) - Eventually(Integration(ns, name), TestTimeoutLong).Should(BeNil()) - Expect(DeleteSecret(ns, secretName)).To(Succeed()) - Eventually(SecretByName(ns, secretName), TestTimeoutLong).Should(BeNil()) - Expect(DeleteKamelet(ns, "iconfig07-timer-source")).To(Succeed()) - }) - - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) -} - -func TestKameletImplicitConfigNamedMountedConfigmap(t *testing.T) { - RegisterTestingT(t) - - t.Run("run test named config using mounted configmap", func(t *testing.T) { - - Expect(CreateTimerKamelet(ns, "iconfig08-timer-source")()).To(Succeed()) - - name := RandomizedSuffixName("iconfig-test-timer-source-int8") - cmName := "my-iconfig-int8-configmap" - - var cmData = make(map[string]string) - cmData["camel.kamelet.iconfig08-timer-source.mynamedconfig.message"] = "very top named mounted configmap message" - Expect(CreatePlainTextConfigmap(ns, cmName, cmData)).To(Succeed()) - - Expect(KamelRunWithID(operatorID, ns, "files/TimerKameletIntegrationNamedConfiguration08.java", - "-p", "camel.kamelet.iconfig08-timer-source.message='Default message 08'", - "-t", "mount.configs=configmap:"+cmName, - "--name", name).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns, name)).Should(ContainSubstring("very top named mounted configmap message")) - - Expect(Kamel("delete", name, "-n", ns).Execute()).To(Succeed()) - Eventually(Integration(ns, name), TestTimeoutLong).Should(BeNil()) - Expect(DeleteConfigmap(ns, cmName)).To(Succeed()) - Expect(DeleteKamelet(ns, "iconfig08-timer-source")).To(Succeed()) - }) - - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) -} - -func TestKameletImplicitConfigDefaultLabeledSecret(t *testing.T) { - RegisterTestingT(t) - - t.Run("run test default config using labeled secret", func(t *testing.T) { - - Expect(CreateTimerKamelet(ns, "iconfig09-timer-source")()).To(Succeed()) - - name := RandomizedSuffixName("iconfig-test-timer-source-int9") - secretName := "my-iconfig-int9-secret" - - var secData = make(map[string]string) - secData["camel.kamelet.iconfig09-timer-source.message"] = "very top labeled secret message" - var labels = make(map[string]string) - labels["camel.apache.org/kamelet"] = "iconfig09-timer-source" - Expect(CreatePlainTextSecretWithLabels(ns, secretName, secData, labels)).To(Succeed()) - Eventually(SecretByName(ns, secretName), TestTimeoutLong).Should(Not(BeNil())) - - Expect(KamelRunWithID(operatorID, ns, "files/TimerKameletIntegrationConfiguration09.java", - "--name", name).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns, name)).Should(ContainSubstring("very top labeled secret message")) - - Expect(Kamel("delete", name, "-n", ns).Execute()).To(Succeed()) - Eventually(Integration(ns, name), TestTimeoutLong).Should(BeNil()) - Expect(DeleteSecret(ns, secretName)).To(Succeed()) - Eventually(SecretByName(ns, secretName), TestTimeoutLong).Should(BeNil()) - Expect(DeleteKamelet(ns, "iconfig09-timer-source")).To(Succeed()) - }) - - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) -} - -// Tests on integration with kamelets containing configuration from properties and secrets with parameters inside the integration. - -func TestKameletConfigInlinedUserPropery(t *testing.T) { - RegisterTestingT(t) - t.Run("run test default config inlined properties", func(t *testing.T) { - - Expect(CreateTimerKamelet(ns, "config01-timer-source")()).To(Succeed()) - Expect(CreateLogKamelet(ns, "config01-log-sink")()).To(Succeed()) - - name := RandomizedSuffixName("config-test-timer-source-int1") - - Expect(KamelRunWithID(operatorID, ns, "files/timer-kamelet-integration-inlined-configuration-01.yaml", - "--name", name).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns, name)).Should(ContainSubstring("important message")) - Eventually(IntegrationLogs(ns, name)).Should(ContainSubstring("integrationLogger")) - - Expect(Kamel("delete", name, "-n", ns).Execute()).To(Succeed()) - Eventually(Integration(ns, name), TestTimeoutLong).Should(BeNil()) - Expect(DeleteKamelet(ns, "config01-timer-source")).To(Succeed()) - Expect(DeleteKamelet(ns, "config01-log-sink")).To(Succeed()) - }) + g.Expect(Kamel(t, ctx, "delete", name, "-n", ns).Execute()).To(Succeed()) + g.Eventually(Integration(t, ctx, ns, name), TestTimeoutLong).Should(BeNil()) + g.Expect(DeleteSecret(t, ctx, ns, secretName)).To(Succeed()) + g.Expect(DeleteKamelet(t, ctx, ns, "config03-timer-source")).To(Succeed()) + g.Expect(DeleteKamelet(t, ctx, ns, "config03-log-sink")).To(Succeed()) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) -} - -func TestKameletConfigDefaultParamUserPropery(t *testing.T) { - RegisterTestingT(t) - t.Run("run test default config parameters properties", func(t *testing.T) { - - Expect(CreateTimerKamelet(ns, "config02-timer-source")()).To(Succeed()) - Expect(CreateLogKamelet(ns, "config02-log-sink")()).To(Succeed()) - - name := RandomizedSuffixName("config-test-timer-source-int2") - - Expect(KamelRunWithID(operatorID, ns, "files/timer-kamelet-integration-parameters-configuration-02.yaml", - "-p", "my-message='My parameter message 02'", - "-p", "my-logger='myIntegrationLogger02'", - "--name", name).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns, name)).Should(ContainSubstring("My parameter message 02")) - Eventually(IntegrationLogs(ns, name)).Should(ContainSubstring("myIntegrationLogger02")) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) - Expect(Kamel("delete", name, "-n", ns).Execute()).To(Succeed()) - Eventually(Integration(ns, name), TestTimeoutLong).Should(BeNil()) - Expect(DeleteKamelet(ns, "config02-timer-source")).To(Succeed()) - Expect(DeleteKamelet(ns, "config02-log-sink")).To(Succeed()) - }) + t.Run("run test default config configmap properties", func(t *testing.T) { + + g.Expect(CreateTimerKamelet(t, ctx, operatorID, ns, "config04-timer-source")()).To(Succeed()) + g.Expect(CreateLogKamelet(t, ctx, operatorID, ns, "config04-log-sink")()).To(Succeed()) + + name := RandomizedSuffixName("config-test-timer-source-int4") + cmName := "my-config-int4-configmap" + + var cmData = make(map[string]string) + cmData["my-message"] = "My configmap message 04" + cmData["my-logger"] = "myConfigmapIntegrationLogger04" + g.Expect(CreatePlainTextConfigmap(t, ctx, ns, cmName, cmData)).To(Succeed()) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) -} + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/timer-kamelet-integration-parameters-configuration-04.yaml", + "-t", "mount.configs=configmap:"+cmName, + "--name", name).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, name)).Should(ContainSubstring("My configmap message 04")) + g.Eventually(IntegrationLogs(t, ctx, ns, name)).Should(ContainSubstring("myConfigmapIntegrationLogger04")) -func TestKameletConfigDefaultParamMountedSecret(t *testing.T) { - RegisterTestingT(t) - t.Run("run test default config secret properties", func(t *testing.T) { - - Expect(CreateTimerKamelet(ns, "config03-timer-source")()).To(Succeed()) - Expect(CreateLogKamelet(ns, "config03-log-sink")()).To(Succeed()) - - name := RandomizedSuffixName("config-test-timer-source-int3") - secretName := "my-config-int3-secret" - - var secData = make(map[string]string) - secData["my-message"] = "My secret message 03" - secData["my-logger"] = "mySecretIntegrationLogger03" - Expect(CreatePlainTextSecret(ns, secretName, secData)).To(Succeed()) - - Expect(KamelRunWithID(operatorID, ns, "files/timer-kamelet-integration-parameters-configuration-03.yaml", - "-t", "mount.configs=secret:"+secretName, - "--name", name).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns, name)).Should(ContainSubstring("My secret message 03")) - Eventually(IntegrationLogs(ns, name)).Should(ContainSubstring("mySecretIntegrationLogger03")) - - Expect(Kamel("delete", name, "-n", ns).Execute()).To(Succeed()) - Eventually(Integration(ns, name), TestTimeoutLong).Should(BeNil()) - Expect(DeleteSecret(ns, secretName)).To(Succeed()) - Expect(DeleteKamelet(ns, "config03-timer-source")).To(Succeed()) - Expect(DeleteKamelet(ns, "config03-log-sink")).To(Succeed()) - }) + g.Expect(Kamel(t, ctx, "delete", name, "-n", ns).Execute()).To(Succeed()) + g.Eventually(Integration(t, ctx, ns, name), TestTimeoutLong).Should(BeNil()) + g.Expect(DeleteConfigmap(t, ctx, ns, cmName)).To(Succeed()) + g.Expect(DeleteKamelet(t, ctx, ns, "config04-timer-source")).To(Succeed()) + g.Expect(DeleteKamelet(t, ctx, ns, "config04-log-sink")).To(Succeed()) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) -} + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) -func TestKameletConfigDefaultParamMountedConfigmap(t *testing.T) { - RegisterTestingT(t) - t.Run("run test default config configmap properties", func(t *testing.T) { - - Expect(CreateTimerKamelet(ns, "config04-timer-source")()).To(Succeed()) - Expect(CreateLogKamelet(ns, "config04-log-sink")()).To(Succeed()) - - name := RandomizedSuffixName("config-test-timer-source-int4") - cmName := "my-config-int4-configmap" - - var cmData = make(map[string]string) - cmData["my-message"] = "My configmap message 04" - cmData["my-logger"] = "myConfigmapIntegrationLogger04" - Expect(CreatePlainTextConfigmap(ns, cmName, cmData)).To(Succeed()) - - Expect(KamelRunWithID(operatorID, ns, "files/timer-kamelet-integration-parameters-configuration-04.yaml", - "-t", "mount.configs=configmap:"+cmName, - "--name", name).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns, name)).Should(ContainSubstring("My configmap message 04")) - Eventually(IntegrationLogs(ns, name)).Should(ContainSubstring("myConfigmapIntegrationLogger04")) - - Expect(Kamel("delete", name, "-n", ns).Execute()).To(Succeed()) - Eventually(Integration(ns, name), TestTimeoutLong).Should(BeNil()) - Expect(DeleteConfigmap(ns, cmName)).To(Succeed()) - Expect(DeleteKamelet(ns, "config04-timer-source")).To(Succeed()) - Expect(DeleteKamelet(ns, "config04-log-sink")).To(Succeed()) }) - - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) } diff --git a/e2e/common/config/pipe_config_test.go b/e2e/common/config/pipe_config_test.go index caf93ece9f..3c3acc4382 100644 --- a/e2e/common/config/pipe_config_test.go +++ b/e2e/common/config/pipe_config_test.go @@ -23,211 +23,221 @@ limitations under the License. package config import ( + "context" "testing" . "github.com/onsi/gomega" corev1 "k8s.io/api/core/v1" . "github.com/apache/camel-k/v2/e2e/support" + v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" ) // Tests on pipe with kamelets containing configuration from properties and secrets. func TestPipeConfig(t *testing.T) { - RegisterTestingT(t) - t.Run("test custom source/sink pipe", func(t *testing.T) { - Expect(CreateTimerKamelet(ns, "my-pipe-timer-source")()).To(Succeed()) - Expect(CreateLogKamelet(ns, "my-pipe-log-sink")()).To(Succeed()) - t.Run("run test default config using properties", func(t *testing.T) { - name := RandomizedSuffixName("my-pipe-with-properties") - - Expect(KamelBindWithID(operatorID, ns, - "my-pipe-timer-source", - "my-pipe-log-sink", - "-p", "source.message=My pipe message", - "-p", "sink.loggerName=myPipeLogger", - "--name", name, - ).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns, name)).Should(ContainSubstring("My pipe message")) - Eventually(IntegrationLogs(ns, name)).Should(ContainSubstring("myPipeLogger")) - - Expect(Kamel("delete", name, "-n", ns).Execute()).To(Succeed()) + t.Parallel() + + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-pipe-config" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + + t.Run("test custom source/sink pipe", func(t *testing.T) { + g.Expect(CreateTimerKamelet(t, ctx, operatorID, ns, "my-pipe-timer-source")()).To(Succeed()) + g.Expect(CreateLogKamelet(t, ctx, operatorID, ns, "my-pipe-log-sink")()).To(Succeed()) + t.Run("run test default config using properties", func(t *testing.T) { + name := RandomizedSuffixName("my-pipe-with-properties") + + g.Expect(KamelBindWithID(t, ctx, operatorID, ns, + "my-pipe-timer-source", + "my-pipe-log-sink", + "-p", "source.message=My pipe message", + "-p", "sink.loggerName=myPipeLogger", + "--name", name, + ).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, name)).Should(ContainSubstring("My pipe message")) + g.Eventually(IntegrationLogs(t, ctx, ns, name)).Should(ContainSubstring("myPipeLogger")) + + g.Expect(Kamel(t, ctx, "delete", name, "-n", ns).Execute()).To(Succeed()) + }) + + t.Run("run test implicit default config using labeled secret", func(t *testing.T) { + name := RandomizedSuffixName("my-pipe-with-default-implicit-secret") + secretName := "my-pipe-default-implicit-secret" + + var secData = make(map[string]string) + secData["camel.kamelet.my-pipe-timer-source.message"] = "My pipe secret message" + var labels = make(map[string]string) + labels["camel.apache.org/kamelet"] = "my-pipe-timer-source" + g.Expect(CreatePlainTextSecretWithLabels(t, ctx, ns, secretName, secData, labels)).To(Succeed()) + + g.Expect(KamelBindWithID(t, ctx, operatorID, ns, + "my-pipe-timer-source", + "my-pipe-log-sink", + "-p", "sink.loggerName=myDefaultLogger", + "--name", name, + ).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, name)).Should(ContainSubstring("My pipe secret message")) + g.Eventually(IntegrationLogs(t, ctx, ns, name)).Should(ContainSubstring("myDefaultLogger")) + + g.Expect(Kamel(t, ctx, "delete", name, "-n", ns).Execute()).To(Succeed()) + g.Expect(DeleteSecret(t, ctx, ns, secretName)).To(Succeed()) + }) + + t.Run("run test implicit default config using mounted secret", func(t *testing.T) { + name := RandomizedSuffixName("my-pipe-with-default-implicit-secret") + secretName := "my-pipe-default-implicit-secret" + + var secData = make(map[string]string) + secData["camel.kamelet.my-pipe-timer-source.message"] = "My pipe secret message" + secData["camel.kamelet.my-pipe-log-sink.loggerName"] = "myPipeSecretLogger" + g.Expect(CreatePlainTextSecret(t, ctx, ns, secretName, secData)).To(Succeed()) + + g.Expect(KamelBindWithID(t, ctx, operatorID, ns, + "my-pipe-timer-source", + "my-pipe-log-sink", + "-t", "mount.configs=secret:"+secretName, + "--name", name, + ).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, name)).Should(ContainSubstring("My pipe secret message")) + g.Eventually(IntegrationLogs(t, ctx, ns, name)).Should(ContainSubstring("myPipeSecretLogger")) + + g.Expect(Kamel(t, ctx, "delete", name, "-n", ns).Execute()).To(Succeed()) + g.Expect(DeleteSecret(t, ctx, ns, secretName)).To(Succeed()) + }) + + t.Run("run test implicit default config using mounted configmap", func(t *testing.T) { + name := RandomizedSuffixName("my-pipe-with-default-implicit-configmap") + cmName := "my-pipe-default-implicit-configmap" + + var cmData = make(map[string]string) + cmData["camel.kamelet.my-pipe-timer-source.message"] = "My pipe configmap message" + cmData["camel.kamelet.my-pipe-log-sink.loggerName"] = "myPipeConfigmapLogger" + g.Expect(CreatePlainTextConfigmap(t, ctx, ns, cmName, cmData)).To(Succeed()) + + g.Expect(KamelBindWithID(t, ctx, operatorID, ns, + "my-pipe-timer-source", + "my-pipe-log-sink", + "-t", "mount.configs=configmap:"+cmName, + "--name", name, + ).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, name)).Should(ContainSubstring("My pipe configmap message")) + g.Eventually(IntegrationLogs(t, ctx, ns, name)).Should(ContainSubstring("myPipeConfigmapLogger")) + + g.Expect(Kamel(t, ctx, "delete", name, "-n", ns).Execute()).To(Succeed()) + g.Expect(DeleteConfigmap(t, ctx, ns, cmName)).To(Succeed()) + }) + + t.Run("run test implicit named config using mounted secret", func(t *testing.T) { + name := RandomizedSuffixName("my-pipe-with-named-implicit-secret") + secretName := "my-pipe-named-implicit-secret" + + var secData = make(map[string]string) + secData["camel.kamelet.my-pipe-timer-source.mynamedconfig.message"] = "My pipe named secret message" + secData["camel.kamelet.my-pipe-log-sink.mynamedconfig.loggerName"] = "myPipeNamedSecretLogger" + g.Expect(CreatePlainTextSecret(t, ctx, ns, secretName, secData)).To(Succeed()) + + g.Expect(KamelBindWithID(t, ctx, operatorID, ns, + "my-pipe-timer-source", + "my-pipe-log-sink", + "-t", "mount.configs=secret:"+secretName, + "-p", "source.message={{mynamedconfig.message}}", + "-p", "sink.loggerName={{mynamedconfig.loggerName}}", + "--name", name, + ).Execute()).To(Succeed()) + + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, name)).Should(ContainSubstring("My pipe named secret message")) + g.Eventually(IntegrationLogs(t, ctx, ns, name)).Should(ContainSubstring("myPipeNamedSecretLogger")) + + g.Expect(Kamel(t, ctx, "delete", name, "-n", ns).Execute()).To(Succeed()) + g.Expect(DeleteSecret(t, ctx, ns, secretName)).To(Succeed()) + }) + + t.Run("run test implicit named config using mounted configmap", func(t *testing.T) { + name := RandomizedSuffixName("my-pipe-with-named-implicit-configmap") + cmName := "my-pipe-named-implicit-configmap" + + var cmData = make(map[string]string) + cmData["camel.kamelet.my-pipe-timer-source.mynamedconfig.message"] = "My pipe named configmap message" + cmData["camel.kamelet.my-pipe-log-sink.mynamedconfig.loggerName"] = "myPipeNamedConfigmapLogger" + g.Expect(CreatePlainTextConfigmap(t, ctx, ns, cmName, cmData)).To(Succeed()) + + g.Expect(KamelBindWithID(t, ctx, operatorID, ns, + "my-pipe-timer-source", + "my-pipe-log-sink", + "-t", "mount.configs=configmap:"+cmName, + "-p", "source.message={{mynamedconfig.message}}", + "-p", "sink.loggerName={{mynamedconfig.loggerName}}", + "--name", name, + ).Execute()).To(Succeed()) + + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, name)).Should(ContainSubstring("My pipe named configmap message")) + g.Eventually(IntegrationLogs(t, ctx, ns, name)).Should(ContainSubstring("myPipeNamedConfigmapLogger")) + + g.Expect(Kamel(t, ctx, "delete", name, "-n", ns).Execute()).To(Succeed()) + g.Expect(DeleteConfigmap(t, ctx, ns, cmName)).To(Succeed()) + }) + t.Run("run test implicit specific config using mounted secret", func(t *testing.T) { + name := RandomizedSuffixName("my-pipe-with-specific-secret") + secretName := "my-pipe-specific-secret" + + var secData = make(map[string]string) + secData["mynamedconfig.message"] = "My pipe specific secret message" + secData["mynamedconfig.loggerName"] = "myPipeSpecificSecretLogger" + g.Expect(CreatePlainTextSecret(t, ctx, ns, secretName, secData)).To(Succeed()) + + g.Expect(KamelBindWithID(t, ctx, operatorID, ns, + "my-pipe-timer-source", + "my-pipe-log-sink", + "-t", "mount.configs=secret:"+secretName, + "-p", "source.message={{mynamedconfig.message}}", + "-p", "sink.loggerName={{mynamedconfig.loggerName}}", + "--name", name, + ).Execute()).To(Succeed()) + + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, name)).Should(ContainSubstring("My pipe specific secret message")) + g.Eventually(IntegrationLogs(t, ctx, ns, name)).Should(ContainSubstring("myPipeSpecificSecretLogger")) + + g.Expect(Kamel(t, ctx, "delete", name, "-n", ns).Execute()).To(Succeed()) + g.Expect(DeleteSecret(t, ctx, ns, secretName)).To(Succeed()) + }) + t.Run("run test implicit specific config using mounted configmap", func(t *testing.T) { + name := RandomizedSuffixName("my-pipe-with-specific-configmap") + cmName := "my-pipe-specific-configmap" + + var cmData = make(map[string]string) + cmData["mynamedconfig.message"] = "My pipe specific configmap message" + cmData["mynamedconfig.loggerName"] = "myPipeSpecificConfgmapLogger" + g.Expect(CreatePlainTextConfigmap(t, ctx, ns, cmName, cmData)).To(Succeed()) + + g.Expect(KamelBindWithID(t, ctx, operatorID, ns, + "my-pipe-timer-source", + "my-pipe-log-sink", + "-t", "mount.configs=configmap:"+cmName, + "-p", "source.message={{mynamedconfig.message}}", + "-p", "sink.loggerName={{mynamedconfig.loggerName}}", + "--name", name, + ).Execute()).To(Succeed()) + + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, name)).Should(ContainSubstring("My pipe specific configmap message")) + g.Eventually(IntegrationLogs(t, ctx, ns, name)).Should(ContainSubstring("myPipeSpecificConfgmapLogger")) + + g.Expect(Kamel(t, ctx, "delete", name, "-n", ns).Execute()).To(Succeed()) + g.Expect(DeleteConfigmap(t, ctx, ns, cmName)).To(Succeed()) + }) }) - t.Run("run test implicit default config using labeled secret", func(t *testing.T) { - name := RandomizedSuffixName("my-pipe-with-default-implicit-secret") - secretName := "my-pipe-default-implicit-secret" - - var secData = make(map[string]string) - secData["camel.kamelet.my-pipe-timer-source.message"] = "My pipe secret message" - var labels = make(map[string]string) - labels["camel.apache.org/kamelet"] = "my-pipe-timer-source" - Expect(CreatePlainTextSecretWithLabels(ns, secretName, secData, labels)).To(Succeed()) - - Expect(KamelBindWithID(operatorID, ns, - "my-pipe-timer-source", - "my-pipe-log-sink", - "-p", "sink.loggerName=myDefaultLogger", - "--name", name, - ).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns, name)).Should(ContainSubstring("My pipe secret message")) - Eventually(IntegrationLogs(ns, name)).Should(ContainSubstring("myDefaultLogger")) - - Expect(Kamel("delete", name, "-n", ns).Execute()).To(Succeed()) - Expect(DeleteSecret(ns, secretName)).To(Succeed()) - }) - - t.Run("run test implicit default config using mounted secret", func(t *testing.T) { - name := RandomizedSuffixName("my-pipe-with-default-implicit-secret") - secretName := "my-pipe-default-implicit-secret" - - var secData = make(map[string]string) - secData["camel.kamelet.my-pipe-timer-source.message"] = "My pipe secret message" - secData["camel.kamelet.my-pipe-log-sink.loggerName"] = "myPipeSecretLogger" - Expect(CreatePlainTextSecret(ns, secretName, secData)).To(Succeed()) - - Expect(KamelBindWithID(operatorID, ns, - "my-pipe-timer-source", - "my-pipe-log-sink", - "-t", "mount.configs=secret:"+secretName, - "--name", name, - ).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns, name)).Should(ContainSubstring("My pipe secret message")) - Eventually(IntegrationLogs(ns, name)).Should(ContainSubstring("myPipeSecretLogger")) - - Expect(Kamel("delete", name, "-n", ns).Execute()).To(Succeed()) - Expect(DeleteSecret(ns, secretName)).To(Succeed()) - }) - - t.Run("run test implicit default config using mounted configmap", func(t *testing.T) { - name := RandomizedSuffixName("my-pipe-with-default-implicit-configmap") - cmName := "my-pipe-default-implicit-configmap" - - var cmData = make(map[string]string) - cmData["camel.kamelet.my-pipe-timer-source.message"] = "My pipe configmap message" - cmData["camel.kamelet.my-pipe-log-sink.loggerName"] = "myPipeConfigmapLogger" - Expect(CreatePlainTextConfigmap(ns, cmName, cmData)).To(Succeed()) - - Expect(KamelBindWithID(operatorID, ns, - "my-pipe-timer-source", - "my-pipe-log-sink", - "-t", "mount.configs=configmap:"+cmName, - "--name", name, - ).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns, name)).Should(ContainSubstring("My pipe configmap message")) - Eventually(IntegrationLogs(ns, name)).Should(ContainSubstring("myPipeConfigmapLogger")) - - Expect(Kamel("delete", name, "-n", ns).Execute()).To(Succeed()) - Expect(DeleteConfigmap(ns, cmName)).To(Succeed()) - }) - - t.Run("run test implicit named config using mounted secret", func(t *testing.T) { - name := RandomizedSuffixName("my-pipe-with-named-implicit-secret") - secretName := "my-pipe-named-implicit-secret" - - var secData = make(map[string]string) - secData["camel.kamelet.my-pipe-timer-source.mynamedconfig.message"] = "My pipe named secret message" - secData["camel.kamelet.my-pipe-log-sink.mynamedconfig.loggerName"] = "myPipeNamedSecretLogger" - Expect(CreatePlainTextSecret(ns, secretName, secData)).To(Succeed()) - - Expect(KamelBindWithID(operatorID, ns, - "my-pipe-timer-source", - "my-pipe-log-sink", - "-t", "mount.configs=secret:"+secretName, - "-p", "source.message={{mynamedconfig.message}}", - "-p", "sink.loggerName={{mynamedconfig.loggerName}}", - "--name", name, - ).Execute()).To(Succeed()) - - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns, name)).Should(ContainSubstring("My pipe named secret message")) - Eventually(IntegrationLogs(ns, name)).Should(ContainSubstring("myPipeNamedSecretLogger")) - - Expect(Kamel("delete", name, "-n", ns).Execute()).To(Succeed()) - Expect(DeleteSecret(ns, secretName)).To(Succeed()) - }) - - t.Run("run test implicit named config using mounted configmap", func(t *testing.T) { - name := RandomizedSuffixName("my-pipe-with-named-implicit-configmap") - cmName := "my-pipe-named-implicit-configmap" - - var cmData = make(map[string]string) - cmData["camel.kamelet.my-pipe-timer-source.mynamedconfig.message"] = "My pipe named configmap message" - cmData["camel.kamelet.my-pipe-log-sink.mynamedconfig.loggerName"] = "myPipeNamedConfigmapLogger" - Expect(CreatePlainTextConfigmap(ns, cmName, cmData)).To(Succeed()) - - Expect(KamelBindWithID(operatorID, ns, - "my-pipe-timer-source", - "my-pipe-log-sink", - "-t", "mount.configs=configmap:"+cmName, - "-p", "source.message={{mynamedconfig.message}}", - "-p", "sink.loggerName={{mynamedconfig.loggerName}}", - "--name", name, - ).Execute()).To(Succeed()) - - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns, name)).Should(ContainSubstring("My pipe named configmap message")) - Eventually(IntegrationLogs(ns, name)).Should(ContainSubstring("myPipeNamedConfigmapLogger")) - - Expect(Kamel("delete", name, "-n", ns).Execute()).To(Succeed()) - Expect(DeleteConfigmap(ns, cmName)).To(Succeed()) - }) - t.Run("run test implicit specific config using mounted secret", func(t *testing.T) { - name := RandomizedSuffixName("my-pipe-with-specific-secret") - secretName := "my-pipe-specific-secret" - - var secData = make(map[string]string) - secData["mynamedconfig.message"] = "My pipe specific secret message" - secData["mynamedconfig.loggerName"] = "myPipeSpecificSecretLogger" - Expect(CreatePlainTextSecret(ns, secretName, secData)).To(Succeed()) - - Expect(KamelBindWithID(operatorID, ns, - "my-pipe-timer-source", - "my-pipe-log-sink", - "-t", "mount.configs=secret:"+secretName, - "-p", "source.message={{mynamedconfig.message}}", - "-p", "sink.loggerName={{mynamedconfig.loggerName}}", - "--name", name, - ).Execute()).To(Succeed()) - - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns, name)).Should(ContainSubstring("My pipe specific secret message")) - Eventually(IntegrationLogs(ns, name)).Should(ContainSubstring("myPipeSpecificSecretLogger")) - - Expect(Kamel("delete", name, "-n", ns).Execute()).To(Succeed()) - Expect(DeleteSecret(ns, secretName)).To(Succeed()) - }) - t.Run("run test implicit specific config using mounted configmap", func(t *testing.T) { - name := RandomizedSuffixName("my-pipe-with-specific-configmap") - cmName := "my-pipe-specific-configmap" - - var cmData = make(map[string]string) - cmData["mynamedconfig.message"] = "My pipe specific configmap message" - cmData["mynamedconfig.loggerName"] = "myPipeSpecificConfgmapLogger" - Expect(CreatePlainTextConfigmap(ns, cmName, cmData)).To(Succeed()) - - Expect(KamelBindWithID(operatorID, ns, - "my-pipe-timer-source", - "my-pipe-log-sink", - "-t", "mount.configs=configmap:"+cmName, - "-p", "source.message={{mynamedconfig.message}}", - "-p", "sink.loggerName={{mynamedconfig.loggerName}}", - "--name", name, - ).Execute()).To(Succeed()) - - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns, name)).Should(ContainSubstring("My pipe specific configmap message")) - Eventually(IntegrationLogs(ns, name)).Should(ContainSubstring("myPipeSpecificConfgmapLogger")) - - Expect(Kamel("delete", name, "-n", ns).Execute()).To(Succeed()) - Expect(DeleteConfigmap(ns, cmName)).To(Succeed()) - }) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) - - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) - Expect(DeleteKamelet(ns, "my-pipe-timer-source")).To(Succeed()) - Expect(DeleteKamelet(ns, "my-pipe-log-sink")).To(Succeed()) } diff --git a/e2e/common/languages/default.go b/e2e/common/languages/default.go deleted file mode 100644 index 433ca1e6f0..0000000000 --- a/e2e/common/languages/default.go +++ /dev/null @@ -1,26 +0,0 @@ -//go:build integration -// +build integration - -/* -Licensed to the Apache Software Foundation (ASF) under one or more -contributor license agreements. See the NOTICE file distributed with -this work for additional information regarding copyright ownership. -The ASF licenses this file to You under the Apache License, Version 2.0 -(the "License"); you may not use this file except in compliance with -the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package languages - -import "github.com/apache/camel-k/v2/e2e/support" - -var ns = support.GetEnvOrDefault("CAMEL_K_TEST_NAMESPACE", support.GetCIProcessID()) -var operatorID = support.GetEnvOrDefault("CAMEL_K_OPERATOR_ID", support.GetCIProcessID()) diff --git a/e2e/common/languages/groovy_test.go b/e2e/common/languages/groovy_test.go index 253081bef7..424f1d02e5 100644 --- a/e2e/common/languages/groovy_test.go +++ b/e2e/common/languages/groovy_test.go @@ -23,25 +23,35 @@ limitations under the License. package languages import ( + "context" "testing" . "github.com/onsi/gomega" - v1 "k8s.io/api/core/v1" + corev1 "k8s.io/api/core/v1" . "github.com/apache/camel-k/v2/e2e/support" - camelv1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" + v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" ) func TestRunSimpleGroovyExamples(t *testing.T) { - RegisterTestingT(t) + t.Parallel() - t.Run("run groovy", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "files/groovy.groovy").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "groovy"), TestTimeoutLong).Should(Equal(v1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "groovy", camelv1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(v1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "groovy"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - }) + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-runtimes-groovy" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + t.Run("run groovy", func(t *testing.T) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/groovy.groovy").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "groovy"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "groovy", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "groovy"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + }) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) } diff --git a/e2e/common/languages/java_test.go b/e2e/common/languages/java_test.go index 903fd083be..7a94420f42 100644 --- a/e2e/common/languages/java_test.go +++ b/e2e/common/languages/java_test.go @@ -23,25 +23,35 @@ limitations under the License. package languages import ( + "context" "testing" . "github.com/onsi/gomega" - v1 "k8s.io/api/core/v1" + corev1 "k8s.io/api/core/v1" . "github.com/apache/camel-k/v2/e2e/support" - camelv1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" + v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" ) func TestRunSimpleJavaExamples(t *testing.T) { - RegisterTestingT(t) + t.Parallel() - t.Run("run java", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "files/Java.java").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "java"), TestTimeoutLong).Should(Equal(v1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "java", camelv1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(v1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "java"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - }) + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-runtimes-java" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + t.Run("run java", func(t *testing.T) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "java"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "java", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "java"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + }) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) } diff --git a/e2e/common/languages/js_test.go b/e2e/common/languages/js_test.go index 8bf0c42954..a07d3dbe94 100644 --- a/e2e/common/languages/js_test.go +++ b/e2e/common/languages/js_test.go @@ -23,25 +23,35 @@ limitations under the License. package languages import ( + "context" "testing" . "github.com/onsi/gomega" - v1 "k8s.io/api/core/v1" + corev1 "k8s.io/api/core/v1" . "github.com/apache/camel-k/v2/e2e/support" - camelv1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" + v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" ) func TestRunSimpleJavaScriptExamples(t *testing.T) { - RegisterTestingT(t) + t.Parallel() - t.Run("run js", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "files/js.js").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "js"), TestTimeoutLong).Should(Equal(v1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "js", camelv1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(v1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "js"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - }) + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-runtimes-js" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + t.Run("run js", func(t *testing.T) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/js.js").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "js"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "js", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "js"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + }) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) } diff --git a/e2e/common/languages/kotlin_test.go b/e2e/common/languages/kotlin_test.go index da210afc2a..c0cac74937 100644 --- a/e2e/common/languages/kotlin_test.go +++ b/e2e/common/languages/kotlin_test.go @@ -23,25 +23,35 @@ limitations under the License. package languages import ( + "context" "testing" . "github.com/onsi/gomega" - v1 "k8s.io/api/core/v1" + corev1 "k8s.io/api/core/v1" . "github.com/apache/camel-k/v2/e2e/support" - camelv1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" + v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" ) func TestRunSimpleKotlinExamples(t *testing.T) { - RegisterTestingT(t) + t.Parallel() - t.Run("run kotlin", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "files/kotlin.kts").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "kotlin"), TestTimeoutLong).Should(Equal(v1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "kotlin", camelv1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(v1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "kotlin"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - }) + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-runtimes-kotlin" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + t.Run("run kotlin", func(t *testing.T) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/kotlin.kts").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "kotlin"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "kotlin", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "kotlin"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + }) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) } diff --git a/e2e/common/languages/polyglot_test.go b/e2e/common/languages/polyglot_test.go index b441d41023..457ded99ff 100644 --- a/e2e/common/languages/polyglot_test.go +++ b/e2e/common/languages/polyglot_test.go @@ -23,26 +23,36 @@ limitations under the License. package languages import ( + "context" "testing" . "github.com/onsi/gomega" - v1 "k8s.io/api/core/v1" + corev1 "k8s.io/api/core/v1" . "github.com/apache/camel-k/v2/e2e/support" - camelv1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" + v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" ) func TestRunPolyglotExamples(t *testing.T) { - RegisterTestingT(t) - - t.Run("run polyglot", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "--name", "polyglot", "files/js-polyglot.js", "files/yaml-polyglot.yaml").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "polyglot"), TestTimeoutLong).Should(Equal(v1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "polyglot", camelv1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(v1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "polyglot"), TestTimeoutShort).Should(ContainSubstring("Magicpolyglot-yaml")) - Eventually(IntegrationLogs(ns, "polyglot"), TestTimeoutShort).Should(ContainSubstring("Magicpolyglot-js")) - }) + t.Parallel() + + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-runtimes-polyglot" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + t.Run("run polyglot", func(t *testing.T) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "--name", "polyglot", "files/js-polyglot.js", "files/yaml-polyglot.yaml").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "polyglot"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "polyglot", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "polyglot"), TestTimeoutShort).Should(ContainSubstring("Magicpolyglot-yaml")) + g.Eventually(IntegrationLogs(t, ctx, ns, "polyglot"), TestTimeoutShort).Should(ContainSubstring("Magicpolyglot-js")) + }) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) } diff --git a/e2e/common/languages/xml_test.go b/e2e/common/languages/xml_test.go index 1ea6f8dd5e..90c3ccde0b 100644 --- a/e2e/common/languages/xml_test.go +++ b/e2e/common/languages/xml_test.go @@ -23,25 +23,35 @@ limitations under the License. package languages import ( + "context" "testing" . "github.com/onsi/gomega" - v1 "k8s.io/api/core/v1" + corev1 "k8s.io/api/core/v1" . "github.com/apache/camel-k/v2/e2e/support" - camelv1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" + v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" ) func TestRunSimpleXmlExamples(t *testing.T) { - RegisterTestingT(t) + t.Parallel() - t.Run("run xml", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "files/xml.xml").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "xml"), TestTimeoutLong).Should(Equal(v1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "xml", camelv1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(v1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "xml"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - }) + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-runtimes-xml" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + t.Run("run xml", func(t *testing.T) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/xml.xml").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "xml"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "xml", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "xml"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + }) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) } diff --git a/e2e/common/languages/yaml_test.go b/e2e/common/languages/yaml_test.go index 7e3dba1a46..6eb6b44825 100644 --- a/e2e/common/languages/yaml_test.go +++ b/e2e/common/languages/yaml_test.go @@ -23,25 +23,35 @@ limitations under the License. package languages import ( + "context" "testing" . "github.com/onsi/gomega" - v1 "k8s.io/api/core/v1" + corev1 "k8s.io/api/core/v1" . "github.com/apache/camel-k/v2/e2e/support" - camelv1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" + v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" ) func TestRunSimpleYamlExamples(t *testing.T) { - RegisterTestingT(t) + t.Parallel() - t.Run("run yaml", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "files/yaml.yaml").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "yaml"), TestTimeoutLong).Should(Equal(v1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "yaml", camelv1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(v1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "yaml"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - }) + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-runtimes-yaml" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + t.Run("run yaml", func(t *testing.T) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/yaml.yaml").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "yaml"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "yaml", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "yaml"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + }) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) } diff --git a/e2e/common/main_test.go b/e2e/common/main_test.go new file mode 100644 index 0000000000..c077ae4b0c --- /dev/null +++ b/e2e/common/main_test.go @@ -0,0 +1,69 @@ +//go:build integration +// +build integration + +// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration" + +/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package common + +import ( + "fmt" + "os" + "testing" + + . "github.com/onsi/gomega" + corev1 "k8s.io/api/core/v1" + + . "github.com/apache/camel-k/v2/e2e/support" + v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" + "github.com/apache/camel-k/v2/pkg/platform" +) + +func TestMain(m *testing.M) { + justCompile := GetEnvOrDefault("CAMEL_K_E2E_JUST_COMPILE", "false") + if justCompile == "true" { + os.Exit(m.Run()) + } + + fastSetup := GetEnvOrDefault("CAMEL_K_E2E_FAST_SETUP", "false") + if fastSetup == "true" { + operatorID := platform.DefaultPlatformName + ns := GetEnvOrDefault("CAMEL_K_GLOBAL_OPERATOR_NS", TestDefaultNamespace) + + g := NewGomega(func(message string, callerSkip ...int) { + fmt.Printf("Test setup failed! - %s\n", message) + }) + + var t *testing.T + + g.Expect(TestClient(t)).ShouldNot(BeNil()) + ctx := TestContext() + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "languages/files/Java.java").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "java"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "java", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "java"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "languages/files/yaml.yaml").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "yaml"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "yaml", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "yaml"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + } + + os.Exit(m.Run()) +} diff --git a/e2e/common/misc/client_test.go b/e2e/common/misc/client_test.go index 89bacee629..54dbbd99d8 100644 --- a/e2e/common/misc/client_test.go +++ b/e2e/common/misc/client_test.go @@ -23,9 +23,11 @@ limitations under the License. package misc import ( + "context" "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -38,31 +40,33 @@ import ( ) func TestClientFunctionalities(t *testing.T) { - RegisterTestingT(t) - - cfg, err := config.GetConfig() - assert.Nil(t, err) - camel, err := versioned.NewForConfig(cfg) - assert.Nil(t, err) - - lst, err := camel.CamelV1().Integrations(ns).List(TestContext, metav1.ListOptions{}) - assert.Nil(t, err) - assert.Empty(t, lst.Items) - - integration, err := camel.CamelV1().Integrations(ns).Create(TestContext, &v1.Integration{ - ObjectMeta: metav1.ObjectMeta{ - Name: "dummy", - }, - }, metav1.CreateOptions{}) - assert.Nil(t, err) - - lst, err = camel.CamelV1().Integrations(ns).List(TestContext, metav1.ListOptions{}) - assert.Nil(t, err) - assert.NotEmpty(t, lst.Items) - assert.Equal(t, lst.Items[0].Name, integration.Name) - - err = camel.CamelV1().Integrations(ns).Delete(TestContext, "dummy", metav1.DeleteOptions{}) - assert.Nil(t, err) - - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + t.Parallel() + + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + cfg, err := config.GetConfig() + require.NoError(t, err) + camel, err := versioned.NewForConfig(cfg) + require.NoError(t, err) + + lst, err := camel.CamelV1().Integrations(ns).List(ctx, metav1.ListOptions{}) + require.NoError(t, err) + assert.Empty(t, lst.Items) + + integration, err := camel.CamelV1().Integrations(ns).Create(ctx, &v1.Integration{ + ObjectMeta: metav1.ObjectMeta{ + Name: "dummy", + }, + }, metav1.CreateOptions{}) + require.NoError(t, err) + + lst, err = camel.CamelV1().Integrations(ns).List(ctx, metav1.ListOptions{}) + require.NoError(t, err) + assert.NotEmpty(t, lst.Items) + assert.Equal(t, lst.Items[0].Name, integration.Name) + + err = camel.CamelV1().Integrations(ns).Delete(ctx, "dummy", metav1.DeleteOptions{}) + require.NoError(t, err) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) } diff --git a/e2e/common/misc/cron_test.go b/e2e/common/misc/cron_test.go index 9368108c4d..256ef653cf 100644 --- a/e2e/common/misc/cron_test.go +++ b/e2e/common/misc/cron_test.go @@ -23,6 +23,7 @@ limitations under the License. package misc import ( + "context" "testing" . "github.com/onsi/gomega" @@ -34,42 +35,51 @@ import ( ) func TestRunCronExample(t *testing.T) { - RegisterTestingT(t) - - t.Run("cron", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "files/cron.yaml").Execute()).To(Succeed()) - Eventually(IntegrationCronJob(ns, "cron"), TestTimeoutMedium).ShouldNot(BeNil()) - Eventually(IntegrationConditionStatus(ns, "cron", v1.IntegrationConditionReady), TestTimeoutMedium).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "cron"), TestTimeoutMedium).Should(ContainSubstring("Magicstring!")) - }) - - t.Run("cron-yaml", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "files/cron-yaml.yaml").Execute()).To(Succeed()) - Eventually(IntegrationCronJob(ns, "cron-yaml"), TestTimeoutMedium).ShouldNot(BeNil()) - Eventually(IntegrationConditionStatus(ns, "cron-yaml", v1.IntegrationConditionReady), TestTimeoutMedium).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "cron-yaml"), TestTimeoutMedium).Should(ContainSubstring("Magicstring!")) - }) - - t.Run("cron-timer", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "files/cron-timer.yaml").Execute()).To(Succeed()) - Eventually(IntegrationCronJob(ns, "cron-timer"), TestTimeoutMedium).ShouldNot(BeNil()) - Eventually(IntegrationConditionStatus(ns, "cron-timer", v1.IntegrationConditionReady), TestTimeoutMedium).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "cron-timer"), TestTimeoutMedium).Should(ContainSubstring("Magicstring!")) + t.Parallel() + + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-cron" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + + t.Run("cron", func(t *testing.T) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/cron.yaml").Execute()).To(Succeed()) + g.Eventually(IntegrationCronJob(t, ctx, ns, "cron"), TestTimeoutLong).ShouldNot(BeNil()) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "cron", v1.IntegrationConditionReady), TestTimeoutMedium).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "cron"), TestTimeoutMedium).Should(ContainSubstring("Magicstring!")) + }) + + t.Run("cron-yaml", func(t *testing.T) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/cron-yaml.yaml").Execute()).To(Succeed()) + g.Eventually(IntegrationCronJob(t, ctx, ns, "cron-yaml"), TestTimeoutLong).ShouldNot(BeNil()) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "cron-yaml", v1.IntegrationConditionReady), TestTimeoutMedium).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "cron-yaml"), TestTimeoutMedium).Should(ContainSubstring("Magicstring!")) + }) + + t.Run("cron-timer", func(t *testing.T) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/cron-timer.yaml").Execute()).To(Succeed()) + g.Eventually(IntegrationCronJob(t, ctx, ns, "cron-timer"), TestTimeoutLong).ShouldNot(BeNil()) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "cron-timer", v1.IntegrationConditionReady), TestTimeoutMedium).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "cron-timer"), TestTimeoutMedium).Should(ContainSubstring("Magicstring!")) + }) + + t.Run("cron-fallback", func(t *testing.T) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/cron-fallback.yaml").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "cron-fallback"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "cron-fallback", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "cron-fallback"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + }) + + t.Run("cron-quartz", func(t *testing.T) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/cron-quartz.yaml").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "cron-quartz"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "cron-quartz", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "cron-quartz"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + }) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) - - t.Run("cron-fallback", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "files/cron-fallback.yaml").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "cron-fallback"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "cron-fallback", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "cron-fallback"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - }) - - t.Run("cron-quartz", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "files/cron-quartz.yaml").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "cron-quartz"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "cron-quartz", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "cron-quartz"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - }) - - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) } diff --git a/e2e/common/misc/default.go b/e2e/common/misc/default.go deleted file mode 100644 index 76b897333b..0000000000 --- a/e2e/common/misc/default.go +++ /dev/null @@ -1,26 +0,0 @@ -//go:build integration -// +build integration - -/* -Licensed to the Apache Software Foundation (ASF) under one or more -contributor license agreements. See the NOTICE file distributed with -this work for additional information regarding copyright ownership. -The ASF licenses this file to You under the Apache License, Version 2.0 -(the "License"); you may not use this file except in compliance with -the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package misc - -import "github.com/apache/camel-k/v2/e2e/support" - -var ns = support.GetEnvOrDefault("CAMEL_K_TEST_NAMESPACE", support.GetCIProcessID()) -var operatorID = support.GetEnvOrDefault("CAMEL_K_OPERATOR_ID", support.GetCIProcessID()) diff --git a/e2e/common/misc/integration_fail_test.go b/e2e/common/misc/integration_fail_test.go index 58d98f6d1a..cdd731be46 100644 --- a/e2e/common/misc/integration_fail_test.go +++ b/e2e/common/misc/integration_fail_test.go @@ -23,6 +23,7 @@ limitations under the License. package misc import ( + "context" "testing" "time" @@ -35,151 +36,159 @@ import ( ) func TestBadRouteIntegration(t *testing.T) { - RegisterTestingT(t) - - t.Run("run bad java route", func(t *testing.T) { - name := RandomizedSuffixName("bad-route") - Expect(KamelRunWithID(operatorID, ns, "files/BadRoute.java", "--name", name).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationPhase(ns, name), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseError)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort). - Should(Equal(corev1.ConditionFalse)) - - // Make sure the Integration can be scaled - Expect(ScaleIntegration(ns, name, 2)).To(Succeed()) - // Check the scale cascades into the Deployment scale - Eventually(IntegrationPods(ns, name), TestTimeoutShort).Should(HaveLen(2)) - // Check it also cascades into the Integration scale subresource Status field - Eventually(IntegrationStatusReplicas(ns, name), TestTimeoutShort). - Should(gstruct.PointTo(BeNumerically("==", 2))) - // Check the Integration stays in error phase - Eventually(IntegrationPhase(ns, name), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseError)) - - // Kit valid - kitName := IntegrationKit(ns, name)() - integrationKitNamespace := IntegrationKitNamespace(ns, name)() - Eventually(KitPhase(integrationKitNamespace, kitName), TestTimeoutShort).Should(Equal(v1.IntegrationKitPhaseReady)) + t.Parallel() + + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-bad-route" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + + t.Run("run bad java route", func(t *testing.T) { + name := RandomizedSuffixName("bad-route") + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/BadRoute.java", "--name", name).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationPhase(t, ctx, ns, name), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseError)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort). + Should(Equal(corev1.ConditionFalse)) + + // Make sure the Integration can be scaled + g.Expect(ScaleIntegration(t, ctx, ns, name, 2)).To(Succeed()) + // Check the scale cascades into the Deployment scale + g.Eventually(IntegrationPods(t, ctx, ns, name), TestTimeoutShort).Should(HaveLen(2)) + // Check it also cascades into the Integration scale subresource Status field + g.Eventually(IntegrationStatusReplicas(t, ctx, ns, name), TestTimeoutShort). + Should(gstruct.PointTo(BeNumerically("==", 2))) + // Check the Integration stays in error phase + g.Eventually(IntegrationPhase(t, ctx, ns, name), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseError)) + + // Kit valid + kitName := IntegrationKit(t, ctx, ns, name)() + integrationKitNamespace := IntegrationKitNamespace(t, ctx, ns, name)() + g.Eventually(KitPhase(t, ctx, integrationKitNamespace, kitName), TestTimeoutShort).Should(Equal(v1.IntegrationKitPhaseReady)) + }) + + t.Run("run missing dependency java route", func(t *testing.T) { + name := RandomizedSuffixName("java-route") + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", name, + "-d", "mvn:com.example:nonexistent:1.0").Execute()).To(Succeed()) + // Integration in error + g.Eventually(IntegrationPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(v1.IntegrationPhaseError)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionKitAvailable), TestTimeoutShort).Should(Equal(corev1.ConditionFalse)) + g.Eventually(IntegrationCondition(t, ctx, ns, name, v1.IntegrationConditionKitAvailable), TestTimeoutShort).Should( + WithTransform(IntegrationConditionReason, Equal(v1.IntegrationConditionKitAvailableReason))) + g.Eventually(IntegrationCondition(t, ctx, ns, name, v1.IntegrationConditionKitAvailable), TestTimeoutShort).Should( + WithTransform(IntegrationConditionMessage, ContainSubstring("is in state \"Error\""))) + // Kit in error + kitName := IntegrationKit(t, ctx, ns, name)() + integrationKitNamespace := IntegrationKitNamespace(t, ctx, ns, name)() + g.Eventually(KitPhase(t, ctx, integrationKitNamespace, kitName), TestTimeoutShort).Should(Equal(v1.IntegrationKitPhaseError)) + //Build in error with 5 attempts + build := Build(t, ctx, integrationKitNamespace, kitName)() + g.Eventually(build.Status.Phase, TestTimeoutShort).Should(Equal(v1.BuildPhaseError)) + g.Eventually(build.Status.Failure.Recovery.Attempt, TestTimeoutShort).Should(Equal(5)) + + // Fixing the route should reconcile the Integration + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", name).Execute()).To(Succeed()) + g.Eventually(IntegrationPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(v1.IntegrationPhaseRunning)) + // New Kit success + kitRecoveryName := IntegrationKit(t, ctx, ns, name)() + integrationKitRecoveryNamespace := IntegrationKitNamespace(t, ctx, ns, name)() + g.Eventually(KitPhase(t, ctx, integrationKitRecoveryNamespace, kitRecoveryName), TestTimeoutShort).Should(Equal(v1.IntegrationKitPhaseReady)) + g.Expect(kitRecoveryName).NotTo(Equal(kitName)) + // New Build success + buildRecovery := Build(t, ctx, integrationKitRecoveryNamespace, kitRecoveryName)() + g.Eventually(buildRecovery.Status.Phase, TestTimeoutShort).Should(Equal(v1.BuildPhaseSucceeded)) + + }) + + t.Run("run invalid dependency java route", func(t *testing.T) { + name := RandomizedSuffixName("invalid-dependency") + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", name, "-d", "camel:non-existent").Execute()).To(Succeed()) + // Integration in error with Initialization Failed condition + g.Eventually(IntegrationPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(v1.IntegrationPhaseError)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort). + Should(Equal(corev1.ConditionFalse)) + g.Eventually(IntegrationCondition(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(And( + WithTransform(IntegrationConditionReason, Equal(v1.IntegrationConditionInitializationFailedReason)), + WithTransform(IntegrationConditionMessage, HavePrefix("error during trait customization")), + )) + // Kit shouldn't be created + g.Consistently(IntegrationKit(t, ctx, ns, name), 10*time.Second).Should(BeEmpty()) + + // Fixing the route should reconcile the Integration in Initialization Failed condition to Running + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", name).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort). + Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + // New Kit success + kitRecoveryName := IntegrationKit(t, ctx, ns, name)() + integrationKitRecoveryNamespace := IntegrationKitNamespace(t, ctx, ns, name)() + g.Eventually(KitPhase(t, ctx, integrationKitRecoveryNamespace, kitRecoveryName), TestTimeoutShort).Should(Equal(v1.IntegrationKitPhaseReady)) + // New Build success + buildRecovery := Build(t, ctx, integrationKitRecoveryNamespace, kitRecoveryName)() + g.Eventually(buildRecovery.Status.Phase, TestTimeoutShort).Should(Equal(v1.BuildPhaseSucceeded)) + }) + + t.Run("run unresolvable component java route", func(t *testing.T) { + name := RandomizedSuffixName("unresolvable-route") + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Unresolvable.java", "--name", name).Execute()).To(Succeed()) + // Integration in error with Initialization Failed condition + g.Eventually(IntegrationPhase(t, ctx, ns, name), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseError)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort). + Should(Equal(corev1.ConditionFalse)) + g.Eventually(IntegrationCondition(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(And( + WithTransform(IntegrationConditionReason, Equal(v1.IntegrationConditionInitializationFailedReason)), + WithTransform(IntegrationConditionMessage, HavePrefix("error during trait customization")), + )) + // Kit shouldn't be created + g.Consistently(IntegrationKit(t, ctx, ns, name), 10*time.Second).Should(BeEmpty()) + + // Fixing the route should reconcile the Integration in Initialization Failed condition to Running + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", name).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort). + Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + // New Kit success + kitRecoveryName := IntegrationKit(t, ctx, ns, name)() + integrationKitRecoveryNamespace := IntegrationKitNamespace(t, ctx, ns, name)() + g.Eventually(KitPhase(t, ctx, integrationKitRecoveryNamespace, kitRecoveryName), TestTimeoutShort).Should(Equal(v1.IntegrationKitPhaseReady)) + // New Build success + buildRecovery := Build(t, ctx, integrationKitRecoveryNamespace, kitRecoveryName)() + g.Eventually(buildRecovery.Status.Phase, TestTimeoutShort).Should(Equal(v1.BuildPhaseSucceeded)) + }) + + t.Run("run invalid java route", func(t *testing.T) { + name := RandomizedSuffixName("invalid-java-route") + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/InvalidJava.java", "--name", name).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationPhase(t, ctx, ns, name), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseError)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort). + Should(Equal(corev1.ConditionFalse)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Compilation error")) + + // Kit valid + kitName := IntegrationKit(t, ctx, ns, name)() + integrationKitNamespace := IntegrationKitNamespace(t, ctx, ns, name)() + g.Eventually(KitPhase(t, ctx, integrationKitNamespace, kitName), TestTimeoutShort).Should(Equal(v1.IntegrationKitPhaseReady)) + + // Fixing the route should reconcile the Integration in Initialization Failed condition to Running + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", name).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort). + Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + + // Kit should not have changed + kitRecoveryName := IntegrationKit(t, ctx, ns, name)() + g.Expect(kitRecoveryName).To(Equal(kitName)) + + }) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) - - t.Run("run missing dependency java route", func(t *testing.T) { - name := RandomizedSuffixName("java-route") - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", "--name", name, - "-d", "mvn:com.example:nonexistent:1.0").Execute()).To(Succeed()) - // Integration in error - Eventually(IntegrationPhase(ns, name), TestTimeoutLong).Should(Equal(v1.IntegrationPhaseError)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionKitAvailable), TestTimeoutShort).Should(Equal(corev1.ConditionFalse)) - Eventually(IntegrationCondition(ns, name, v1.IntegrationConditionKitAvailable), TestTimeoutShort).Should( - WithTransform(IntegrationConditionReason, Equal(v1.IntegrationConditionKitAvailableReason))) - Eventually(IntegrationCondition(ns, name, v1.IntegrationConditionKitAvailable), TestTimeoutShort).Should( - WithTransform(IntegrationConditionMessage, ContainSubstring("is in state \"Error\""))) - // Kit in error - kitName := IntegrationKit(ns, name)() - integrationKitNamespace := IntegrationKitNamespace(ns, name)() - Eventually(KitPhase(integrationKitNamespace, kitName), TestTimeoutShort).Should(Equal(v1.IntegrationKitPhaseError)) - //Build in error with 5 attempts - build := Build(integrationKitNamespace, kitName)() - Eventually(build.Status.Phase, TestTimeoutShort).Should(Equal(v1.BuildPhaseError)) - Eventually(build.Status.Failure.Recovery.Attempt, TestTimeoutShort).Should(Equal(5)) - - // Fixing the route should reconcile the Integration - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", "--name", name).Execute()).To(Succeed()) - Eventually(IntegrationPhase(ns, name), TestTimeoutLong).Should(Equal(v1.IntegrationPhaseRunning)) - // New Kit success - kitRecoveryName := IntegrationKit(ns, name)() - integrationKitRecoveryNamespace := IntegrationKitNamespace(ns, name)() - Eventually(KitPhase(integrationKitRecoveryNamespace, kitRecoveryName), TestTimeoutShort).Should(Equal(v1.IntegrationKitPhaseReady)) - Expect(kitRecoveryName).NotTo(Equal(kitName)) - // New Build success - buildRecovery := Build(integrationKitRecoveryNamespace, kitRecoveryName)() - Eventually(buildRecovery.Status.Phase, TestTimeoutShort).Should(Equal(v1.BuildPhaseSucceeded)) - - }) - - t.Run("run invalid dependency java route", func(t *testing.T) { - name := RandomizedSuffixName("invalid-dependency") - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", "--name", name, - "-d", "camel:non-existent").Execute()).To(Succeed()) - // Integration in error with Initialization Failed condition - Eventually(IntegrationPhase(ns, name), TestTimeoutLong).Should(Equal(v1.IntegrationPhaseError)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort). - Should(Equal(corev1.ConditionFalse)) - Eventually(IntegrationCondition(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(And( - WithTransform(IntegrationConditionReason, Equal(v1.IntegrationConditionInitializationFailedReason)), - WithTransform(IntegrationConditionMessage, HavePrefix("error during trait customization")), - )) - // Kit shouldn't be created - Consistently(IntegrationKit(ns, name), 10*time.Second).Should(BeEmpty()) - - // Fixing the route should reconcile the Integration in Initialization Failed condition to Running - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", "--name", name).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort). - Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - // New Kit success - kitRecoveryName := IntegrationKit(ns, name)() - integrationKitRecoveryNamespace := IntegrationKitNamespace(ns, name)() - Eventually(KitPhase(integrationKitRecoveryNamespace, kitRecoveryName), TestTimeoutShort).Should(Equal(v1.IntegrationKitPhaseReady)) - // New Build success - buildRecovery := Build(integrationKitRecoveryNamespace, kitRecoveryName)() - Eventually(buildRecovery.Status.Phase, TestTimeoutShort).Should(Equal(v1.BuildPhaseSucceeded)) - }) - - t.Run("run unresolvable component java route", func(t *testing.T) { - name := RandomizedSuffixName("unresolvable-route") - Expect(KamelRunWithID(operatorID, ns, "files/Unresolvable.java", "--name", name).Execute()).To(Succeed()) - // Integration in error with Initialization Failed condition - Eventually(IntegrationPhase(ns, name), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseError)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort). - Should(Equal(corev1.ConditionFalse)) - Eventually(IntegrationCondition(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(And( - WithTransform(IntegrationConditionReason, Equal(v1.IntegrationConditionInitializationFailedReason)), - WithTransform(IntegrationConditionMessage, HavePrefix("error during trait customization")), - )) - // Kit shouldn't be created - Consistently(IntegrationKit(ns, name), 10*time.Second).Should(BeEmpty()) - - // Fixing the route should reconcile the Integration in Initialization Failed condition to Running - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", "--name", name).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort). - Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - // New Kit success - kitRecoveryName := IntegrationKit(ns, name)() - integrationKitRecoveryNamespace := IntegrationKitNamespace(ns, name)() - Eventually(KitPhase(integrationKitRecoveryNamespace, kitRecoveryName), TestTimeoutShort).Should(Equal(v1.IntegrationKitPhaseReady)) - // New Build success - buildRecovery := Build(integrationKitRecoveryNamespace, kitRecoveryName)() - Eventually(buildRecovery.Status.Phase, TestTimeoutShort).Should(Equal(v1.BuildPhaseSucceeded)) - }) - - t.Run("run invalid java route", func(t *testing.T) { - name := RandomizedSuffixName("invalid-java-route") - Expect(KamelRunWithID(operatorID, ns, "files/InvalidJava.java", "--name", name).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationPhase(ns, name), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseError)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort). - Should(Equal(corev1.ConditionFalse)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Compilation error")) - - // Kit valid - kitName := IntegrationKit(ns, name)() - integrationKitNamespace := IntegrationKitNamespace(ns, name)() - Eventually(KitPhase(integrationKitNamespace, kitName), TestTimeoutShort).Should(Equal(v1.IntegrationKitPhaseReady)) - - // Fixing the route should reconcile the Integration in Initialization Failed condition to Running - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", "--name", name).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort). - Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - - // Kit should not have changed - kitRecoveryName := IntegrationKit(ns, name)() - Expect(kitRecoveryName).To(Equal(kitName)) - - }) - - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) } diff --git a/e2e/common/misc/integration_trait_update_test.go b/e2e/common/misc/integration_trait_update_test.go index 132d628620..839c51e580 100644 --- a/e2e/common/misc/integration_trait_update_test.go +++ b/e2e/common/misc/integration_trait_update_test.go @@ -23,6 +23,7 @@ limitations under the License. package misc import ( + "context" "testing" "time" @@ -34,20 +35,29 @@ import ( ) func TestTraitUpdates(t *testing.T) { - RegisterTestingT(t) - - t.Run("run and update trait", func(t *testing.T) { - name := RandomizedSuffixName("yaml-route") - Expect(KamelRunWithID(operatorID, ns, "files/yaml.yaml", "--name", name).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - var numberOfPods = func(pods *int32) bool { - return *pods >= 1 && *pods <= 2 - } - // Adding a property will change the camel trait - Expect(KamelRunWithID(operatorID, ns, "files/yaml.yaml", "--name", name, "-p", "hello=world").Execute()).To(Succeed()) - Consistently(IntegrationPodsNumbers(ns, name), TestTimeoutShort, 1*time.Second).Should(Satisfy(numberOfPods)) + t.Parallel() + + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-trait-update" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + + t.Run("run and update trait", func(t *testing.T) { + name := RandomizedSuffixName("yaml-route") + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/yaml.yaml", "--name", name).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + var numberOfPods = func(pods *int32) bool { + return *pods >= 1 && *pods <= 2 + } + // Adding a property will change the camel trait + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/yaml.yaml", "--name", name, "-p", "hello=world").Execute()).To(Succeed()) + g.Consistently(IntegrationPodsNumbers(t, ctx, ns, name), TestTimeoutShort, 1*time.Second).Should(Satisfy(numberOfPods)) + }) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) - - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) } diff --git a/e2e/common/misc/kamelet_test.go b/e2e/common/misc/kamelet_test.go index 66c8c38391..f9b58f279d 100644 --- a/e2e/common/misc/kamelet_test.go +++ b/e2e/common/misc/kamelet_test.go @@ -23,6 +23,7 @@ limitations under the License. package misc import ( + "context" "testing" . "github.com/onsi/gomega" @@ -30,14 +31,23 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" . "github.com/apache/camel-k/v2/e2e/support" + v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" ) func TestKameletClasspathLoading(t *testing.T) { - RegisterTestingT(t) + t.Parallel() - // Store a configmap on the cluster - var cmData = make(map[string]string) - cmData["my-timer-source.kamelet.yaml"] = ` + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-kamelet-loading" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + + // Store a configmap on the cluster + var cmData = make(map[string]string) + cmData["my-timer-source.kamelet.yaml"] = ` # --------------------------------------------------------------------------- # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with @@ -108,27 +118,23 @@ spec: constant: "{{contentType}}" - to: kamelet:sink ` - CreatePlainTextConfigmap(ns, "my-kamelet-cm", cmData) - - // Basic - t.Run("test basic case", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "files/TimerKameletIntegration.java", "-t", "kamelets.enabled=false", - "--resource", "configmap:my-kamelet-cm@/kamelets", - "-p camel.component.kamelet.location=file:/kamelets", - "-d", "camel:yaml-dsl", - // kamelet dependencies - "-d", "camel:timer").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "timer-kamelet-integration"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns, "timer-kamelet-integration")).Should(ContainSubstring("important message")) - - // check integration schema does not contains unwanted default trait value. - Eventually(UnstructuredIntegration(ns, "timer-kamelet-integration")).ShouldNot(BeNil()) - unstructuredIntegration := UnstructuredIntegration(ns, "timer-kamelet-integration")() - kameletsTrait, _, _ := unstructured.NestedMap(unstructuredIntegration.Object, "spec", "traits", "kamelets") - Expect(kameletsTrait).ToNot(BeNil()) - Expect(len(kameletsTrait)).To(Equal(1)) - Expect(kameletsTrait["enabled"]).To(Equal(false)) - }) + CreatePlainTextConfigmap(t, ctx, ns, "my-kamelet-cm", cmData) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + // Basic + t.Run("test basic case", func(t *testing.T) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/TimerKameletIntegration.java", "-t", "kamelets.enabled=false", "--resource", "configmap:my-kamelet-cm@/kamelets", "-p camel.component.kamelet.location=file:/kamelets", "-d", "camel:yaml-dsl", "-d", "camel:timer").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "timer-kamelet-integration"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, "timer-kamelet-integration")).Should(ContainSubstring("important message")) + + // check integration schema does not contains unwanted default trait value. + g.Eventually(UnstructuredIntegration(t, ctx, ns, "timer-kamelet-integration")).ShouldNot(BeNil()) + unstructuredIntegration := UnstructuredIntegration(t, ctx, ns, "timer-kamelet-integration")() + kameletsTrait, _, _ := unstructured.NestedMap(unstructuredIntegration.Object, "spec", "traits", "kamelets") + g.Expect(kameletsTrait).ToNot(BeNil()) + g.Expect(len(kameletsTrait)).To(Equal(1)) + g.Expect(kameletsTrait["enabled"]).To(Equal(false)) + }) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) } diff --git a/e2e/common/misc/kamelet_update_test.go b/e2e/common/misc/kamelet_update_test.go index e0f1228c97..2be7c7e82c 100644 --- a/e2e/common/misc/kamelet_update_test.go +++ b/e2e/common/misc/kamelet_update_test.go @@ -23,6 +23,7 @@ limitations under the License. package misc import ( + "context" "testing" "time" @@ -35,20 +36,29 @@ import ( const customLabel = "custom-label" func TestBundleKameletUpdate(t *testing.T) { - RegisterTestingT(t) + t.Parallel() - Expect(createBundleKamelet(ns, "my-http-sink")()).To(Succeed()) // Going to be replaced - Expect(createUserKamelet(ns, "user-sink")()).To(Succeed()) // Left intact by the operator + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-kamelet-bundle" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) - Eventually(Kamelet("my-http-sink", ns)). - Should(WithTransform(KameletLabels, HaveKeyWithValue(customLabel, "true"))) - Consistently(Kamelet("user-sink", ns), 5*time.Second, 1*time.Second). - Should(WithTransform(KameletLabels, HaveKeyWithValue(customLabel, "true"))) + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + g.Expect(createBundleKamelet(t, ctx, operatorID, ns, "my-http-sink")()).To(Succeed()) // Going to be replaced + g.Expect(createUserKamelet(t, ctx, operatorID, ns, "user-sink")()).To(Succeed()) // Left intact by the operator + + g.Eventually(Kamelet(t, ctx, "my-http-sink", ns)). + Should(WithTransform(KameletLabels, HaveKeyWithValue(customLabel, "true"))) + g.Consistently(Kamelet(t, ctx, "user-sink", ns), 5*time.Second, 1*time.Second). + Should(WithTransform(KameletLabels, HaveKeyWithValue(customLabel, "true"))) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) } -func createBundleKamelet(ns string, name string) func() error { +func createBundleKamelet(t *testing.T, ctx context.Context, operatorID string, ns string, name string) func() error { flow := map[string]interface{}{ "from": map[string]interface{}{ "uri": "kamelet:source", @@ -59,10 +69,10 @@ func createBundleKamelet(ns string, name string) func() error { customLabel: "true", v1.KameletBundledLabel: "true", } - return CreateKamelet(ns, name, flow, nil, labels) + return CreateKamelet(t, operatorID, ctx, ns, name, flow, nil, labels) } -func createUserKamelet(ns string, name string) func() error { +func createUserKamelet(t *testing.T, ctx context.Context, operatorID string, ns string, name string) func() error { flow := map[string]interface{}{ "from": map[string]interface{}{ "uri": "kamelet:source", @@ -72,5 +82,5 @@ func createUserKamelet(ns string, name string) func() error { labels := map[string]string{ customLabel: "true", } - return CreateKamelet(ns, name, flow, nil, labels) + return CreateKamelet(t, operatorID, ctx, ns, name, flow, nil, labels) } diff --git a/e2e/common/misc/maven_repository_test.go b/e2e/common/misc/maven_repository_test.go index 066a1d1eee..3be75182e3 100644 --- a/e2e/common/misc/maven_repository_test.go +++ b/e2e/common/misc/maven_repository_test.go @@ -23,6 +23,7 @@ limitations under the License. package misc import ( + "context" "testing" . "github.com/onsi/gomega" @@ -34,21 +35,27 @@ import ( ) func TestRunExtraRepository(t *testing.T) { - RegisterTestingT(t) - name := RandomizedSuffixName("java") - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", - "--maven-repository", "https://maven.repository.redhat.com/ga@id=redhat", - "--dependency", "mvn:org.jolokia:jolokia-core:1.7.1.redhat-00001", - "--name", name, - ).Execute()).To(Succeed()) - - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - Eventually(Integration(ns, name)).Should(WithTransform(IntegrationSpec, And( - HaveExistingField("Repositories"), - HaveField("Repositories", ContainElements("https://maven.repository.redhat.com/ga@id=redhat")), - ))) - - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + t.Parallel() + + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-extra-repository" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + + name := RandomizedSuffixName("java") + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--maven-repository", "https://maven.repository.redhat.com/ga@id=redhat", "--dependency", "mvn:org.jolokia:jolokia-core:1.7.1.redhat-00001", "--name", name).Execute()).To(Succeed()) + + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + g.Eventually(Integration(t, ctx, ns, name)).Should(WithTransform(IntegrationSpec, And( + HaveExistingField("Repositories"), + HaveField("Repositories", ContainElements("https://maven.repository.redhat.com/ga@id=redhat")), + ))) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) } diff --git a/e2e/common/misc/pipe_test.go b/e2e/common/misc/pipe_test.go index 49a559bbb9..eb79f82083 100644 --- a/e2e/common/misc/pipe_test.go +++ b/e2e/common/misc/pipe_test.go @@ -23,6 +23,7 @@ limitations under the License. package misc import ( + "context" "testing" . "github.com/onsi/gomega" @@ -35,87 +36,91 @@ import ( ) func TestPipe(t *testing.T) { - RegisterTestingT(t) - - // Error Handler testing - t.Run("test error handler", func(t *testing.T) { - Expect(createErrorProducerKamelet(ns, "my-own-error-producer-source")()).To(Succeed()) - Expect(CreateLogKamelet(ns, "my-own-log-sink")()).To(Succeed()) - - t.Run("throw error test", func(t *testing.T) { - Expect(KamelBindWithID(operatorID, ns, - "my-own-error-producer-source", - "my-own-log-sink", - "--error-handler", "sink:my-own-log-sink", - "-p", "source.message=throw Error", - "-p", "sink.loggerName=integrationLogger", - "-p", "error-handler.loggerName=kameletErrorHandler", - "--name", "throw-error-binding", - ).Execute()).To(Succeed()) - - Eventually(IntegrationPodPhase(ns, "throw-error-binding"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns, "throw-error-binding"), TestTimeoutShort).Should(ContainSubstring("kameletErrorHandler")) - Eventually(IntegrationLogs(ns, "throw-error-binding"), TestTimeoutShort).ShouldNot(ContainSubstring("integrationLogger")) - + t.Parallel() + + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-pipe" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + + // Error Handler testing + t.Run("test error handler", func(t *testing.T) { + g.Expect(createErrorProducerKamelet(t, ctx, operatorID, ns, "my-own-error-producer-source")()).To(Succeed()) + g.Expect(CreateLogKamelet(t, ctx, operatorID, ns, "my-own-log-sink")()).To(Succeed()) + + t.Run("throw error test", func(t *testing.T) { + g.Expect(KamelBindWithID(t, ctx, operatorID, ns, "my-own-error-producer-source", "my-own-log-sink", + "--error-handler", "sink:my-own-log-sink", + "-p", "source.message=throw Error", + "-p", "sink.loggerName=integrationLogger", + "-p", "error-handler.loggerName=kameletErrorHandler", + // Needed in the test to make sure to do the right string comparison later + "-t", "logging.color=false", + "--name", "throw-error-binding").Execute()).To(Succeed()) + + g.Eventually(IntegrationPodPhase(t, ctx, ns, "throw-error-binding"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, "throw-error-binding"), TestTimeoutShort).Should(ContainSubstring("[kameletErrorHandler] (Camel (camel-1) thread #1 - timer://tick)")) + g.Eventually(IntegrationLogs(t, ctx, ns, "throw-error-binding"), TestTimeoutShort).ShouldNot(ContainSubstring("[integrationLogger] (Camel (camel-1) thread #1 - timer://tick)")) + + }) + + t.Run("don't throw error test", func(t *testing.T) { + g.Expect(KamelBindWithID(t, ctx, operatorID, ns, "my-own-error-producer-source", "my-own-log-sink", + "--error-handler", "sink:my-own-log-sink", + "-p", "source.message=true", + "-p", "sink.loggerName=integrationLogger", + "-p", "error-handler.loggerName=kameletErrorHandler", + // Needed in the test to make sure to do the right string comparison later + "-t", "logging.color=false", + "--name", "no-error-binding").Execute()).To(Succeed()) + + g.Eventually(IntegrationPodPhase(t, ctx, ns, "no-error-binding"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, "no-error-binding"), TestTimeoutShort).ShouldNot(ContainSubstring("[kameletErrorHandler] (Camel (camel-1) thread #1 - timer://tick)")) + g.Eventually(IntegrationLogs(t, ctx, ns, "no-error-binding"), TestTimeoutShort).Should(ContainSubstring("[integrationLogger] (Camel (camel-1) thread #1 - timer://tick)")) + + }) }) - t.Run("don't throw error test", func(t *testing.T) { - Expect(KamelBindWithID(operatorID, ns, - "my-own-error-producer-source", - "my-own-log-sink", - "--error-handler", "sink:my-own-log-sink", - "-p", "source.message=true", - "-p", "sink.loggerName=integrationLogger", - "-p", "error-handler.loggerName=kameletErrorHandler", - "--name", "no-error-binding", - ).Execute()).To(Succeed()) + //Pipe with traits testing + t.Run("test Pipe with trait", func(t *testing.T) { + g.Expect(CreateTimerKamelet(t, ctx, operatorID, ns, "my-own-timer-source")()).To(Succeed()) + // Log sink kamelet exists from previous test - Eventually(IntegrationPodPhase(ns, "no-error-binding"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns, "no-error-binding"), TestTimeoutShort).ShouldNot(ContainSubstring("kameletErrorHandler")) - Eventually(IntegrationLogs(ns, "no-error-binding"), TestTimeoutShort).Should(ContainSubstring("integrationLogger")) + g.Expect(KamelBindWithID(t, ctx, operatorID, ns, "my-own-timer-source", "my-own-log-sink", + "-p", "source.message=hello from test", + "-p", "sink.loggerName=integrationLogger", + "--annotation", "trait.camel.apache.org/camel.properties=[\"camel.prop1=a\",\"camel.prop2=b\"]", + "--name", "kb-with-traits").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "kb-with-traits"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, "kb-with-traits"), TestTimeoutShort).Should(ContainSubstring("hello from test")) + g.Eventually(IntegrationLogs(t, ctx, ns, "kb-with-traits"), TestTimeoutShort).Should(ContainSubstring("integrationLogger")) }) - }) - //Pipe with traits testing - t.Run("test Pipe with trait", func(t *testing.T) { - Expect(CreateTimerKamelet(ns, "my-own-timer-source")()).To(Succeed()) - // Log sink kamelet exists from previous test - - Expect(KamelBindWithID(operatorID, ns, - "my-own-timer-source", - "my-own-log-sink", - "-p", "source.message=hello from test", - "-p", "sink.loggerName=integrationLogger", - "--annotation", "trait.camel.apache.org/camel.properties=[\"camel.prop1=a\",\"camel.prop2=b\"]", - "--name", "kb-with-traits", - ).Execute()).To(Succeed()) - - Eventually(IntegrationPodPhase(ns, "kb-with-traits"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns, "kb-with-traits"), TestTimeoutShort).Should(ContainSubstring("hello from test")) - Eventually(IntegrationLogs(ns, "kb-with-traits"), TestTimeoutShort).Should(ContainSubstring("integrationLogger")) - }) + // Pipe with wrong spec + t.Run("test Pipe with wrong spec", func(t *testing.T) { + name := RandomizedSuffixName("bad-klb") + kb := v1.NewPipe(ns, name) + kb.Spec = v1.PipeSpec{} + _, err := kubernetes.ReplaceResource(ctx, TestClient(t), &kb) + g.Eventually(err).Should(BeNil()) + g.Eventually(PipePhase(t, ctx, ns, name), TestTimeoutShort).Should(Equal(v1.PipePhaseError)) + g.Eventually(PipeConditionStatus(t, ctx, ns, name, v1.PipeConditionReady), TestTimeoutShort).ShouldNot(Equal(corev1.ConditionTrue)) + g.Eventually(PipeCondition(t, ctx, ns, name, v1.PipeIntegrationConditionError), TestTimeoutShort).Should( + WithTransform(PipeConditionMessage, And( + ContainSubstring("could not determine source URI"), + ContainSubstring("no ref or URI specified in endpoint"), + ))) + }) - // Pipe with wrong spec - t.Run("test Pipe with wrong spec", func(t *testing.T) { - name := RandomizedSuffixName("bad-klb") - kb := v1.NewPipe(ns, name) - kb.Spec = v1.PipeSpec{} - _, err := kubernetes.ReplaceResource(TestContext, TestClient(), &kb) - Eventually(err).Should(BeNil()) - Eventually(PipePhase(ns, name), TestTimeoutShort).Should(Equal(v1.PipePhaseError)) - Eventually(PipeConditionStatus(ns, name, v1.PipeConditionReady), TestTimeoutShort).ShouldNot(Equal(corev1.ConditionTrue)) - Eventually(PipeCondition(ns, name, v1.PipeIntegrationConditionError), TestTimeoutShort).Should( - WithTransform(PipeConditionMessage, And( - ContainSubstring("could not determine source URI"), - ContainSubstring("no ref or URI specified in endpoint"), - ))) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) - - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) } -func createErrorProducerKamelet(ns string, name string) func() error { +func createErrorProducerKamelet(t *testing.T, ctx context.Context, operatorID string, ns string, name string) func() error { props := map[string]v1.JSONSchemaProp{ "message": { Type: "string", @@ -143,5 +148,5 @@ func createErrorProducerKamelet(ns string, name string) func() error { }, } - return CreateKamelet(ns, name, flow, props, nil) + return CreateKamelet(t, operatorID, ctx, ns, name, flow, props, nil) } diff --git a/e2e/common/misc/pipe_with_image_test.go b/e2e/common/misc/pipe_with_image_test.go index d34e67d393..de47c8cdab 100644 --- a/e2e/common/misc/pipe_with_image_test.go +++ b/e2e/common/misc/pipe_with_image_test.go @@ -23,6 +23,7 @@ limitations under the License. package misc import ( + "context" "testing" . "github.com/onsi/gomega" @@ -31,67 +32,59 @@ import ( corev1 "k8s.io/api/core/v1" . "github.com/apache/camel-k/v2/e2e/support" + v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" ) func TestPipeWithImage(t *testing.T) { - RegisterTestingT(t) - - bindingID := "with-image-binding" - - t.Run("run with initial image", func(t *testing.T) { - expectedImage := "docker.io/jmalloc/echo-server:0.3.2" - - Expect(KamelBindWithID(operatorID, ns, - "my-own-timer-source", - "my-own-log-sink", - "--annotation", "trait.camel.apache.org/container.image="+expectedImage, - "--annotation", "trait.camel.apache.org/jvm.enabled=false", - "--annotation", "trait.camel.apache.org/kamelets.enabled=false", - "--annotation", "trait.camel.apache.org/dependencies.enabled=false", - "--annotation", "test=1", - "--name", bindingID, - ).Execute()).To(Succeed()) - - Eventually(IntegrationGeneration(ns, bindingID)). - Should(gstruct.PointTo(BeNumerically("==", 1))) - Eventually(Integration(ns, bindingID)).Should(WithTransform(Annotations, And( - HaveKeyWithValue("test", "1"), - HaveKeyWithValue("trait.camel.apache.org/container.image", expectedImage), - ))) - Eventually(IntegrationStatusImage(ns, bindingID)). - Should(Equal(expectedImage)) - Eventually(IntegrationPodPhase(ns, bindingID), TestTimeoutLong). - Should(Equal(corev1.PodRunning)) - Eventually(IntegrationPodImage(ns, bindingID)). - Should(Equal(expectedImage)) + t.Parallel() + + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-pipe-image" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + + bindingID := "with-image-binding" + + t.Run("run with initial image", func(t *testing.T) { + expectedImage := "docker.io/jmalloc/echo-server:0.3.2" + + g.Expect(KamelBindWithID(t, ctx, operatorID, ns, "my-own-timer-source", "my-own-log-sink", "--annotation", "trait.camel.apache.org/container.image="+expectedImage, "--annotation", "trait.camel.apache.org/jvm.enabled=false", "--annotation", "trait.camel.apache.org/kamelets.enabled=false", "--annotation", "trait.camel.apache.org/dependencies.enabled=false", "--annotation", "test=1", "--name", bindingID).Execute()).To(Succeed()) + + g.Eventually(IntegrationGeneration(t, ctx, ns, bindingID)). + Should(gstruct.PointTo(BeNumerically("==", 1))) + g.Eventually(Integration(t, ctx, ns, bindingID)).Should(WithTransform(Annotations, And( + HaveKeyWithValue("test", "1"), + HaveKeyWithValue("trait.camel.apache.org/container.image", expectedImage), + ))) + g.Eventually(IntegrationStatusImage(t, ctx, ns, bindingID)). + Should(Equal(expectedImage)) + g.Eventually(IntegrationPodPhase(t, ctx, ns, bindingID), TestTimeoutLong). + Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationPodImage(t, ctx, ns, bindingID)). + Should(Equal(expectedImage)) + }) + + t.Run("run with new image", func(t *testing.T) { + expectedImage := "docker.io/jmalloc/echo-server:0.3.3" + + g.Expect(KamelBindWithID(t, ctx, operatorID, ns, "my-own-timer-source", "my-own-log-sink", "--annotation", "trait.camel.apache.org/container.image="+expectedImage, "--annotation", "trait.camel.apache.org/jvm.enabled=false", "--annotation", "trait.camel.apache.org/kamelets.enabled=false", "--annotation", "trait.camel.apache.org/dependencies.enabled=false", "--annotation", "test=2", "--name", bindingID).Execute()).To(Succeed()) + g.Eventually(IntegrationGeneration(t, ctx, ns, bindingID)). + Should(gstruct.PointTo(BeNumerically("==", 1))) + g.Eventually(Integration(t, ctx, ns, bindingID)).Should(WithTransform(Annotations, And( + HaveKeyWithValue("test", "2"), + HaveKeyWithValue("trait.camel.apache.org/container.image", expectedImage), + ))) + g.Eventually(IntegrationStatusImage(t, ctx, ns, bindingID)). + Should(Equal(expectedImage)) + g.Eventually(IntegrationPodPhase(t, ctx, ns, bindingID), TestTimeoutLong). + Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationPodImage(t, ctx, ns, bindingID)). + Should(Equal(expectedImage)) + }) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) - - t.Run("run with new image", func(t *testing.T) { - expectedImage := "docker.io/jmalloc/echo-server:0.3.3" - - Expect(KamelBindWithID(operatorID, ns, - "my-own-timer-source", - "my-own-log-sink", - "--annotation", "trait.camel.apache.org/container.image="+expectedImage, - "--annotation", "trait.camel.apache.org/jvm.enabled=false", - "--annotation", "trait.camel.apache.org/kamelets.enabled=false", - "--annotation", "trait.camel.apache.org/dependencies.enabled=false", - "--annotation", "test=2", - "--name", bindingID, - ).Execute()).To(Succeed()) - Eventually(IntegrationGeneration(ns, bindingID)). - Should(gstruct.PointTo(BeNumerically("==", 1))) - Eventually(Integration(ns, bindingID)).Should(WithTransform(Annotations, And( - HaveKeyWithValue("test", "2"), - HaveKeyWithValue("trait.camel.apache.org/container.image", expectedImage), - ))) - Eventually(IntegrationStatusImage(ns, bindingID)). - Should(Equal(expectedImage)) - Eventually(IntegrationPodPhase(ns, bindingID), TestTimeoutLong). - Should(Equal(corev1.PodRunning)) - Eventually(IntegrationPodImage(ns, bindingID)). - Should(Equal(expectedImage)) - }) - - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) } diff --git a/e2e/common/misc/registry_maven_wagon_test.go b/e2e/common/misc/registry_maven_wagon_test.go index 0d54a48afb..9f474eee56 100644 --- a/e2e/common/misc/registry_maven_wagon_test.go +++ b/e2e/common/misc/registry_maven_wagon_test.go @@ -23,12 +23,13 @@ limitations under the License. package misc import ( + "context" "fmt" "path/filepath" "testing" . "github.com/onsi/gomega" - "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" @@ -38,104 +39,110 @@ import ( ) func TestImageRegistryIsAMavenRepository(t *testing.T) { - RegisterTestingT(t) - ocp, err := openshift.IsOpenShift(TestClient()) - assert.Nil(t, err) + t.Parallel() + + ocp, err := openshift.IsOpenShift(TestClient(t)) + require.NoError(t, err) if ocp { t.Skip("Avoid running on OpenShift until CA and secret are injected client side") return } - t.Run("image registry is a maven repository", func(t *testing.T) { - // Create integration that should decrypt an encrypted message to "foobar" and log it - name := RandomizedSuffixName("foobar-decryption") - jar, err := filepath.Abs("files/registry/sample-decryption-1.0.jar?skipPOM=true") - assert.Nil(t, err) - pom, err := filepath.Abs("files/registry/sample-decryption-1.0.pom") - assert.Nil(t, err) - - Expect(KamelRunWithID(operatorID, ns, "files/registry/FoobarDecryption.java", - "--name", name, - "-d", fmt.Sprintf("file://%s", jar), - "-d", fmt.Sprintf("file://%s", pom), - ).Execute()).To(Succeed()) - - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutMedium).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("foobar")) - }) - - t.Run("local files are mounted in the integration container at the default path", func(t *testing.T) { - name := RandomizedSuffixName("laughing-route-default-path") - - Expect(KamelRunWithID(operatorID, ns, "files/registry/LaughingRoute.java", - "--name", name, - "-p", "location=/deployments/?filename=laugh.txt", - "-d", "file://files/registry/laugh.txt", - ).Execute()).To(Succeed()) - - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("haha")) + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-registry-maven-repo" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + + t.Run("image registry is a maven repository", func(t *testing.T) { + // Create integration that should decrypt an encrypted message to "foobar" and log it + name := RandomizedSuffixName("foobar-decryption") + jar, err := filepath.Abs("files/registry/sample-decryption-1.0.jar?skipPOM=true") + require.NoError(t, err) + pom, err := filepath.Abs("files/registry/sample-decryption-1.0.pom") + require.NoError(t, err) + + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/registry/FoobarDecryption.java", + "--name", name, + "-d", fmt.Sprintf("file://%s", jar), + "-d", fmt.Sprintf("file://%s", pom)).Execute()).To(Succeed()) + + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutMedium).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("foobar")) + }) + + t.Run("local files are mounted in the integration container at the default path", func(t *testing.T) { + name := RandomizedSuffixName("laughing-route-default-path") + + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/registry/LaughingRoute.java", + "--name", name, + "-p", "location=/deployments/?filename=laugh.txt", + "-d", "file://files/registry/laugh.txt").Execute()).To(Succeed()) + + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("haha")) + }) + + t.Run("local files are mounted in the integration container at a custom path", func(t *testing.T) { + name := RandomizedSuffixName("laughing-route-custom-path") + customPath := "this/is/a/custom/path/" + + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/registry/LaughingRoute.java", + "--name", name, + "-p", fmt.Sprintf("location=%s", customPath), + "-d", fmt.Sprintf("file://files/registry/laugh.txt?targetPath=%slaugh.txt", customPath)).Execute()).To(Succeed()) + + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("haha")) + }) + + t.Run("local directory is mounted in the integration container", func(t *testing.T) { + name := RandomizedSuffixName("laughing-route-directory") + + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/registry/LaughingRoute.java", + "--name", name, + "-p", "location=files/registry/", + "-d", fmt.Sprintf("file://files/registry/laughs/?targetPath=files/registry/")).Execute()).To(Succeed()) + + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("haha")) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("hehe")) + }) + + t.Run("pom file is extracted from JAR", func(t *testing.T) { + // Create integration that should decrypt foobar and log it + name := RandomizedSuffixName("foobar-decryption-pom-extraction") + jar, err := filepath.Abs("files/registry/sample-decryption-1.0.jar") + require.NoError(t, err) + + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/registry/FoobarDecryption.java", + "--name", name, + "-d", fmt.Sprintf("file://%s", jar)).Execute()).To(Succeed()) + + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("foobar")) + }) + + t.Run("dependency can be used at build time", func(t *testing.T) { + // Create integration that should run a Xslt transformation whose template needs to be present at build time + name := RandomizedSuffixName("xslt") + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/registry/classpath/Xslt.java", + "--name", name, + "-d", "file://files/registry/classpath/cheese.xsl?targetPath=xslt/cheese.xsl&classpath=true").Execute()).To(Succeed()) + + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutMedium).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("A")) + }) + + // Clean up + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) - - t.Run("local files are mounted in the integration container at a custom path", func(t *testing.T) { - name := RandomizedSuffixName("laughing-route-custom-path") - customPath := "this/is/a/custom/path/" - - Expect(KamelRunWithID(operatorID, ns, "files/registry/LaughingRoute.java", - "--name", name, - "-p", fmt.Sprintf("location=%s", customPath), - "-d", fmt.Sprintf("file://files/registry/laugh.txt?targetPath=%slaugh.txt", customPath), - ).Execute()).To(Succeed()) - - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("haha")) - }) - - t.Run("local directory is mounted in the integration container", func(t *testing.T) { - name := RandomizedSuffixName("laughing-route-directory") - - Expect(KamelRunWithID(operatorID, ns, "files/registry/LaughingRoute.java", - "--name", name, - "-p", "location=files/registry/", - "-d", fmt.Sprintf("file://files/registry/laughs/?targetPath=files/registry/"), - ).Execute()).To(Succeed()) - - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("haha")) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("hehe")) - }) - - t.Run("pom file is extracted from JAR", func(t *testing.T) { - // Create integration that should decrypt foobar and log it - name := RandomizedSuffixName("foobar-decryption-pom-extraction") - jar, err := filepath.Abs("files/registry/sample-decryption-1.0.jar") - assert.Nil(t, err) - - Expect(KamelRunWithID(operatorID, ns, "files/registry/FoobarDecryption.java", - "--name", name, - "-d", fmt.Sprintf("file://%s", jar), - ).Execute()).To(Succeed()) - - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("foobar")) - }) - t.Run("dependency can be used at build time", func(t *testing.T) { - // Create integration that should run an Xslt transformation whose template needs to be present at build time - name := RandomizedSuffixName("xslt") - Expect(KamelRunWithID(operatorID, ns, "files/registry/classpath/Xslt.java", "--name", name, - "-d", "file://files/registry/classpath/cheese.xsl?targetPath=xslt/cheese.xsl&classpath=true", - ).Execute()).To(Succeed()) - - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutMedium).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("A")) - }) - - // Clean up - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) } diff --git a/e2e/common/misc/rest_test.go b/e2e/common/misc/rest_test.go index 89b2c9b09f..680f06adb7 100644 --- a/e2e/common/misc/rest_test.go +++ b/e2e/common/misc/rest_test.go @@ -23,6 +23,7 @@ limitations under the License. package misc import ( + "context" "fmt" "io" "net/http" @@ -30,46 +31,55 @@ import ( "time" . "github.com/onsi/gomega" - "github.com/stretchr/testify/assert" - + "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" . "github.com/apache/camel-k/v2/e2e/support" + v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" "github.com/apache/camel-k/v2/pkg/util/openshift" ) func TestRunRest(t *testing.T) { - RegisterTestingT(t) - - ocp, err := openshift.IsOpenShift(TestClient()) - assert.Nil(t, err) - - Expect(KamelRunWithID(operatorID, ns, "files/rest-consumer.yaml").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "rest-consumer"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - - t.Run("Service works", func(t *testing.T) { - name := RandomizedSuffixName("John") - service := Service(ns, "rest-consumer") - Eventually(service, TestTimeoutShort).ShouldNot(BeNil()) - Expect(KamelRunWithID(operatorID, ns, "files/rest-producer.yaml", "-p", "serviceName=rest-consumer", "-p", "name="+name).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "rest-producer"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns, "rest-consumer"), TestTimeoutLong).Should(ContainSubstring(fmt.Sprintf("get %s", name))) - Eventually(IntegrationLogs(ns, "rest-producer"), TestTimeoutLong).Should(ContainSubstring(fmt.Sprintf("%s Doe", name))) - }) - - if ocp { - t.Run("Route works", func(t *testing.T) { - name := RandomizedSuffixName("Peter") - route := Route(ns, "rest-consumer") - Eventually(route, TestTimeoutShort).ShouldNot(BeNil()) - Eventually(RouteStatus(ns, "rest-consumer"), TestTimeoutMedium).Should(Equal("True")) - url := fmt.Sprintf("http://%s/customers/%s", route().Spec.Host, name) - Eventually(httpRequest(url), TestTimeoutMedium).Should(Equal(fmt.Sprintf("%s Doe", name))) - Eventually(IntegrationLogs(ns, "rest-consumer"), TestTimeoutShort).Should(ContainSubstring(fmt.Sprintf("get %s", name))) + t.Parallel() + + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-rest" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + + ocp, err := openshift.IsOpenShift(TestClient(t)) + require.NoError(t, err) + + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/rest-consumer.yaml").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "rest-consumer"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + + t.Run("Service works", func(t *testing.T) { + name := RandomizedSuffixName("John") + service := Service(t, ctx, ns, "rest-consumer") + g.Eventually(service, TestTimeoutShort).ShouldNot(BeNil()) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/rest-producer.yaml", "-p", "serviceName=rest-consumer", "-p", "name="+name).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "rest-producer"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, "rest-consumer"), TestTimeoutLong).Should(ContainSubstring(fmt.Sprintf("get %s", name))) + g.Eventually(IntegrationLogs(t, ctx, ns, "rest-producer"), TestTimeoutLong).Should(ContainSubstring(fmt.Sprintf("%s Doe", name))) }) - } - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + if ocp { + t.Run("Route works", func(t *testing.T) { + name := RandomizedSuffixName("Peter") + route := Route(t, ctx, ns, "rest-consumer") + g.Eventually(route, TestTimeoutShort).ShouldNot(BeNil()) + g.Eventually(RouteStatus(t, ctx, ns, "rest-consumer"), TestTimeoutMedium).Should(Equal("True")) + url := fmt.Sprintf("http://%s/customers/%s", route().Spec.Host, name) + g.Eventually(httpRequest(url), TestTimeoutMedium).Should(Equal(fmt.Sprintf("%s Doe", name))) + g.Eventually(IntegrationLogs(t, ctx, ns, "rest-consumer"), TestTimeoutShort).Should(ContainSubstring(fmt.Sprintf("get %s", name))) + }) + } + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) } func httpRequest(url string) func() (string, error) { diff --git a/e2e/common/misc/scale_binding_test.go b/e2e/common/misc/scale_binding_test.go index bae14ab230..0b1bdd6433 100644 --- a/e2e/common/misc/scale_binding_test.go +++ b/e2e/common/misc/scale_binding_test.go @@ -23,11 +23,12 @@ limitations under the License. package misc import ( + "context" "testing" . "github.com/onsi/gomega" "github.com/onsi/gomega/gstruct" - "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -40,93 +41,102 @@ import ( ) func TestPipeScale(t *testing.T) { - RegisterTestingT(t) - - ocp, err := openshift.IsOpenShift(TestClient()) - assert.Nil(t, err) - if ocp { - t.Skip("TODO: Temporarily disabled as this test is flaky on OpenShift 3") - return - } - - name := RandomizedSuffixName("timer2log") - Expect(KamelBindWithID(operatorID, ns, "timer-source?message=HelloPipe", "log-sink", "--name", name).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(PipeConditionStatus(ns, name, v1.PipeConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("HelloPipe")) - - t.Run("Update Pipe scale spec", func(t *testing.T) { - Expect(ScalePipe(ns, name, 3)).To(Succeed()) - // Check the scale cascades into the Deployment scale - Eventually(IntegrationPods(ns, name), TestTimeoutShort).Should(HaveLen(3)) - // Check it also cascades into the Integration scale subresource Status field - Eventually(IntegrationStatusReplicas(ns, name), TestTimeoutShort). - Should(gstruct.PointTo(BeNumerically("==", 3))) - // Check it also cascades into the Pipe scale subresource Status field - Eventually(PipeStatusReplicas(ns, name), TestTimeoutShort). - Should(gstruct.PointTo(BeNumerically("==", 3))) - // Check the readiness condition becomes truthy back - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutMedium).Should(Equal(corev1.ConditionTrue)) - // Finally check the readiness condition becomes truthy back onPipe - Eventually(PipeConditionStatus(ns, name, v1.PipeConditionReady), TestTimeoutMedium).Should(Equal(corev1.ConditionTrue)) + t.Parallel() + + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-pipe-scale" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithIDAndKameletCatalog(t, ctx, operatorID, ns)).To(Succeed()) + + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + + ocp, err := openshift.IsOpenShift(TestClient(t)) + require.NoError(t, err) + if ocp { + t.Skip("TODO: Temporarily disabled as this test is flaky on OpenShift 3") + return + } + + name := RandomizedSuffixName("timer2log") + g.Expect(KamelBindWithID(t, ctx, operatorID, ns, "timer-source?message=HelloPipe", "log-sink", "--name", name).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(PipeConditionStatus(t, ctx, ns, name, v1.PipeConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("HelloPipe")) + + t.Run("Update Pipe scale spec", func(t *testing.T) { + g.Expect(ScalePipe(t, ctx, ns, name, 3)).To(Succeed()) + // Check the scale cascades into the Deployment scale + g.Eventually(IntegrationPods(t, ctx, ns, name), TestTimeoutShort).Should(HaveLen(3)) + // Check it also cascades into the Integration scale subresource Status field + g.Eventually(IntegrationStatusReplicas(t, ctx, ns, name), TestTimeoutShort). + Should(gstruct.PointTo(BeNumerically("==", 3))) + // Check it also cascades into the Pipe scale subresource Status field + g.Eventually(PipeStatusReplicas(t, ctx, ns, name), TestTimeoutShort). + Should(gstruct.PointTo(BeNumerically("==", 3))) + // Check the readiness condition becomes truthy back + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutMedium).Should(Equal(corev1.ConditionTrue)) + // Finally check the readiness condition becomes truthy back onPipe + g.Eventually(PipeConditionStatus(t, ctx, ns, name, v1.PipeConditionReady), TestTimeoutMedium).Should(Equal(corev1.ConditionTrue)) + }) + + t.Run("ScalePipe with polymorphic client", func(t *testing.T) { + scaleClient, err := TestClient(t).ScalesClient() + g.Expect(err).To(BeNil()) + + // Patch the integration scale subresource + patch := "{\"spec\":{\"replicas\":2}}" + _, err = scaleClient.Scales(ns).Patch(ctx, v1.SchemeGroupVersion.WithResource("Pipes"), name, types.MergePatchType, []byte(patch), metav1.PatchOptions{}) + g.Expect(err).To(BeNil()) + + // Check the readiness condition is still truthy as down-scaling + g.Expect(PipeConditionStatus(t, ctx, ns, name, v1.PipeConditionReady)()).To(Equal(corev1.ConditionTrue)) + // Check the Integration scale subresource Spec field + g.Eventually(IntegrationSpecReplicas(t, ctx, ns, name), TestTimeoutShort). + Should(gstruct.PointTo(BeNumerically("==", 2))) + // Then check it cascades into the Deployment scale + g.Eventually(IntegrationPods(t, ctx, ns, name), TestTimeoutShort).Should(HaveLen(2)) + // Check it cascades into the Integration scale subresource Status field + g.Eventually(IntegrationStatusReplicas(t, ctx, ns, name), TestTimeoutShort). + Should(gstruct.PointTo(BeNumerically("==", 2))) + // Finally check it cascades into the Pipe scale subresource Status field + g.Eventually(PipeStatusReplicas(t, ctx, ns, name), TestTimeoutShort). + Should(gstruct.PointTo(BeNumerically("==", 2))) + }) + + t.Run("ScalePipe with Camel K client", func(t *testing.T) { + camel, err := versioned.NewForConfig(TestClient(t).GetConfig()) + g.Expect(err).To(BeNil()) + + // Getter + PipeScale, err := camel.CamelV1().Pipes(ns).GetScale(ctx, name, metav1.GetOptions{}) + g.Expect(err).To(BeNil()) + g.Expect(PipeScale.Spec.Replicas).To(BeNumerically("==", 2)) + g.Expect(PipeScale.Status.Replicas).To(BeNumerically("==", 2)) + + // Setter + PipeScale.Spec.Replicas = 1 + _, err = camel.CamelV1().Pipes(ns).UpdateScale(ctx, name, PipeScale, metav1.UpdateOptions{}) + g.Expect(err).To(BeNil()) + + // Check the readiness condition is still truthy as down-scaling inPipe + g.Expect(PipeConditionStatus(t, ctx, ns, name, v1.PipeConditionReady)()).To(Equal(corev1.ConditionTrue)) + // Check the Pipe scale subresource Spec field + g.Eventually(PipeSpecReplicas(t, ctx, ns, name), TestTimeoutShort). + Should(gstruct.PointTo(BeNumerically("==", 1))) + // Check the readiness condition is still truthy as down-scaling + g.Expect(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady)()).To(Equal(corev1.ConditionTrue)) + // Check the Integration scale subresource Spec field + g.Eventually(IntegrationSpecReplicas(t, ctx, ns, name), TestTimeoutShort). + Should(gstruct.PointTo(BeNumerically("==", 1))) + // Then check it cascades into the Deployment scale + g.Eventually(IntegrationPods(t, ctx, ns, name), TestTimeoutShort).Should(HaveLen(1)) + // Finally check it cascades into the Integration scale subresource Status field + g.Eventually(IntegrationStatusReplicas(t, ctx, ns, name), TestTimeoutShort). + Should(gstruct.PointTo(BeNumerically("==", 1))) + }) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) - - t.Run("ScalePipe with polymorphic client", func(t *testing.T) { - scaleClient, err := TestClient().ScalesClient() - Expect(err).To(BeNil()) - - // Patch the integration scale subresource - patch := "{\"spec\":{\"replicas\":2}}" - _, err = scaleClient.Scales(ns).Patch(TestContext, v1.SchemeGroupVersion.WithResource("Pipes"), name, types.MergePatchType, []byte(patch), metav1.PatchOptions{}) - Expect(err).To(BeNil()) - - // Check the readiness condition is still truthy as down-scaling - Expect(PipeConditionStatus(ns, name, v1.PipeConditionReady)()).To(Equal(corev1.ConditionTrue)) - // Check the Integration scale subresource Spec field - Eventually(IntegrationSpecReplicas(ns, name), TestTimeoutShort). - Should(gstruct.PointTo(BeNumerically("==", 2))) - // Then check it cascades into the Deployment scale - Eventually(IntegrationPods(ns, name), TestTimeoutShort).Should(HaveLen(2)) - // Check it cascades into the Integration scale subresource Status field - Eventually(IntegrationStatusReplicas(ns, name), TestTimeoutShort). - Should(gstruct.PointTo(BeNumerically("==", 2))) - // Finally check it cascades into the Pipe scale subresource Status field - Eventually(PipeStatusReplicas(ns, name), TestTimeoutShort). - Should(gstruct.PointTo(BeNumerically("==", 2))) - }) - - t.Run("ScalePipe with Camel K client", func(t *testing.T) { - camel, err := versioned.NewForConfig(TestClient().GetConfig()) - Expect(err).To(BeNil()) - - // Getter - PipeScale, err := camel.CamelV1().Pipes(ns).GetScale(TestContext, name, metav1.GetOptions{}) - Expect(err).To(BeNil()) - Expect(PipeScale.Spec.Replicas).To(BeNumerically("==", 2)) - Expect(PipeScale.Status.Replicas).To(BeNumerically("==", 2)) - - // Setter - PipeScale.Spec.Replicas = 1 - _, err = camel.CamelV1().Pipes(ns).UpdateScale(TestContext, name, PipeScale, metav1.UpdateOptions{}) - Expect(err).To(BeNil()) - - // Check the readiness condition is still truthy as down-scaling inPipe - Expect(PipeConditionStatus(ns, name, v1.PipeConditionReady)()).To(Equal(corev1.ConditionTrue)) - // Check the Pipe scale subresource Spec field - Eventually(PipeSpecReplicas(ns, name), TestTimeoutShort). - Should(gstruct.PointTo(BeNumerically("==", 1))) - // Check the readiness condition is still truthy as down-scaling - Expect(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady)()).To(Equal(corev1.ConditionTrue)) - // Check the Integration scale subresource Spec field - Eventually(IntegrationSpecReplicas(ns, name), TestTimeoutShort). - Should(gstruct.PointTo(BeNumerically("==", 1))) - // Then check it cascades into the Deployment scale - Eventually(IntegrationPods(ns, name), TestTimeoutShort).Should(HaveLen(1)) - // Finally check it cascades into the Integration scale subresource Status field - Eventually(IntegrationStatusReplicas(ns, name), TestTimeoutShort). - Should(gstruct.PointTo(BeNumerically("==", 1))) - }) - - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) } diff --git a/e2e/common/misc/scale_integration_test.go b/e2e/common/misc/scale_integration_test.go index 422adfa59c..d2fb9a37d6 100644 --- a/e2e/common/misc/scale_integration_test.go +++ b/e2e/common/misc/scale_integration_test.go @@ -23,6 +23,7 @@ limitations under the License. package misc import ( + "context" "fmt" "testing" @@ -39,93 +40,101 @@ import ( ) func TestIntegrationScale(t *testing.T) { - RegisterTestingT(t) - - name := RandomizedSuffixName("java") - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", "--name", name).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - - t.Run("Update integration scale spec", func(t *testing.T) { - RegisterTestingT(t) - Expect(ScaleIntegration(ns, name, 3)).To(Succeed()) - // Check the readiness condition becomes falsy - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionFalse)) - // Check the scale cascades into the Deployment scale - Eventually(IntegrationPods(ns, name), TestTimeoutShort).Should(HaveLen(3)) - // Check it also cascades into the Integration scale subresource Status field - Eventually(IntegrationStatusReplicas(ns, name), TestTimeoutShort). - Should(gstruct.PointTo(BeNumerically("==", 3))) - // Finally check the readiness condition becomes truthy back - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutMedium).Should(Equal(corev1.ConditionTrue)) + t.Parallel() + + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-integration-scale" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + + name := RandomizedSuffixName("java") + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", name).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + + t.Run("Update integration scale spec", func(t *testing.T) { + g.Expect(ScaleIntegration(t, ctx, ns, name, 3)).To(Succeed()) + // Check the readiness condition becomes falsy + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionFalse)) + // Check the scale cascades into the Deployment scale + g.Eventually(IntegrationPods(t, ctx, ns, name), TestTimeoutShort).Should(HaveLen(3)) + // Check it also cascades into the Integration scale subresource Status field + g.Eventually(IntegrationStatusReplicas(t, ctx, ns, name), TestTimeoutShort). + Should(gstruct.PointTo(BeNumerically("==", 3))) + // Finally check the readiness condition becomes truthy back + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutMedium).Should(Equal(corev1.ConditionTrue)) + }) + + t.Run("Scale integration with polymorphic client", func(t *testing.T) { + scaleClient, err := TestClient(t).ScalesClient() + g.Expect(err).To(BeNil()) + + // Patch the integration scale subresource + patch := "{\"spec\":{\"replicas\":2}}" + _, err = scaleClient.Scales(ns).Patch(ctx, v1.SchemeGroupVersion.WithResource("integrations"), name, types.MergePatchType, []byte(patch), metav1.PatchOptions{}) + g.Expect(err).To(BeNil()) + + // Check the readiness condition is still truthy as down-scaling + g.Expect(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady)()).To(Equal(corev1.ConditionTrue)) + // Check the Integration scale subresource Spec field + g.Eventually(IntegrationSpecReplicas(t, ctx, ns, name), TestTimeoutShort). + Should(gstruct.PointTo(BeNumerically("==", 2))) + // Then check it cascades into the Deployment scale + g.Eventually(IntegrationPods(t, ctx, ns, name), TestTimeoutShort).Should(HaveLen(2)) + // Finally check it cascades into the Integration scale subresource Status field + g.Eventually(IntegrationStatusReplicas(t, ctx, ns, name), TestTimeoutShort). + Should(gstruct.PointTo(BeNumerically("==", 2))) + }) + + t.Run("Scale integration with Camel K client", func(t *testing.T) { + camel, err := versioned.NewForConfig(TestClient(t).GetConfig()) + g.Expect(err).To(BeNil()) + + // Getter + integrationScale, err := camel.CamelV1().Integrations(ns).GetScale(ctx, name, metav1.GetOptions{}) + g.Expect(err).To(BeNil()) + g.Expect(integrationScale.Spec.Replicas).To(BeNumerically("==", 2)) + g.Expect(integrationScale.Status.Replicas).To(BeNumerically("==", 2)) + + // Setter + integrationScale.Spec.Replicas = 1 + integrationScale, err = camel.CamelV1().Integrations(ns).UpdateScale(ctx, name, integrationScale, metav1.UpdateOptions{}) + g.Expect(err).To(BeNil()) + + // Check the readiness condition is still truthy as down-scaling + g.Expect(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady)()).To(Equal(corev1.ConditionTrue)) + // Check the Integration scale subresource Spec field + g.Eventually(IntegrationSpecReplicas(t, ctx, ns, name), TestTimeoutShort). + Should(gstruct.PointTo(BeNumerically("==", 1))) + // Then check it cascades into the Deployment scale + g.Eventually(IntegrationPods(t, ctx, ns, name), TestTimeoutShort).Should(HaveLen(1)) + // Finally check it cascades into the Integration scale subresource Status field + g.Eventually(IntegrationStatusReplicas(t, ctx, ns, name), TestTimeoutShort). + Should(gstruct.PointTo(BeNumerically("==", 1))) + }) + + t.Run("Scale integration with external image", func(t *testing.T) { + image := IntegrationPodImage(t, ctx, ns, name)() + g.Expect(image).NotTo(BeEmpty()) + // Save resources by deleting the integration + g.Expect(Kamel(t, ctx, "delete", name, "-n", ns).Execute()).To(Succeed()) + + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", "pre-built", "-t", fmt.Sprintf("container.image=%s", image)).Execute()).To(Succeed()) + g.Eventually(IntegrationPhase(t, ctx, ns, "pre-built"), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseRunning)) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "pre-built"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Expect(ScaleIntegration(t, ctx, ns, "pre-built", 0)).To(Succeed()) + g.Eventually(IntegrationPod(t, ctx, ns, "pre-built"), TestTimeoutMedium).Should(BeNil()) + g.Expect(ScaleIntegration(t, ctx, ns, "pre-built", 1)).To(Succeed()) + g.Eventually(IntegrationPhase(t, ctx, ns, "pre-built"), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseRunning)) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "pre-built"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + + g.Expect(Kamel(t, ctx, "delete", "pre-built", "-n", ns).Execute()).To(Succeed()) + }) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) - - t.Run("Scale integration with polymorphic client", func(t *testing.T) { - scaleClient, err := TestClient().ScalesClient() - Expect(err).To(BeNil()) - - // Patch the integration scale subresource - patch := "{\"spec\":{\"replicas\":2}}" - _, err = scaleClient.Scales(ns).Patch(TestContext, v1.SchemeGroupVersion.WithResource("integrations"), name, types.MergePatchType, []byte(patch), metav1.PatchOptions{}) - Expect(err).To(BeNil()) - - // Check the readiness condition is still truthy as down-scaling - Expect(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady)()).To(Equal(corev1.ConditionTrue)) - // Check the Integration scale subresource Spec field - Eventually(IntegrationSpecReplicas(ns, name), TestTimeoutShort). - Should(gstruct.PointTo(BeNumerically("==", 2))) - // Then check it cascades into the Deployment scale - Eventually(IntegrationPods(ns, name), TestTimeoutShort).Should(HaveLen(2)) - // Finally check it cascades into the Integration scale subresource Status field - Eventually(IntegrationStatusReplicas(ns, name), TestTimeoutShort). - Should(gstruct.PointTo(BeNumerically("==", 2))) - }) - - t.Run("Scale integration with Camel K client", func(t *testing.T) { - camel, err := versioned.NewForConfig(TestClient().GetConfig()) - Expect(err).To(BeNil()) - - // Getter - integrationScale, err := camel.CamelV1().Integrations(ns).GetScale(TestContext, name, metav1.GetOptions{}) - Expect(err).To(BeNil()) - Expect(integrationScale.Spec.Replicas).To(BeNumerically("==", 2)) - Expect(integrationScale.Status.Replicas).To(BeNumerically("==", 2)) - - // Setter - integrationScale.Spec.Replicas = 1 - integrationScale, err = camel.CamelV1().Integrations(ns).UpdateScale(TestContext, name, integrationScale, metav1.UpdateOptions{}) - Expect(err).To(BeNil()) - - // Check the readiness condition is still truthy as down-scaling - Expect(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady)()).To(Equal(corev1.ConditionTrue)) - // Check the Integration scale subresource Spec field - Eventually(IntegrationSpecReplicas(ns, name), TestTimeoutShort). - Should(gstruct.PointTo(BeNumerically("==", 1))) - // Then check it cascades into the Deployment scale - Eventually(IntegrationPods(ns, name), TestTimeoutShort).Should(HaveLen(1)) - // Finally check it cascades into the Integration scale subresource Status field - Eventually(IntegrationStatusReplicas(ns, name), TestTimeoutShort). - Should(gstruct.PointTo(BeNumerically("==", 1))) - }) - - t.Run("Scale integration with external image", func(t *testing.T) { - image := IntegrationPodImage(ns, name)() - Expect(image).NotTo(BeEmpty()) - // Save resources by deleting the integration - Expect(Kamel("delete", name, "-n", ns).Execute()).To(Succeed()) - - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", "--name", "pre-built", "-t", fmt.Sprintf("container.image=%s", image)).Execute()).To(Succeed()) - Eventually(IntegrationPhase(ns, "pre-built"), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseRunning)) - Eventually(IntegrationPodPhase(ns, "pre-built"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Expect(ScaleIntegration(ns, "pre-built", 0)).To(Succeed()) - Eventually(IntegrationPod(ns, "pre-built"), TestTimeoutMedium).Should(BeNil()) - Expect(ScaleIntegration(ns, "pre-built", 1)).To(Succeed()) - Eventually(IntegrationPhase(ns, "pre-built"), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseRunning)) - Eventually(IntegrationPodPhase(ns, "pre-built"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - - Expect(Kamel("delete", "pre-built", "-n", ns).Execute()).To(Succeed()) - }) - - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) } diff --git a/e2e/common/misc/structured_logs_test.go b/e2e/common/misc/structured_logs_test.go index a78561618c..da6765bdea 100644 --- a/e2e/common/misc/structured_logs_test.go +++ b/e2e/common/misc/structured_logs_test.go @@ -23,6 +23,7 @@ limitations under the License. package misc import ( + "context" "fmt" "testing" @@ -35,31 +36,38 @@ import ( ) func TestStructuredLogs(t *testing.T) { - RegisterTestingT(t) - - name := RandomizedSuffixName("java") - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", - "--name", name, - "-t", "logging.format=json").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - - pod := OperatorPod(ns)() - Expect(pod).NotTo(BeNil()) - - // pod.Namespace could be different from ns if using global operator - fmt.Printf("Fetching logs for operator pod %s in namespace %s", pod.Name, pod.Namespace) - logOptions := &corev1.PodLogOptions{ - Container: "camel-k-operator", - } - logs, err := StructuredLogs(pod.Namespace, pod.Name, logOptions, false) - Expect(err).To(BeNil()) - Expect(logs).NotTo(BeEmpty()) - - it := Integration(ns, name)() - Expect(it).NotTo(BeNil()) - build := Build(IntegrationKitNamespace(ns, name)(), IntegrationKit(ns, name)())() - Expect(build).NotTo(BeNil()) - - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + t.Parallel() + + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-structured-logs" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + + name := RandomizedSuffixName("java") + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", name, "-t", "logging.format=json").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + + pod := OperatorPod(t, ctx, ns)() + g.Expect(pod).NotTo(BeNil()) + + // pod.Namespace could be different from ns if using global operator + fmt.Printf("Fetching logs for operator pod %s in namespace %s", pod.Name, pod.Namespace) + logOptions := &corev1.PodLogOptions{ + Container: "camel-k-operator", + } + logs, err := StructuredLogs(t, ctx, pod.Namespace, pod.Name, logOptions, false) + g.Expect(err).To(BeNil()) + g.Expect(logs).NotTo(BeEmpty()) + + it := Integration(t, ctx, ns, name)() + g.Expect(it).NotTo(BeNil()) + build := Build(t, ctx, IntegrationKitNamespace(t, ctx, ns, name)(), IntegrationKit(t, ctx, ns, name)())() + g.Expect(build).NotTo(BeNil()) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) } diff --git a/e2e/common/runtimes/default.go b/e2e/common/runtimes/default.go deleted file mode 100644 index 1cc41c3f9a..0000000000 --- a/e2e/common/runtimes/default.go +++ /dev/null @@ -1,26 +0,0 @@ -//go:build integration -// +build integration - -/* -Licensed to the Apache Software Foundation (ASF) under one or more -contributor license agreements. See the NOTICE file distributed with -this work for additional information regarding copyright ownership. -The ASF licenses this file to You under the Apache License, Version 2.0 -(the "License"); you may not use this file except in compliance with -the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package runtimes - -import "github.com/apache/camel-k/v2/e2e/support" - -var ns = support.GetEnvOrDefault("CAMEL_K_TEST_NAMESPACE", support.GetCIProcessID()) -var operatorID = support.GetEnvOrDefault("CAMEL_K_OPERATOR_ID", support.GetCIProcessID()) diff --git a/e2e/common/runtimes/runtimes_test.go b/e2e/common/runtimes/runtimes_test.go index 87f6394e17..dee3ae100f 100644 --- a/e2e/common/runtimes/runtimes_test.go +++ b/e2e/common/runtimes/runtimes_test.go @@ -23,6 +23,7 @@ limitations under the License. package runtimes import ( + "context" "testing" . "github.com/onsi/gomega" @@ -34,40 +35,50 @@ import ( ) func TestSourceLessIntegrations(t *testing.T) { - RegisterTestingT(t) - var cmData = make(map[string]string) - cmData["my-file.txt"] = "Hello World!" - CreatePlainTextConfigmap(ns, "my-cm-sourceless", cmData) - - t.Run("Camel Main", func(t *testing.T) { - itName := "my-camel-main-v1" - Expect(KamelRunWithID(operatorID, ns, "--image", "docker.io/squakez/my-camel-main:1.0.0", "--resource", "configmap:my-cm-sourceless@/tmp/app/data").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, itName), TestTimeoutShort).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, itName, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationCondition(ns, itName, v1.IntegrationConditionTraitInfo)().Message).Should(Equal("explicitly disabled by the platform: integration kit was not created via Camel K operator")) - Eventually(IntegrationLogs(ns, itName), TestTimeoutShort).Should(ContainSubstring(cmData["my-file.txt"])) - Eventually(IntegrationLogs(ns, itName), TestTimeoutShort).Should(ContainSubstring("Apache Camel (Main)")) - }) + t.Parallel() - t.Run("Camel Spring Boot", func(t *testing.T) { - itName := "my-camel-sb-v1" - Expect(KamelRunWithID(operatorID, ns, "--image", "docker.io/squakez/my-camel-sb:1.0.0", "--resource", "configmap:my-cm-sourceless@/tmp/app/data").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, itName), TestTimeoutShort).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, itName, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationCondition(ns, itName, v1.IntegrationConditionTraitInfo)().Message).Should(Equal("explicitly disabled by the platform: integration kit was not created via Camel K operator")) - Eventually(IntegrationLogs(ns, itName), TestTimeoutShort).Should(ContainSubstring(cmData["my-file.txt"])) - Eventually(IntegrationLogs(ns, itName), TestTimeoutShort).Should(ContainSubstring("Spring Boot")) - }) + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-runtimes" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) - t.Run("Camel Quarkus", func(t *testing.T) { - itName := "my-camel-quarkus-v1" - Expect(KamelRunWithID(operatorID, ns, "--image", "docker.io/squakez/my-camel-quarkus:1.0.0", "--resource", "configmap:my-cm-sourceless@/tmp/app/data").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, itName), TestTimeoutShort).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, itName, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationCondition(ns, itName, v1.IntegrationConditionTraitInfo)().Message).Should(Equal("explicitly disabled by the platform: integration kit was not created via Camel K operator")) - Eventually(IntegrationLogs(ns, itName), TestTimeoutShort).Should(ContainSubstring(cmData["my-file.txt"])) - Eventually(IntegrationLogs(ns, itName), TestTimeoutShort).Should(ContainSubstring("powered by Quarkus")) - }) + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + + var cmData = make(map[string]string) + cmData["my-file.txt"] = "Hello World!" + CreatePlainTextConfigmap(t, ctx, ns, "my-cm-sourceless", cmData) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + t.Run("Camel Main", func(t *testing.T) { + itName := "my-camel-main-v1" + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "--image", "docker.io/squakez/my-camel-main:1.0.0", "--resource", "configmap:my-cm-sourceless@/tmp/app/data").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, itName), TestTimeoutShort).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, itName, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationCondition(t, ctx, ns, itName, v1.IntegrationConditionType("JVMTraitInfo"))().Message).Should(Equal("explicitly disabled by the platform: integration kit was not created via Camel K operator")) + g.Eventually(IntegrationLogs(t, ctx, ns, itName), TestTimeoutShort).Should(ContainSubstring(cmData["my-file.txt"])) + g.Eventually(IntegrationLogs(t, ctx, ns, itName), TestTimeoutShort).Should(ContainSubstring("Apache Camel (Main)")) + }) + + t.Run("Camel Spring Boot", func(t *testing.T) { + itName := "my-camel-sb-v1" + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "--image", "docker.io/squakez/my-camel-sb:1.0.0", "--resource", "configmap:my-cm-sourceless@/tmp/app/data").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, itName), TestTimeoutShort).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, itName, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationCondition(t, ctx, ns, itName, v1.IntegrationConditionType("JVMTraitInfo"))().Message).Should(Equal("explicitly disabled by the platform: integration kit was not created via Camel K operator")) + g.Eventually(IntegrationLogs(t, ctx, ns, itName), TestTimeoutShort).Should(ContainSubstring(cmData["my-file.txt"])) + g.Eventually(IntegrationLogs(t, ctx, ns, itName), TestTimeoutShort).Should(ContainSubstring("Spring Boot")) + }) + + t.Run("Camel Quarkus", func(t *testing.T) { + itName := "my-camel-quarkus-v1" + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "--image", "docker.io/squakez/my-camel-quarkus:1.0.0", "--resource", "configmap:my-cm-sourceless@/tmp/app/data").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, itName), TestTimeoutShort).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, itName, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationCondition(t, ctx, ns, itName, v1.IntegrationConditionType("JVMTraitInfo"))().Message).Should(Equal("explicitly disabled by the platform: integration kit was not created via Camel K operator")) + g.Eventually(IntegrationLogs(t, ctx, ns, itName), TestTimeoutShort).Should(ContainSubstring(cmData["my-file.txt"])) + g.Eventually(IntegrationLogs(t, ctx, ns, itName), TestTimeoutShort).Should(ContainSubstring("powered by Quarkus")) + }) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) } diff --git a/e2e/common/support/teardown_test.go b/e2e/common/support/teardown_test.go deleted file mode 100644 index 78546c7f77..0000000000 --- a/e2e/common/support/teardown_test.go +++ /dev/null @@ -1,40 +0,0 @@ -//go:build integration -// +build integration - -// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration" - -/* -Licensed to the Apache Software Foundation (ASF) under one or more -contributor license agreements. See the NOTICE file distributed with -this work for additional information regarding copyright ownership. -The ASF licenses this file to You under the Apache License, Version 2.0 -(the "License"); you may not use this file except in compliance with -the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package support - -import ( - "testing" - - . "github.com/onsi/gomega" - - . "github.com/apache/camel-k/v2/e2e/support" -) - -func TestCommonCamelKInstallTeardown(t *testing.T) { - RegisterTestingT(t) - - ns := GetCIProcessID() - Expect(ns).ShouldNot(Equal("")) - Expect(DeleteNamespace(t, ns)).To(Succeed()) - DeleteCIProcessID() -} diff --git a/e2e/common/traits/affinity_test.go b/e2e/common/traits/affinity_test.go index 7ce8a20eba..3b99863f59 100644 --- a/e2e/common/traits/affinity_test.go +++ b/e2e/common/traits/affinity_test.go @@ -23,6 +23,7 @@ limitations under the License. package traits import ( + "context" "fmt" "testing" @@ -37,90 +38,90 @@ import ( ) func TestAffinityTrait(t *testing.T) { - RegisterTestingT(t) - - var hostname string - if node, err := selectSchedulableNode(); err == nil { - hostname = node.Labels["kubernetes.io/hostname"] - } else { - // if 'get nodes' is not allowed, just skip tests for node affinity - hostname = "" - } + t.Parallel() + + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-traits-affinity" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + + var hostname string + if node, err := selectSchedulableNode(t, ctx); err == nil { + hostname = node.Labels["kubernetes.io/hostname"] + } else { + // if 'get nodes' is not allowed, just skip tests for node affinity + hostname = "" + } - if hostname != "" { - t.Run("Run Java with node affinity", func(t *testing.T) { - name1 := RandomizedSuffixName("java1") - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", - "--name", name1, - "-t", "affinity.enabled=true", - "-t", fmt.Sprintf("affinity.node-affinity-labels=kubernetes.io/hostname in(%s)", hostname)).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name1), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name1, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name1), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - - pod := IntegrationPod(ns, name1)() - Expect(pod.Spec.Affinity).NotTo(BeNil()) - Expect(pod.Spec.Affinity.NodeAffinity).To(Equal(&corev1.NodeAffinity{ - RequiredDuringSchedulingIgnoredDuringExecution: nodeSelector("kubernetes.io/hostname", corev1.NodeSelectorOpIn, hostname), - })) - Expect(pod.Spec.NodeName).To(Equal(hostname)) - - // check integration schema does not contains unwanted default trait value. - Eventually(UnstructuredIntegration(ns, name1)).ShouldNot(BeNil()) - unstructuredIntegration := UnstructuredIntegration(ns, name1)() - affinityTrait, _, _ := unstructured.NestedMap(unstructuredIntegration.Object, "spec", "traits", "affinity") - Expect(affinityTrait).NotTo(BeNil()) - Expect(len(affinityTrait)).To(Equal(2)) - Expect(affinityTrait["enabled"]).To(Equal(true)) - Expect(affinityTrait["nodeAffinityLabels"]).NotTo(BeNil()) - - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) - }) - } + if hostname != "" { + t.Run("Run Java with node affinity", func(t *testing.T) { + name1 := RandomizedSuffixName("java1") + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", name1, "-t", "affinity.enabled=true", "-t", fmt.Sprintf("affinity.node-affinity-labels=kubernetes.io/hostname in(%s)", hostname)).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name1), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name1, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name1), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + + pod := IntegrationPod(t, ctx, ns, name1)() + g.Expect(pod.Spec.Affinity).NotTo(BeNil()) + g.Expect(pod.Spec.Affinity.NodeAffinity).To(Equal(&corev1.NodeAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: nodeSelector("kubernetes.io/hostname", corev1.NodeSelectorOpIn, hostname), + })) + g.Expect(pod.Spec.NodeName).To(Equal(hostname)) + + // check integration schema does not contains unwanted default trait value. + g.Eventually(UnstructuredIntegration(t, ctx, ns, name1)).ShouldNot(BeNil()) + unstructuredIntegration := UnstructuredIntegration(t, ctx, ns, name1)() + affinityTrait, _, _ := unstructured.NestedMap(unstructuredIntegration.Object, "spec", "traits", "affinity") + g.Expect(affinityTrait).NotTo(BeNil()) + g.Expect(len(affinityTrait)).To(Equal(2)) + g.Expect(affinityTrait["enabled"]).To(Equal(true)) + g.Expect(affinityTrait["nodeAffinityLabels"]).NotTo(BeNil()) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) + } - t.Run("Run Java with pod affinity", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", - "--name", "java2", - "-t", "affinity.enabled=true", - "-t", "affinity.pod-affinity-labels=camel.apache.org/integration").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "java2"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "java2", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "java2"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - - pod := IntegrationPod(ns, "java2")() - Expect(pod.Spec.Affinity).NotTo(BeNil()) - Expect(pod.Spec.Affinity.PodAffinity).To(Equal(&corev1.PodAffinity{ - RequiredDuringSchedulingIgnoredDuringExecution: []corev1.PodAffinityTerm{ - podAffinityTerm("camel.apache.org/integration", metav1.LabelSelectorOpExists, "kubernetes.io/hostname"), - }, - })) + t.Run("Run Java with pod affinity", func(t *testing.T) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", "java2", "-t", "affinity.enabled=true", "-t", "affinity.pod-affinity-labels=camel.apache.org/integration").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "java2"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "java2", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "java2"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + + pod := IntegrationPod(t, ctx, ns, "java2")() + g.Expect(pod.Spec.Affinity).NotTo(BeNil()) + g.Expect(pod.Spec.Affinity.PodAffinity).To(Equal(&corev1.PodAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: []corev1.PodAffinityTerm{ + podAffinityTerm("camel.apache.org/integration", metav1.LabelSelectorOpExists, "kubernetes.io/hostname"), + }, + })) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) - }) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) - t.Run("Run Java with pod anti affinity", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", - "--name", "java3", - "-t", "affinity.enabled=true", - "-t", "affinity.pod-anti-affinity-labels=camel.apache.org/integration").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "java3"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "java3", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "java3"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - - pod := IntegrationPod(ns, "java3")() - Expect(pod.Spec.Affinity).NotTo(BeNil()) - Expect(pod.Spec.Affinity.PodAntiAffinity).To(Equal(&corev1.PodAntiAffinity{ - RequiredDuringSchedulingIgnoredDuringExecution: []corev1.PodAffinityTerm{ - podAffinityTerm("camel.apache.org/integration", metav1.LabelSelectorOpExists, "kubernetes.io/hostname"), - }, - })) + t.Run("Run Java with pod anti affinity", func(t *testing.T) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", "java3", "-t", "affinity.enabled=true", "-t", "affinity.pod-anti-affinity-labels=camel.apache.org/integration").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "java3"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "java3", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "java3"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + + pod := IntegrationPod(t, ctx, ns, "java3")() + g.Expect(pod.Spec.Affinity).NotTo(BeNil()) + g.Expect(pod.Spec.Affinity.PodAntiAffinity).To(Equal(&corev1.PodAntiAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: []corev1.PodAffinityTerm{ + podAffinityTerm("camel.apache.org/integration", metav1.LabelSelectorOpExists, "kubernetes.io/hostname"), + }, + })) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) }) } -func selectSchedulableNode() (*corev1.Node, error) { - nodes, err := TestClient().CoreV1().Nodes().List(TestContext, metav1.ListOptions{}) +func selectSchedulableNode(t *testing.T, ctx context.Context) (*corev1.Node, error) { + nodes, err := TestClient(t).CoreV1().Nodes().List(ctx, metav1.ListOptions{}) if err != nil { return nil, err } diff --git a/e2e/common/traits/builder_test.go b/e2e/common/traits/builder_test.go index dea284e839..b329f5c2d5 100644 --- a/e2e/common/traits/builder_test.go +++ b/e2e/common/traits/builder_test.go @@ -23,6 +23,7 @@ limitations under the License. package traits import ( + "context" "fmt" "testing" @@ -30,256 +31,241 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" . "github.com/apache/camel-k/v2/e2e/support" v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" ) func TestBuilderTrait(t *testing.T) { - RegisterTestingT(t) - - t.Run("Run build strategy routine", func(t *testing.T) { - name := RandomizedSuffixName("java") - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", - "--name", name, - "-t", "builder.strategy=routine").Execute()).To(Succeed()) - - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - - integrationKitName := IntegrationKit(ns, name)() - integrationKitNamespace := IntegrationKitNamespace(ns, name)() - builderKitName := fmt.Sprintf("camel-k-%s-builder", integrationKitName) - Eventually(BuildConfig(integrationKitNamespace, integrationKitName)().Strategy, TestTimeoutShort).Should(Equal(v1.BuildStrategyRoutine)) - Eventually(BuildConfig(integrationKitNamespace, integrationKitName)().OrderStrategy, TestTimeoutShort).Should(Equal(v1.BuildOrderStrategySequential)) - // Default resource CPU Check - Eventually(BuildConfig(integrationKitNamespace, integrationKitName)().RequestCPU, TestTimeoutShort).Should(Equal("")) - Eventually(BuildConfig(integrationKitNamespace, integrationKitName)().LimitCPU, TestTimeoutShort).Should(Equal("")) - Eventually(BuildConfig(integrationKitNamespace, integrationKitName)().RequestMemory, TestTimeoutShort).Should(Equal("")) - Eventually(BuildConfig(integrationKitNamespace, integrationKitName)().LimitMemory, TestTimeoutShort).Should(Equal("")) - - Eventually(BuilderPod(integrationKitNamespace, builderKitName), TestTimeoutShort).Should(BeNil()) - - // We need to remove the kit as well - Expect(Kamel("reset", "-n", ns).Execute()).To(Succeed()) - }) - - t.Run("Run build order strategy dependencies", func(t *testing.T) { - name := RandomizedSuffixName("java-dependencies-strategy") - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", - "--name", name, - "-t", "builder.order-strategy=dependencies").Execute()).To(Succeed()) - - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - - integrationKitName := IntegrationKit(ns, name)() - integrationKitNamespace := IntegrationKitNamespace(ns, name)() - builderKitName := fmt.Sprintf("camel-k-%s-builder", integrationKitName) - Eventually(BuildConfig(integrationKitNamespace, integrationKitName)().Strategy, TestTimeoutShort).Should(Equal(v1.BuildStrategyRoutine)) - Eventually(BuildConfig(integrationKitNamespace, integrationKitName)().OrderStrategy, TestTimeoutShort).Should(Equal(v1.BuildOrderStrategyDependencies)) - // Default resource CPU Check - Eventually(BuildConfig(integrationKitNamespace, integrationKitName)().RequestCPU, TestTimeoutShort).Should(Equal("")) - Eventually(BuildConfig(integrationKitNamespace, integrationKitName)().LimitCPU, TestTimeoutShort).Should(Equal("")) - Eventually(BuildConfig(integrationKitNamespace, integrationKitName)().RequestMemory, TestTimeoutShort).Should(Equal("")) - Eventually(BuildConfig(integrationKitNamespace, integrationKitName)().LimitMemory, TestTimeoutShort).Should(Equal("")) - - Eventually(BuilderPod(integrationKitNamespace, builderKitName), TestTimeoutShort).Should(BeNil()) - - // check integration schema does not contains unwanted default trait value. - Eventually(UnstructuredIntegration(ns, name)).ShouldNot(BeNil()) - unstructuredIntegration := UnstructuredIntegration(ns, name)() - builderTrait, _, _ := unstructured.NestedMap(unstructuredIntegration.Object, "spec", "traits", "builder") - Expect(builderTrait).NotTo(BeNil()) - Expect(len(builderTrait)).To(Equal(1)) - Expect(builderTrait["orderStrategy"]).To(Equal("dependencies")) - - // We need to remove the kit as well - Expect(Kamel("reset", "-n", ns).Execute()).To(Succeed()) - }) - - t.Run("Run build order strategy fifo", func(t *testing.T) { - name := RandomizedSuffixName("java-fifo-strategy") - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", - "--name", name, - "-t", "builder.order-strategy=fifo").Execute()).To(Succeed()) - - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - - integrationKitName := IntegrationKit(ns, name)() - integrationKitNamespace := IntegrationKitNamespace(ns, name)() - builderKitName := fmt.Sprintf("camel-k-%s-builder", integrationKitName) - Eventually(BuildConfig(integrationKitNamespace, integrationKitName)().Strategy, TestTimeoutShort).Should(Equal(v1.BuildStrategyRoutine)) - Eventually(BuildConfig(integrationKitNamespace, integrationKitName)().OrderStrategy, TestTimeoutShort).Should(Equal(v1.BuildOrderStrategyFIFO)) - // Default resource CPU Check - Eventually(BuildConfig(integrationKitNamespace, integrationKitName)().RequestCPU, TestTimeoutShort).Should(Equal("")) - Eventually(BuildConfig(integrationKitNamespace, integrationKitName)().LimitCPU, TestTimeoutShort).Should(Equal("")) - Eventually(BuildConfig(integrationKitNamespace, integrationKitName)().RequestMemory, TestTimeoutShort).Should(Equal("")) - Eventually(BuildConfig(integrationKitNamespace, integrationKitName)().LimitMemory, TestTimeoutShort).Should(Equal("")) - - Eventually(BuilderPod(integrationKitNamespace, builderKitName), TestTimeoutShort).Should(BeNil()) - - // We need to remove the kit as well - Expect(Kamel("reset", "-n", ns).Execute()).To(Succeed()) - }) - - t.Run("Run build resources configuration", func(t *testing.T) { - name := RandomizedSuffixName("java-resource-config") - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", - "--name", name, - "-t", "builder.tasks-request-cpu=builder:500m", - "-t", "builder.tasks-limit-cpu=builder:1000m", - "-t", "builder.tasks-request-memory=builder:2Gi", - "-t", "builder.tasks-limit-memory=builder:3Gi", - "-t", "builder.strategy=pod", - ).Execute()).To(Succeed()) - - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - - integrationKitName := IntegrationKit(ns, name)() - integrationKitNamespace := IntegrationKitNamespace(ns, name)() - builderKitName := fmt.Sprintf("camel-k-%s-builder", integrationKitName) - - Eventually(BuildConfig(integrationKitNamespace, integrationKitName)().Strategy, TestTimeoutShort).Should(Equal(v1.BuildStrategyPod)) - Eventually(BuildConfig(integrationKitNamespace, integrationKitName)().OrderStrategy, TestTimeoutShort).Should(Equal(v1.BuildOrderStrategySequential)) - Eventually(BuildConfig(integrationKitNamespace, integrationKitName)().RequestCPU, TestTimeoutShort).Should(Equal("500m")) - Eventually(BuildConfig(integrationKitNamespace, integrationKitName)().LimitCPU, TestTimeoutShort).Should(Equal("1000m")) - Eventually(BuildConfig(integrationKitNamespace, integrationKitName)().RequestMemory, TestTimeoutShort).Should(Equal("2Gi")) - Eventually(BuildConfig(integrationKitNamespace, integrationKitName)().LimitMemory, TestTimeoutShort).Should(Equal("3Gi")) - - Eventually(BuilderPod(integrationKitNamespace, builderKitName), TestTimeoutShort).ShouldNot(BeNil()) - // Let's assert we set the resources on the builder container - Eventually(BuilderPod(integrationKitNamespace, builderKitName)().Spec.InitContainers[0].Name, TestTimeoutShort).Should(Equal("builder")) - Eventually(BuilderPod(integrationKitNamespace, builderKitName)().Spec.InitContainers[0].Resources.Requests.Cpu().String(), TestTimeoutShort).Should(Equal("500m")) - Eventually(BuilderPod(integrationKitNamespace, builderKitName)().Spec.InitContainers[0].Resources.Limits.Cpu().String(), TestTimeoutShort).Should(Equal("1")) - Eventually(BuilderPod(integrationKitNamespace, builderKitName)().Spec.InitContainers[0].Resources.Requests.Memory().String(), TestTimeoutShort).Should(Equal("2Gi")) - Eventually(BuilderPod(integrationKitNamespace, builderKitName)().Spec.InitContainers[0].Resources.Limits.Memory().String(), TestTimeoutShort).Should(Equal("3Gi")) - - Expect(Kamel("reset", "-n", ns).Execute()).To(Succeed()) - }) - - t.Run("Run custom pipeline task", func(t *testing.T) { - name := RandomizedSuffixName("java-pipeline") - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", - "--name", name, - "-t", "builder.tasks=custom1;alpine;tree", - "-t", "builder.tasks=custom2;alpine;cat maven/pom.xml", - "-t", "builder.strategy=pod", - ).Execute()).To(Succeed()) - - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutLong).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - - integrationKitName := IntegrationKit(ns, name)() - integrationKitNamespace := IntegrationKitNamespace(ns, name)() - builderKitName := fmt.Sprintf("camel-k-%s-builder", integrationKitName) - Eventually(BuilderPod(integrationKitNamespace, builderKitName), TestTimeoutShort).ShouldNot(BeNil()) - Eventually(len(BuilderPod(integrationKitNamespace, builderKitName)().Spec.InitContainers), TestTimeoutShort).Should(Equal(4)) - Eventually(BuilderPod(integrationKitNamespace, builderKitName)().Spec.InitContainers[0].Name, TestTimeoutShort).Should(Equal("builder")) - Eventually(BuilderPod(integrationKitNamespace, builderKitName)().Spec.InitContainers[1].Name, TestTimeoutShort).Should(Equal("custom1")) - Eventually(BuilderPod(integrationKitNamespace, builderKitName)().Spec.InitContainers[2].Name, TestTimeoutShort).Should(Equal("custom2")) - - // Check containers conditions - Eventually(Build(integrationKitNamespace, integrationKitName), TestTimeoutShort).ShouldNot(BeNil()) - Eventually( - Build( - integrationKitNamespace, integrationKitName)().Status.GetCondition(v1.BuildConditionType("Container custom1 succeeded")).Status, - TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually( - Build(integrationKitNamespace, integrationKitName)().Status.GetCondition(v1.BuildConditionType("Container custom1 succeeded")).Message, - TestTimeoutShort).Should(ContainSubstring("generated-bytecode.jar")) - Eventually(Build(integrationKitNamespace, integrationKitName), TestTimeoutShort).ShouldNot(BeNil()) - Eventually( - Build(integrationKitNamespace, integrationKitName)().Status.GetCondition(v1.BuildConditionType("Container custom2 succeeded")).Status, - TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually( - Build(integrationKitNamespace, integrationKitName)().Status.GetCondition(v1.BuildConditionType("Container custom2 succeeded")).Message, - TestTimeoutShort).Should(ContainSubstring("")) - - // Check logs - Eventually(Logs(integrationKitNamespace, builderKitName, corev1.PodLogOptions{Container: "custom1"})).Should(ContainSubstring(`generated-bytecode.jar`)) - Eventually(Logs(integrationKitNamespace, builderKitName, corev1.PodLogOptions{Container: "custom2"})).Should(ContainSubstring(`camel-k-runtime-bom`)) - - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) - }) - - t.Run("Run custom pipeline task error", func(t *testing.T) { - name := RandomizedSuffixName("java-error") - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", - "--name", name, - "-t", "builder.tasks=custom1;alpine;cat missingfile.txt", - "-t", "builder.strategy=pod", - ).Execute()).To(Succeed()) - - Eventually(IntegrationPhase(ns, name)).Should(Equal(v1.IntegrationPhaseBuildingKit)) - integrationKitName := IntegrationKit(ns, name)() - integrationKitNamespace := IntegrationKitNamespace(ns, name)() - // Check containers conditions - Eventually(Build(integrationKitNamespace, integrationKitName), TestTimeoutLong).ShouldNot(BeNil()) - Eventually(BuildConditions(integrationKitNamespace, integrationKitName), TestTimeoutLong).ShouldNot(BeNil()) - Eventually(BuildCondition(integrationKitNamespace, integrationKitName, v1.BuildConditionType("Container custom1 succeeded")), TestTimeoutMedium).ShouldNot(BeNil()) - Eventually( - BuildCondition(integrationKitNamespace, integrationKitName, v1.BuildConditionType("Container custom1 succeeded"))().Status, - TestTimeoutShort).Should(Equal(corev1.ConditionFalse)) - Eventually( - BuildCondition(integrationKitNamespace, integrationKitName, v1.BuildConditionType("Container custom1 succeeded"))().Message, - TestTimeoutShort).Should(ContainSubstring("No such file or directory")) - - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) - }) - - t.Run("Run maven profile", func(t *testing.T) { - name := RandomizedSuffixName("java-maven-profile") - - mavenProfile1Cm := newMavenProfileConfigMap(ns, "maven-profile-owasp", "owasp-profile") - Expect(TestClient().Create(TestContext, mavenProfile1Cm)).To(Succeed()) - mavenProfile2Cm := newMavenProfileConfigMap(ns, "maven-profile-dependency", "dependency-profile") - Expect(TestClient().Create(TestContext, mavenProfile2Cm)).To(Succeed()) - - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", - "--name", name, - "-t", "builder.maven-profiles=configmap:maven-profile-owasp/owasp-profile", - "-t", "builder.maven-profiles=configmap:maven-profile-dependency/dependency-profile", - "-t", "builder.tasks=custom1;alpine;cat maven/pom.xml", - "-t", "builder.strategy=pod", - ).Execute()).To(Succeed()) - - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutLong).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - - integrationKitName := IntegrationKit(ns, name)() - builderKitName := fmt.Sprintf("camel-k-%s-builder", integrationKitName) - Eventually(BuilderPod(ns, builderKitName), TestTimeoutShort).ShouldNot(BeNil()) - Eventually(len(BuilderPod(ns, builderKitName)().Spec.InitContainers), TestTimeoutShort).Should(Equal(3)) - Eventually(BuilderPod(ns, builderKitName)().Spec.InitContainers[0].Name, TestTimeoutShort).Should(Equal("builder")) - Eventually(BuilderPod(ns, builderKitName)().Spec.InitContainers[1].Name, TestTimeoutShort).Should(Equal("custom1")) - Eventually(BuilderPod(ns, builderKitName)().Spec.InitContainers[2].Name, TestTimeoutShort).Should(Equal("package")) - - // Check containers conditions - Eventually(Build(ns, integrationKitName), TestTimeoutShort).ShouldNot(BeNil()) - Eventually( - Build(ns, integrationKitName)().Status.GetCondition(v1.BuildConditionType("Container custom1 succeeded")).Status, - TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually( - Build(ns, integrationKitName)().Status.GetCondition(v1.BuildConditionType("Container custom1 succeeded")).Message, - TestTimeoutShort).Should(ContainSubstring("")) - - // Check logs - Eventually(Logs(ns, builderKitName, corev1.PodLogOptions{Container: "custom1"})).Should(ContainSubstring(`owasp-profile`)) - Eventually(Logs(ns, builderKitName, corev1.PodLogOptions{Container: "custom1"})).Should(ContainSubstring(`dependency-profile`)) - - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) - Expect(TestClient().Delete(TestContext, mavenProfile1Cm)).To(Succeed()) - Expect(TestClient().Delete(TestContext, mavenProfile2Cm)).To(Succeed()) + t.Parallel() + + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-traits-builder" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + + t.Run("Run build strategy routine", func(t *testing.T) { + name := RandomizedSuffixName("java") + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", name, "-t", "builder.order-strategy=sequential", "-t", "builder.strategy=routine").Execute()).To(Succeed()) + + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + + integrationKitName := IntegrationKit(t, ctx, ns, name)() + integrationKitNamespace := IntegrationKitNamespace(t, ctx, ns, name)() + builderKitName := fmt.Sprintf("camel-k-%s-builder", integrationKitName) + g.Eventually(BuildConfig(t, ctx, integrationKitNamespace, integrationKitName)().Strategy, TestTimeoutShort).Should(Equal(v1.BuildStrategyRoutine)) + g.Eventually(BuildConfig(t, ctx, integrationKitNamespace, integrationKitName)().OrderStrategy, TestTimeoutShort).Should(Equal(v1.BuildOrderStrategySequential)) + // Default resource CPU Check + g.Eventually(BuildConfig(t, ctx, integrationKitNamespace, integrationKitName)().RequestCPU, TestTimeoutShort).Should(Equal("")) + g.Eventually(BuildConfig(t, ctx, integrationKitNamespace, integrationKitName)().LimitCPU, TestTimeoutShort).Should(Equal("")) + g.Eventually(BuildConfig(t, ctx, integrationKitNamespace, integrationKitName)().RequestMemory, TestTimeoutShort).Should(Equal("")) + g.Eventually(BuildConfig(t, ctx, integrationKitNamespace, integrationKitName)().LimitMemory, TestTimeoutShort).Should(Equal("")) + + g.Eventually(BuilderPod(t, ctx, integrationKitNamespace, builderKitName), TestTimeoutShort).Should(BeNil()) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) + + t.Run("Run build order strategy dependencies", func(t *testing.T) { + name := RandomizedSuffixName("java-dependencies-strategy") + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", + "--name", name, + // This is required in order to avoid reusing a Kit already existing (which is the default behavior) + "--build-property", "strategy=dependencies", + "-t", "builder.order-strategy=dependencies").Execute()).To(Succeed()) + + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + + integrationKitName := IntegrationKit(t, ctx, ns, name)() + integrationKitNamespace := IntegrationKitNamespace(t, ctx, ns, name)() + builderKitName := fmt.Sprintf("camel-k-%s-builder", integrationKitName) + g.Eventually(BuildConfig(t, ctx, integrationKitNamespace, integrationKitName)().Strategy, TestTimeoutShort).Should(Equal(v1.BuildStrategyRoutine)) + g.Eventually(BuildConfig(t, ctx, integrationKitNamespace, integrationKitName)().OrderStrategy, TestTimeoutShort).Should(Equal(v1.BuildOrderStrategyDependencies)) + // Default resource CPU Check + g.Eventually(BuildConfig(t, ctx, integrationKitNamespace, integrationKitName)().RequestCPU, TestTimeoutShort).Should(Equal("")) + g.Eventually(BuildConfig(t, ctx, integrationKitNamespace, integrationKitName)().LimitCPU, TestTimeoutShort).Should(Equal("")) + g.Eventually(BuildConfig(t, ctx, integrationKitNamespace, integrationKitName)().RequestMemory, TestTimeoutShort).Should(Equal("")) + g.Eventually(BuildConfig(t, ctx, integrationKitNamespace, integrationKitName)().LimitMemory, TestTimeoutShort).Should(Equal("")) + g.Eventually(BuilderPod(t, ctx, integrationKitNamespace, builderKitName), TestTimeoutShort).Should(BeNil()) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) + + t.Run("Run build order strategy fifo", func(t *testing.T) { + name := RandomizedSuffixName("java-fifo-strategy") + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", + "--name", name, + // This is required in order to avoid reusing a Kit already existing (which is the default behavior) + "--build-property", "strategy=fifo", + "-t", "builder.order-strategy=fifo").Execute()).To(Succeed()) + + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + + integrationKitName := IntegrationKit(t, ctx, ns, name)() + integrationKitNamespace := IntegrationKitNamespace(t, ctx, ns, name)() + builderKitName := fmt.Sprintf("camel-k-%s-builder", integrationKitName) + g.Eventually(BuildConfig(t, ctx, integrationKitNamespace, integrationKitName)().Strategy, TestTimeoutShort).Should(Equal(v1.BuildStrategyRoutine)) + g.Eventually(BuildConfig(t, ctx, integrationKitNamespace, integrationKitName)().OrderStrategy, TestTimeoutShort).Should(Equal(v1.BuildOrderStrategyFIFO)) + // Default resource CPU Check + g.Eventually(BuildConfig(t, ctx, integrationKitNamespace, integrationKitName)().RequestCPU, TestTimeoutShort).Should(Equal("")) + g.Eventually(BuildConfig(t, ctx, integrationKitNamespace, integrationKitName)().LimitCPU, TestTimeoutShort).Should(Equal("")) + g.Eventually(BuildConfig(t, ctx, integrationKitNamespace, integrationKitName)().RequestMemory, TestTimeoutShort).Should(Equal("")) + g.Eventually(BuildConfig(t, ctx, integrationKitNamespace, integrationKitName)().LimitMemory, TestTimeoutShort).Should(Equal("")) + + g.Eventually(BuilderPod(t, ctx, integrationKitNamespace, builderKitName), TestTimeoutShort).Should(BeNil()) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) + + t.Run("Run build resources configuration", func(t *testing.T) { + name := RandomizedSuffixName("java-resource-config") + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", + "--name", name, + // This is required in order to avoid reusing a Kit already existing (which is the default behavior) + "--build-property", "resources=new-build", + "-t", "builder.tasks-request-cpu=builder:500m", + "-t", "builder.tasks-limit-cpu=builder:1000m", + "-t", "builder.tasks-request-memory=builder:2Gi", + "-t", "builder.tasks-limit-memory=builder:3Gi", + "-t", "builder.strategy=pod", + ).Execute()).To(Succeed()) + + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + + integrationKitName := IntegrationKit(t, ctx, ns, name)() + integrationKitNamespace := IntegrationKitNamespace(t, ctx, ns, name)() + builderKitName := fmt.Sprintf("camel-k-%s-builder", integrationKitName) + + g.Eventually(BuildConfig(t, ctx, integrationKitNamespace, integrationKitName)().Strategy, TestTimeoutShort).Should(Equal(v1.BuildStrategyPod)) + g.Eventually(BuildConfig(t, ctx, integrationKitNamespace, integrationKitName)().OrderStrategy, TestTimeoutShort).Should(Equal(v1.BuildOrderStrategySequential)) + g.Eventually(BuildConfig(t, ctx, integrationKitNamespace, integrationKitName)().RequestCPU, TestTimeoutShort).Should(Equal("500m")) + g.Eventually(BuildConfig(t, ctx, integrationKitNamespace, integrationKitName)().LimitCPU, TestTimeoutShort).Should(Equal("1000m")) + g.Eventually(BuildConfig(t, ctx, integrationKitNamespace, integrationKitName)().RequestMemory, TestTimeoutShort).Should(Equal("2Gi")) + g.Eventually(BuildConfig(t, ctx, integrationKitNamespace, integrationKitName)().LimitMemory, TestTimeoutShort).Should(Equal("3Gi")) + + g.Eventually(BuilderPod(t, ctx, integrationKitNamespace, builderKitName), TestTimeoutShort).ShouldNot(BeNil()) + // Let's assert we set the resources on the builder container + g.Eventually(BuilderPod(t, ctx, integrationKitNamespace, builderKitName)().Spec.InitContainers[0].Name, TestTimeoutShort).Should(Equal("builder")) + g.Eventually(BuilderPod(t, ctx, integrationKitNamespace, builderKitName)().Spec.InitContainers[0].Resources.Requests.Cpu().String(), TestTimeoutShort).Should(Equal("500m")) + g.Eventually(BuilderPod(t, ctx, integrationKitNamespace, builderKitName)().Spec.InitContainers[0].Resources.Limits.Cpu().String(), TestTimeoutShort).Should(Equal("1")) + g.Eventually(BuilderPod(t, ctx, integrationKitNamespace, builderKitName)().Spec.InitContainers[0].Resources.Requests.Memory().String(), TestTimeoutShort).Should(Equal("2Gi")) + g.Eventually(BuilderPod(t, ctx, integrationKitNamespace, builderKitName)().Spec.InitContainers[0].Resources.Limits.Memory().String(), TestTimeoutShort).Should(Equal("3Gi")) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) + + t.Run("Run custom pipeline task", func(t *testing.T) { + name := RandomizedSuffixName("java-pipeline") + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", name, "-t", "builder.tasks=custom1;alpine;tree", "-t", "builder.tasks=custom2;alpine;cat maven/pom.xml", "-t", "builder.strategy=pod").Execute()).To(Succeed()) + + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutLong).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + + integrationKitName := IntegrationKit(t, ctx, ns, name)() + integrationKitNamespace := IntegrationKitNamespace(t, ctx, ns, name)() + builderKitName := fmt.Sprintf("camel-k-%s-builder", integrationKitName) + g.Eventually(BuilderPod(t, ctx, integrationKitNamespace, builderKitName), TestTimeoutShort).ShouldNot(BeNil()) + g.Eventually(len(BuilderPod(t, ctx, integrationKitNamespace, builderKitName)().Spec.InitContainers), TestTimeoutShort).Should(Equal(4)) + g.Eventually(BuilderPod(t, ctx, integrationKitNamespace, builderKitName)().Spec.InitContainers[0].Name, TestTimeoutShort).Should(Equal("builder")) + g.Eventually(BuilderPod(t, ctx, integrationKitNamespace, builderKitName)().Spec.InitContainers[1].Name, TestTimeoutShort).Should(Equal("custom1")) + g.Eventually(BuilderPod(t, ctx, integrationKitNamespace, builderKitName)().Spec.InitContainers[2].Name, TestTimeoutShort).Should(Equal("custom2")) + + // Check containers conditions + g.Eventually(Build(t, ctx, integrationKitNamespace, integrationKitName), TestTimeoutShort).ShouldNot(BeNil()) + g.Eventually( + Build(t, ctx, integrationKitNamespace, integrationKitName)().Status.GetCondition(v1.BuildConditionType("Containercustom1Succeeded")).Status, + TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually( + Build(t, ctx, integrationKitNamespace, integrationKitName)().Status.GetCondition(v1.BuildConditionType("Containercustom1Succeeded")).Message, + TestTimeoutShort).Should(ContainSubstring("generated-bytecode.jar")) + g.Eventually(Build(t, ctx, integrationKitNamespace, integrationKitName), TestTimeoutShort).ShouldNot(BeNil()) + g.Eventually( + Build(t, ctx, integrationKitNamespace, integrationKitName)().Status.GetCondition(v1.BuildConditionType("Containercustom2Succeeded")).Status, + TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually( + Build(t, ctx, integrationKitNamespace, integrationKitName)().Status.GetCondition(v1.BuildConditionType("Containercustom2Succeeded")).Message, + TestTimeoutShort).Should(ContainSubstring("")) + + // Check logs + g.Eventually(Logs(t, ctx, integrationKitNamespace, builderKitName, corev1.PodLogOptions{Container: "custom1"})).Should(ContainSubstring(`generated-bytecode.jar`)) + g.Eventually(Logs(t, ctx, integrationKitNamespace, builderKitName, corev1.PodLogOptions{Container: "custom2"})).Should(ContainSubstring(`camel-k-runtime-bom`)) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) + + t.Run("Run custom pipeline task error", func(t *testing.T) { + name := RandomizedSuffixName("java-error") + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", name, "-t", "builder.tasks=custom1;alpine;cat missingfile.txt", "-t", "builder.strategy=pod").Execute()).To(Succeed()) + + g.Eventually(IntegrationPhase(t, ctx, ns, name)).Should(Equal(v1.IntegrationPhaseBuildingKit)) + integrationKitName := IntegrationKit(t, ctx, ns, name)() + integrationKitNamespace := IntegrationKitNamespace(t, ctx, ns, name)() + // Check containers conditions + g.Eventually(Build(t, ctx, integrationKitNamespace, integrationKitName), TestTimeoutLong).ShouldNot(BeNil()) + g.Eventually(BuildConditions(t, ctx, integrationKitNamespace, integrationKitName), TestTimeoutLong).ShouldNot(BeNil()) + g.Eventually(BuildCondition(t, ctx, integrationKitNamespace, integrationKitName, v1.BuildConditionType("Containercustom1Succeeded")), TestTimeoutMedium).ShouldNot(BeNil()) + g.Eventually( + BuildCondition(t, ctx, integrationKitNamespace, integrationKitName, v1.BuildConditionType("Containercustom1Succeeded"))().Status, + TestTimeoutShort).Should(Equal(corev1.ConditionFalse)) + g.Eventually( + BuildCondition(t, ctx, integrationKitNamespace, integrationKitName, v1.BuildConditionType("Containercustom1Succeeded"))().Message, + TestTimeoutShort).Should(ContainSubstring("No such file or directory")) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) + + t.Run("Run maven profile", func(t *testing.T) { + name := RandomizedSuffixName("java-maven-profile") + + mavenProfile1Cm := newMavenProfileConfigMap(ns, "maven-profile-owasp", "owasp-profile") + g.Expect(TestClient(t).Create(ctx, mavenProfile1Cm)).To(Succeed()) + mavenProfile2Cm := newMavenProfileConfigMap(ns, "maven-profile-dependency", "dependency-profile") + g.Expect(TestClient(t).Create(ctx, mavenProfile2Cm)).To(Succeed()) + + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", name, "-t", "builder.maven-profiles=configmap:maven-profile-owasp/owasp-profile", "-t", "builder.maven-profiles=configmap:maven-profile-dependency/dependency-profile", "-t", "builder.tasks=custom1;alpine;cat maven/pom.xml", "-t", "builder.strategy=pod").Execute()).To(Succeed()) + + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutLong).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + + integrationKitName := IntegrationKit(t, ctx, ns, name)() + integrationKitNamespace := IntegrationKitNamespace(t, ctx, ns, name)() + builderKitName := fmt.Sprintf("camel-k-%s-builder", integrationKitName) + g.Eventually(BuilderPod(t, ctx, integrationKitNamespace, builderKitName), TestTimeoutShort).ShouldNot(BeNil()) + g.Eventually(len(BuilderPod(t, ctx, integrationKitNamespace, builderKitName)().Spec.InitContainers), TestTimeoutShort).Should(Equal(3)) + g.Eventually(BuilderPod(t, ctx, integrationKitNamespace, builderKitName)().Spec.InitContainers[0].Name, TestTimeoutShort).Should(Equal("builder")) + g.Eventually(BuilderPod(t, ctx, integrationKitNamespace, builderKitName)().Spec.InitContainers[1].Name, TestTimeoutShort).Should(Equal("custom1")) + g.Eventually(BuilderPod(t, ctx, integrationKitNamespace, builderKitName)().Spec.InitContainers[2].Name, TestTimeoutShort).Should(Equal("package")) + + // Check containers conditions + g.Eventually(Build(t, ctx, integrationKitNamespace, integrationKitName), TestTimeoutShort).ShouldNot(BeNil()) + g.Eventually( + Build(t, ctx, integrationKitNamespace, integrationKitName)().Status.GetCondition(v1.BuildConditionType("Containercustom1Succeeded")).Status, + TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually( + Build(t, ctx, integrationKitNamespace, integrationKitName)().Status.GetCondition(v1.BuildConditionType("Containercustom1Succeeded")).Message, + TestTimeoutShort).Should(ContainSubstring("")) + + // Check logs + g.Eventually(Logs(t, ctx, integrationKitNamespace, builderKitName, corev1.PodLogOptions{Container: "custom1"})).Should(ContainSubstring(`owasp-profile`)) + g.Eventually(Logs(t, ctx, integrationKitNamespace, builderKitName, corev1.PodLogOptions{Container: "custom1"})).Should(ContainSubstring(`dependency-profile`)) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + g.Expect(TestClient(t).Delete(ctx, mavenProfile1Cm)).To(Succeed()) + g.Expect(TestClient(t).Delete(ctx, mavenProfile2Cm)).To(Succeed()) + }) }) } diff --git a/e2e/common/traits/camel_test.go b/e2e/common/traits/camel_test.go index f431b5b58f..e854b53b64 100644 --- a/e2e/common/traits/camel_test.go +++ b/e2e/common/traits/camel_test.go @@ -23,6 +23,7 @@ limitations under the License. package traits import ( + "context" "testing" . "github.com/onsi/gomega" @@ -34,36 +35,40 @@ import ( ) func TestCamelTrait(t *testing.T) { - RegisterTestingT(t) - - t.Run("properties changes should not rebuild", func(t *testing.T) { - - Expect(Kamel("reset", "-n", ns).Execute()).To(Succeed()) - - name := RandomizedSuffixName("java") - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", - "--name", name, - ).Execute()).To(Succeed()) - - // checking the integration status - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - integrationKit := IntegrationKit(ns, name)() - - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", - "--name", name, - "-p", "a=1", - ).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutShort).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - Eventually(IntegrationKit(ns, name)).Should(Equal(integrationKit)) - - Expect(Kamel("delete", name, "-n", ns).Execute()).To(Succeed()) - Eventually(Integration(ns, name), TestTimeoutLong).Should(BeNil()) - }) + t.Parallel() + + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-traits-camel" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + + t.Run("properties changes should not rebuild", func(t *testing.T) { + + g.Expect(Kamel(t, ctx, "reset", "-n", ns).Execute()).To(Succeed()) - // Clean-up - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + name := RandomizedSuffixName("java") + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", name).Execute()).To(Succeed()) + + // checking the integration status + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + integrationKit := IntegrationKit(t, ctx, ns, name)() + + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", name, "-p", "a=1").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutShort).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + g.Eventually(IntegrationKit(t, ctx, ns, name)).Should(Equal(integrationKit)) + + g.Expect(Kamel(t, ctx, "delete", name, "-n", ns).Execute()).To(Succeed()) + g.Eventually(Integration(t, ctx, ns, name), TestTimeoutLong).Should(BeNil()) + }) + + // Clean-up + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) } diff --git a/e2e/common/traits/container_test.go b/e2e/common/traits/container_test.go index 6bd6ba4ec6..1365d139bb 100644 --- a/e2e/common/traits/container_test.go +++ b/e2e/common/traits/container_test.go @@ -23,6 +23,7 @@ limitations under the License. package traits import ( + "context" "testing" . "github.com/onsi/gomega" @@ -35,75 +36,74 @@ import ( ) func TestContainerTrait(t *testing.T) { - RegisterTestingT(t) - - t.Run("Container image pull policy and resources configuration", func(t *testing.T) { - name := RandomizedSuffixName("java1") - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", - "-t", "container.image-pull-policy=Always", - "-t", "container.request-cpu=0.005", - "-t", "container.request-memory=100Mi", - "-t", "container.limit-cpu=200m", - "-t", "container.limit-memory=500Mi", - "--name", name, - ).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - Eventually(IntegrationPodHas(ns, name, func(pod *corev1.Pod) bool { - if len(pod.Spec.Containers) != 1 { - return false - } - imagePullPolicy := pod.Spec.Containers[0].ImagePullPolicy - return imagePullPolicy == "Always" - }), TestTimeoutShort).Should(BeTrue()) - Eventually(IntegrationPodHas(ns, name, func(pod *corev1.Pod) bool { - if len(pod.Spec.Containers) != 1 { - return false - } - limitsCpu := pod.Spec.Containers[0].Resources.Limits.Cpu() - requestsCpu := pod.Spec.Containers[0].Resources.Requests.Cpu() - return limitsCpu != nil && limitsCpu.String() == "200m" && requestsCpu != nil && requestsCpu.String() == "5m" - }), TestTimeoutShort).Should(BeTrue()) - Eventually(IntegrationPodHas(ns, name, func(pod *corev1.Pod) bool { - if len(pod.Spec.Containers) != 1 { - return false - } - limitsMemory := pod.Spec.Containers[0].Resources.Limits.Memory() - requestsMemory := pod.Spec.Containers[0].Resources.Requests.Memory() - return limitsMemory != nil && limitsMemory.String() == "500Mi" && requestsMemory != nil && requestsMemory.String() == "100Mi" - }), TestTimeoutShort).Should(BeTrue()) - + t.Parallel() + + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-traits-container" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + + t.Run("Container image pull policy and resources configuration", func(t *testing.T) { + name := RandomizedSuffixName("java1") + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "-t", "container.image-pull-policy=Always", "-t", "container.request-cpu=0.005", "-t", "container.request-memory=100Mi", "-t", "container.limit-cpu=200m", "-t", "container.limit-memory=500Mi", "--name", name).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + g.Eventually(IntegrationPodHas(t, ctx, ns, name, func(pod *corev1.Pod) bool { + if len(pod.Spec.Containers) != 1 { + return false + } + imagePullPolicy := pod.Spec.Containers[0].ImagePullPolicy + return imagePullPolicy == "Always" + }), TestTimeoutShort).Should(BeTrue()) + g.Eventually(IntegrationPodHas(t, ctx, ns, name, func(pod *corev1.Pod) bool { + if len(pod.Spec.Containers) != 1 { + return false + } + limitsCpu := pod.Spec.Containers[0].Resources.Limits.Cpu() + requestsCpu := pod.Spec.Containers[0].Resources.Requests.Cpu() + return limitsCpu != nil && limitsCpu.String() == "200m" && requestsCpu != nil && requestsCpu.String() == "5m" + }), TestTimeoutShort).Should(BeTrue()) + g.Eventually(IntegrationPodHas(t, ctx, ns, name, func(pod *corev1.Pod) bool { + if len(pod.Spec.Containers) != 1 { + return false + } + limitsMemory := pod.Spec.Containers[0].Resources.Limits.Memory() + requestsMemory := pod.Spec.Containers[0].Resources.Requests.Memory() + return limitsMemory != nil && limitsMemory.String() == "500Mi" && requestsMemory != nil && requestsMemory.String() == "100Mi" + }), TestTimeoutShort).Should(BeTrue()) + + }) + + t.Run("Container name", func(t *testing.T) { + name := RandomizedSuffixName("java2") + containerName := "my-container-name" + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "-t", "container.name="+containerName, "--name", name).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + g.Eventually(IntegrationPodHas(t, ctx, ns, name, func(pod *corev1.Pod) bool { + if len(pod.Spec.Containers) != 1 { + return false + } + podContainerName := pod.Spec.Containers[0].Name + return podContainerName == containerName + }), TestTimeoutShort).Should(BeTrue()) + + // check integration schema does not contains unwanted default trait value. + g.Eventually(UnstructuredIntegration(t, ctx, ns, name)).ShouldNot(BeNil()) + unstructuredIntegration := UnstructuredIntegration(t, ctx, ns, name)() + containerTrait, _, _ := unstructured.NestedMap(unstructuredIntegration.Object, "spec", "traits", "container") + g.Expect(containerTrait).ToNot(BeNil()) + g.Expect(len(containerTrait)).To(Equal(1)) + g.Expect(containerTrait["name"]).To(Equal(containerName)) + + }) + + // Clean-up + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) - - t.Run("Container name", func(t *testing.T) { - name := RandomizedSuffixName("java2") - containerName := "my-container-name" - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", - "-t", "container.name="+containerName, - "--name", name, - ).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - Eventually(IntegrationPodHas(ns, name, func(pod *corev1.Pod) bool { - if len(pod.Spec.Containers) != 1 { - return false - } - podContainerName := pod.Spec.Containers[0].Name - return podContainerName == containerName - }), TestTimeoutShort).Should(BeTrue()) - - // check integration schema does not contains unwanted default trait value. - Eventually(UnstructuredIntegration(ns, name)).ShouldNot(BeNil()) - unstructuredIntegration := UnstructuredIntegration(ns, name)() - containerTrait, _, _ := unstructured.NestedMap(unstructuredIntegration.Object, "spec", "traits", "container") - Expect(containerTrait).ToNot(BeNil()) - Expect(len(containerTrait)).To(Equal(1)) - Expect(containerTrait["name"]).To(Equal(containerName)) - - }) - - // Clean-up - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) } diff --git a/e2e/common/traits/default.go b/e2e/common/traits/default.go deleted file mode 100644 index 59a520c863..0000000000 --- a/e2e/common/traits/default.go +++ /dev/null @@ -1,26 +0,0 @@ -//go:build integration -// +build integration - -/* -Licensed to the Apache Software Foundation (ASF) under one or more -contributor license agreements. See the NOTICE file distributed with -this work for additional information regarding copyright ownership. -The ASF licenses this file to You under the Apache License, Version 2.0 -(the "License"); you may not use this file except in compliance with -the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package traits - -import "github.com/apache/camel-k/v2/e2e/support" - -var ns = support.GetEnvOrDefault("CAMEL_K_TEST_NAMESPACE", support.GetCIProcessID()) -var operatorID = support.GetEnvOrDefault("CAMEL_K_OPERATOR_ID", support.GetCIProcessID()) diff --git a/e2e/common/traits/deployment_test.go b/e2e/common/traits/deployment_test.go index 08a589e5ed..37fb099cad 100644 --- a/e2e/common/traits/deployment_test.go +++ b/e2e/common/traits/deployment_test.go @@ -23,6 +23,7 @@ limitations under the License. package traits import ( + "context" "testing" appsv1 "k8s.io/api/apps/v1" @@ -38,68 +39,82 @@ import ( ) func TestRecreateDeploymentStrategyTrait(t *testing.T) { - RegisterTestingT(t) - - t.Run("Run with Recreate Deployment Strategy", func(t *testing.T) { - name := RandomizedSuffixName("java") - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", - "--name", name, - "-t", "deployment.strategy="+string(appsv1.RecreateDeploymentStrategyType)). - Execute()).To(Succeed()) - - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - - Eventually(Deployment(ns, name), TestTimeoutMedium).Should(PointTo(MatchFields(IgnoreExtras, - Fields{ - "Spec": MatchFields(IgnoreExtras, - Fields{ - "Strategy": MatchFields(IgnoreExtras, - Fields{ - "Type": Equal(appsv1.RecreateDeploymentStrategyType), - }), - }), - }), - )) - - // check integration schema does not contains unwanted default trait value. - Eventually(UnstructuredIntegration(ns, name)).ShouldNot(BeNil()) - unstructuredIntegration := UnstructuredIntegration(ns, name)() - deploymentTrait, _, _ := unstructured.NestedMap(unstructuredIntegration.Object, "spec", "traits", "deployment") - Expect(deploymentTrait).ToNot(BeNil()) - Expect(len(deploymentTrait)).To(Equal(1)) - Expect(deploymentTrait["strategy"]).To(Equal(string(appsv1.RecreateDeploymentStrategyType))) - + t.Parallel() + + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-traits-deployment" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + + t.Run("Run with Recreate Deployment Strategy", func(t *testing.T) { + name := RandomizedSuffixName("java") + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", name, "-t", "deployment.strategy="+string(appsv1.RecreateDeploymentStrategyType)). + Execute()).To(Succeed()) + + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + + g.Eventually(Deployment(t, ctx, ns, name), TestTimeoutMedium).Should(PointTo(MatchFields(IgnoreExtras, + Fields{ + "Spec": MatchFields(IgnoreExtras, + Fields{ + "Strategy": MatchFields(IgnoreExtras, + Fields{ + "Type": Equal(appsv1.RecreateDeploymentStrategyType), + }), + }), + }), + )) + + // check integration schema does not contains unwanted default trait value. + g.Eventually(UnstructuredIntegration(t, ctx, ns, name)).ShouldNot(BeNil()) + unstructuredIntegration := UnstructuredIntegration(t, ctx, ns, name)() + deploymentTrait, _, _ := unstructured.NestedMap(unstructuredIntegration.Object, "spec", "traits", "deployment") + g.Expect(deploymentTrait).ToNot(BeNil()) + g.Expect(len(deploymentTrait)).To(Equal(1)) + g.Expect(deploymentTrait["strategy"]).To(Equal(string(appsv1.RecreateDeploymentStrategyType))) + }) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) - - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) } func TestRollingUpdateDeploymentStrategyTrait(t *testing.T) { - RegisterTestingT(t) - - t.Run("Run with RollingUpdate Deployment Strategy", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", - "-t", "deployment.strategy="+string(appsv1.RollingUpdateDeploymentStrategyType)). - Execute()).To(Succeed()) - - Eventually(IntegrationPodPhase(ns, "java"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "java", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "java"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - - Eventually(Deployment(ns, "java"), TestTimeoutMedium).Should(PointTo(MatchFields(IgnoreExtras, - Fields{ - "Spec": MatchFields(IgnoreExtras, - Fields{ - "Strategy": MatchFields(IgnoreExtras, - Fields{ - "Type": Equal(appsv1.RollingUpdateDeploymentStrategyType), - }), - }), - }), - )) + t.Parallel() + + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-traits-deployment-rolling" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + + t.Run("Run with RollingUpdate Deployment Strategy", func(t *testing.T) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "-t", "deployment.strategy="+string(appsv1.RollingUpdateDeploymentStrategyType)). + Execute()).To(Succeed()) + + g.Eventually(IntegrationPodPhase(t, ctx, ns, "java"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "java", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "java"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + + g.Eventually(Deployment(t, ctx, ns, "java"), TestTimeoutMedium).Should(PointTo(MatchFields(IgnoreExtras, + Fields{ + "Spec": MatchFields(IgnoreExtras, + Fields{ + "Strategy": MatchFields(IgnoreExtras, + Fields{ + "Type": Equal(appsv1.RollingUpdateDeploymentStrategyType), + }), + }), + }), + )) + }) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) - - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) } diff --git a/e2e/common/traits/error_handler_test.go b/e2e/common/traits/error_handler_test.go index 081a9f542d..5e727b508e 100644 --- a/e2e/common/traits/error_handler_test.go +++ b/e2e/common/traits/error_handler_test.go @@ -23,6 +23,7 @@ limitations under the License. package traits import ( + "context" "testing" . "github.com/onsi/gomega" @@ -34,20 +35,23 @@ import ( ) func TestErrorHandlerTrait(t *testing.T) { - RegisterTestingT(t) - - t.Run("Run errored integration with error handler", func(t *testing.T) { - name := RandomizedSuffixName("error-handler") - Expect(KamelRunWithID(operatorID, ns, "files/ErroredRoute.java", - "--name", name, - "-t", "error-handler.enabled=true", - "-t", "error-handler.ref=defaultErrorHandler", - "-p", "camel.beans.defaultErrorHandler=#class:org.apache.camel.builder.DeadLetterChannelBuilder", - "-p", "camel.beans.defaultErrorHandler.deadLetterUri=log:my-special-error-handler-in-place?level=ERROR&showCaughtException=false&showBody=false&showBodyType=false&showExchangePattern=false", - ).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).ShouldNot(ContainSubstring("InvalidPayloadException")) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("my-special-error-handler-in-place")) + t.Parallel() + + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-traits-errorhandler" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + + t.Run("Run errored integration with error handler", func(t *testing.T) { + name := RandomizedSuffixName("error-handler") + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/ErroredRoute.java", "--name", name, "-t", "error-handler.enabled=true", "-t", "error-handler.ref=defaultErrorHandler", "-p", "camel.beans.defaultErrorHandler=#class:org.apache.camel.builder.DeadLetterChannelBuilder", "-p", "camel.beans.defaultErrorHandler.deadLetterUri=log:my-special-error-handler-in-place?level=ERROR&showCaughtException=false&showBody=false&showBodyType=false&showExchangePattern=false").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).ShouldNot(ContainSubstring("InvalidPayloadException")) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("my-special-error-handler-in-place")) + }) }) } diff --git a/e2e/common/traits/errored_trait_test.go b/e2e/common/traits/errored_trait_test.go index 80cb6a4de3..a113e021eb 100644 --- a/e2e/common/traits/errored_trait_test.go +++ b/e2e/common/traits/errored_trait_test.go @@ -23,6 +23,7 @@ limitations under the License. package traits import ( + "context" "testing" . "github.com/onsi/gomega" @@ -34,45 +35,48 @@ import ( ) func TestErroredTrait(t *testing.T) { - RegisterTestingT(t) + t.Parallel() - t.Run("Integration trait should fail", func(t *testing.T) { - name := RandomizedSuffixName("it-errored") - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", - "--name", name, - "-t", "kamelets.list=missing", - ).Execute()).To(Succeed()) - Eventually(IntegrationPhase(ns, name), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseError)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionFalse)) - Eventually(IntegrationCondition(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(And( - WithTransform(IntegrationConditionReason, Equal(v1.IntegrationConditionInitializationFailedReason)), - WithTransform(IntegrationConditionMessage, HavePrefix("error during trait customization")), - )) - }) + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-traits-error" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) - t.Run("Pipe trait should fail", func(t *testing.T) { - name := RandomizedSuffixName("kb-errored") - Expect(KamelBindWithID(operatorID, ns, "timer:foo", "log:bar", - "--name", name, - "-t", "kamelets.list=missing", - ).Execute()).To(Succeed()) - // Pipe - Eventually(PipePhase(ns, name), TestTimeoutShort).Should(Equal(v1.PipePhaseError)) - Eventually(PipeConditionStatus(ns, name, v1.PipeConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionFalse)) - Eventually(PipeCondition(ns, name, v1.PipeConditionReady), TestTimeoutShort).Should( - WithTransform(PipeConditionMessage, And( - ContainSubstring("error during trait customization"), - ContainSubstring("[missing] not found"), - ))) - // Integration related - Eventually(IntegrationPhase(ns, name), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseError)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionFalse)) - Eventually(IntegrationCondition(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(And( - WithTransform(IntegrationConditionReason, Equal(v1.IntegrationConditionInitializationFailedReason)), - WithTransform(IntegrationConditionMessage, HavePrefix("error during trait customization")), - )) - }) + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + + t.Run("Integration trait should fail", func(t *testing.T) { + name := RandomizedSuffixName("it-errored") + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", name, "-t", "kamelets.list=missing").Execute()).To(Succeed()) + g.Eventually(IntegrationPhase(t, ctx, ns, name), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseError)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionFalse)) + g.Eventually(IntegrationCondition(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(And( + WithTransform(IntegrationConditionReason, Equal(v1.IntegrationConditionInitializationFailedReason)), + WithTransform(IntegrationConditionMessage, HavePrefix("error during trait customization")), + )) + }) - // Clean up - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + t.Run("Pipe trait should fail", func(t *testing.T) { + name := RandomizedSuffixName("kb-errored") + g.Expect(KamelBindWithID(t, ctx, operatorID, ns, "timer:foo", "log:bar", "--name", name, "-t", "kamelets.list=missing").Execute()).To(Succeed()) + // Pipe + g.Eventually(PipePhase(t, ctx, ns, name), TestTimeoutShort).Should(Equal(v1.PipePhaseError)) + g.Eventually(PipeConditionStatus(t, ctx, ns, name, v1.PipeConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionFalse)) + g.Eventually(PipeCondition(t, ctx, ns, name, v1.PipeConditionReady), TestTimeoutShort).Should( + WithTransform(PipeConditionMessage, And( + ContainSubstring("error during trait customization"), + ContainSubstring("[missing] not found"), + ))) + // Integration related + g.Eventually(IntegrationPhase(t, ctx, ns, name), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseError)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionFalse)) + g.Eventually(IntegrationCondition(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(And( + WithTransform(IntegrationConditionReason, Equal(v1.IntegrationConditionInitializationFailedReason)), + WithTransform(IntegrationConditionMessage, HavePrefix("error during trait customization")), + )) + }) + + // Clean up + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) } diff --git a/e2e/common/traits/health_test.go b/e2e/common/traits/health_test.go index 6cbdefb360..7e1cd608cf 100644 --- a/e2e/common/traits/health_test.go +++ b/e2e/common/traits/health_test.go @@ -23,6 +23,7 @@ limitations under the License. package traits import ( + "context" "encoding/json" "fmt" "strings" @@ -43,47 +44,127 @@ import ( ) func TestHealthTrait(t *testing.T) { - RegisterTestingT(t) - - t.Run("Readiness condition with stopped route scaled", func(t *testing.T) { - name := RandomizedSuffixName("java") - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", - "-t", "health.enabled=true", - // Enable Jolokia for the test to stop the Camel route - "-t", "jolokia.enabled=true", - "-t", "jolokia.use-ssl-client-authentication=false", - "-t", "jolokia.protocol=http", - "--name", name, - ).Execute()).To(Succeed()) - - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationPhase(ns, name), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort). - Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - - Expect(ScaleIntegration(ns, name, 3)).To(Succeed()) - // Check the readiness condition becomes falsy - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionFalse)) - // Check the scale cascades into the Deployment scale - Eventually(IntegrationPods(ns, name), TestTimeoutShort).Should(HaveLen(3)) - // Check it also cascades into the Integration scale subresource Status field - Eventually(IntegrationStatusReplicas(ns, name), TestTimeoutShort). - Should(gstruct.PointTo(BeNumerically("==", 3))) - // Finally check the readiness condition becomes truthy back - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutMedium).Should(Equal(corev1.ConditionTrue)) - - // check integration schema does not contains unwanted default trait value. - Eventually(UnstructuredIntegration(ns, name)).ShouldNot(BeNil()) - unstructuredIntegration := UnstructuredIntegration(ns, name)() - healthTrait, _, _ := unstructured.NestedMap(unstructuredIntegration.Object, "spec", "traits", "health") - Expect(healthTrait).ToNot(BeNil()) - Expect(len(healthTrait)).To(Equal(1)) - Expect(healthTrait["enabled"]).To(Equal(true)) - - pods := IntegrationPods(ns, name)() - - for i, pod := range pods { + t.Parallel() + + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-traits-health" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + + t.Run("Readiness condition with stopped route scaled", func(t *testing.T) { + name := RandomizedSuffixName("java") + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "-t", "health.enabled=true", "-t", "jolokia.enabled=true", "-t", "jolokia.use-ssl-client-authentication=false", "-t", "jolokia.protocol=http", "--name", name).Execute()).To(Succeed()) + + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationPhase(t, ctx, ns, name), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort). + Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + + g.Expect(ScaleIntegration(t, ctx, ns, name, 3)).To(Succeed()) + // Check the readiness condition becomes falsy + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionFalse)) + // Check the scale cascades into the Deployment scale + g.Eventually(IntegrationPods(t, ctx, ns, name), TestTimeoutShort).Should(HaveLen(3)) + // Check it also cascades into the Integration scale subresource Status field + g.Eventually(IntegrationStatusReplicas(t, ctx, ns, name), TestTimeoutShort). + Should(gstruct.PointTo(BeNumerically("==", 3))) + // Finally check the readiness condition becomes truthy back + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutMedium).Should(Equal(corev1.ConditionTrue)) + + // check integration schema does not contains unwanted default trait value. + g.Eventually(UnstructuredIntegration(t, ctx, ns, name)).ShouldNot(BeNil()) + unstructuredIntegration := UnstructuredIntegration(t, ctx, ns, name)() + healthTrait, _, _ := unstructured.NestedMap(unstructuredIntegration.Object, "spec", "traits", "health") + g.Expect(healthTrait).ToNot(BeNil()) + g.Expect(len(healthTrait)).To(Equal(1)) + g.Expect(healthTrait["enabled"]).To(Equal(true)) + + pods := IntegrationPods(t, ctx, ns, name)() + + for i, pod := range pods { + // Stop the Camel route + request := map[string]string{ + "type": "exec", + "mbean": "org.apache.camel:context=camel-1,name=\"route1\",type=routes", + "operation": "stop()", + } + body, err := json.Marshal(request) + g.Expect(err).To(BeNil()) + + response, err := TestClient(t).CoreV1().RESTClient().Post(). + AbsPath(fmt.Sprintf("/api/v1/namespaces/%s/pods/%s/proxy/jolokia/", ns, pod.Name)). + Body(body). + DoRaw(ctx) + g.Expect(err).To(BeNil()) + g.Expect(response).To(ContainSubstring(`"status":200`)) + + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort). + Should(Equal(corev1.ConditionFalse)) + + g.Eventually(IntegrationCondition(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutLong).Should(And( + WithTransform(IntegrationConditionReason, Equal(v1.IntegrationConditionRuntimeNotReadyReason)), + WithTransform(IntegrationConditionMessage, Equal(fmt.Sprintf("%d/3 pods are not ready", i+1))))) + } + + g.Eventually(IntegrationCondition(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutLong).Should( + Satisfy(func(c *v1.IntegrationCondition) bool { + if c.Status != corev1.ConditionFalse { + return false + } + if len(c.Pods) != 3 { + return false + } + + var r *v1.HealthCheckResponse + + for _, pod := range c.Pods { + for h := range pod.Health { + if pod.Health[h].Name == "camel-routes" { + r = &pod.Health[h] + } + } + + if r == nil { + return false + } + + if r.Data == nil { + return false + } + + var data map[string]interface{} + if err := json.Unmarshal(r.Data, &data); err != nil { + return false + } + if data["check.kind"].(string) != "READINESS" || data["route.status"].(string) != "Stopped" { + return false + } + } + return true + })) + + g.Eventually(IntegrationPhase(t, ctx, ns, name), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseError)) + + // Clean-up + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) + + t.Run("Readiness condition with stopped route", func(t *testing.T) { + name := RandomizedSuffixName("java") + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "-t", "health.enabled=true", "-t", "jolokia.enabled=true", "-t", "jolokia.use-ssl-client-authentication=false", "-t", "jolokia.protocol=http", "--name", name).Execute()).To(Succeed()) + + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationPhase(t, ctx, ns, name), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort). + Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + + pod := IntegrationPod(t, ctx, ns, name)() + // Stop the Camel route request := map[string]string{ "type": "exec", @@ -91,38 +172,49 @@ func TestHealthTrait(t *testing.T) { "operation": "stop()", } body, err := json.Marshal(request) - Expect(err).To(BeNil()) + g.Expect(err).To(BeNil()) - response, err := TestClient().CoreV1().RESTClient().Post(). + response, err := TestClient(t).CoreV1().RESTClient().Post(). AbsPath(fmt.Sprintf("/api/v1/namespaces/%s/pods/%s/proxy/jolokia/", ns, pod.Name)). Body(body). - DoRaw(TestContext) - Expect(err).To(BeNil()) - Expect(response).To(ContainSubstring(`"status":200`)) + DoRaw(ctx) + g.Expect(err).To(BeNil()) + g.Expect(response).To(ContainSubstring(`"status":200`)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort). + // Check the ready condition has turned false + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort). Should(Equal(corev1.ConditionFalse)) - - Eventually(IntegrationCondition(ns, name, v1.IntegrationConditionReady), TestTimeoutLong).Should(And( + // And it contains details about the runtime state + + // + // TODO + // Integration has different runtime state reporting on OCP4 + // + // lastProbeTime: null + // lastTransitionTime: "2021-12-08T20:12:14Z" + // message: 'containers with unready status: [integration]' + // reason: ContainersNotReady + // status: "False" + // type: Ready + // + g.Eventually(IntegrationCondition(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutLong).Should(And( WithTransform(IntegrationConditionReason, Equal(v1.IntegrationConditionRuntimeNotReadyReason)), - WithTransform(IntegrationConditionMessage, Equal(fmt.Sprintf("%d/3 pods are not ready", i+1))))) - } + WithTransform(IntegrationConditionMessage, Equal("1/1 pods are not ready")))) - Eventually(IntegrationCondition(ns, name, v1.IntegrationConditionReady), TestTimeoutLong).Should( - Satisfy(func(c *v1.IntegrationCondition) bool { - if c.Status != corev1.ConditionFalse { - return false - } - if len(c.Pods) != 3 { - return false - } + g.Eventually(IntegrationCondition(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutLong).Should( + Satisfy(func(c *v1.IntegrationCondition) bool { + if c.Status != corev1.ConditionFalse { + return false + } + if len(c.Pods) != 1 { + return false + } - var r *v1.HealthCheckResponse + var r *v1.HealthCheckResponse - for _, pod := range c.Pods { - for h := range pod.Health { - if pod.Health[h].Name == "camel-routes" { - r = &pod.Health[h] + for h := range c.Pods[0].Health { + if c.Pods[0].Health[h].Name == "camel-routes" { + r = &c.Pods[0].Health[h] } } @@ -138,378 +230,259 @@ func TestHealthTrait(t *testing.T) { if err := json.Unmarshal(r.Data, &data); err != nil { return false } - if data["check.kind"].(string) != "READINESS" || data["route.status"].(string) != "Stopped" { - return false - } - } - return true - })) - Eventually(IntegrationPhase(ns, name), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseError)) + return data["check.kind"].(string) == "READINESS" && data["route.status"].(string) == "Stopped" + })) - // Clean-up - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) - }) + g.Eventually(IntegrationPhase(t, ctx, ns, name), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseError)) - t.Run("Readiness condition with stopped route", func(t *testing.T) { - name := RandomizedSuffixName("java") - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", - "-t", "health.enabled=true", - // Enable Jolokia for the test to stop the Camel route - "-t", "jolokia.enabled=true", - "-t", "jolokia.use-ssl-client-authentication=false", - "-t", "jolokia.protocol=http", - "--name", name, - ).Execute()).To(Succeed()) - - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationPhase(ns, name), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort). - Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - - pod := IntegrationPod(ns, name)() - - // Stop the Camel route - request := map[string]string{ - "type": "exec", - "mbean": "org.apache.camel:context=camel-1,name=\"route1\",type=routes", - "operation": "stop()", - } - body, err := json.Marshal(request) - Expect(err).To(BeNil()) - - response, err := TestClient().CoreV1().RESTClient().Post(). - AbsPath(fmt.Sprintf("/api/v1/namespaces/%s/pods/%s/proxy/jolokia/", ns, pod.Name)). - Body(body). - DoRaw(TestContext) - Expect(err).To(BeNil()) - Expect(response).To(ContainSubstring(`"status":200`)) - - // Check the ready condition has turned false - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort). - Should(Equal(corev1.ConditionFalse)) - // And it contains details about the runtime state - - // - // TODO - // Integration has different runtime state reporting on OCP4 - // - // lastProbeTime: null - // lastTransitionTime: "2021-12-08T20:12:14Z" - // message: 'containers with unready status: [integration]' - // reason: ContainersNotReady - // status: "False" - // type: Ready - // - Eventually(IntegrationCondition(ns, name, v1.IntegrationConditionReady), TestTimeoutLong).Should(And( - WithTransform(IntegrationConditionReason, Equal(v1.IntegrationConditionRuntimeNotReadyReason)), - WithTransform(IntegrationConditionMessage, Equal("1/1 pods are not ready")))) - - Eventually(IntegrationCondition(ns, name, v1.IntegrationConditionReady), TestTimeoutLong).Should( - Satisfy(func(c *v1.IntegrationCondition) bool { - if c.Status != corev1.ConditionFalse { - return false - } - if len(c.Pods) != 1 { - return false - } + // Clean-up + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) - var r *v1.HealthCheckResponse + t.Run("Readiness condition with stopped binding", func(t *testing.T) { + name := RandomizedSuffixName("stopped-binding") + source := RandomizedSuffixName("my-health-timer-source") + sink := RandomizedSuffixName("my-health-log-sink") - for h := range c.Pods[0].Health { - if c.Pods[0].Health[h].Name == "camel-routes" { - r = &c.Pods[0].Health[h] - } - } + g.Expect(CreateTimerKamelet(t, ctx, operatorID, ns, source)()).To(Succeed()) + g.Expect(CreateLogKamelet(t, ctx, operatorID, ns, sink)()).To(Succeed()) - if r == nil { - return false - } + g.Expect(KamelBindWithID(t, ctx, operatorID, ns, source, sink, "-p", "source.message=Magicstring!", "-p", "sink.loggerName=binding", "--annotation", "trait.camel.apache.org/health.enabled=true", "--annotation", "trait.camel.apache.org/jolokia.enabled=true", "--annotation", "trait.camel.apache.org/jolokia.use-ssl-client-authentication=false", "--annotation", "trait.camel.apache.org/jolokia.protocol=http", "--name", name).Execute()).To(Succeed()) - if r.Data == nil { - return false - } + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationPhase(t, ctx, ns, name), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - var data map[string]interface{} - if err := json.Unmarshal(r.Data, &data); err != nil { - return false - } + pod := IntegrationPod(t, ctx, ns, name)() - return data["check.kind"].(string) == "READINESS" && data["route.status"].(string) == "Stopped" - })) + // Stop the Camel route + request := map[string]string{ + "type": "exec", + "mbean": "org.apache.camel:context=camel-1,name=\"binding\",type=routes", + "operation": "stop()", + } + body, err := json.Marshal(request) + g.Expect(err).To(BeNil()) - Eventually(IntegrationPhase(ns, name), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseError)) + response, err := TestClient(t).CoreV1().RESTClient().Post(). + AbsPath(fmt.Sprintf("/api/v1/namespaces/%s/pods/%s/proxy/jolokia/", ns, pod.Name)). + Body(body). + DoRaw(ctx) - // Clean-up - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) - }) + g.Expect(err).To(BeNil()) + g.Expect(response).To(ContainSubstring(`"status":200`)) - t.Run("Readiness condition with stopped binding", func(t *testing.T) { - name := RandomizedSuffixName("stopped-binding") - source := RandomizedSuffixName("my-health-timer-source") - sink := RandomizedSuffixName("my-health-log-sink") - - Expect(CreateTimerKamelet(ns, source)()).To(Succeed()) - Expect(CreateLogKamelet(ns, sink)()).To(Succeed()) - - Expect(KamelBindWithID(operatorID, ns, - source, - sink, - "-p", "source.message=Magicstring!", - "-p", "sink.loggerName=binding", - "--annotation", "trait.camel.apache.org/health.enabled=true", - "--annotation", "trait.camel.apache.org/jolokia.enabled=true", - "--annotation", "trait.camel.apache.org/jolokia.use-ssl-client-authentication=false", - "--annotation", "trait.camel.apache.org/jolokia.protocol=http", - "--name", name, - ).Execute()).To(Succeed()) - - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationPhase(ns, name), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - - pod := IntegrationPod(ns, name)() - - // Stop the Camel route - request := map[string]string{ - "type": "exec", - "mbean": "org.apache.camel:context=camel-1,name=\"binding\",type=routes", - "operation": "stop()", - } - body, err := json.Marshal(request) - Expect(err).To(BeNil()) - - response, err := TestClient().CoreV1().RESTClient().Post(). - AbsPath(fmt.Sprintf("/api/v1/namespaces/%s/pods/%s/proxy/jolokia/", ns, pod.Name)). - Body(body). - DoRaw(TestContext) - - Expect(err).To(BeNil()) - Expect(response).To(ContainSubstring(`"status":200`)) - - // Check the ready condition has turned false - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort). - Should(Equal(corev1.ConditionFalse)) - // And it contains details about the runtime state - - Eventually(IntegrationCondition(ns, name, v1.IntegrationConditionReady), TestTimeoutLong).Should(And( - WithTransform(IntegrationConditionReason, Equal(v1.IntegrationConditionRuntimeNotReadyReason)), - WithTransform(IntegrationConditionMessage, Equal("1/1 pods are not ready")))) - - Eventually(IntegrationCondition(ns, name, v1.IntegrationConditionReady), TestTimeoutLong).Should( - Satisfy(func(c *v1.IntegrationCondition) bool { - if c.Status != corev1.ConditionFalse { - return false - } - if len(c.Pods) != 1 { - return false - } + // Check the ready condition has turned false + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort). + Should(Equal(corev1.ConditionFalse)) + // And it contains details about the runtime state - var r *v1.HealthCheckResponse + g.Eventually(IntegrationCondition(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutLong).Should(And( + WithTransform(IntegrationConditionReason, Equal(v1.IntegrationConditionRuntimeNotReadyReason)), + WithTransform(IntegrationConditionMessage, Equal("1/1 pods are not ready")))) - for h := range c.Pods[0].Health { - if c.Pods[0].Health[h].Name == "camel-routes" { - r = &c.Pods[0].Health[h] + g.Eventually(IntegrationCondition(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutLong).Should( + Satisfy(func(c *v1.IntegrationCondition) bool { + if c.Status != corev1.ConditionFalse { + return false + } + if len(c.Pods) != 1 { + return false } - } - if r == nil { - return false - } + var r *v1.HealthCheckResponse - if r.Data == nil { - return false - } + for h := range c.Pods[0].Health { + if c.Pods[0].Health[h].Name == "camel-routes" { + r = &c.Pods[0].Health[h] + } + } - var data map[string]interface{} - if err := json.Unmarshal(r.Data, &data); err != nil { - return false - } + if r == nil { + return false + } - return data["check.kind"].(string) == "READINESS" && data["route.status"].(string) == "Stopped" && data["route.id"].(string) == "binding" - })) + if r.Data == nil { + return false + } - Eventually(PipeCondition(ns, name, camelv1.PipeConditionReady), TestTimeoutLong).Should( - Satisfy(func(c *camelv1.PipeCondition) bool { - if c.Status != corev1.ConditionFalse { - return false - } - if len(c.Pods) != 1 { - return false - } + var data map[string]interface{} + if err := json.Unmarshal(r.Data, &data); err != nil { + return false + } - var r *v1.HealthCheckResponse + return data["check.kind"].(string) == "READINESS" && data["route.status"].(string) == "Stopped" && data["route.id"].(string) == "binding" + })) - for h := range c.Pods[0].Health { - if c.Pods[0].Health[h].Name == "camel-routes" { - r = &c.Pods[0].Health[h] + g.Eventually(PipeCondition(t, ctx, ns, name, camelv1.PipeConditionReady), TestTimeoutLong).Should( + Satisfy(func(c *camelv1.PipeCondition) bool { + if c.Status != corev1.ConditionFalse { + return false + } + if len(c.Pods) != 1 { + return false } - } - if r == nil { - return false - } + var r *v1.HealthCheckResponse - if r.Data == nil { - return false - } + for h := range c.Pods[0].Health { + if c.Pods[0].Health[h].Name == "camel-routes" { + r = &c.Pods[0].Health[h] + } + } - var data map[string]interface{} - if err := json.Unmarshal(r.Data, &data); err != nil { - return false - } + if r == nil { + return false + } - return data["check.kind"].(string) == "READINESS" && data["route.status"].(string) == "Stopped" && data["route.id"].(string) == "binding" - })) + if r.Data == nil { + return false + } - // Clean-up - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) - Expect(DeleteKamelet(ns, source)).To(Succeed()) - Expect(DeleteKamelet(ns, sink)).To(Succeed()) - }) + var data map[string]interface{} + if err := json.Unmarshal(r.Data, &data); err != nil { + return false + } - t.Run("Readiness condition with never ready route", func(t *testing.T) { - name := RandomizedSuffixName("never-ready") - - Expect(KamelRunWithID(operatorID, ns, "files/NeverReady.java", - "--name", name, - "-t", "health.enabled=true", - ).Execute()).To(Succeed()) - - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationPhase(ns, name), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseRunning)) - Consistently(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), 1*time.Minute). - Should(Equal(corev1.ConditionFalse)) - Eventually(IntegrationPhase(ns, name), TestTimeoutLong).Should(Equal(v1.IntegrationPhaseError)) - - // Check that the error message is propagated from health checks even if deployment never becomes ready - Eventually(IntegrationCondition(ns, name, v1.IntegrationConditionReady), TestTimeoutLong).Should(And( - WithTransform(IntegrationConditionReason, Equal(v1.IntegrationConditionRuntimeNotReadyReason)), - WithTransform(IntegrationConditionMessage, Equal("1/1 pods are not ready")))) - - Eventually(IntegrationCondition(ns, name, v1.IntegrationConditionReady), TestTimeoutLong).Should( - Satisfy(func(c *v1.IntegrationCondition) bool { - if c.Status != corev1.ConditionFalse { - return false - } - if len(c.Pods) != 1 { - return false - } + return data["check.kind"].(string) == "READINESS" && data["route.status"].(string) == "Stopped" && data["route.id"].(string) == "binding" + })) + + // Clean-up + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + g.Expect(DeleteKamelet(t, ctx, ns, source)).To(Succeed()) + g.Expect(DeleteKamelet(t, ctx, ns, sink)).To(Succeed()) + }) - var r *v1.HealthCheckResponse + t.Run("Readiness condition with never ready route", func(t *testing.T) { + name := RandomizedSuffixName("never-ready") - for h := range c.Pods[0].Health { - if c.Pods[0].Health[h].Name == "camel-routes" { - r = &c.Pods[0].Health[h] + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/NeverReady.java", "--name", name, "-t", "health.enabled=true").Execute()).To(Succeed()) + + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationPhase(t, ctx, ns, name), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseRunning)) + g.Consistently(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), 1*time.Minute). + Should(Equal(corev1.ConditionFalse)) + g.Eventually(IntegrationPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(v1.IntegrationPhaseError)) + + // Check that the error message is propagated from health checks even if deployment never becomes ready + g.Eventually(IntegrationCondition(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutLong).Should(And( + WithTransform(IntegrationConditionReason, Equal(v1.IntegrationConditionRuntimeNotReadyReason)), + WithTransform(IntegrationConditionMessage, Equal("1/1 pods are not ready")))) + + g.Eventually(IntegrationCondition(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutLong).Should( + Satisfy(func(c *v1.IntegrationCondition) bool { + if c.Status != corev1.ConditionFalse { + return false + } + if len(c.Pods) != 1 { + return false } - } - if r == nil { - return false - } + var r *v1.HealthCheckResponse - if r.Data == nil { - return false - } + for h := range c.Pods[0].Health { + if c.Pods[0].Health[h].Name == "camel-routes" { + r = &c.Pods[0].Health[h] + } + } - var data map[string]interface{} - if err := json.Unmarshal(r.Data, &data); err != nil { - return false - } + if r == nil { + return false + } - return data["check.kind"].(string) == "READINESS" && data["route.status"].(string) == "Stopped" && data["route.id"].(string) == "never-ready" - })) - }) + if r.Data == nil { + return false + } - t.Run("Startup condition with never ready route", func(t *testing.T) { - name := RandomizedSuffixName("startup-probe-never-ready-route") - - Expect(KamelRunWithID(operatorID, ns, "files/NeverReady.java", - "--name", name, - "-t", "health.enabled=true", - "-t", "health.startup-probe-enabled=true", - "-t", "health.startup-timeout=60", - ).Execute()).To(Succeed()) - - Eventually(IntegrationPodPhase(ns, name), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationPhase(ns, name), TestTimeoutMedium).Should(Equal(v1.IntegrationPhaseRunning)) - Consistently(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), 1*time.Minute).Should(Equal(corev1.ConditionFalse)) - Eventually(IntegrationPhase(ns, name), TestTimeoutLong).Should(Equal(v1.IntegrationPhaseError)) - - Eventually(IntegrationCondition(ns, name, v1.IntegrationConditionReady), TestTimeoutLong).Should(And( - WithTransform(IntegrationConditionReason, Equal(v1.IntegrationConditionRuntimeNotReadyReason)), - WithTransform(IntegrationConditionMessage, Equal("1/1 pods are not ready")))) - - Eventually(IntegrationCondition(ns, name, v1.IntegrationConditionReady), TestTimeoutLong).Should( - Satisfy(func(c *v1.IntegrationCondition) bool { - if c.Status != corev1.ConditionFalse { - return false - } - if len(c.Pods) != 1 { - return false - } + var data map[string]interface{} + if err := json.Unmarshal(r.Data, &data); err != nil { + return false + } - var r *v1.HealthCheckResponse + return data["check.kind"].(string) == "READINESS" && data["route.status"].(string) == "Stopped" && data["route.id"].(string) == "never-ready" + })) + }) + + t.Run("Startup condition with never ready route", func(t *testing.T) { + name := RandomizedSuffixName("startup-probe-never-ready-route") + + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/NeverReady.java", "--name", name, "-t", "health.enabled=true", "-t", "health.startup-probe-enabled=true", "-t", "health.startup-timeout=60").Execute()).To(Succeed()) + + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationPhase(t, ctx, ns, name), TestTimeoutMedium).Should(Equal(v1.IntegrationPhaseRunning)) + g.Consistently(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), 1*time.Minute).Should(Equal(corev1.ConditionFalse)) + g.Eventually(IntegrationPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(v1.IntegrationPhaseError)) + + g.Eventually(IntegrationCondition(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutLong).Should(And( + WithTransform(IntegrationConditionReason, Equal(v1.IntegrationConditionRuntimeNotReadyReason)), + WithTransform(IntegrationConditionMessage, Equal("1/1 pods are not ready")))) - for h := range c.Pods[0].Health { - if c.Pods[0].Health[h].Name == "camel-routes" && c.Pods[0].Health[h].Status == "DOWN" { - r = &c.Pods[0].Health[h] + g.Eventually(IntegrationCondition(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutLong).Should( + Satisfy(func(c *v1.IntegrationCondition) bool { + if c.Status != corev1.ConditionFalse { + return false + } + if len(c.Pods) != 1 { + return false } - } - if r == nil { - return false - } + var r *v1.HealthCheckResponse - if r.Data == nil { - return false - } + for h := range c.Pods[0].Health { + if c.Pods[0].Health[h].Name == "camel-routes" && c.Pods[0].Health[h].Status == "DOWN" { + r = &c.Pods[0].Health[h] + } + } - var data map[string]interface{} - if err := json.Unmarshal(r.Data, &data); err != nil { - return false - } + if r == nil { + return false + } - return data["check.kind"].(string) == "READINESS" && data["route.status"].(string) == "Stopped" && data["route.id"].(string) == "never-ready" - })) + if r.Data == nil { + return false + } - Satisfy(func(events *corev1.EventList) bool { - for e := range events.Items { - if events.Items[e].Type == "Warning" && events.Items[e].Reason == "Unhealthy" && strings.Contains(events.Items[e].Message, "Startup probe failed") { - return true + var data map[string]interface{} + if err := json.Unmarshal(r.Data, &data); err != nil { + return false + } + + return data["check.kind"].(string) == "READINESS" && data["route.status"].(string) == "Stopped" && data["route.id"].(string) == "never-ready" + })) + + Satisfy(func(events *corev1.EventList) bool { + for e := range events.Items { + if events.Items[e].Type == "Warning" && events.Items[e].Reason == "Unhealthy" && strings.Contains(events.Items[e].Message, "Startup probe failed") { + return true + } } - } - return false + return false + }) }) - }) - t.Run("Startup condition with ready route", func(t *testing.T) { - name := RandomizedSuffixName("startup-probe-ready-route") + t.Run("Startup condition with ready route", func(t *testing.T) { + name := RandomizedSuffixName("startup-probe-ready-route") - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", - "--name", name, - "-t", "health.enabled=true", - "-t", "health.startup-probe-enabled=true", - "-t", "health.startup-timeout=60", - ).Execute()).To(Succeed()) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", name, "-t", "health.enabled=true", "-t", "health.startup-probe-enabled=true", "-t", "health.startup-timeout=60").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationPhase(ns, name), TestTimeoutMedium).Should(Equal(v1.IntegrationPhaseRunning)) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationPhase(t, ctx, ns, name), TestTimeoutMedium).Should(Equal(v1.IntegrationPhaseRunning)) - Eventually(IntegrationCondition(ns, name, v1.IntegrationConditionReady), TestTimeoutMedium).Should(And( - WithTransform(IntegrationConditionReason, Equal(v1.IntegrationConditionDeploymentReadyReason)), - WithTransform(IntegrationConditionMessage, Equal("1/1 ready replicas")))) + g.Eventually(IntegrationCondition(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutMedium).Should(And( + WithTransform(IntegrationConditionReason, Equal(v1.IntegrationConditionDeploymentReadyReason)), + WithTransform(IntegrationConditionMessage, Equal("1/1 ready replicas")))) + + Satisfy(func(is *v1.IntegrationSpec) bool { + if *is.Traits.Health.Enabled == true && *is.Traits.Health.StartupProbeEnabled == true && is.Traits.Health.StartupTimeout == 60 { + return true + } + return false + }) - Satisfy(func(is *v1.IntegrationSpec) bool { - if *is.Traits.Health.Enabled == true && *is.Traits.Health.StartupProbeEnabled == true && is.Traits.Health.StartupTimeout == 60 { - return true - } - return false }) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) - - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) } diff --git a/e2e/common/traits/istio_test.go b/e2e/common/traits/istio_test.go index 5d507c8235..bfe419efbc 100644 --- a/e2e/common/traits/istio_test.go +++ b/e2e/common/traits/istio_test.go @@ -23,6 +23,7 @@ limitations under the License. package traits import ( + "context" "testing" . "github.com/onsi/gomega" @@ -35,32 +36,39 @@ import ( ) func TestIstioTrait(t *testing.T) { - RegisterTestingT(t) - - t.Run("Run Java with Istio", func(t *testing.T) { - name := RandomizedSuffixName("java") - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", - "--name", name, - "-t", "istio.enabled=true").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - - pod := IntegrationPod(ns, name)() - Expect(pod.ObjectMeta.Annotations).NotTo(BeNil()) - annotations := pod.ObjectMeta.Annotations - Expect(annotations["sidecar.istio.io/inject"]).To(Equal("true")) - Expect(annotations["traffic.sidecar.istio.io/includeOutboundIPRanges"]).To(Equal("10.0.0.0/8,172.16.0.0/12,192.168.0.0/16")) - - // check integration schema does not contains unwanted default trait value. - Eventually(UnstructuredIntegration(ns, name)).ShouldNot(BeNil()) - unstructuredIntegration := UnstructuredIntegration(ns, name)() - istioTrait, _, _ := unstructured.NestedMap(unstructuredIntegration.Object, "spec", "traits", "istio") - Expect(istioTrait).ToNot(BeNil()) - Expect(len(istioTrait)).To(Equal(1)) - Expect(istioTrait["enabled"]).To(Equal(true)) + t.Parallel() - }) + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-traits-istio" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + + t.Run("Run Java with Istio", func(t *testing.T) { + name := RandomizedSuffixName("java") + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", name, "-t", "istio.enabled=true").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + + pod := IntegrationPod(t, ctx, ns, name)() + g.Expect(pod.ObjectMeta.Annotations).NotTo(BeNil()) + annotations := pod.ObjectMeta.Annotations + g.Expect(annotations["sidecar.istio.io/inject"]).To(Equal("true")) + g.Expect(annotations["traffic.sidecar.istio.io/includeOutboundIPRanges"]).To(Equal("10.0.0.0/8,172.16.0.0/12,192.168.0.0/16")) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + // check integration schema does not contains unwanted default trait value. + g.Eventually(UnstructuredIntegration(t, ctx, ns, name)).ShouldNot(BeNil()) + unstructuredIntegration := UnstructuredIntegration(t, ctx, ns, name)() + istioTrait, _, _ := unstructured.NestedMap(unstructuredIntegration.Object, "spec", "traits", "istio") + g.Expect(istioTrait).ToNot(BeNil()) + g.Expect(len(istioTrait)).To(Equal(1)) + g.Expect(istioTrait["enabled"]).To(Equal(true)) + + }) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) } diff --git a/e2e/common/traits/jolokia_test.go b/e2e/common/traits/jolokia_test.go index c06e8d53a3..bb62cb096b 100644 --- a/e2e/common/traits/jolokia_test.go +++ b/e2e/common/traits/jolokia_test.go @@ -23,6 +23,7 @@ limitations under the License. package traits import ( + "context" "fmt" "testing" @@ -36,39 +37,42 @@ import ( ) func TestJolokiaTrait(t *testing.T) { - RegisterTestingT(t) - - t.Run("Run Java with Jolokia", func(t *testing.T) { - name := RandomizedSuffixName("java") - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", - "--name", name, - "-t", "jolokia.enabled=true", - "-t", "jolokia.use-ssl-client-authentication=false", - "-t", "jolokia.protocol=http", - "-t", "jolokia.extended-client-check=false").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - - pod := IntegrationPod(ns, name) - response, err := TestClient().CoreV1().RESTClient().Get(). - AbsPath(fmt.Sprintf("/api/v1/namespaces/%s/pods/%s/proxy/jolokia/", ns, pod().Name)).DoRaw(TestContext) - Expect(err).To(BeNil()) - Expect(response).To(ContainSubstring(`"status":200`)) - - // check integration schema does not contains unwanted default trait value. - Eventually(UnstructuredIntegration(ns, name)).ShouldNot(BeNil()) - unstructuredIntegration := UnstructuredIntegration(ns, name)() - jolokiaTrait, _, _ := unstructured.NestedMap(unstructuredIntegration.Object, "spec", "traits", "jolokia") - Expect(jolokiaTrait).ToNot(BeNil()) - Expect(len(jolokiaTrait)).To(Equal(4)) - Expect(jolokiaTrait["enabled"]).To(Equal(true)) - Expect(jolokiaTrait["useSSLClientAuthentication"]).To(Equal(false)) - Expect(jolokiaTrait["protocol"]).To(Equal("http")) - Expect(jolokiaTrait["extendedClientCheck"]).To(Equal(false)) - + t.Parallel() + + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-traits-jolokia" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + + t.Run("Run Java with Jolokia", func(t *testing.T) { + name := RandomizedSuffixName("java") + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", name, "-t", "jolokia.enabled=true", "-t", "jolokia.use-ssl-client-authentication=false", "-t", "jolokia.protocol=http", "-t", "jolokia.extended-client-check=false").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + + pod := IntegrationPod(t, ctx, ns, name) + response, err := TestClient(t).CoreV1().RESTClient().Get(). + AbsPath(fmt.Sprintf("/api/v1/namespaces/%s/pods/%s/proxy/jolokia/", ns, pod().Name)).DoRaw(ctx) + g.Expect(err).To(BeNil()) + g.Expect(response).To(ContainSubstring(`"status":200`)) + + // check integration schema does not contains unwanted default trait value. + g.Eventually(UnstructuredIntegration(t, ctx, ns, name)).ShouldNot(BeNil()) + unstructuredIntegration := UnstructuredIntegration(t, ctx, ns, name)() + jolokiaTrait, _, _ := unstructured.NestedMap(unstructuredIntegration.Object, "spec", "traits", "jolokia") + g.Expect(jolokiaTrait).ToNot(BeNil()) + g.Expect(len(jolokiaTrait)).To(Equal(4)) + g.Expect(jolokiaTrait["enabled"]).To(Equal(true)) + g.Expect(jolokiaTrait["useSSLClientAuthentication"]).To(Equal(false)) + g.Expect(jolokiaTrait["protocol"]).To(Equal("http")) + g.Expect(jolokiaTrait["extendedClientCheck"]).To(Equal(false)) + + }) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) - - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) - } diff --git a/e2e/common/traits/jvm_test.go b/e2e/common/traits/jvm_test.go index 395a51705c..958763f794 100644 --- a/e2e/common/traits/jvm_test.go +++ b/e2e/common/traits/jvm_test.go @@ -23,11 +23,12 @@ limitations under the License. package traits import ( + "context" "os" "testing" . "github.com/onsi/gomega" - "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -37,34 +38,40 @@ import ( ) func TestJVMTrait(t *testing.T) { - RegisterTestingT(t) - - // Store a configmap holding a jar - var cmData = make(map[string][]byte) - // We calculate the expected content - source, err := os.ReadFile("./files/jvm/sample-1.0.jar") - assert.Nil(t, err) - cmData["sample-1.0.jar"] = source - err = CreateBinaryConfigmap(ns, "my-deps", cmData) - assert.Nil(t, err) - - t.Run("JVM trait classpath", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "./files/jvm/Classpath.java", - "--resource", "configmap:my-deps", - "-t", "jvm.classpath=/etc/camel/resources/my-deps/sample-1.0.jar", - ).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "classpath"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "classpath", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "classpath"), TestTimeoutShort).Should(ContainSubstring("Hello World!")) - - // check integration schema does not contains unwanted default trait value. - Eventually(UnstructuredIntegration(ns, "classpath")).ShouldNot(BeNil()) - unstructuredIntegration := UnstructuredIntegration(ns, "classpath")() - jvmTrait, _, _ := unstructured.NestedMap(unstructuredIntegration.Object, "spec", "traits", "jvm") - Expect(jvmTrait).ToNot(BeNil()) - Expect(len(jvmTrait)).To(Equal(1)) - Expect(jvmTrait["classpath"]).To(Equal("/etc/camel/resources/my-deps/sample-1.0.jar")) - - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + t.Parallel() + + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-traits-jvm" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + + // Store a configmap holding a jar + var cmData = make(map[string][]byte) + // We calculate the expected content + source, err := os.ReadFile("./files/jvm/sample-1.0.jar") + require.NoError(t, err) + cmData["sample-1.0.jar"] = source + err = CreateBinaryConfigmap(t, ctx, ns, "my-deps", cmData) + require.NoError(t, err) + + t.Run("JVM trait classpath", func(t *testing.T) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "./files/jvm/Classpath.java", "--resource", "configmap:my-deps", "-t", "jvm.classpath=/etc/camel/resources/my-deps/sample-1.0.jar").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "classpath"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "classpath", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "classpath"), TestTimeoutShort).Should(ContainSubstring("Hello World!")) + + // check integration schema does not contains unwanted default trait value. + g.Eventually(UnstructuredIntegration(t, ctx, ns, "classpath")).ShouldNot(BeNil()) + unstructuredIntegration := UnstructuredIntegration(t, ctx, ns, "classpath")() + jvmTrait, _, _ := unstructured.NestedMap(unstructuredIntegration.Object, "spec", "traits", "jvm") + g.Expect(jvmTrait).ToNot(BeNil()) + g.Expect(len(jvmTrait)).To(Equal(1)) + g.Expect(jvmTrait["classpath"]).To(Equal("/etc/camel/resources/my-deps/sample-1.0.jar")) + }) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) } diff --git a/e2e/common/traits/kamelet_test.go b/e2e/common/traits/kamelet_test.go index 201caee706..bd744ea2a4 100644 --- a/e2e/common/traits/kamelet_test.go +++ b/e2e/common/traits/kamelet_test.go @@ -23,6 +23,7 @@ limitations under the License. package traits import ( + "context" "testing" . "github.com/onsi/gomega" @@ -34,34 +35,43 @@ import ( ) func TestKameletTrait(t *testing.T) { - RegisterTestingT(t) + t.Parallel() - t.Run("discover kamelet capabilities", func(t *testing.T) { - template := map[string]interface{}{ - "from": map[string]interface{}{ - "uri": "platform-http:///webhook", - "steps": []map[string]interface{}{ - { - "to": "kamelet:sink", + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-traits-kamelet" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + + t.Run("discover kamelet capabilities", func(t *testing.T) { + template := map[string]interface{}{ + "from": map[string]interface{}{ + "uri": "platform-http:///webhook", + "steps": []map[string]interface{}{ + { + "to": "kamelet:sink", + }, }, }, - }, - } - Expect(CreateKamelet(ns, "capabilities-webhook-source", template, nil, nil)()).To(Succeed()) + } + g.Expect(CreateKamelet(t, operatorID, ctx, ns, "capabilities-webhook-source", template, nil, nil)()).To(Succeed()) - name := RandomizedSuffixName("webhook") - Expect(KamelRunWithID(operatorID, ns, "files/webhook.yaml", "--name", name).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Started capabilities-webhook-source-1 (platform-http:///webhook)")) - // Verify Integration capabilities - Eventually(IntegrationStatusCapabilities(ns, name), TestTimeoutShort).Should(ContainElements("platform-http")) - // Verify expected resources from Kamelet (Service in this case) - service := Service(ns, name) - Eventually(service, TestTimeoutShort).ShouldNot(BeNil()) - }) + name := RandomizedSuffixName("webhook") + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/webhook.yaml", "--name", name).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Started capabilities-webhook-source-1 (platform-http:///webhook)")) + // Verify Integration capabilities + g.Eventually(IntegrationStatusCapabilities(t, ctx, ns, name), TestTimeoutShort).Should(ContainElements("platform-http")) + // Verify expected resources from Kamelet (Service in this case) + service := Service(t, ctx, ns, name) + g.Eventually(service, TestTimeoutShort).ShouldNot(BeNil()) + }) - // Clean-up - Expect(DeleteKamelet(ns, "capabilities-webhook-source")).To(Succeed()) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + // Clean-up + g.Expect(DeleteKamelet(t, ctx, ns, "capabilities-webhook-source")).To(Succeed()) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) } diff --git a/e2e/common/traits/master_test.go b/e2e/common/traits/master_test.go index 111760b022..96541a8cc5 100644 --- a/e2e/common/traits/master_test.go +++ b/e2e/common/traits/master_test.go @@ -23,6 +23,7 @@ limitations under the License. package traits import ( + "context" "testing" "time" @@ -32,50 +33,49 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" . "github.com/apache/camel-k/v2/e2e/support" + v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" ) func TestMasterTrait(t *testing.T) { - RegisterTestingT(t) + t.Parallel() - t.Run("master works", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "files/Master.java").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "master"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns, "master"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) - }) + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-traits-master" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) - t.Run("only one integration with master runs", func(t *testing.T) { - nameFirst := RandomizedSuffixName("first") - Expect(KamelRunWithID(operatorID, ns, "files/Master.java", - "--name", nameFirst, - "--label", "leader-group=same", - "-t", "master.label-key=leader-group", - "-t", "master.label-value=same", - "-t", "owner.target-labels=leader-group").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, nameFirst), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns, nameFirst), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - // Start a second integration with the same lock (it should not start the route) - nameSecond := RandomizedSuffixName("second") - Expect(KamelRunWithID(operatorID, ns, "files/Master.java", - "--name", nameSecond, - "--label", "leader-group=same", - "-t", "master.label-key=leader-group", - "-t", "master.label-value=same", - "-t", "master.resource-name=first-lock", - "-t", "owner.target-labels=leader-group").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, nameSecond), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns, nameSecond), TestTimeoutShort).Should(ContainSubstring("started in")) - Eventually(IntegrationLogs(ns, nameSecond), 30*time.Second).ShouldNot(ContainSubstring("Magicstring!")) - - // check integration schema does not contains unwanted default trait value. - Eventually(UnstructuredIntegration(ns, nameFirst)).ShouldNot(BeNil()) - unstructuredIntegration := UnstructuredIntegration(ns, nameFirst)() - builderTrait, _, _ := unstructured.NestedMap(unstructuredIntegration.Object, "spec", "traits", "addons", "master") - Expect(builderTrait).ToNot(BeNil()) - Expect(len(builderTrait)).To(Equal(2)) - Expect(builderTrait["labelKey"]).To(Equal("leader-group")) - Expect(builderTrait["labelValue"]).To(Equal("same")) - }) + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + + t.Run("master works", func(t *testing.T) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Master.java").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "master"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, "master"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + t.Run("only one integration with master runs", func(t *testing.T) { + nameFirst := RandomizedSuffixName("first") + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Master.java", "--name", nameFirst, "--label", "leader-group=same", "-t", "master.label-key=leader-group", "-t", "master.label-value=same", "-t", "owner.target-labels=leader-group").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, nameFirst), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, nameFirst), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + // Start a second integration with the same lock (it should not start the route) + nameSecond := RandomizedSuffixName("second") + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Master.java", "--name", nameSecond, "--label", "leader-group=same", "-t", "master.label-key=leader-group", "-t", "master.label-value=same", "-t", "master.resource-name=first-lock", "-t", "owner.target-labels=leader-group").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, nameSecond), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, nameSecond), TestTimeoutShort).Should(ContainSubstring("started in")) + g.Eventually(IntegrationLogs(t, ctx, ns, nameSecond), 30*time.Second).ShouldNot(ContainSubstring("Magicstring!")) + + // check integration schema does not contains unwanted default trait value. + g.Eventually(UnstructuredIntegration(t, ctx, ns, nameFirst)).ShouldNot(BeNil()) + unstructuredIntegration := UnstructuredIntegration(t, ctx, ns, nameFirst)() + builderTrait, _, _ := unstructured.NestedMap(unstructuredIntegration.Object, "spec", "traits", "addons", "master") + g.Expect(builderTrait).ToNot(BeNil()) + g.Expect(len(builderTrait)).To(Equal(2)) + g.Expect(builderTrait["labelKey"]).To(Equal("leader-group")) + g.Expect(builderTrait["labelValue"]).To(Equal("same")) + }) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) } diff --git a/e2e/common/traits/openapi_test.go b/e2e/common/traits/openapi_test.go index f1c90ebf68..ef3de8e35b 100644 --- a/e2e/common/traits/openapi_test.go +++ b/e2e/common/traits/openapi_test.go @@ -23,43 +23,50 @@ limitations under the License. package traits import ( + "context" "io/ioutil" "testing" . "github.com/onsi/gomega" - "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" . "github.com/apache/camel-k/v2/e2e/support" + v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" ) func TestOpenAPI(t *testing.T) { - RegisterTestingT(t) - - openapiContent, err := ioutil.ReadFile("./files/openapi/petstore-api.yaml") - assert.Nil(t, err) - var cmDataProps = make(map[string]string) - cmDataProps["petstore-api.yaml"] = string(openapiContent) - CreatePlainTextConfigmap(ns, "my-openapi", cmDataProps) - - Expect(KamelRunWithID(operatorID, ns, - "--name", "petstore", - "--open-api", "configmap:my-openapi", - "files/openapi/petstore.groovy", - ).Execute()).To(Succeed()) - - Eventually(IntegrationPodPhase(ns, "petstore"), TestTimeoutLong). - Should(Equal(corev1.PodRunning)) - Eventually(DeploymentWithIntegrationLabel(ns, "petstore"), TestTimeoutLong). - Should(Not(BeNil())) - - Eventually(IntegrationLogs(ns, "petstore"), TestTimeoutMedium). - Should(ContainSubstring("Started listPets (rest://get:/v1:/pets)")) - Eventually(IntegrationLogs(ns, "petstore"), TestTimeoutMedium). - Should(ContainSubstring("Started createPets (rest://post:/v1:/pets)")) - Eventually(IntegrationLogs(ns, "petstore"), TestTimeoutMedium). - Should(ContainSubstring("Started showPetById (rest://get:/v1:/pets/%7BpetId%7D)")) - - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + t.Parallel() + + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-traits-openapi" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + + openapiContent, err := ioutil.ReadFile("./files/openapi/petstore-api.yaml") + require.NoError(t, err) + var cmDataProps = make(map[string]string) + cmDataProps["petstore-api.yaml"] = string(openapiContent) + CreatePlainTextConfigmap(t, ctx, ns, "my-openapi", cmDataProps) + + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "--name", "petstore", "--open-api", "configmap:my-openapi", "files/openapi/petstore.groovy").Execute()).To(Succeed()) + + g.Eventually(IntegrationPodPhase(t, ctx, ns, "petstore"), TestTimeoutLong). + Should(Equal(corev1.PodRunning)) + g.Eventually(DeploymentWithIntegrationLabel(t, ctx, ns, "petstore"), TestTimeoutLong). + Should(Not(BeNil())) + + g.Eventually(IntegrationLogs(t, ctx, ns, "petstore"), TestTimeoutMedium). + Should(ContainSubstring("Started listPets (rest://get:/v1:/pets)")) + g.Eventually(IntegrationLogs(t, ctx, ns, "petstore"), TestTimeoutMedium). + Should(ContainSubstring("Started createPets (rest://post:/v1:/pets)")) + g.Eventually(IntegrationLogs(t, ctx, ns, "petstore"), TestTimeoutMedium). + Should(ContainSubstring("Started showPetById (rest://get:/v1:/pets/%7BpetId%7D)")) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) } diff --git a/e2e/common/traits/pdb_test.go b/e2e/common/traits/pdb_test.go index 7c43e1ff75..86e873ae3f 100644 --- a/e2e/common/traits/pdb_test.go +++ b/e2e/common/traits/pdb_test.go @@ -23,6 +23,7 @@ limitations under the License. package traits import ( + "context" "net/http" "testing" @@ -43,113 +44,118 @@ import ( ) func TestPodDisruptionBudgetTrait(t *testing.T) { - RegisterTestingT(t) - - name := RandomizedSuffixName("java") - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", - "--name", name, - "-t", "pdb.enabled=true", - "-t", "pdb.min-available=2", - ).Execute()).To(Succeed()) - - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - - // check integration schema does not contains unwanted default trait value. - Eventually(UnstructuredIntegration(ns, name)).ShouldNot(BeNil()) - unstructuredIntegration := UnstructuredIntegration(ns, name)() - pdbTrait, _, _ := unstructured.NestedMap(unstructuredIntegration.Object, "spec", "traits", "pdb") - Expect(pdbTrait).ToNot(BeNil()) - Expect(len(pdbTrait)).To(Equal(2)) - Expect(pdbTrait["enabled"]).To(Equal(true)) - Expect(pdbTrait["minAvailable"]).To(Equal("2")) - - // Check PodDisruptionBudget - Eventually(podDisruptionBudget(ns, name), TestTimeoutShort).ShouldNot(BeNil()) - pdb := podDisruptionBudget(ns, name)() - // Assert PDB Spec - Expect(pdb.Spec.MinAvailable).To(PointTo(Equal(intstr.FromInt(2)))) - // Assert PDB Status - Eventually(podDisruptionBudget(ns, name), TestTimeoutShort). - Should(MatchFieldsP(IgnoreExtras, Fields{ - "Status": MatchFields(IgnoreExtras, Fields{ - "ObservedGeneration": BeNumerically("==", 1), - "DisruptionsAllowed": BeNumerically("==", 0), - "CurrentHealthy": BeNumerically("==", 1), - "DesiredHealthy": BeNumerically("==", 2), - "ExpectedPods": BeNumerically("==", 1), - }), + t.Parallel() + + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-traits-pdb" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + + name := RandomizedSuffixName("java") + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", name, "-t", "pdb.enabled=true", "-t", "pdb.min-available=2").Execute()).To(Succeed()) + + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + + // check integration schema does not contains unwanted default trait value. + g.Eventually(UnstructuredIntegration(t, ctx, ns, name)).ShouldNot(BeNil()) + unstructuredIntegration := UnstructuredIntegration(t, ctx, ns, name)() + pdbTrait, _, _ := unstructured.NestedMap(unstructuredIntegration.Object, "spec", "traits", "pdb") + g.Expect(pdbTrait).ToNot(BeNil()) + g.Expect(len(pdbTrait)).To(Equal(2)) + g.Expect(pdbTrait["enabled"]).To(Equal(true)) + g.Expect(pdbTrait["minAvailable"]).To(Equal("2")) + + // Check PodDisruptionBudget + g.Eventually(podDisruptionBudget(t, ctx, ns, name), TestTimeoutShort).ShouldNot(BeNil()) + pdb := podDisruptionBudget(t, ctx, ns, name)() + // Assert PDB Spec + g.Expect(pdb.Spec.MinAvailable).To(PointTo(Equal(intstr.FromInt(2)))) + // Assert PDB Status + g.Eventually(podDisruptionBudget(t, ctx, ns, name), TestTimeoutShort). + Should(MatchFieldsP(IgnoreExtras, Fields{ + "Status": MatchFields(IgnoreExtras, Fields{ + "ObservedGeneration": BeNumerically("==", 1), + "DisruptionsAllowed": BeNumerically("==", 0), + "CurrentHealthy": BeNumerically("==", 1), + "DesiredHealthy": BeNumerically("==", 2), + "ExpectedPods": BeNumerically("==", 1), + }), + })) + + // Scale Integration + g.Expect(ScaleIntegration(t, ctx, ns, name, 2)).To(Succeed()) + g.Eventually(IntegrationPods(t, ctx, ns, name), TestTimeoutMedium).Should(HaveLen(2)) + g.Eventually(IntegrationStatusReplicas(t, ctx, ns, name), TestTimeoutShort). + Should(PointTo(BeNumerically("==", 2))) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + + // Check PodDisruptionBudget + pdb = podDisruptionBudget(t, ctx, ns, name)() + g.Expect(pdb).NotTo(BeNil()) + // Assert PDB Status according to the scale change + g.Eventually(podDisruptionBudget(t, ctx, ns, name), TestTimeoutShort). + Should(MatchFieldsP(IgnoreExtras, Fields{ + "Status": MatchFields(IgnoreExtras, Fields{ + "ObservedGeneration": BeNumerically("==", 1), + "DisruptionsAllowed": BeNumerically("==", 0), + "CurrentHealthy": BeNumerically("==", 2), + "DesiredHealthy": BeNumerically("==", 2), + "ExpectedPods": BeNumerically("==", 2), + }), + })) + + // Eviction attempt + pods := IntegrationPods(t, ctx, ns, name)() + g.Expect(pods).To(HaveLen(2)) + err := TestClient(t).CoreV1().Pods(ns).EvictV1(ctx, &policyv1.Eviction{ + ObjectMeta: metav1.ObjectMeta{ + Name: pods[0].Name, + }, + }) + g.Expect(err).To(MatchError(&k8serrors.StatusError{ + ErrStatus: metav1.Status{ + Status: "Failure", + Message: "Cannot evict pod as it would violate the pod's disruption budget.", + Reason: "TooManyRequests", + Code: http.StatusTooManyRequests, + Details: &metav1.StatusDetails{ + Causes: []metav1.StatusCause{ + { + Type: "DisruptionBudget", + Message: "The disruption budget " + name + " needs 2 healthy pods and has 2 currently", + }, + }, + }, + }, })) - // Scale Integration - Expect(ScaleIntegration(ns, name, 2)).To(Succeed()) - Eventually(IntegrationPods(ns, name), TestTimeoutMedium).Should(HaveLen(2)) - Eventually(IntegrationStatusReplicas(ns, name), TestTimeoutShort). - Should(PointTo(BeNumerically("==", 2))) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - - // Check PodDisruptionBudget - pdb = podDisruptionBudget(ns, name)() - Expect(pdb).NotTo(BeNil()) - // Assert PDB Status according to the scale change - Eventually(podDisruptionBudget(ns, name), TestTimeoutShort). - Should(MatchFieldsP(IgnoreExtras, Fields{ - "Status": MatchFields(IgnoreExtras, Fields{ - "ObservedGeneration": BeNumerically("==", 1), - "DisruptionsAllowed": BeNumerically("==", 0), - "CurrentHealthy": BeNumerically("==", 2), - "DesiredHealthy": BeNumerically("==", 2), - "ExpectedPods": BeNumerically("==", 2), - }), - })) + // Scale Integration to Scale > PodDisruptionBudgetSpec.MinAvailable + // for the eviction request to succeed once replicas are ready + g.Expect(ScaleIntegration(t, ctx, ns, name, 3)).To(Succeed()) + g.Eventually(IntegrationPods(t, ctx, ns, name), TestTimeoutMedium).Should(HaveLen(3)) + g.Eventually(IntegrationStatusReplicas(t, ctx, ns, name), TestTimeoutShort). + Should(PointTo(BeNumerically("==", 3))) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + + pods = IntegrationPods(t, ctx, ns, name)() + g.Expect(pods).To(HaveLen(3)) + g.Expect(TestClient(t).CoreV1().Pods(ns).EvictV1(ctx, &policyv1.Eviction{ + ObjectMeta: metav1.ObjectMeta{ + Name: pods[0].Name, + }, + })).To(Succeed()) - // Eviction attempt - pods := IntegrationPods(ns, name)() - Expect(pods).To(HaveLen(2)) - err := TestClient().CoreV1().Pods(ns).EvictV1(TestContext, &policyv1.Eviction{ - ObjectMeta: metav1.ObjectMeta{ - Name: pods[0].Name, - }, + // Clean up + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) - Expect(err).To(MatchError(&k8serrors.StatusError{ - ErrStatus: metav1.Status{ - Status: "Failure", - Message: "Cannot evict pod as it would violate the pod's disruption budget.", - Reason: "TooManyRequests", - Code: http.StatusTooManyRequests, - Details: &metav1.StatusDetails{ - Causes: []metav1.StatusCause{ - { - Type: "DisruptionBudget", - Message: "The disruption budget " + name + " needs 2 healthy pods and has 2 currently", - }, - }, - }, - }, - })) - - // Scale Integration to Scale > PodDisruptionBudgetSpec.MinAvailable - // for the eviction request to succeed once replicas are ready - Expect(ScaleIntegration(ns, name, 3)).To(Succeed()) - Eventually(IntegrationPods(ns, name), TestTimeoutMedium).Should(HaveLen(3)) - Eventually(IntegrationStatusReplicas(ns, name), TestTimeoutShort). - Should(PointTo(BeNumerically("==", 3))) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - - pods = IntegrationPods(ns, name)() - Expect(pods).To(HaveLen(3)) - Expect(TestClient().CoreV1().Pods(ns).EvictV1(TestContext, &policyv1.Eviction{ - ObjectMeta: metav1.ObjectMeta{ - Name: pods[0].Name, - }, - })).To(Succeed()) - - // Clean up - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) } -func podDisruptionBudget(ns string, name string) func() *policyv1.PodDisruptionBudget { +func podDisruptionBudget(t *testing.T, ctx context.Context, ns string, name string) func() *policyv1.PodDisruptionBudget { return func() *policyv1.PodDisruptionBudget { pdb := policyv1.PodDisruptionBudget{ TypeMeta: metav1.TypeMeta{ @@ -161,7 +167,7 @@ func podDisruptionBudget(ns string, name string) func() *policyv1.PodDisruptionB Name: name, }, } - err := TestClient().Get(TestContext, ctrl.ObjectKeyFromObject(&pdb), &pdb) + err := TestClient(t).Get(ctx, ctrl.ObjectKeyFromObject(&pdb), &pdb) if err != nil && k8serrors.IsNotFound(err) { return nil } else if err != nil { diff --git a/e2e/common/traits/pod_test.go b/e2e/common/traits/pod_test.go index 19c2290649..54726a5744 100644 --- a/e2e/common/traits/pod_test.go +++ b/e2e/common/traits/pod_test.go @@ -23,6 +23,7 @@ limitations under the License. package traits import ( + "context" "testing" . "github.com/onsi/gomega" @@ -34,72 +35,78 @@ import ( ) func TestPodTrait(t *testing.T) { - RegisterTestingT(t) - - tc := []struct { - name string - templateName string - assertions func(t *testing.T, ns string, name string) - }{ - { - name: "pod trait with env vars and volume mounts", - templateName: "files/template.yaml", - //nolint: thelper - assertions: func(t *testing.T, ns string, name string) { - // check that integrations is working and reading data created by sidecar container - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Content from the sidecar container")) - // check that env var is injected - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("hello from the template")) - pod := IntegrationPod(ns, name)() - - // check if ENV variable is applied - envValue := getEnvVar("TEST_VARIABLE", pod.Spec) - Expect(envValue).To(Equal("hello from the template")) + t.Parallel() + + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-traits-pod" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + + tc := []struct { + name string + templateName string + assertions func(t *testing.T, ns string, name string) + }{ + { + name: "pod trait with env vars and volume mounts", + templateName: "files/template.yaml", + //nolint: thelper + assertions: func(t *testing.T, ns string, name string) { + // check that integrations is working and reading data created by sidecar container + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Content from the sidecar container")) + // check that env var is injected + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("hello from the template")) + pod := IntegrationPod(t, ctx, ns, name)() + + // check if ENV variable is applied + envValue := getEnvVar("TEST_VARIABLE", pod.Spec) + g.Expect(envValue).To(Equal("hello from the template")) + }, }, - }, - { - name: "pod trait with supplemental groups", - templateName: "files/template-with-supplemental-groups.yaml", - //nolint: thelper - assertions: func(t *testing.T, ns string, name string) { - Eventually(IntegrationPodHas(ns, name, func(pod *corev1.Pod) bool { - if pod.Spec.SecurityContext == nil { - return false - } - for _, sg := range pod.Spec.SecurityContext.SupplementalGroups { - if sg == 666 { - return true + { + name: "pod trait with supplemental groups", + templateName: "files/template-with-supplemental-groups.yaml", + //nolint: thelper + assertions: func(t *testing.T, ns string, name string) { + g.Eventually(IntegrationPodHas(t, ctx, ns, name, func(pod *corev1.Pod) bool { + if pod.Spec.SecurityContext == nil { + return false + } + for _, sg := range pod.Spec.SecurityContext.SupplementalGroups { + if sg == 666 { + return true + } } - } - return false - }), TestTimeoutShort).Should(BeTrue()) + return false + }), TestTimeoutShort).Should(BeTrue()) + }, }, - }, - } + } - name := RandomizedSuffixName("pod-template-test") + name := RandomizedSuffixName("pod-template-test") - for i := range tc { - test := tc[i] + for i := range tc { + test := tc[i] - t.Run(test.name, func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "files/PodTest.groovy", - "--name", name, - "--pod-template", test.templateName, - ).Execute()).To(Succeed()) + t.Run(test.name, func(t *testing.T) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/PodTest.groovy", "--name", name, "--pod-template", test.templateName).Execute()).To(Succeed()) - // check integration is deployed - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + // check integration is deployed + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - test.assertions(t, ns, name) + test.assertions(t, ns, name) - // Clean up - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) - }) - } + // Clean up + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) + } - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) } func getEnvVar(name string, spec corev1.PodSpec) string { diff --git a/e2e/common/traits/prometheus_test.go b/e2e/common/traits/prometheus_test.go index 1a40ddab74..d50e27059c 100644 --- a/e2e/common/traits/prometheus_test.go +++ b/e2e/common/traits/prometheus_test.go @@ -23,11 +23,13 @@ limitations under the License. package traits import ( + "context" "fmt" "testing" . "github.com/onsi/gomega" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" k8serrors "k8s.io/apimachinery/pkg/api/errors" @@ -43,55 +45,62 @@ import ( ) func TestPrometheusTrait(t *testing.T) { - RegisterTestingT(t) - - ocp, err := openshift.IsOpenShift(TestClient()) - assert.Nil(t, err) - // Do not create PodMonitor for the time being as CI test runs on OCP 3.11 - createPodMonitor := false - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", - "-t", "prometheus.enabled=true", - "-t", fmt.Sprintf("prometheus.pod-monitor=%v", createPodMonitor)).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "java"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "java", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "java"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - - // check integration schema does not contains unwanted default trait value. - Eventually(UnstructuredIntegration(ns, "java")).ShouldNot(BeNil()) - unstructuredIntegration := UnstructuredIntegration(ns, "java")() - prometheusTrait, _, _ := unstructured.NestedMap(unstructuredIntegration.Object, "spec", "traits", "prometheus") - Expect(prometheusTrait).ToNot(BeNil()) - Expect(len(prometheusTrait)).To(Equal(2)) - Expect(prometheusTrait["enabled"]).To(Equal(true)) - Expect(prometheusTrait["podMonitor"]).ToNot(BeNil()) - t.Run("Metrics endpoint works", func(t *testing.T) { - pod := IntegrationPod(ns, "java") - response, err := TestClient().CoreV1().RESTClient().Get(). - AbsPath(fmt.Sprintf("/api/v1/namespaces/%s/pods/%s/proxy/q/metrics", ns, pod().Name)).DoRaw(TestContext) - if err != nil { - assert.Fail(t, err.Error()) - } - assert.Contains(t, string(response), "camel_exchanges_total") - }) - - if ocp && createPodMonitor { - t.Run("PodMonitor is created", func(t *testing.T) { - sm := podMonitor(ns, "java") - Eventually(sm, TestTimeoutShort).ShouldNot(BeNil()) + t.Parallel() + + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-traits-prometheus" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + + ocp, err := openshift.IsOpenShift(TestClient(t)) + require.NoError(t, err) + // Do not create PodMonitor for the time being as CI test runs on OCP 3.11 + createPodMonitor := false + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "-t", "prometheus.enabled=true", "-t", fmt.Sprintf("prometheus.pod-monitor=%v", createPodMonitor)).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "java"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "java", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "java"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + + // check integration schema does not contains unwanted default trait value. + g.Eventually(UnstructuredIntegration(t, ctx, ns, "java")).ShouldNot(BeNil()) + unstructuredIntegration := UnstructuredIntegration(t, ctx, ns, "java")() + prometheusTrait, _, _ := unstructured.NestedMap(unstructuredIntegration.Object, "spec", "traits", "prometheus") + g.Expect(prometheusTrait).ToNot(BeNil()) + g.Expect(len(prometheusTrait)).To(Equal(2)) + g.Expect(prometheusTrait["enabled"]).To(Equal(true)) + g.Expect(prometheusTrait["podMonitor"]).ToNot(BeNil()) + t.Run("Metrics endpoint works", func(t *testing.T) { + pod := IntegrationPod(t, ctx, ns, "java") + response, err := TestClient(t).CoreV1().RESTClient().Get(). + AbsPath(fmt.Sprintf("/api/v1/namespaces/%s/pods/%s/proxy/q/metrics", ns, pod().Name)).DoRaw(ctx) + if err != nil { + assert.Fail(t, err.Error()) + } + assert.Contains(t, string(response), "camel_exchanges_total") }) - } - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + if ocp && createPodMonitor { + t.Run("PodMonitor is created", func(t *testing.T) { + sm := podMonitor(t, ctx, ns, "java") + g.Eventually(sm, TestTimeoutShort).ShouldNot(BeNil()) + }) + } + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) } -func podMonitor(ns string, name string) func() *monitoringv1.PodMonitor { +func podMonitor(t *testing.T, ctx context.Context, ns string, name string) func() *monitoringv1.PodMonitor { return func() *monitoringv1.PodMonitor { pm := monitoringv1.PodMonitor{} key := ctrl.ObjectKey{ Namespace: ns, Name: name, } - err := TestClient().Get(TestContext, key, &pm) + err := TestClient(t).Get(ctx, key, &pm) if err != nil && k8serrors.IsNotFound(err) { return nil } else if err != nil { diff --git a/e2e/common/traits/pull_secret_test.go b/e2e/common/traits/pull_secret_test.go index ade72f1447..7436cfec1e 100644 --- a/e2e/common/traits/pull_secret_test.go +++ b/e2e/common/traits/pull_secret_test.go @@ -23,6 +23,7 @@ limitations under the License. package traits import ( + "context" "testing" . "github.com/onsi/gomega" @@ -36,64 +37,70 @@ import ( ) func TestPullSecretTrait(t *testing.T) { - RegisterTestingT(t) - - ocp, err := openshift.IsOpenShift(TestClient()) - Expect(err).To(BeNil()) - - t.Run("Image pull secret is set on pod", func(t *testing.T) { - name := RandomizedSuffixName("java1") - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", "--name", name, - "-t", "pull-secret.enabled=true", - "-t", "pull-secret.secret-name=dummy-secret").Execute()).To(Succeed()) - // pod may not run because the pull secret is dummy - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Or(Equal(corev1.PodRunning), Equal(corev1.PodPending))) - - pod := IntegrationPod(ns, name)() - Expect(pod.Spec.ImagePullSecrets).NotTo(BeEmpty()) - Expect(pod.Spec.ImagePullSecrets[0].Name).To(Equal("dummy-secret")) - }) + t.Parallel() - t.Run("Explicitly disable image pull secret", func(t *testing.T) { - name := RandomizedSuffixName("java2") - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", "--name", name, - "-t", "pull-secret.enabled=false").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - - // check integration schema does not contains unwanted default trait value. - Eventually(UnstructuredIntegration(ns, name)).ShouldNot(BeNil()) - unstructuredIntegration := UnstructuredIntegration(ns, name)() - pullSecretTrait, _, _ := unstructured.NestedMap(unstructuredIntegration.Object, "spec", "traits", "pull-secret") - Expect(pullSecretTrait).ToNot(BeNil()) - Expect(len(pullSecretTrait)).To(Equal(1)) - Expect(pullSecretTrait["enabled"]).To(Equal(false)) - - pod := IntegrationPod(ns, name)() - if ocp { - // OpenShift `default` service account has imagePullSecrets so it's always set - Expect(pod.Spec.ImagePullSecrets).NotTo(BeEmpty()) - } else { - Expect(pod.Spec.ImagePullSecrets).To(BeNil()) - } - }) + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-traits-pull-secret" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + + ocp, err := openshift.IsOpenShift(TestClient(t)) + g.Expect(err).To(BeNil()) + + t.Run("Image pull secret is set on pod", func(t *testing.T) { + name := RandomizedSuffixName("java1") + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", name, "-t", "pull-secret.enabled=true", "-t", "pull-secret.secret-name=dummy-secret").Execute()).To(Succeed()) + // pod may not run because the pull secret is dummy + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Or(Equal(corev1.PodRunning), Equal(corev1.PodPending))) - if ocp { - // OpenShift always has an internal registry so image pull secret is set by default - t.Run("Image pull secret is automatically set by default", func(t *testing.T) { - name := RandomizedSuffixName("java3") - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", "--name", name).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - - pod := IntegrationPod(ns, name)() - Expect(pod.Spec.ImagePullSecrets).NotTo(BeEmpty()) - Expect(pod.Spec.ImagePullSecrets[0].Name).To(HavePrefix("default-dockercfg-")) + pod := IntegrationPod(t, ctx, ns, name)() + g.Expect(pod.Spec.ImagePullSecrets).NotTo(BeEmpty()) + g.Expect(pod.Spec.ImagePullSecrets[0].Name).To(Equal("dummy-secret")) }) - } - // Clean-up - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + t.Run("Explicitly disable image pull secret", func(t *testing.T) { + name := RandomizedSuffixName("java2") + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", name, "-t", "pull-secret.enabled=false").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + + // check integration schema does not contains unwanted default trait value. + g.Eventually(UnstructuredIntegration(t, ctx, ns, name)).ShouldNot(BeNil()) + unstructuredIntegration := UnstructuredIntegration(t, ctx, ns, name)() + pullSecretTrait, _, _ := unstructured.NestedMap(unstructuredIntegration.Object, "spec", "traits", "pull-secret") + g.Expect(pullSecretTrait).ToNot(BeNil()) + g.Expect(len(pullSecretTrait)).To(Equal(1)) + g.Expect(pullSecretTrait["enabled"]).To(Equal(false)) + + pod := IntegrationPod(t, ctx, ns, name)() + if ocp { + // OpenShift `default` service account has imagePullSecrets so it's always set + g.Expect(pod.Spec.ImagePullSecrets).NotTo(BeEmpty()) + } else { + g.Expect(pod.Spec.ImagePullSecrets).To(BeNil()) + } + }) + + if ocp { + // OpenShift always has an internal registry so image pull secret is set by default + t.Run("Image pull secret is automatically set by default", func(t *testing.T) { + name := RandomizedSuffixName("java3") + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", name).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + + pod := IntegrationPod(t, ctx, ns, name)() + g.Expect(pod.Spec.ImagePullSecrets).NotTo(BeEmpty()) + g.Expect(pod.Spec.ImagePullSecrets[0].Name).To(HavePrefix("default-dockercfg-")) + }) + } + + // Clean-up + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) } diff --git a/e2e/common/traits/route_test.go b/e2e/common/traits/route_test.go index a06b03bbbe..ce31bfa617 100644 --- a/e2e/common/traits/route_test.go +++ b/e2e/common/traits/route_test.go @@ -24,6 +24,7 @@ package traits import ( "bytes" + "context" "crypto/rand" "crypto/rsa" "crypto/tls" @@ -37,13 +38,13 @@ import ( "time" . "github.com/onsi/gomega" - "github.com/stretchr/testify/assert" - + "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" . "github.com/apache/camel-k/v2/e2e/support" + v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" "github.com/apache/camel-k/v2/pkg/util" "github.com/apache/camel-k/v2/pkg/util/openshift" ) @@ -72,158 +73,139 @@ var certPem []byte var skipClientTLSVerification = true func TestRunRoutes(t *testing.T) { - RegisterTestingT(t) - - ocp, err := openshift.IsOpenShift(TestClient()) - if !ocp { - t.Skip("This test requires route object which is available on OpenShift only.") - return - } - assert.Nil(t, err) - - operatorID := "camel-k-trait-route" - Expect(KamelInstallWithID(operatorID, ns, "--trait-profile=openshift").Execute()).To(Succeed()) - - // create a test secret of type tls with certificates - // this secret is used to setupt the route TLS object across diferent tests - secret, err := createSecret(ns) - assert.Nil(t, err) - - // they refer to the certificates create in the secret and are reused the different tests - refKey := secretName + "/" + corev1.TLSPrivateKeyKey - refCert := secretName + "/" + corev1.TLSCertKey - - // ============================= - // Insecure Route / No TLS - // ============================= - t.Run("Route unsecure http works", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "files/PlatformHttpServer.java").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, integrationName), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - route := Route(ns, integrationName) - Eventually(route, TestTimeoutMedium).ShouldNot(BeNil()) - // must wait a little time after route is created, before doing an http request, - // otherwise the route is unavailable and the http request will fail - time.Sleep(waitBeforeHttpRequest) - url := fmt.Sprintf("http://%s/hello?name=Simple", route().Spec.Host) - Eventually(httpRequest(url, false), TestTimeoutShort).Should(Equal("Hello Simple")) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).Should(BeNil()) - }) + t.Parallel() - // ============================= - // TLS Route Edge - // ============================= - t.Run("Route Edge https works", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "files/PlatformHttpServer.java", "-t", "route.tls-termination=edge").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, integrationName), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - route := Route(ns, integrationName) - Eventually(route, TestTimeoutMedium).ShouldNot(BeNil()) - // must wait a little time after route is created, before an http request, - // otherwise the route is unavailable and the http request will fail - time.Sleep(waitBeforeHttpRequest) - url := fmt.Sprintf("https://%s/hello?name=TLS_Edge", route().Spec.Host) - Eventually(httpRequest(url, true), TestTimeoutShort).Should(Equal("Hello TLS_Edge")) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).Should(BeNil()) - }) + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-traits-route" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns, "--trait-profile=openshift")).To(Succeed()) - // ============================= - // TLS Route Edge with custom certificate - // ============================= - t.Run("Route Edge (custom certificate) https works", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "files/PlatformHttpServer.java", - "-t", "route.tls-termination=edge", - "-t", "route.tls-certificate-secret="+refCert, - "-t", "route.tls-key-secret="+refKey, - ).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, integrationName), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - route := Route(ns, integrationName) - Eventually(route, TestTimeoutMedium).ShouldNot(BeNil()) - // must wait a little time after route is created, before an http request, - // otherwise the route is unavailable and the http request will fail - time.Sleep(waitBeforeHttpRequest) - code := "TLS_EdgeCustomCertificate" - url := fmt.Sprintf("https://%s/hello?name=%s", route().Spec.Host, code) - Eventually(httpRequest(url, true), TestTimeoutShort).Should(Equal("Hello " + code)) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).Should(BeNil()) - }) + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) - // ============================= - // TLS Route Passthrough - // ============================= - t.Run("Route passthrough https works", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "files/PlatformHttpServer.java", - // the --resource mounts the certificates inside secret as files in the integration pod - "--resource", "secret:"+secretName+"@/etc/ssl/"+secretName, - // quarkus platform-http uses these two properties to setup the HTTP endpoint with TLS support - "-p", "quarkus.http.ssl.certificate.file=/etc/ssl/"+secretName+"/tls.crt", - "-p", "quarkus.http.ssl.certificate.key-file=/etc/ssl/"+secretName+"/tls.key", - "-t", "route.tls-termination=passthrough", - "-t", "container.port=8443", - ).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, integrationName), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - route := Route(ns, integrationName) - Eventually(route, TestTimeoutMedium).ShouldNot(BeNil()) - // must wait a little time after route is created, before an http request, - // otherwise the route is unavailable and the http request will fail - time.Sleep(waitBeforeHttpRequest) - code := "TLS_Passthrough" - url := fmt.Sprintf("https://%s/hello?name=%s", route().Spec.Host, code) - Eventually(httpRequest(url, true), TestTimeoutShort).Should(Equal("Hello " + code)) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).Should(BeNil()) - }) - - // ============================= - // TLS Route Reencrypt - // ============================= - t.Run("Route Reencrypt https works", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "files/PlatformHttpServer.java", - // the --resource mounts the certificates inside secret as files in the integration pod - "--resource", "secret:"+secretName+"@/etc/ssl/"+secretName, - // quarkus platform-http uses these two properties to setup the HTTP endpoint with TLS support - "-p", "quarkus.http.ssl.certificate.file=/etc/ssl/"+secretName+"/tls.crt", - "-p", "quarkus.http.ssl.certificate.key-file=/etc/ssl/"+secretName+"/tls.key", - "-t", "route.tls-termination=reencrypt", - // the destination CA certificate which the route service uses to validate the HTTP endpoint TLS certificate - "-t", "route.tls-destination-ca-certificate-secret="+refCert, - "-t", "route.tls-certificate-secret="+refCert, - "-t", "route.tls-key-secret="+refKey, - "-t", "container.port=8443", - ).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, integrationName), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - - route := Route(ns, integrationName) - Eventually(route, TestTimeoutMedium).ShouldNot(BeNil()) - // must wait a little time after route is created, before an http request, - // otherwise the route is unavailable and the http request will fail - time.Sleep(waitBeforeHttpRequest) - code := "TLS_Reencrypt" - url := fmt.Sprintf("https://%s/hello?name=%s", route().Spec.Host, code) - Eventually(httpRequest(url, true), TestTimeoutShort).Should(Equal("Hello " + code)) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).Should(BeNil()) - }) - - t.Run("Route annotations added", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "files/PlatformHttpServer.java", - "-t", "route.annotations.'haproxy.router.openshift.io/balance'=roundrobin").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, integrationName), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - route := RouteFull(ns, integrationName)() - Eventually(route, TestTimeoutMedium).ShouldNot(BeNil()) - // must wait a little time after route is created, before an http request, - // otherwise the route is unavailable and the http request will fail - time.Sleep(waitBeforeHttpRequest) - var annotations = route.ObjectMeta.Annotations - Expect(annotations["haproxy.router.openshift.io/balance"]).To(Equal("roundrobin")) - - // check integration schema does not contains unwanted default trait value. - Eventually(UnstructuredIntegration(ns, integrationName)).ShouldNot(BeNil()) - unstructuredIntegration := UnstructuredIntegration(ns, integrationName)() - routeTrait, _, _ := unstructured.NestedMap(unstructuredIntegration.Object, "spec", "traits", "route") - Expect(routeTrait).ToNot(BeNil()) - Expect(len(routeTrait)).To(Equal(1)) - Expect(routeTrait["enabled"]).To(Equal(true)) - - Expect(Kamel("delete", "--all", "-n", ns).Execute()).Should(BeNil()) + ocp, err := openshift.IsOpenShift(TestClient(t)) + if !ocp { + t.Skip("This test requires route object which is available on OpenShift only.") + return + } + require.NoError(t, err) + + // create a test secret of type tls with certificates + // this secret is used to setupt the route TLS object across diferent tests + secret, err := createSecret(t, ctx, ns) + require.NoError(t, err) + + // they refer to the certificates create in the secret and are reused the different tests + refKey := secretName + "/" + corev1.TLSPrivateKeyKey + refCert := secretName + "/" + corev1.TLSCertKey + + // ============================= + // Insecure Route / No TLS + // ============================= + t.Run("Route unsecure http works", func(t *testing.T) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/PlatformHttpServer.java").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, integrationName), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + route := Route(t, ctx, ns, integrationName) + g.Eventually(route, TestTimeoutMedium).ShouldNot(BeNil()) + // must wait a little time after route is created, before doing an http request, + // otherwise the route is unavailable and the http request will fail + time.Sleep(waitBeforeHttpRequest) + url := fmt.Sprintf("http://%s/hello?name=Simple", route().Spec.Host) + g.Eventually(httpRequest(url, false), TestTimeoutShort).Should(Equal("Hello Simple")) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).Should(BeNil()) + }) + + // ============================= + // TLS Route Edge + // ============================= + t.Run("Route Edge https works", func(t *testing.T) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/PlatformHttpServer.java", "-t", "route.tls-termination=edge").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, integrationName), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + route := Route(t, ctx, ns, integrationName) + g.Eventually(route, TestTimeoutMedium).ShouldNot(BeNil()) + // must wait a little time after route is created, before an http request, + // otherwise the route is unavailable and the http request will fail + time.Sleep(waitBeforeHttpRequest) + url := fmt.Sprintf("https://%s/hello?name=TLS_Edge", route().Spec.Host) + g.Eventually(httpRequest(url, true), TestTimeoutShort).Should(Equal("Hello TLS_Edge")) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).Should(BeNil()) + }) + + // ============================= + // TLS Route Edge with custom certificate + // ============================= + t.Run("Route Edge (custom certificate) https works", func(t *testing.T) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/PlatformHttpServer.java", "-t", "route.tls-termination=edge", "-t", "route.tls-certificate-secret="+refCert, "-t", "route.tls-key-secret="+refKey).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, integrationName), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + route := Route(t, ctx, ns, integrationName) + g.Eventually(route, TestTimeoutMedium).ShouldNot(BeNil()) + // must wait a little time after route is created, before an http request, + // otherwise the route is unavailable and the http request will fail + time.Sleep(waitBeforeHttpRequest) + code := "TLS_EdgeCustomCertificate" + url := fmt.Sprintf("https://%s/hello?name=%s", route().Spec.Host, code) + g.Eventually(httpRequest(url, true), TestTimeoutShort).Should(Equal("Hello " + code)) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).Should(BeNil()) + }) + + // ============================= + // TLS Route Passthrough + // ============================= + t.Run("Route passthrough https works", func(t *testing.T) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/PlatformHttpServer.java", "--resource", "secret:"+secretName+"@/etc/ssl/"+secretName, "-p", "quarkus.http.ssl.certificate.file=/etc/ssl/"+secretName+"/tls.crt", "-p", "quarkus.http.ssl.certificate.key-file=/etc/ssl/"+secretName+"/tls.key", "-t", "route.tls-termination=passthrough", "-t", "container.port=8443").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, integrationName), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + route := Route(t, ctx, ns, integrationName) + g.Eventually(route, TestTimeoutMedium).ShouldNot(BeNil()) + // must wait a little time after route is created, before an http request, + // otherwise the route is unavailable and the http request will fail + time.Sleep(waitBeforeHttpRequest) + code := "TLS_Passthrough" + url := fmt.Sprintf("https://%s/hello?name=%s", route().Spec.Host, code) + g.Eventually(httpRequest(url, true), TestTimeoutShort).Should(Equal("Hello " + code)) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).Should(BeNil()) + }) + + // ============================= + // TLS Route Reencrypt + // ============================= + t.Run("Route Reencrypt https works", func(t *testing.T) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/PlatformHttpServer.java", "--resource", "secret:"+secretName+"@/etc/ssl/"+secretName, "-p", "quarkus.http.ssl.certificate.file=/etc/ssl/"+secretName+"/tls.crt", "-p", "quarkus.http.ssl.certificate.key-file=/etc/ssl/"+secretName+"/tls.key", "-t", "route.tls-termination=reencrypt", "-t", "route.tls-destination-ca-certificate-secret="+refCert, "-t", "route.tls-certificate-secret="+refCert, "-t", "route.tls-key-secret="+refKey, "-t", "container.port=8443").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, integrationName), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + + route := Route(t, ctx, ns, integrationName) + g.Eventually(route, TestTimeoutMedium).ShouldNot(BeNil()) + // must wait a little time after route is created, before an http request, + // otherwise the route is unavailable and the http request will fail + time.Sleep(waitBeforeHttpRequest) + code := "TLS_Reencrypt" + url := fmt.Sprintf("https://%s/hello?name=%s", route().Spec.Host, code) + g.Eventually(httpRequest(url, true), TestTimeoutShort).Should(Equal("Hello " + code)) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).Should(BeNil()) + }) + + t.Run("Route annotations added", func(t *testing.T) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/PlatformHttpServer.java", "-t", "route.annotations.'haproxy.router.openshift.io/balance'=roundrobin").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, integrationName), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + route := RouteFull(t, ctx, ns, integrationName)() + g.Eventually(route, TestTimeoutMedium).ShouldNot(BeNil()) + // must wait a little time after route is created, before an http request, + // otherwise the route is unavailable and the http request will fail + time.Sleep(waitBeforeHttpRequest) + var annotations = route.ObjectMeta.Annotations + g.Expect(annotations["haproxy.router.openshift.io/balance"]).To(Equal("roundrobin")) + + // check integration schema does not contains unwanted default trait value. + g.Eventually(UnstructuredIntegration(t, ctx, ns, integrationName)).ShouldNot(BeNil()) + unstructuredIntegration := UnstructuredIntegration(t, ctx, ns, integrationName)() + routeTrait, _, _ := unstructured.NestedMap(unstructuredIntegration.Object, "spec", "traits", "route") + g.Expect(routeTrait).ToNot(BeNil()) + g.Expect(len(routeTrait)).To(Equal(1)) + g.Expect(routeTrait["enabled"]).To(Equal(true)) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).Should(BeNil()) + }) + g.Expect(TestClient(t).Delete(ctx, &secret)).To(Succeed()) }) - Expect(TestClient().Delete(TestContext, &secret)).To(Succeed()) } func httpRequest(url string, tlsEnabled bool) func() (string, error) { @@ -274,8 +256,8 @@ func httpClient(tlsEnabled bool, timeout time.Duration) (*http.Client, error) { return &client, nil } -func createSecret(ns string) (corev1.Secret, error) { - keyCertPair := generateSampleKeyAndCertificate(ns) +func createSecret(t *testing.T, ctx context.Context, ns string) (corev1.Secret, error) { + keyCertPair := generateSampleKeyAndCertificate(t, ctx, ns) sec := corev1.Secret{ TypeMeta: metav1.TypeMeta{ Kind: "Secret", @@ -291,12 +273,12 @@ func createSecret(ns string) (corev1.Secret, error) { corev1.TLSCertKey: keyCertPair.Certificate, }, } - return sec, TestClient().Create(TestContext, &sec) + return sec, TestClient(t).Create(ctx, &sec) } -func generateSampleKeyAndCertificate(ns string) keyCertificatePair { +func generateSampleKeyAndCertificate(t *testing.T, ctx context.Context, ns string) keyCertificatePair { serialNumber := big.NewInt(util.RandomInt63()) - domainName, err := ClusterDomainName() + domainName, err := ClusterDomainName(t, ctx) if err != nil { fmt.Printf("Error retrieving cluster domain object, then the http client request will skip TLS validation: %s\n", err) skipClientTLSVerification = true diff --git a/e2e/common/traits/service_binding_test.go b/e2e/common/traits/service_binding_test.go index ae43c5f8c6..b5862d2fa5 100644 --- a/e2e/common/traits/service_binding_test.go +++ b/e2e/common/traits/service_binding_test.go @@ -23,6 +23,7 @@ limitations under the License. package traits import ( + "context" "fmt" "testing" @@ -36,73 +37,77 @@ import ( ) func TestServiceBindingTrait(t *testing.T) { - RegisterTestingT(t) - - t.Run("Integration Service Binding", func(t *testing.T) { - // Create our mock service config - host := "hostname" - port := "12324" - service := &corev1.ConfigMap{ - TypeMeta: metav1.TypeMeta{ - Kind: "ConfigMap", - APIVersion: "v1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "mock-service-config-it", - Namespace: ns, - Annotations: map[string]string{ - "service.binding/host": "path={.data.service-host}", - "service.binding/port": "path={.data.service-port}", + t.Parallel() + + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-traits-service-binding" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + + t.Run("Integration Service Binding", func(t *testing.T) { + // Create our mock service config + host := "hostname" + port := "12324" + service := &corev1.ConfigMap{ + TypeMeta: metav1.TypeMeta{ + Kind: "ConfigMap", + APIVersion: "v1", }, - }, - Data: map[string]string{ - "service-host": host, - "service-port": port, - }, - } - serviceRef := fmt.Sprintf("%s:%s/%s", service.TypeMeta.Kind, ns, service.ObjectMeta.Name) - Expect(TestClient().Create(TestContext, service)).To(Succeed()) - // Create integration and bind it to our service - name := RandomizedSuffixName("service-binding") - Expect(KamelRunWithID(operatorID, ns, "files/ServiceBinding.java", - "--name", name, - "--connect", serviceRef, - ).Execute()).To(Succeed()) - - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring(fmt.Sprintf("%s:%s", host, port))) - }) + ObjectMeta: metav1.ObjectMeta{ + Name: "mock-service-config-it", + Namespace: ns, + Annotations: map[string]string{ + "service.binding/host": "path={.data.service-host}", + "service.binding/port": "path={.data.service-port}", + }, + }, + Data: map[string]string{ + "service-host": host, + "service-port": port, + }, + } + serviceRef := fmt.Sprintf("%s:%s/%s", service.TypeMeta.Kind, ns, service.ObjectMeta.Name) + g.Expect(TestClient(t).Create(ctx, service)).To(Succeed()) + // Create integration and bind it to our service + name := RandomizedSuffixName("service-binding") + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/ServiceBinding.java", "--name", name, "--connect", serviceRef).Execute()).To(Succeed()) - t.Run("Binding Service Binding", func(t *testing.T) { - // Create our mock service config - message := "hello" - service := &corev1.ConfigMap{ - TypeMeta: metav1.TypeMeta{ - Kind: "ConfigMap", - APIVersion: "v1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "mock-service-config-kb", - Namespace: ns, - Annotations: map[string]string{ - "service.binding/message": "path={.data.message}", + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring(fmt.Sprintf("%s:%s", host, port))) + }) + + t.Run("Binding Service Binding", func(t *testing.T) { + // Create our mock service config + message := "hello" + service := &corev1.ConfigMap{ + TypeMeta: metav1.TypeMeta{ + Kind: "ConfigMap", + APIVersion: "v1", }, - }, - Data: map[string]string{ - "message": message, - }, - } - serviceRef := fmt.Sprintf("%s:%s/%s", service.TypeMeta.Kind, ns, service.ObjectMeta.Name) - Expect(TestClient().Create(TestContext, service)).To(Succeed()) - Expect(CreateTimerKamelet(ns, "my-timer-source")()).To(Succeed()) - Expect(KamelBindWithID(operatorID, ns, "my-timer-source", "log:info", - "-p", "source.message=Hello+world", - "--connect", serviceRef).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "my-timer-source-to-log"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns, "my-timer-source-to-log")).Should(ContainSubstring("Body: Hello+world")) - }) + ObjectMeta: metav1.ObjectMeta{ + Name: "mock-service-config-kb", + Namespace: ns, + Annotations: map[string]string{ + "service.binding/message": "path={.data.message}", + }, + }, + Data: map[string]string{ + "message": message, + }, + } + serviceRef := fmt.Sprintf("%s:%s/%s", service.TypeMeta.Kind, ns, service.ObjectMeta.Name) + g.Expect(TestClient(t).Create(ctx, service)).To(Succeed()) + g.Expect(CreateTimerKamelet(t, ctx, operatorID, ns, "my-timer-source")()).To(Succeed()) + g.Expect(KamelBindWithID(t, ctx, operatorID, ns, "my-timer-source", "log:info", "-p", "source.message=Hello+world", "--connect", serviceRef).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "my-timer-source-to-log"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, "my-timer-source-to-log")).Should(ContainSubstring("Body: Hello+world")) + }) - // Clean up - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + // Clean up + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) } diff --git a/e2e/common/traits/service_test.go b/e2e/common/traits/service_test.go index 8b5e5f168c..e18e23735e 100644 --- a/e2e/common/traits/service_test.go +++ b/e2e/common/traits/service_test.go @@ -23,6 +23,7 @@ limitations under the License. package traits import ( + "context" "testing" . "github.com/onsi/gomega" @@ -31,91 +32,93 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" . "github.com/apache/camel-k/v2/e2e/support" + v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" ) func TestServiceTrait(t *testing.T) { - RegisterTestingT(t) - - t.Run("NodePort service", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "files/PlatformHttpServer.java", - "-t", "service.enabled=true", - "-t", "service.node-port=true").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "platform-http-server"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - - // - // Service names can vary with the ExternalName Service - // sometimes being created first and being given the root name - // - Eventually(ServicesByType(ns, corev1.ServiceTypeNodePort), TestTimeoutLong).ShouldNot(BeEmpty()) - - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) - }) - - t.Run("Default service (ClusterIP)", func(t *testing.T) { - // Service trait is enabled by default - Expect(KamelRunWithID(operatorID, ns, "files/PlatformHttpServer.java").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "platform-http-server"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - - // - // Service names can vary with the ExternalName Service - // sometimes being created first and being given the root name - // - Eventually(ServicesByType(ns, corev1.ServiceTypeClusterIP), TestTimeoutLong).ShouldNot(BeEmpty()) - - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) - }) - - t.Run("NodePort service from Type", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "files/PlatformHttpServer.java", - "-t", "service.enabled=true", - "-t", "service.type=NodePort").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "platform-http-server"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - - // - // Service names can vary with the ExternalName Service - // sometimes being created first and being given the root name - // - Eventually(ServicesByType(ns, corev1.ServiceTypeNodePort), TestTimeoutLong).ShouldNot(BeEmpty()) - - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) - }) - - t.Run("ClusterIP service from Type", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "files/PlatformHttpServer.java", - "-t", "service.enabled=true", - "-t", "service.type=ClusterIP").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "platform-http-server"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - - // - // Service names can vary with the ExternalName Service - // sometimes being created first and being given the root name - // - Eventually(ServicesByType(ns, corev1.ServiceTypeClusterIP), TestTimeoutLong).ShouldNot(BeEmpty()) - - // check integration schema does not contains unwanted default trait value. - Eventually(UnstructuredIntegration(ns, "platform-http-server")).ShouldNot(BeNil()) - unstructuredIntegration := UnstructuredIntegration(ns, "platform-http-server")() - serviceTrait, _, _ := unstructured.NestedMap(unstructuredIntegration.Object, "spec", "traits", "service") - Expect(serviceTrait).ToNot(BeNil()) - Expect(len(serviceTrait)).To(Equal(2)) - Expect(serviceTrait["enabled"]).To(Equal(true)) - Expect(serviceTrait["type"]).To(Equal("ClusterIP")) - - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) - }) - - t.Run("LoadBalancer service from Type", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "files/PlatformHttpServer.java", - "-t", "service.enabled=true", - "-t", "service.type=LoadBalancer").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "platform-http-server"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - - // - // Service names can vary with the ExternalName Service - // sometimes being created first and being given the root name - // - Eventually(ServicesByType(ns, corev1.ServiceTypeLoadBalancer), TestTimeoutLong).ShouldNot(BeEmpty()) - - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + t.Parallel() + + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-traits-service" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + + t.Run("NodePort service", func(t *testing.T) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/PlatformHttpServer.java", "-t", "service.enabled=true", "-t", "service.node-port=true").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "platform-http-server"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + + // + // Service names can vary with the ExternalName Service + // sometimes being created first and being given the root name + // + g.Eventually(ServicesByType(t, ctx, ns, corev1.ServiceTypeNodePort), TestTimeoutLong).ShouldNot(BeEmpty()) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) + + t.Run("Default service (ClusterIP)", func(t *testing.T) { + // Service trait is enabled by default + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/PlatformHttpServer.java").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "platform-http-server"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + + // + // Service names can vary with the ExternalName Service + // sometimes being created first and being given the root name + // + g.Eventually(ServicesByType(t, ctx, ns, corev1.ServiceTypeClusterIP), TestTimeoutLong).ShouldNot(BeEmpty()) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) + + t.Run("NodePort service from Type", func(t *testing.T) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/PlatformHttpServer.java", "-t", "service.enabled=true", "-t", "service.type=NodePort").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "platform-http-server"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + + // + // Service names can vary with the ExternalName Service + // sometimes being created first and being given the root name + // + g.Eventually(ServicesByType(t, ctx, ns, corev1.ServiceTypeNodePort), TestTimeoutLong).ShouldNot(BeEmpty()) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) + + t.Run("ClusterIP service from Type", func(t *testing.T) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/PlatformHttpServer.java", "-t", "service.enabled=true", "-t", "service.type=ClusterIP").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "platform-http-server"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + + // + // Service names can vary with the ExternalName Service + // sometimes being created first and being given the root name + // + g.Eventually(ServicesByType(t, ctx, ns, corev1.ServiceTypeClusterIP), TestTimeoutLong).ShouldNot(BeEmpty()) + + // check integration schema does not contains unwanted default trait value. + g.Eventually(UnstructuredIntegration(t, ctx, ns, "platform-http-server")).ShouldNot(BeNil()) + unstructuredIntegration := UnstructuredIntegration(t, ctx, ns, "platform-http-server")() + serviceTrait, _, _ := unstructured.NestedMap(unstructuredIntegration.Object, "spec", "traits", "service") + g.Expect(serviceTrait).ToNot(BeNil()) + g.Expect(len(serviceTrait)).To(Equal(2)) + g.Expect(serviceTrait["enabled"]).To(Equal(true)) + g.Expect(serviceTrait["type"]).To(Equal("ClusterIP")) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) + + t.Run("LoadBalancer service from Type", func(t *testing.T) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/PlatformHttpServer.java", "-t", "service.enabled=true", "-t", "service.type=LoadBalancer").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "platform-http-server"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + + // + // Service names can vary with the ExternalName Service + // sometimes being created first and being given the root name + // + g.Eventually(ServicesByType(t, ctx, ns, corev1.ServiceTypeLoadBalancer), TestTimeoutLong).ShouldNot(BeEmpty()) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) }) } diff --git a/e2e/common/traits/toleration_test.go b/e2e/common/traits/toleration_test.go index 5a723785bb..98e8def887 100644 --- a/e2e/common/traits/toleration_test.go +++ b/e2e/common/traits/toleration_test.go @@ -23,6 +23,7 @@ limitations under the License. package traits import ( + "context" "testing" . "github.com/onsi/gomega" @@ -36,94 +37,87 @@ import ( ) func TestTolerationTrait(t *testing.T) { - RegisterTestingT(t) - - t.Run("Run Java with node toleration operation exists", func(t *testing.T) { - name := RandomizedSuffixName("java1") - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", - "--name", name, - "-t", "toleration.enabled=true", - "-t", "toleration.taints=camel.apache.org/master:NoExecute:300", - ).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - - pod := IntegrationPod(ns, name)() - Expect(pod.Spec.Tolerations).NotTo(BeNil()) - - Expect(pod.Spec.Tolerations).To(ContainElement(corev1.Toleration{ - Key: "camel.apache.org/master", - Operator: corev1.TolerationOpExists, - Effect: corev1.TaintEffectNoExecute, - TolerationSeconds: pointer.Int64(300), - })) - }) - - t.Run("Run Java with node toleration operation equals", func(t *testing.T) { - name := RandomizedSuffixName("java2") - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", - "--name", name, - "-t", "toleration.enabled=true", - "-t", "toleration.taints=camel.apache.org/master=test:NoExecute:300", - ).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - - pod := IntegrationPod(ns, name)() - Expect(pod.Spec.Tolerations).NotTo(BeNil()) - - Expect(pod.Spec.Tolerations).To(ContainElement(corev1.Toleration{ - Key: "camel.apache.org/master", - Operator: corev1.TolerationOpEqual, - Value: "test", Effect: corev1.TaintEffectNoExecute, - TolerationSeconds: pointer.Int64(300), - })) - }) - - t.Run("Run Java with master node toleration", func(t *testing.T) { - if len(Nodes()()) == 1 { - t.Skip("Skip master node toleration test on single-node cluster") - } - - name := RandomizedSuffixName("java3") - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", - "--name", name, - // Use the affinity trait to force the scheduling of the Integration pod onto a master node - "-t", "affinity.enabled=true", - "-t", "affinity.node-affinity-labels=node-role.kubernetes.io/master", - // And tolerate the corresponding taint - "-t", "toleration.enabled=true", - "-t", "toleration.taints=node-role.kubernetes.io/master:NoSchedule", - ).Execute()).To(Succeed()) - - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - - pod := IntegrationPod(ns, name)() - Expect(pod).NotTo(BeNil()) - - // Check the Integration pod contains the toleration - Expect(pod.Spec.Tolerations).To(ContainElement(corev1.Toleration{ - Key: "node-role.kubernetes.io/master", - Operator: corev1.TolerationOpExists, - Effect: corev1.TaintEffectNoSchedule, - })) - - // Check the Integration pod is running on a master node - Expect(Node(pod.Spec.NodeName)()).NotTo(BeNil()) - Expect(Node(pod.Spec.NodeName)()).To(PointTo(MatchFields(IgnoreExtras, Fields{ - "Spec": MatchFields(IgnoreExtras, Fields{ - "Taints": ContainElement(corev1.Taint{ - Key: "node-role.kubernetes.io/master", - Effect: corev1.TaintEffectNoSchedule, + t.Parallel() + + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + operatorID := "camel-k-traits-toleration" + g.Expect(CopyCamelCatalog(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(CopyIntegrationKits(t, ctx, ns, operatorID)).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + + t.Run("Run Java with node toleration operation exists", func(t *testing.T) { + name := RandomizedSuffixName("java1") + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", name, "-t", "toleration.enabled=true", "-t", "toleration.taints=camel.apache.org/master:NoExecute:300").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + + pod := IntegrationPod(t, ctx, ns, name)() + g.Expect(pod.Spec.Tolerations).NotTo(BeNil()) + + g.Expect(pod.Spec.Tolerations).To(ContainElement(corev1.Toleration{ + Key: "camel.apache.org/master", + Operator: corev1.TolerationOpExists, + Effect: corev1.TaintEffectNoExecute, + TolerationSeconds: pointer.Int64(300), + })) + }) + + t.Run("Run Java with node toleration operation equals", func(t *testing.T) { + name := RandomizedSuffixName("java2") + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", name, "-t", "toleration.enabled=true", "-t", "toleration.taints=camel.apache.org/master=test:NoExecute:300").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + + pod := IntegrationPod(t, ctx, ns, name)() + g.Expect(pod.Spec.Tolerations).NotTo(BeNil()) + + g.Expect(pod.Spec.Tolerations).To(ContainElement(corev1.Toleration{ + Key: "camel.apache.org/master", + Operator: corev1.TolerationOpEqual, + Value: "test", Effect: corev1.TaintEffectNoExecute, + TolerationSeconds: pointer.Int64(300), + })) + }) + + t.Run("Run Java with master node toleration", func(t *testing.T) { + if len(Nodes(t, ctx)()) == 1 { + t.Skip("Skip master node toleration test on single-node cluster") + } + + name := RandomizedSuffixName("java3") + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", name, "-t", "affinity.enabled=true", "-t", "affinity.node-affinity-labels=node-role.kubernetes.io/master", "-t", "toleration.enabled=true", "-t", "toleration.taints=node-role.kubernetes.io/master:NoSchedule").Execute()).To(Succeed()) + + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + + pod := IntegrationPod(t, ctx, ns, name)() + g.Expect(pod).NotTo(BeNil()) + + // Check the Integration pod contains the toleration + g.Expect(pod.Spec.Tolerations).To(ContainElement(corev1.Toleration{ + Key: "node-role.kubernetes.io/master", + Operator: corev1.TolerationOpExists, + Effect: corev1.TaintEffectNoSchedule, + })) + + // Check the Integration pod is running on a master node + g.Expect(Node(t, ctx, pod.Spec.NodeName)()).NotTo(BeNil()) + g.Expect(Node(t, ctx, pod.Spec.NodeName)()).To(PointTo(MatchFields(IgnoreExtras, Fields{ + "Spec": MatchFields(IgnoreExtras, Fields{ + "Taints": ContainElement(corev1.Taint{ + Key: "node-role.kubernetes.io/master", + Effect: corev1.TaintEffectNoSchedule, + }), }), - }), - }))) - }) + }))) + }) - // Clean up - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + // Clean up + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) } diff --git a/e2e/install/cli/global_kamelet_test.go b/e2e/install/cli/global_kamelet_test.go index 62fe111341..40a17645a8 100644 --- a/e2e/install/cli/global_kamelet_test.go +++ b/e2e/install/cli/global_kamelet_test.go @@ -23,6 +23,7 @@ limitations under the License. package cli import ( + "context" "testing" . "github.com/onsi/gomega" @@ -32,42 +33,42 @@ import ( ) func TestRunGlobalKamelet(t *testing.T) { - WithGlobalOperatorNamespace(t, func(operatorNamespace string) { + WithGlobalOperatorNamespace(t, func(ctx context.Context, g *WithT, operatorNamespace string) { operatorID := "camel-k-global-kamelet" - Expect(KamelInstallWithID(operatorID, operatorNamespace, "--global", "--force").Execute()).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, operatorNamespace, "--global", "--force")).To(Succeed()) t.Run("Global operator + namespaced kamelet test", func(t *testing.T) { // NS2: namespace without operator - WithNewTestNamespace(t, func(ns2 string) { - Expect(CreateTimerKamelet(ns2, "my-own-timer-source")()).To(Succeed()) + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns2 string) { + g.Expect(CreateTimerKamelet(t, ctx, operatorID, ns2, "my-own-timer-source")()).To(Succeed()) - Expect(KamelInstallWithID(operatorID, ns2, "--skip-operator-setup", "--olm=false").Execute()).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns2, "--skip-operator-setup", "--olm=false")).To(Succeed()) - Expect(KamelRunWithID(operatorID, ns2, "files/timer-kamelet-usage.groovy").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns2, "timer-kamelet-usage"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns2, "timer-kamelet-usage"), TestTimeoutShort).Should(ContainSubstring("Hello world")) - Expect(Kamel("delete", "--all", "-n", ns2).Execute()).To(Succeed()) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns2, "files/timer-kamelet-usage.groovy").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns2, "timer-kamelet-usage"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns2, "timer-kamelet-usage"), TestTimeoutShort).Should(ContainSubstring("Hello world")) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns2).Execute()).To(Succeed()) }) }) t.Run("Global operator + global kamelet test", func(t *testing.T) { - Expect(CreateTimerKamelet(operatorNamespace, "my-own-timer-source")()).To(Succeed()) + g.Expect(CreateTimerKamelet(t, ctx, operatorID, operatorNamespace, "my-own-timer-source")()).To(Succeed()) // NS3: namespace without operator - WithNewTestNamespace(t, func(ns3 string) { - Expect(KamelInstallWithID(operatorID, ns3, "--skip-operator-setup", "--olm=false").Execute()).To(Succeed()) - - Expect(KamelRunWithID(operatorID, ns3, "files/timer-kamelet-usage.groovy").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns3, "timer-kamelet-usage"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns3, "timer-kamelet-usage"), TestTimeoutShort).Should(ContainSubstring("Hello world")) - Expect(Kamel("delete", "--all", "-n", ns3).Execute()).To(Succeed()) - Expect(TestClient().Delete(TestContext, Kamelet("my-own-timer-source", operatorNamespace)())).To(Succeed()) + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns3 string) { + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns3, "--skip-operator-setup", "--olm=false")).To(Succeed()) + + g.Expect(KamelRunWithID(t, ctx, operatorID, ns3, "files/timer-kamelet-usage.groovy").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns3, "timer-kamelet-usage"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns3, "timer-kamelet-usage"), TestTimeoutShort).Should(ContainSubstring("Hello world")) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns3).Execute()).To(Succeed()) + g.Expect(TestClient(t).Delete(ctx, Kamelet(t, ctx, "my-own-timer-source", operatorNamespace)())).To(Succeed()) }) }) - Expect(Kamel("uninstall", "-n", operatorNamespace, "--skip-crd", "--skip-cluster-roles=false", "--skip-cluster-role-bindings=false").Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "uninstall", "-n", operatorNamespace, "--skip-crd", "--skip-cluster-roles=false", "--skip-cluster-role-bindings=false").Execute()).To(Succeed()) }) } diff --git a/e2e/install/cli/global_test.go b/e2e/install/cli/global_test.go index 8ec5e60e27..436c92e63f 100644 --- a/e2e/install/cli/global_test.go +++ b/e2e/install/cli/global_test.go @@ -23,6 +23,7 @@ limitations under the License. package cli import ( + "context" "fmt" "strings" "testing" @@ -40,91 +41,89 @@ import ( ) func TestRunGlobalInstall(t *testing.T) { - RegisterTestingT(t) - - WithGlobalOperatorNamespace(t, func(operatorNamespace string) { - Expect(KamelInstall(operatorNamespace, "--global", "--force").Execute()).To(Succeed()) - Eventually(OperatorPodPhase(operatorNamespace), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) + WithGlobalOperatorNamespace(t, func(ctx context.Context, g *WithT, operatorNamespace string) { + g.Expect(KamelInstall(t, ctx, operatorNamespace, "--global", "--force")).To(Succeed()) + g.Eventually(OperatorPodPhase(t, ctx, operatorNamespace), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) t.Run("Global CamelCatalog reconciliation", func(t *testing.T) { - Eventually(Platform(operatorNamespace)).ShouldNot(BeNil()) - Eventually(PlatformConditionStatus(operatorNamespace, v1.IntegrationPlatformConditionTypeCreated), TestTimeoutShort). + g.Eventually(Platform(t, ctx, operatorNamespace)).ShouldNot(BeNil()) + g.Eventually(PlatformConditionStatus(t, ctx, operatorNamespace, v1.IntegrationPlatformConditionTypeCreated), TestTimeoutShort). Should(Equal(corev1.ConditionTrue)) catalogName := fmt.Sprintf("camel-catalog-%s", strings.ToLower(defaults.DefaultRuntimeVersion)) - Eventually(CamelCatalog(operatorNamespace, catalogName)).ShouldNot(BeNil()) - Eventually(CamelCatalogPhase(operatorNamespace, catalogName), TestTimeoutMedium).Should(Equal(v1.CamelCatalogPhaseReady)) + g.Eventually(CamelCatalog(t, ctx, operatorNamespace, catalogName)).ShouldNot(BeNil()) + g.Eventually(CamelCatalogPhase(t, ctx, operatorNamespace, catalogName), TestTimeoutMedium).Should(Equal(v1.CamelCatalogPhaseReady)) }) t.Run("Global test on namespace with platform", func(t *testing.T) { - WithNewTestNamespace(t, func(ns2 string) { + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns2 string) { // Creating namespace local platform - Expect(KamelInstall(ns2, "--skip-operator-setup", "--olm=false").Execute()).To(Succeed()) - Eventually(Platform(ns2)).ShouldNot(BeNil()) + g.Expect(KamelInstall(t, ctx, ns2, "--skip-operator-setup", "--olm=false")).To(Succeed()) + g.Eventually(Platform(t, ctx, ns2)).ShouldNot(BeNil()) // Run with global operator id - Expect(KamelRun(ns2, "files/Java.java").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns2, "java"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns2, "java"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - Expect(IntegrationConditionMessage(IntegrationCondition(ns2, "java", v1.IntegrationConditionPlatformAvailable)())).To(MatchRegexp(ns2 + "\\/.*")) - kit := IntegrationKit(ns2, "java")() - Expect(Kamel("delete", "--all", "-n", ns2).Execute()).To(Succeed()) - Expect(Kits(ns2)()).Should(WithTransform(integrationKitsToNamesTransform(), ContainElement(kit))) - Expect(Kits(operatorNamespace)()).Should(WithTransform(integrationKitsToNamesTransform(), Not(ContainElement(kit)))) - - Expect(Lease(ns2, platform.DefaultPlatformName)()).To(BeNil(), "No locking Leases expected") + g.Expect(KamelRun(t, ctx, ns2, "files/Java.java").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns2, "java"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns2, "java"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + g.Expect(IntegrationConditionMessage(IntegrationCondition(t, ctx, ns2, "java", v1.IntegrationConditionPlatformAvailable)())).To(MatchRegexp(ns2 + "\\/.*")) + kit := IntegrationKit(t, ctx, ns2, "java")() + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns2).Execute()).To(Succeed()) + g.Expect(Kits(t, ctx, ns2)()).Should(WithTransform(integrationKitsToNamesTransform(), ContainElement(kit))) + g.Expect(Kits(t, ctx, operatorNamespace)()).Should(WithTransform(integrationKitsToNamesTransform(), Not(ContainElement(kit)))) + + g.Expect(Lease(t, ctx, ns2, platform.DefaultPlatformName)()).To(BeNil(), "No locking Leases expected") }) }) t.Run("Global test on namespace with its own operator", func(t *testing.T) { - WithNewTestNamespace(t, func(ns3 string) { + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns3 string) { operatorID := "camel-k-local-ns3" if NoOlmOperatorImage != "" { - Expect(KamelInstallWithID(operatorID, ns3, "--olm=false", "--operator-image", NoOlmOperatorImage).Execute()).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns3, "--olm=false", "--operator-image", NoOlmOperatorImage)).To(Succeed()) } else { - Expect(KamelInstallWithID(operatorID, ns3, "--olm=false").Execute()).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns3, "--olm=false")).To(Succeed()) } - Eventually(OperatorPodPhase(ns3), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) - Expect(KamelRunWithID(operatorID, ns3, "files/Java.java").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns3, "java"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns3, "java"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - Expect(IntegrationConditionMessage(IntegrationCondition(ns3, "java", v1.IntegrationConditionPlatformAvailable)())).To(MatchRegexp(ns3 + "\\/.*")) - kit := IntegrationKit(ns3, "java")() - Expect(Kits(ns3)()).Should(WithTransform(integrationKitsToNamesTransform(), ContainElement(kit))) - Expect(Kamel("delete", "--all", "-n", ns3).Execute()).To(Succeed()) - - Expect(Lease(ns3, platform.OperatorLockName)()).To(BeNil(), "No locking Leases expected") - Expect(Lease(ns3, platform.GetOperatorLockName(operatorID))()).ShouldNot(BeNil(), + g.Eventually(OperatorPodPhase(t, ctx, ns3), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns3, "files/Java.java").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns3, "java"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns3, "java"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + g.Expect(IntegrationConditionMessage(IntegrationCondition(t, ctx, ns3, "java", v1.IntegrationConditionPlatformAvailable)())).To(MatchRegexp(ns3 + "\\/.*")) + kit := IntegrationKit(t, ctx, ns3, "java")() + g.Expect(Kits(t, ctx, ns3)()).Should(WithTransform(integrationKitsToNamesTransform(), ContainElement(kit))) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns3).Execute()).To(Succeed()) + + g.Expect(Lease(t, ctx, ns3, platform.OperatorLockName)()).To(BeNil(), "No locking Leases expected") + g.Expect(Lease(t, ctx, ns3, platform.GetOperatorLockName(operatorID))()).ShouldNot(BeNil(), "Controller Runtime is expected to use Leases for leader election: if this changes we should update our locking logic", ) }) }) t.Run("Global test on namespace without platform", func(t *testing.T) { - WithNewTestNamespace(t, func(ns4 string) { - Expect(KamelRun(ns4, "files/Java.java").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns4, "java"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns4, "java"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - Expect(IntegrationConditionMessage(IntegrationCondition(ns4, "java", v1.IntegrationConditionPlatformAvailable)())).To(MatchRegexp(operatorNamespace + "\\/.*")) - kit := IntegrationKit(ns4, "java")() - Expect(Kamel("delete", "--all", "-n", ns4).Execute()).To(Succeed()) - Expect(Kits(ns4)()).Should(WithTransform(integrationKitsToNamesTransform(), Not(ContainElement(kit)))) - Expect(Kits(operatorNamespace)()).Should(WithTransform(integrationKitsToNamesTransform(), ContainElement(kit))) // Kit built globally - - Expect(Lease(ns4, platform.OperatorLockName)()).To(BeNil(), "No locking Leases expected") + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns4 string) { + g.Expect(KamelRun(t, ctx, ns4, "files/Java.java").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns4, "java"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns4, "java"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + g.Expect(IntegrationConditionMessage(IntegrationCondition(t, ctx, ns4, "java", v1.IntegrationConditionPlatformAvailable)())).To(MatchRegexp(operatorNamespace + "\\/.*")) + kit := IntegrationKit(t, ctx, ns4, "java")() + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns4).Execute()).To(Succeed()) + g.Expect(Kits(t, ctx, ns4)()).Should(WithTransform(integrationKitsToNamesTransform(), Not(ContainElement(kit)))) + g.Expect(Kits(t, ctx, operatorNamespace)()).Should(WithTransform(integrationKitsToNamesTransform(), ContainElement(kit))) // Kit built globally + + g.Expect(Lease(t, ctx, ns4, platform.OperatorLockName)()).To(BeNil(), "No locking Leases expected") }) }) t.Run("Global test on namespace without platform with external kit", func(t *testing.T) { - WithNewTestNamespace(t, func(ns5 string) { - Expect(KamelRun(ns5, "files/Java.java").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns5, "java"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns5, "java"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - Expect(IntegrationConditionMessage(IntegrationCondition(ns5, "java", v1.IntegrationConditionPlatformAvailable)())).To(MatchRegexp(operatorNamespace + "\\/.*")) - kit := IntegrationKit(ns5, "java")() - Expect(Kamel("delete", "--all", "-n", ns5).Execute()).To(Succeed()) - Expect(Kits(ns5)()).Should(WithTransform(integrationKitsToNamesTransform(), Not(ContainElement(kit)))) - globalKits := Kits(operatorNamespace)() - Expect(globalKits).Should(WithTransform(integrationKitsToNamesTransform(), ContainElement(kit))) // Reusing the same global kit + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns5 string) { + g.Expect(KamelRun(t, ctx, ns5, "files/Java.java").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns5, "java"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns5, "java"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + g.Expect(IntegrationConditionMessage(IntegrationCondition(t, ctx, ns5, "java", v1.IntegrationConditionPlatformAvailable)())).To(MatchRegexp(operatorNamespace + "\\/.*")) + kit := IntegrationKit(t, ctx, ns5, "java")() + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns5).Execute()).To(Succeed()) + g.Expect(Kits(t, ctx, ns5)()).Should(WithTransform(integrationKitsToNamesTransform(), Not(ContainElement(kit)))) + globalKits := Kits(t, ctx, operatorNamespace)() + g.Expect(globalKits).Should(WithTransform(integrationKitsToNamesTransform(), ContainElement(kit))) // Reusing the same global kit // external kit mirroring the global one externalKit := v1.IntegrationKit{ @@ -136,24 +135,24 @@ func TestRunGlobalInstall(t *testing.T) { }, }, Spec: v1.IntegrationKitSpec{ - Image: getKitImage(operatorNamespace, kit), + Image: getKitImage(t, ctx, operatorNamespace, kit), }, } - Expect(TestClient().Create(TestContext, &externalKit)).Should(BeNil()) + g.Expect(TestClient(t).Create(ctx, &externalKit)).Should(BeNil()) - Expect(KamelRun(ns5, "files/Java.java", "--name", "ext", "--kit", "external", "-t", "jvm.enabled=true").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns5, "ext"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns5, "ext"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - Expect(IntegrationKit(ns5, "ext")()).Should(Equal("external")) - Expect(Kamel("delete", "--all", "-n", ns5).Execute()).To(Succeed()) - Expect(Kits(ns5)()).Should(WithTransform(integrationKitsToNamesTransform(), ContainElement("external"))) // the external one - Expect(Kits(operatorNamespace)()).Should(WithTransform(integrationKitsToNamesTransform(), ContainElement(kit))) // the global one + g.Expect(KamelRun(t, ctx, ns5, "files/Java.java", "--name", "ext", "--kit", "external", "-t", "jvm.enabled=true").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns5, "ext"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns5, "ext"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + g.Expect(IntegrationKit(t, ctx, ns5, "ext")()).Should(Equal("external")) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns5).Execute()).To(Succeed()) + g.Expect(Kits(t, ctx, ns5)()).Should(WithTransform(integrationKitsToNamesTransform(), ContainElement("external"))) // the external one + g.Expect(Kits(t, ctx, operatorNamespace)()).Should(WithTransform(integrationKitsToNamesTransform(), ContainElement(kit))) // the global one - Expect(Lease(ns5, platform.OperatorLockName)()).To(BeNil(), "No locking Leases expected") + g.Expect(Lease(t, ctx, ns5, platform.OperatorLockName)()).To(BeNil(), "No locking Leases expected") }) }) - Expect(Kamel("uninstall", "-n", operatorNamespace, "--skip-crd", "--skip-cluster-roles").Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "uninstall", "-n", operatorNamespace, "--skip-crd", "--skip-cluster-roles").Execute()).To(Succeed()) }) } @@ -167,7 +166,7 @@ func integrationKitsToNamesTransform() func([]v1.IntegrationKit) []string { } } -func getKitImage(ns string, name string) string { +func getKitImage(t *testing.T, ctx context.Context, ns string, name string) string { get := v1.IntegrationKit{ TypeMeta: metav1.TypeMeta{ Kind: "IntegrationKit", @@ -182,7 +181,7 @@ func getKitImage(ns string, name string) string { Namespace: ns, Name: name, } - if err := TestClient().Get(TestContext, key, &get); err != nil { + if err := TestClient(t).Get(ctx, key, &get); err != nil { return "" } return get.Status.Image diff --git a/e2e/install/cli/install_test.go b/e2e/install/cli/install_test.go index f5d8780caa..ff6bfaaf67 100644 --- a/e2e/install/cli/install_test.go +++ b/e2e/install/cli/install_test.go @@ -24,6 +24,7 @@ package cli import ( "bytes" + "context" "fmt" "os" "reflect" @@ -32,7 +33,7 @@ import ( "text/template" . "github.com/onsi/gomega" - "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" "k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/tools/remotecommand" @@ -47,40 +48,40 @@ import ( ) func TestBasicInstallation(t *testing.T) { - WithNewTestNamespace(t, func(ns string) { + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { operatorID := fmt.Sprintf("camel-k-%s", ns) - Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed()) - Eventually(OperatorPod(ns)).ShouldNot(BeNil()) - Eventually(Platform(ns)).ShouldNot(BeNil()) - Eventually(PlatformConditionStatus(ns, v1.IntegrationPlatformConditionTypeCreated), TestTimeoutShort). + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + g.Eventually(OperatorPod(t, ctx, ns)).ShouldNot(BeNil()) + g.Eventually(Platform(t, ctx, ns)).ShouldNot(BeNil()) + g.Eventually(PlatformConditionStatus(t, ctx, ns, v1.IntegrationPlatformConditionTypeCreated), TestTimeoutShort). Should(Equal(corev1.ConditionTrue)) // Check if restricted security context has been applyed - operatorPod := OperatorPod(ns)() - Expect(operatorPod.Spec.Containers[0].SecurityContext.RunAsNonRoot).To(Equal(kubernetes.DefaultOperatorSecurityContext().RunAsNonRoot)) - Expect(operatorPod.Spec.Containers[0].SecurityContext.Capabilities).To(Equal(kubernetes.DefaultOperatorSecurityContext().Capabilities)) - Expect(operatorPod.Spec.Containers[0].SecurityContext.SeccompProfile).To(Equal(kubernetes.DefaultOperatorSecurityContext().SeccompProfile)) - Expect(operatorPod.Spec.Containers[0].SecurityContext.AllowPrivilegeEscalation).To(Equal(kubernetes.DefaultOperatorSecurityContext().AllowPrivilegeEscalation)) + operatorPod := OperatorPod(t, ctx, ns)() + g.Expect(operatorPod.Spec.Containers[0].SecurityContext.RunAsNonRoot).To(Equal(kubernetes.DefaultOperatorSecurityContext().RunAsNonRoot)) + g.Expect(operatorPod.Spec.Containers[0].SecurityContext.Capabilities).To(Equal(kubernetes.DefaultOperatorSecurityContext().Capabilities)) + g.Expect(operatorPod.Spec.Containers[0].SecurityContext.SeccompProfile).To(Equal(kubernetes.DefaultOperatorSecurityContext().SeccompProfile)) + g.Expect(operatorPod.Spec.Containers[0].SecurityContext.AllowPrivilegeEscalation).To(Equal(kubernetes.DefaultOperatorSecurityContext().AllowPrivilegeEscalation)) t.Run("run yaml", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "files/yaml.yaml").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "yaml"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "yaml", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "yaml"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/yaml.yaml").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "yaml"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "yaml", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "yaml"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) // Check if file exists in operator pod - Expect(OperatorPod(ns)().Name).NotTo(Equal("")) - Expect(OperatorPod(ns)().Spec.Containers[0].Name).NotTo(Equal("")) + g.Expect(OperatorPod(t, ctx, ns)().Name).NotTo(Equal("")) + g.Expect(OperatorPod(t, ctx, ns)().Spec.Containers[0].Name).NotTo(Equal("")) - req := TestClient().CoreV1().RESTClient().Post(). + req := TestClient(t).CoreV1().RESTClient().Post(). Resource("pods"). - Name(OperatorPod(ns)().Name). + Name(OperatorPod(t, ctx, ns)().Name). Namespace(ns). SubResource("exec"). - Param("container", OperatorPod(ns)().Spec.Containers[0].Name) + Param("container", OperatorPod(t, ctx, ns)().Spec.Containers[0].Name) req.VersionedParams(&corev1.PodExecOptions{ - Container: OperatorPod(ns)().Spec.Containers[0].Name, + Container: OperatorPod(t, ctx, ns)().Spec.Containers[0].Name, Command: []string{"test", "-e", defaults.LocalRepository + "/org/apache/camel/k"}, Stdin: false, Stdout: true, @@ -88,8 +89,8 @@ func TestBasicInstallation(t *testing.T) { TTY: false, }, scheme.ParameterCodec) - exec, err := remotecommand.NewSPDYExecutor(TestClient().GetConfig(), "POST", req.URL()) - Expect(err).To(BeNil()) + exec, err := remotecommand.NewSPDYExecutor(TestClient(t).GetConfig(), "POST", req.URL()) + g.Expect(err).To(BeNil()) // returns an error if file does not exists execErr := exec.Stream(remotecommand.StreamOptions{ @@ -97,39 +98,39 @@ func TestBasicInstallation(t *testing.T) { Stderr: os.Stderr, Tty: false, }) - Expect(execErr).To(BeNil()) + g.Expect(execErr).To(BeNil()) }) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) } func TestAlternativeImageInstallation(t *testing.T) { - WithNewTestNamespace(t, func(ns string) { + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { operatorID := fmt.Sprintf("camel-k-%s", ns) - Expect(KamelInstallWithID(operatorID, ns, "--olm=false", "--operator-image", "x/y:latest").Execute()).To(Succeed()) - Eventually(OperatorImage(ns)).Should(Equal("x/y:latest")) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns, "--olm=false", "--operator-image", "x/y:latest")).To(Succeed()) + g.Eventually(OperatorImage(t, ctx, ns)).Should(Equal("x/y:latest")) }) } func TestKitMainInstallation(t *testing.T) { - WithNewTestNamespace(t, func(ns string) { + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { operatorID := fmt.Sprintf("camel-k-%s", ns) - Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed()) - Expect(Kamel("kit", "create", "timer", "-d", "camel:timer", "-x", operatorID, "-n", ns).Execute()).To(Succeed()) - Eventually(Build(ns, "timer"), TestTimeoutMedium).ShouldNot(BeNil()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + g.Expect(Kamel(t, ctx, "kit", "create", "timer", "-d", "camel:timer", "-x", operatorID, "-n", ns).Execute()).To(Succeed()) + g.Eventually(Build(t, ctx, ns, "timer"), TestTimeoutMedium).ShouldNot(BeNil()) }) } func TestMavenRepositoryInstallation(t *testing.T) { - WithNewTestNamespace(t, func(ns string) { + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { operatorID := fmt.Sprintf("camel-k-%s", ns) - Expect(KamelInstallWithID(operatorID, ns, "--maven-repository", "https://my.repo.org/public/").Execute()).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns, "--maven-repository", "https://my.repo.org/public/")).To(Succeed()) configmapName := fmt.Sprintf("%s-maven-settings", operatorID) - Eventually(Configmap(ns, configmapName)).Should(Not(BeNil())) - Eventually(func() string { - return Configmap(ns, configmapName)().Data["settings.xml"] + g.Eventually(Configmap(t, ctx, ns, configmapName)).Should(Not(BeNil())) + g.Eventually(func() string { + return Configmap(t, ctx, ns, configmapName)().Data["settings.xml"] }).Should(ContainSubstring("https://my.repo.org/public/")) }) } @@ -139,12 +140,12 @@ func TestMavenRepositoryInstallation(t *testing.T) { * so the Platform will have an empty Registry structure */ func TestSkipRegistryInstallation(t *testing.T) { - WithNewTestNamespace(t, func(ns string) { + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { operatorID := fmt.Sprintf("camel-k-%s", ns) - Expect(KamelInstallWithID(operatorID, ns, "--skip-registry-setup").Execute()).To(Succeed()) - Eventually(Platform(ns)).ShouldNot(BeNil()) - Eventually(func() v1.RegistrySpec { - return Platform(ns)().Spec.Build.Registry + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns, "--skip-registry-setup")).To(Succeed()) + g.Eventually(Platform(t, ctx, ns)).ShouldNot(BeNil()) + g.Eventually(func() v1.RegistrySpec { + return Platform(t, ctx, ns)().Spec.Build.Registry }, TestTimeoutMedium).Should(Equal(v1.RegistrySpec{})) }) } @@ -155,11 +156,11 @@ type templateArgs struct { } func TestConsoleCliDownload(t *testing.T) { - ocp, err := openshift.IsOpenShift(TestClient()) - assert.Nil(t, err) + ocp, err := openshift.IsOpenShift(TestClient(t)) + require.NoError(t, err) - ok, err := kubernetes.IsAPIResourceInstalled(TestClient(), "console.openshift.io/v1", reflect.TypeOf(consolev1.ConsoleCLIDownload{}).Name()) - assert.Nil(t, err) + ok, err := kubernetes.IsAPIResourceInstalled(TestClient(t), "console.openshift.io/v1", reflect.TypeOf(consolev1.ConsoleCLIDownload{}).Name()) + require.NoError(t, err) if !ocp || !ok { t.Skip("This test requires ConsoleCliDownload object which is available on OpenShift 4+ only.") @@ -171,20 +172,20 @@ func TestConsoleCliDownload(t *testing.T) { args := templateArgs{Version: defaults.Version} templt, err := template.New("downloadLink").Parse(downloadUrlTemplate) - assert.Nil(t, err) + require.NoError(t, err) - WithNewTestNamespace(t, func(ns string) { + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { // make sure there is no preinstalled CliDownload resource - cliDownload := ConsoleCLIDownload(name)() + cliDownload := ConsoleCLIDownload(t, ctx, name)() if cliDownload != nil { - Expect(TestClient().Delete(TestContext, cliDownload)).To(Succeed()) + g.Expect(TestClient(t).Delete(ctx, cliDownload)).To(Succeed()) } operatorID := fmt.Sprintf("camel-k-%s", ns) - Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed()) - Eventually(ConsoleCLIDownload(name), TestTimeoutMedium).Should(Not(BeNil())) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + g.Eventually(ConsoleCLIDownload(t, ctx, name), TestTimeoutMedium).Should(Not(BeNil())) - cliDownload = ConsoleCLIDownload(name)() + cliDownload = ConsoleCLIDownload(t, ctx, name)() links := cliDownload.Spec.Links for _, link := range links { @@ -198,25 +199,25 @@ func TestConsoleCliDownload(t *testing.T) { } templt.Execute(&buf, args) - Expect(link.Href).To(MatchRegexp(buf.String())) + g.Expect(link.Href).To(MatchRegexp(buf.String())) } }) } func TestInstallSkipDefaultKameletsInstallation(t *testing.T) { - WithNewTestNamespace(t, func(ns string) { + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { operatorID := fmt.Sprintf("camel-k-%s", ns) - Expect(KamelInstallWithIDAndKameletCatalog(operatorID, ns, "--skip-default-kamelets-setup").Execute()).To(Succeed()) - Eventually(OperatorPod(ns)).ShouldNot(BeNil()) - Expect(KameletList(ns)()).Should(BeEmpty()) + g.Expect(KamelInstallWithIDAndKameletCatalog(t, ctx, operatorID, ns, "--skip-default-kamelets-setup")).To(Succeed()) + g.Eventually(OperatorPod(t, ctx, ns)).ShouldNot(BeNil()) + g.Expect(KameletList(t, ctx, ns)()).Should(BeEmpty()) }) } func TestInstallDebugLogging(t *testing.T) { - WithNewTestNamespace(t, func(ns string) { + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { operatorID := fmt.Sprintf("camel-k-%s", ns) - Expect(KamelInstallWithID(operatorID, ns, "-z", "debug").Execute()).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns, "-z", "debug")).To(Succeed()) - Eventually(OperatorEnvVarValue(ns, "LOG_LEVEL"), TestTimeoutLong).Should(Equal("debug")) + g.Eventually(OperatorEnvVarValue(t, ctx, ns, "LOG_LEVEL"), TestTimeoutLong).Should(Equal("debug")) }) } diff --git a/e2e/install/cli/maven_ca_secret_test.go b/e2e/install/cli/maven_ca_secret_test.go index b23f78e1d8..fceb53c3ee 100644 --- a/e2e/install/cli/maven_ca_secret_test.go +++ b/e2e/install/cli/maven_ca_secret_test.go @@ -25,6 +25,7 @@ package cli import ( "bufio" "bytes" + "context" "crypto/rand" "crypto/rsa" "crypto/x509" @@ -56,7 +57,7 @@ import ( ) func TestMavenCASecret(t *testing.T) { - WithNewTestNamespace(t, func(ns string) { + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { hostname := fmt.Sprintf("%s.%s.svc", "nexus", ns) tlsMountPath := "/etc/tls/private" @@ -77,7 +78,7 @@ func TestMavenCASecret(t *testing.T) { // generate certPem private key certPrivateKey, err := rsa.GenerateKey(rand.Reader, 2048) - Expect(err).To(BeNil()) + g.Expect(err).To(BeNil()) privateKeyBytes := x509.MarshalPKCS1PrivateKey(certPrivateKey) // encode for storing into secret @@ -88,7 +89,7 @@ func TestMavenCASecret(t *testing.T) { }, ) certBytes, err := x509.CreateCertificate(rand.Reader, cert, cert, &certPrivateKey.PublicKey, certPrivateKey) - Expect(err).To(BeNil()) + g.Expect(err).To(BeNil()) // encode for storing into secret certPem := pem.EncodeToMemory(&pem.Block{ @@ -111,7 +112,7 @@ func TestMavenCASecret(t *testing.T) { corev1.TLSPrivateKeyKey: privateKeyPem, }, } - Expect(TestClient().Create(TestContext, secret)).To(Succeed()) + g.Expect(TestClient(t).Create(ctx, secret)).To(Succeed()) // HTTPD configuration config := &corev1.ConfigMap{ @@ -179,7 +180,7 @@ ProxyPreserveHost On ), }, } - Expect(TestClient().Create(TestContext, config)).To(Succeed()) + g.Expect(TestClient(t).Create(ctx, config)).To(Succeed()) // Deploy Nexus // https://help.sonatype.com/repomanager3/installation/run-behind-a-reverse-proxy @@ -296,7 +297,7 @@ ProxyPreserveHost On }, }, } - Expect(TestClient().Create(TestContext, deployment)).To(Succeed()) + g.Expect(TestClient(t).Create(ctx, deployment)).To(Succeed()) service := &corev1.Service{ TypeMeta: metav1.TypeMeta{ @@ -318,10 +319,10 @@ ProxyPreserveHost On }, }, } - Expect(TestClient().Create(TestContext, service)).To(Succeed()) + g.Expect(TestClient(t).Create(ctx, service)).To(Succeed()) // Wait for the Deployment to become ready - Eventually(Deployment(ns, deployment.Name), TestTimeoutMedium).Should(PointTo(MatchFields(IgnoreExtras, + g.Eventually(Deployment(t, ctx, ns, deployment.Name), TestTimeoutMedium).Should(PointTo(MatchFields(IgnoreExtras, Fields{ "Status": MatchFields(IgnoreExtras, Fields{ @@ -337,14 +338,14 @@ ProxyPreserveHost On APIVersion: corev1.SchemeGroupVersion.String(), }, } - Expect(TestClient().List(TestContext, pods, + g.Expect(TestClient(t).List(ctx, pods, ctrl.InNamespace(ns), ctrl.MatchingLabels{"camel-k": "maven-test-nexus"}, )).To(Succeed()) - Expect(pods.Items).To(HaveLen(1)) + g.Expect(pods.Items).To(HaveLen(1)) // Retrieve the Nexus admin password - req := TestClient().CoreV1().RESTClient().Post(). + req := TestClient(t).CoreV1().RESTClient().Post(). Resource("pods"). Name(pods.Items[0].Name). Namespace(ns). @@ -359,18 +360,18 @@ ProxyPreserveHost On TTY: false, }, scheme.ParameterCodec) - exec, err := remotecommand.NewSPDYExecutor(TestClient().GetConfig(), "POST", req.URL()) - Expect(err).To(BeNil()) + exec, err := remotecommand.NewSPDYExecutor(TestClient(t).GetConfig(), "POST", req.URL()) + g.Expect(err).To(BeNil()) var password bytes.Buffer - Expect(exec.Stream(remotecommand.StreamOptions{ + g.Expect(exec.Stream(remotecommand.StreamOptions{ Stdout: bufio.NewWriter(&password), Stderr: os.Stderr, Tty: false, })).To(Succeed()) // Create the Apache Snapshot proxy repository using the Nexus REST API - req = TestClient().CoreV1().RESTClient().Post(). + req = TestClient(t).CoreV1().RESTClient().Post(). Resource("pods"). Name(pods.Items[0].Name). Namespace(ns). @@ -410,10 +411,10 @@ ProxyPreserveHost On TTY: false, }, scheme.ParameterCodec) - exec, err = remotecommand.NewSPDYExecutor(TestClient().GetConfig(), "POST", req.URL()) - Expect(err).To(BeNil()) + exec, err = remotecommand.NewSPDYExecutor(TestClient(t).GetConfig(), "POST", req.URL()) + g.Expect(err).To(BeNil()) - Expect(exec.Stream(remotecommand.StreamOptions{ + g.Expect(exec.Stream(remotecommand.StreamOptions{ Stdout: os.Stdout, Stderr: os.Stderr, Tty: false, @@ -421,40 +422,34 @@ ProxyPreserveHost On // Install Camel K with the Maven Central Nexus proxy and the corresponding Maven CA secret operatorID := "camel-k-maven-ca-secret" - Expect(KamelInstallWithID(operatorID, ns, - "--maven-repository", fmt.Sprintf(`https://%s/repository/maven-public/@id=central-internal@mirrorOf=central`, hostname), - "--maven-repository", fmt.Sprintf(`https://%s/repository/%s/%s`, hostname, stagingRepository.ID, strings.Join(getRepositoryAttributes(stagingRepository), "")), - "--maven-ca-secret", secret.Name+"/"+corev1.TLSCertKey, - // Active batch mode to assert dependencies download - "--maven-cli-option", "--batch-mode", - ).Execute()).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns, "--maven-repository", fmt.Sprintf(`https://%s/repository/maven-public/@id=central-internal@mirrorOf=central`, hostname), "--maven-repository", fmt.Sprintf(`https://%s/repository/%s/%s`, hostname, stagingRepository.ID, strings.Join(getRepositoryAttributes(stagingRepository), "")), "--maven-ca-secret", secret.Name+"/"+corev1.TLSCertKey, "--maven-cli-option", "--batch-mode")).To(Succeed()) - Eventually(PlatformPhase(ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + g.Eventually(PlatformPhase(t, ctx, ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) // Run the Integration name := RandomizedSuffixName("java") - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", "--name", name).Execute()).To(Succeed()) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", name).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutLong).Should(ContainSubstring("Magicstring!")) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutLong).Should(ContainSubstring("Magicstring!")) // Assert no dependencies have been downloaded from the Maven central repository // Note: this should be adapted for the Pod build strategy - pod := OperatorPod(ns)() - Expect(pod).NotTo(BeNil()) + pod := OperatorPod(t, ctx, ns)() + g.Expect(pod).NotTo(BeNil()) // pod.Namespace could be different from ns if using global operator - logs := Logs(pod.Namespace, pod.Name, corev1.PodLogOptions{})() - Expect(logs).NotTo(BeEmpty()) - Expect(logs).NotTo(ContainSubstring("Downloaded from central:")) + logs := Logs(t, ctx, pod.Namespace, pod.Name, corev1.PodLogOptions{})() + g.Expect(logs).NotTo(BeEmpty()) + g.Expect(logs).NotTo(ContainSubstring("Downloaded from central:")) // Clean up - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) - Expect(TestClient().Delete(TestContext, deployment)).To(Succeed()) - Expect(TestClient().Delete(TestContext, service)).To(Succeed()) - Expect(TestClient().Delete(TestContext, secret)).To(Succeed()) - Expect(TestClient().Delete(TestContext, config)).To(Succeed()) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + g.Expect(TestClient(t).Delete(ctx, deployment)).To(Succeed()) + g.Expect(TestClient(t).Delete(ctx, service)).To(Succeed()) + g.Expect(TestClient(t).Delete(ctx, secret)).To(Succeed()) + g.Expect(TestClient(t).Delete(ctx, config)).To(Succeed()) }) } diff --git a/e2e/install/cli/uninstall_test.go b/e2e/install/cli/uninstall_test.go index 0ff450d115..f50b8bbd3e 100644 --- a/e2e/install/cli/uninstall_test.go +++ b/e2e/install/cli/uninstall_test.go @@ -23,6 +23,7 @@ limitations under the License. package cli import ( + "context" "fmt" . "github.com/onsi/gomega" "testing" @@ -33,124 +34,124 @@ import ( ) func TestBasicUninstall(t *testing.T) { - WithNewTestNamespace(t, func(ns string) { + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { // a successful new installation operatorID := fmt.Sprintf("camel-k-%s", ns) - Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed()) - Eventually(OperatorPod(ns)).ShouldNot(BeNil()) - Eventually(DefaultCamelCatalogPhase(ns), TestTimeoutMedium).Should(Equal(v1.CamelCatalogPhaseReady)) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + g.Eventually(OperatorPod(t, ctx, ns)).ShouldNot(BeNil()) + g.Eventually(DefaultCamelCatalogPhase(t, ctx, ns), TestTimeoutMedium).Should(Equal(v1.CamelCatalogPhaseReady)) // should be completely removed on uninstall - Expect(Kamel("uninstall", "-n", ns, "--skip-crd", "--skip-cluster-roles").Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "uninstall", "-n", ns, "--skip-crd", "--skip-cluster-roles").Execute()).To(Succeed()) // Roles only removed in non-olm use-case uninstallViaOLM := false var err error - if uninstallViaOLM, err = olm.IsAPIAvailable(TestContext, TestClient(), ns); err != nil { + if uninstallViaOLM, err = olm.IsAPIAvailable(TestClient(t)); err != nil { t.Error(err) t.FailNow() } if !uninstallViaOLM { - Eventually(Role(ns)).Should(BeNil()) - Eventually(RoleBinding(ns)).Should(BeNil()) - Eventually(ServiceAccount(ns, "camel-k-operator")).Should(BeNil()) + g.Eventually(Role(t, ctx, ns)).Should(BeNil()) + g.Eventually(RoleBinding(t, ctx, ns)).Should(BeNil()) + g.Eventually(ServiceAccount(t, ctx, ns, "camel-k-operator")).Should(BeNil()) } else { - Eventually(Role(ns)).ShouldNot(BeNil()) - Eventually(RoleBinding(ns)).ShouldNot(BeNil()) + g.Eventually(Role(t, ctx, ns)).ShouldNot(BeNil()) + g.Eventually(RoleBinding(t, ctx, ns)).ShouldNot(BeNil()) } - Eventually(Configmap(ns, "camel-k-maven-settings")).Should(BeNil()) - Eventually(OperatorPod(ns), TestTimeoutMedium).Should(BeNil()) - Eventually(KameletList(ns), TestTimeoutMedium).Should(BeEmpty()) - Eventually(CamelCatalogList(ns), TestTimeoutMedium).Should(BeEmpty()) + g.Eventually(Configmap(t, ctx, ns, "camel-k-maven-settings")).Should(BeNil()) + g.Eventually(OperatorPod(t, ctx, ns), TestTimeoutMedium).Should(BeNil()) + g.Eventually(KameletList(t, ctx, ns), TestTimeoutMedium).Should(BeEmpty()) + g.Eventually(CamelCatalogList(t, ctx, ns), TestTimeoutMedium).Should(BeEmpty()) }) } func TestUninstallSkipOperator(t *testing.T) { - WithNewTestNamespace(t, func(ns string) { + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { // a successful new installation operatorID := fmt.Sprintf("camel-k-%s", ns) - Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed()) - Eventually(OperatorPod(ns)).ShouldNot(BeNil()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + g.Eventually(OperatorPod(t, ctx, ns)).ShouldNot(BeNil()) // on uninstall it should remove everything except operator - Expect(Kamel("uninstall", "-n", ns, "--skip-crd", "--skip-cluster-roles", "--skip-operator").Execute()).To(Succeed()) - Eventually(OperatorPod(ns)).ShouldNot(BeNil()) + g.Expect(Kamel(t, ctx, "uninstall", "-n", ns, "--skip-crd", "--skip-cluster-roles", "--skip-operator").Execute()).To(Succeed()) + g.Eventually(OperatorPod(t, ctx, ns)).ShouldNot(BeNil()) }) } func TestUninstallSkipRole(t *testing.T) { - WithNewTestNamespace(t, func(ns string) { + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { // a successful new installation operatorID := fmt.Sprintf("camel-k-%s", ns) - Expect(KamelInstallWithID(operatorID, ns, "--olm=false").Execute()).To(Succeed()) - Eventually(OperatorPod(ns)).ShouldNot(BeNil()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns, "--olm=false")).To(Succeed()) + g.Eventually(OperatorPod(t, ctx, ns)).ShouldNot(BeNil()) // on uninstall it should remove everything except roles - Expect(Kamel("uninstall", "-n", ns, "--skip-crd", "--skip-cluster-roles", "--skip-roles").Execute()).To(Succeed()) - Eventually(Role(ns)).ShouldNot(BeNil()) + g.Expect(Kamel(t, ctx, "uninstall", "-n", ns, "--skip-crd", "--skip-cluster-roles", "--skip-roles").Execute()).To(Succeed()) + g.Eventually(Role(t, ctx, ns)).ShouldNot(BeNil()) }) } func TestUninstallSkipRoleBinding(t *testing.T) { - WithNewTestNamespace(t, func(ns string) { + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { // a successful new installation operatorID := fmt.Sprintf("camel-k-%s", ns) - Expect(KamelInstallWithID(operatorID, ns, "--olm=false").Execute()).To(Succeed()) - Eventually(OperatorPod(ns)).ShouldNot(BeNil()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns, "--olm=false")).To(Succeed()) + g.Eventually(OperatorPod(t, ctx, ns)).ShouldNot(BeNil()) // on uninstall it should remove everything except role-bindings - Expect(Kamel("uninstall", "-n", ns, "--skip-crd", "--skip-cluster-roles", "--skip-role-bindings").Execute()).To(Succeed()) - Eventually(RoleBinding(ns)).ShouldNot(BeNil()) + g.Expect(Kamel(t, ctx, "uninstall", "-n", ns, "--skip-crd", "--skip-cluster-roles", "--skip-role-bindings").Execute()).To(Succeed()) + g.Eventually(RoleBinding(t, ctx, ns)).ShouldNot(BeNil()) }) } func TestUninstallSkipServiceAccounts(t *testing.T) { - WithNewTestNamespace(t, func(ns string) { + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { // a successful new installation operatorID := fmt.Sprintf("camel-k-%s", ns) - Expect(KamelInstallWithID(operatorID, ns, "--olm=false").Execute()).To(Succeed()) - Eventually(OperatorPod(ns)).ShouldNot(BeNil()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns, "--olm=false")).To(Succeed()) + g.Eventually(OperatorPod(t, ctx, ns)).ShouldNot(BeNil()) // on uninstall it should remove everything except cluster-roles - Expect(Kamel("uninstall", "-n", ns, "--skip-crd", "--skip-cluster-roles", "--skip-service-accounts").Execute()).To(Succeed()) - Eventually(ServiceAccount(ns, "camel-k-operator")).ShouldNot(BeNil()) + g.Expect(Kamel(t, ctx, "uninstall", "-n", ns, "--skip-crd", "--skip-cluster-roles", "--skip-service-accounts").Execute()).To(Succeed()) + g.Eventually(ServiceAccount(t, ctx, ns, "camel-k-operator")).ShouldNot(BeNil()) }) } func TestUninstallSkipIntegrationPlatform(t *testing.T) { - WithNewTestNamespace(t, func(ns string) { + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { // a successful new installation operatorID := fmt.Sprintf("camel-k-%s", ns) - Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed()) - Eventually(OperatorPod(ns)).ShouldNot(BeNil()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + g.Eventually(OperatorPod(t, ctx, ns)).ShouldNot(BeNil()) // on uninstall it should remove everything except cluster-roles // NOTE: skip CRDs is also required in addition to skip integration platform - Expect(Kamel("uninstall", "-n", ns, "--skip-crd", "--skip-cluster-roles", "--skip-integration-platform").Execute()).To(Succeed()) - Eventually(Platform(ns)).ShouldNot(BeNil()) + g.Expect(Kamel(t, ctx, "uninstall", "-n", ns, "--skip-crd", "--skip-cluster-roles", "--skip-integration-platform").Execute()).To(Succeed()) + g.Eventually(Platform(t, ctx, ns)).ShouldNot(BeNil()) }) } func TestUninstallSkipKamelets(t *testing.T) { - WithNewTestNamespace(t, func(ns string) { + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { // a successful new installation operatorID := fmt.Sprintf("camel-k-%s", ns) - Expect(KamelInstallWithIDAndKameletCatalog(operatorID, ns).Execute()).To(Succeed()) - Eventually(OperatorPod(ns)).ShouldNot(BeNil()) - Eventually(KameletList(ns)).ShouldNot(BeEmpty()) + g.Expect(KamelInstallWithIDAndKameletCatalog(t, ctx, operatorID, ns)).To(Succeed()) + g.Eventually(OperatorPod(t, ctx, ns)).ShouldNot(BeNil()) + g.Eventually(KameletList(t, ctx, ns)).ShouldNot(BeEmpty()) // on uninstall it should remove everything except kamelets - Expect(Kamel("uninstall", "-n", ns, "--skip-crd", "--skip-cluster-roles", "--skip-kamelets").Execute()).To(Succeed()) - Eventually(KameletList(ns)).ShouldNot(BeEmpty()) + g.Expect(Kamel(t, ctx, "uninstall", "-n", ns, "--skip-crd", "--skip-cluster-roles", "--skip-kamelets").Execute()).To(Succeed()) + g.Eventually(KameletList(t, ctx, ns)).ShouldNot(BeEmpty()) }) } func TestUninstallSkipCamelCatalogs(t *testing.T) { - WithNewTestNamespace(t, func(ns string) { + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { // a successful new installation operatorID := fmt.Sprintf("camel-k-%s", ns) - Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed()) - Eventually(OperatorPod(ns)).ShouldNot(BeNil()) - Eventually(CamelCatalogList(ns)).ShouldNot(BeEmpty()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + g.Eventually(OperatorPod(t, ctx, ns)).ShouldNot(BeNil()) + g.Eventually(CamelCatalogList(t, ctx, ns)).ShouldNot(BeEmpty()) // on uninstall it should remove everything except camel catalogs - Expect(Kamel("uninstall", "-n", ns, "--skip-crd", "--skip-cluster-roles", "--skip-camel-catalogs").Execute()).To(Succeed()) - Eventually(CamelCatalogList(ns)).ShouldNot(BeEmpty()) + g.Expect(Kamel(t, ctx, "uninstall", "-n", ns, "--skip-crd", "--skip-cluster-roles", "--skip-camel-catalogs").Execute()).To(Succeed()) + g.Eventually(CamelCatalogList(t, ctx, ns)).ShouldNot(BeEmpty()) }) } diff --git a/e2e/install/helm/setup_test.go b/e2e/install/helm/setup_test.go index 139dc9b427..da06c13f6c 100644 --- a/e2e/install/helm/setup_test.go +++ b/e2e/install/helm/setup_test.go @@ -23,6 +23,7 @@ limitations under the License. package helm import ( + "context" "fmt" "os" "os/exec" @@ -37,17 +38,15 @@ import ( ) func TestHelmInstallRunUninstall(t *testing.T) { - RegisterTestingT(t) - KAMEL_INSTALL_REGISTRY := os.Getenv("KAMEL_INSTALL_REGISTRY") customImage := fmt.Sprintf("%s/apache/camel-k", KAMEL_INSTALL_REGISTRY) os.Setenv("CAMEL_K_TEST_MAKE_DIR", "../../../") - WithNewTestNamespace(t, func(ns string) { - ExpectExecSucceed(t, Make(fmt.Sprintf("CUSTOM_IMAGE=%s", customImage), "set-version")) - ExpectExecSucceed(t, Make("release-helm")) - ExpectExecSucceed(t, + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + ExpectExecSucceed(t, g, Make(t, fmt.Sprintf("CUSTOM_IMAGE=%s", customImage), "set-version")) + ExpectExecSucceed(t, g, Make(t, "release-helm")) + ExpectExecSucceed(t, g, exec.Command( "helm", "install", @@ -62,24 +61,24 @@ func TestHelmInstallRunUninstall(t *testing.T) { ), ) - Eventually(OperatorPod(ns)).ShouldNot(BeNil()) + g.Eventually(OperatorPod(t, ctx, ns)).ShouldNot(BeNil()) // Check if restricted security context has been applyed - operatorPod := OperatorPod(ns)() - Expect(operatorPod.Spec.Containers[0].SecurityContext.RunAsNonRoot).To(Equal(kubernetes.DefaultOperatorSecurityContext().RunAsNonRoot)) - Expect(operatorPod.Spec.Containers[0].SecurityContext.Capabilities).To(Equal(kubernetes.DefaultOperatorSecurityContext().Capabilities)) - Expect(operatorPod.Spec.Containers[0].SecurityContext.SeccompProfile).To(Equal(kubernetes.DefaultOperatorSecurityContext().SeccompProfile)) - Expect(operatorPod.Spec.Containers[0].SecurityContext.AllowPrivilegeEscalation).To(Equal(kubernetes.DefaultOperatorSecurityContext().AllowPrivilegeEscalation)) + operatorPod := OperatorPod(t, ctx, ns)() + g.Expect(operatorPod.Spec.Containers[0].SecurityContext.RunAsNonRoot).To(Equal(kubernetes.DefaultOperatorSecurityContext().RunAsNonRoot)) + g.Expect(operatorPod.Spec.Containers[0].SecurityContext.Capabilities).To(Equal(kubernetes.DefaultOperatorSecurityContext().Capabilities)) + g.Expect(operatorPod.Spec.Containers[0].SecurityContext.SeccompProfile).To(Equal(kubernetes.DefaultOperatorSecurityContext().SeccompProfile)) + g.Expect(operatorPod.Spec.Containers[0].SecurityContext.AllowPrivilegeEscalation).To(Equal(kubernetes.DefaultOperatorSecurityContext().AllowPrivilegeEscalation)) //Test a simple route t.Run("simple route", func(t *testing.T) { name := RandomizedSuffixName("yaml") - Expect(KamelRun(ns, "files/yaml.yaml", "--name", name).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + g.Expect(KamelRun(t, ctx, ns, "files/yaml.yaml", "--name", name).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) }) - ExpectExecSucceed(t, + ExpectExecSucceed(t, g, exec.Command( "helm", "uninstall", @@ -89,6 +88,6 @@ func TestHelmInstallRunUninstall(t *testing.T) { ), ) - Eventually(OperatorPod(ns)).Should(BeNil()) + g.Eventually(OperatorPod(t, ctx, ns)).Should(BeNil()) }) } diff --git a/e2e/install/kustomize/operator_test.go b/e2e/install/kustomize/operator_test.go index 418f71ed06..20997cf74a 100644 --- a/e2e/install/kustomize/operator_test.go +++ b/e2e/install/kustomize/operator_test.go @@ -23,6 +23,7 @@ limitations under the License. package kustomize import ( + "context" "fmt" "os" "testing" @@ -40,40 +41,43 @@ func TestOperatorBasic(t *testing.T) { makeDir := testutil.MakeTempCopyDir(t, "../../../install") os.Setenv("CAMEL_K_TEST_MAKE_DIR", makeDir) + ctx := TestContext() + // Ensure no CRDs are already installed - UninstallAll() + g := NewWithT(t) + g.Expect(UninstallAll(t, ctx)).To(Succeed()) // Return the cluster to previous state - defer Cleanup() + defer Cleanup(t, ctx) - WithNewTestNamespace(t, func(ns string) { + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { namespaceArg := fmt.Sprintf("NAMESPACE=%s", ns) - ExpectExecSucceed(t, Make("setup-cluster", namespaceArg)) - ExpectExecSucceed(t, Make("setup", namespaceArg)) + ExpectExecSucceed(t, g, Make(t, "setup-cluster", namespaceArg)) + ExpectExecSucceed(t, g, Make(t, "setup", namespaceArg)) // Skip default kamelets installation for faster test runs - ExpectExecSucceed(t, Make("operator", + ExpectExecSucceed(t, g, Make(t, "operator", namespaceArg, "INSTALL_DEFAULT_KAMELETS=false")) // Refresh the test client to account for the newly installed CRDs - SyncClient() + RefreshClient(t) - Eventually(OperatorPod(ns)).ShouldNot(BeNil()) - Eventually(OperatorPodPhase(ns), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) + g.Eventually(OperatorPod(t, ctx, ns)).ShouldNot(BeNil()) + g.Eventually(OperatorPodPhase(t, ctx, ns), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) // Check if restricted security context has been applyed - operatorPod := OperatorPod(ns)() - Expect(operatorPod.Spec.Containers[0].SecurityContext.RunAsNonRoot).To(Equal(kubernetes.DefaultOperatorSecurityContext().RunAsNonRoot)) - Expect(operatorPod.Spec.Containers[0].SecurityContext.Capabilities).To(Equal(kubernetes.DefaultOperatorSecurityContext().Capabilities)) - Expect(operatorPod.Spec.Containers[0].SecurityContext.SeccompProfile).To(Equal(kubernetes.DefaultOperatorSecurityContext().SeccompProfile)) - Expect(operatorPod.Spec.Containers[0].SecurityContext.AllowPrivilegeEscalation).To(Equal(kubernetes.DefaultOperatorSecurityContext().AllowPrivilegeEscalation)) + operatorPod := OperatorPod(t, ctx, ns)() + g.Expect(operatorPod.Spec.Containers[0].SecurityContext.RunAsNonRoot).To(Equal(kubernetes.DefaultOperatorSecurityContext().RunAsNonRoot)) + g.Expect(operatorPod.Spec.Containers[0].SecurityContext.Capabilities).To(Equal(kubernetes.DefaultOperatorSecurityContext().Capabilities)) + g.Expect(operatorPod.Spec.Containers[0].SecurityContext.SeccompProfile).To(Equal(kubernetes.DefaultOperatorSecurityContext().SeccompProfile)) + g.Expect(operatorPod.Spec.Containers[0].SecurityContext.AllowPrivilegeEscalation).To(Equal(kubernetes.DefaultOperatorSecurityContext().AllowPrivilegeEscalation)) - Eventually(Platform(ns)).ShouldNot(BeNil()) + g.Eventually(Platform(t, ctx, ns)).ShouldNot(BeNil()) registry := os.Getenv("KIND_REGISTRY") if registry != "" { - platform := Platform(ns)() - Expect(platform.Status.Build.Registry).ShouldNot(BeNil()) - Expect(platform.Status.Build.Registry.Address).To(Equal(registry)) + platform := Platform(t, ctx, ns)() + g.Expect(platform.Status.Build.Registry).ShouldNot(BeNil()) + g.Expect(platform.Status.Build.Registry.Address).To(Equal(registry)) } }) @@ -83,30 +87,33 @@ func TestOperatorKustomizeAlternativeImage(t *testing.T) { makeDir := testutil.MakeTempCopyDir(t, "../../../install") os.Setenv("CAMEL_K_TEST_MAKE_DIR", makeDir) + ctx := TestContext() + // Ensure no CRDs are already installed - UninstallAll() + g := NewWithT(t) + g.Expect(UninstallAll(t, ctx)).To(Succeed()) // Return the cluster to previous state - defer Cleanup() + defer Cleanup(t, ctx) - WithNewTestNamespace(t, func(ns string) { + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { namespaceArg := fmt.Sprintf("NAMESPACE=%s", ns) - ExpectExecSucceed(t, Make("setup-cluster", namespaceArg)) - ExpectExecSucceed(t, Make("setup", namespaceArg)) + ExpectExecSucceed(t, g, Make(t, "setup-cluster", namespaceArg)) + ExpectExecSucceed(t, g, Make(t, "setup", namespaceArg)) // Skip default kamelets installation for faster test runs newImage := "quay.io/kameltest/kamel-operator" newTag := "1.1.1" - ExpectExecSucceed(t, Make("operator", + ExpectExecSucceed(t, g, Make(t, "operator", fmt.Sprintf("CUSTOM_IMAGE=%s", newImage), fmt.Sprintf("CUSTOM_VERSION=%s", newTag), namespaceArg, "INSTALL_DEFAULT_KAMELETS=false")) // Refresh the test client to account for the newly installed CRDs - SyncClient() + RefreshClient(t) - Eventually(OperatorImage(ns)).Should(Equal(fmt.Sprintf("%s:%s", newImage, newTag))) + g.Eventually(OperatorImage(t, ctx, ns)).Should(Equal(fmt.Sprintf("%s:%s", newImage, newTag))) }) } @@ -114,47 +121,50 @@ func TestOperatorKustomizeGlobal(t *testing.T) { makeDir := testutil.MakeTempCopyDir(t, "../../../install") os.Setenv("CAMEL_K_TEST_MAKE_DIR", makeDir) + ctx := TestContext() + // Ensure no CRDs are already installed - UninstallAll() + g := NewWithT(t) + g.Expect(UninstallAll(t, ctx)).To(Succeed()) // Return the cluster to previous state - defer Cleanup() + defer Cleanup(t, ctx) - WithNewTestNamespace(t, func(ns string) { + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { namespaceArg := fmt.Sprintf("NAMESPACE=%s", ns) - ExpectExecSucceed(t, Make("setup-cluster", namespaceArg)) - ExpectExecSucceed(t, Make("setup", namespaceArg, "GLOBAL=true")) + ExpectExecSucceed(t, g, Make(t, "setup-cluster", namespaceArg)) + ExpectExecSucceed(t, g, Make(t, "setup", namespaceArg, "GLOBAL=true")) // Skip default kamelets installation for faster test runs - ExpectExecSucceed(t, Make("operator", + ExpectExecSucceed(t, g, Make(t, "operator", namespaceArg, "GLOBAL=true", "INSTALL_DEFAULT_KAMELETS=false")) // Refresh the test client to account for the newly installed CRDs - SyncClient() + RefreshClient(t) - podFunc := OperatorPod(ns) - Eventually(podFunc).ShouldNot(BeNil()) - Eventually(OperatorPodPhase(ns), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) + podFunc := OperatorPod(t, ctx, ns) + g.Eventually(podFunc).ShouldNot(BeNil()) + g.Eventually(OperatorPodPhase(t, ctx, ns), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) pod := podFunc() containers := pod.Spec.Containers - Expect(containers).NotTo(BeEmpty()) + g.Expect(containers).NotTo(BeEmpty()) envvars := containers[0].Env - Expect(envvars).NotTo(BeEmpty()) + g.Expect(envvars).NotTo(BeEmpty()) found := false for _, v := range envvars { if v.Name == "WATCH_NAMESPACE" { - Expect(v.Value).To(Equal("\"\"")) + g.Expect(v.Value).To(Equal("\"\"")) found = true break } } - Expect(found).To(BeTrue()) + g.Expect(found).To(BeTrue()) - Eventually(Platform(ns)).ShouldNot(BeNil()) + g.Eventually(Platform(t, ctx, ns)).ShouldNot(BeNil()) }) } diff --git a/e2e/install/kustomize/setup_test.go b/e2e/install/kustomize/setup_test.go index 429f516e79..79a2d1b723 100644 --- a/e2e/install/kustomize/setup_test.go +++ b/e2e/install/kustomize/setup_test.go @@ -23,44 +23,47 @@ limitations under the License. package kustomize import ( + "context" "fmt" "os" "testing" . "github.com/apache/camel-k/v2/e2e/support" testutil "github.com/apache/camel-k/v2/e2e/support/util" + "github.com/apache/camel-k/v2/pkg/util/defaults" . "github.com/onsi/gomega" ) func TestSetupKustomizeBasic(t *testing.T) { - RegisterTestingT(t) + ctx := TestContext() + g := NewWithT(t) makeDir := testutil.MakeTempCopyDir(t, "../../../install") os.Setenv("CAMEL_K_TEST_MAKE_DIR", makeDir) // Ensure no CRDs are already installed - UninstallAll() - Eventually(CRDs()).Should(HaveLen(0)) + g.Expect(UninstallAll(t, ctx)).To(Succeed()) + g.Eventually(CRDs(t)).Should(HaveLen(0)) // Return the cluster to previous state - defer Cleanup() + defer Cleanup(t, ctx) - WithNewTestNamespace(t, func(ns string) { + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { namespaceArg := fmt.Sprintf("NAMESPACE=%s", ns) - ExpectExecSucceed(t, Make("setup-cluster", namespaceArg)) - Eventually(CRDs()).Should(HaveLen(ExpectedCRDs)) + ExpectExecSucceed(t, g, Make(t, "setup-cluster", namespaceArg)) + g.Eventually(CRDs(t)).Should(HaveLen(GetExpectedCRDs(defaults.Version))) - ExpectExecSucceed(t, Make("setup", namespaceArg)) + ExpectExecSucceed(t, g, Make(t, "setup", namespaceArg)) kpRoles := ExpectedKubePromoteRoles opRoles := kpRoles + ExpectedOSPromoteRoles - Eventually(Role(ns)).Should(Or(HaveLen(kpRoles), HaveLen(opRoles))) + g.Eventually(Role(t, ctx, ns)).Should(Or(HaveLen(kpRoles), HaveLen(opRoles))) kcRoles := ExpectedKubeClusterRoles ocRoles := kcRoles + ExpectedOSClusterRoles - Eventually(ClusterRole()).Should(Or(HaveLen(kcRoles), HaveLen(ocRoles))) + g.Eventually(ClusterRole(t, ctx)).Should(Or(HaveLen(kcRoles), HaveLen(ocRoles))) // Tidy up to ensure next test works - Expect(Kamel("uninstall", "-n", ns).Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "uninstall", "-n", ns).Execute()).To(Succeed()) }) } @@ -69,24 +72,27 @@ func TestSetupKustomizeGlobal(t *testing.T) { makeDir := testutil.MakeTempCopyDir(t, "../../../install") os.Setenv("CAMEL_K_TEST_MAKE_DIR", makeDir) + ctx := TestContext() + // Ensure no CRDs are already installed - UninstallAll() - Eventually(CRDs()).Should(HaveLen(0)) + g := NewWithT(t) + g.Expect(UninstallAll(t, ctx)).To(Succeed()) + g.Eventually(CRDs(t)).Should(HaveLen(0)) // Return the cluster to previous state - defer Cleanup() + defer Cleanup(t, ctx) - WithNewTestNamespace(t, func(ns string) { + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { namespaceArg := fmt.Sprintf("NAMESPACE=%s", ns) - ExpectExecSucceed(t, Make("setup-cluster", namespaceArg)) - Eventually(CRDs()).Should(HaveLen(ExpectedCRDs)) + ExpectExecSucceed(t, g, Make(t, "setup-cluster", namespaceArg)) + g.Eventually(CRDs(t)).Should(HaveLen(GetExpectedCRDs(defaults.Version))) - ExpectExecSucceed(t, Make("setup", "GLOBAL=true", namespaceArg)) + ExpectExecSucceed(t, g, Make(t, "setup", "GLOBAL=true", namespaceArg)) - Eventually(Role(ns)).Should(HaveLen(0)) + g.Eventually(Role(t, ctx, ns)).Should(HaveLen(0)) kcpRoles := ExpectedKubeClusterRoles + ExpectedKubePromoteRoles ocpRoles := kcpRoles + ExpectedOSClusterRoles + ExpectedOSPromoteRoles - Eventually(ClusterRole()).Should(Or(HaveLen(kcpRoles), HaveLen(ocpRoles))) + g.Eventually(ClusterRole(t, ctx)).Should(Or(HaveLen(kcpRoles), HaveLen(ocpRoles))) }) } diff --git a/e2e/install/kustomize/uninstall_test.go b/e2e/install/kustomize/uninstall_test.go index c56bc74f5d..305fa7512d 100644 --- a/e2e/install/kustomize/uninstall_test.go +++ b/e2e/install/kustomize/uninstall_test.go @@ -23,6 +23,7 @@ limitations under the License. package kustomize import ( + "context" "fmt" "os" "testing" @@ -31,92 +32,95 @@ import ( . "github.com/apache/camel-k/v2/e2e/support" testutil "github.com/apache/camel-k/v2/e2e/support/util" + "github.com/apache/camel-k/v2/pkg/util/defaults" . "github.com/onsi/gomega" ) func TestKustomizeUninstallBasic(t *testing.T) { - RegisterTestingT(t) + ctx := TestContext() + g := NewWithT(t) makeDir := testutil.MakeTempCopyDir(t, "../../../install") os.Setenv("CAMEL_K_TEST_MAKE_DIR", makeDir) // Ensure no CRDs are already installed - UninstallAll() - Eventually(CRDs()).Should(HaveLen(0)) + g.Expect(UninstallAll(t, ctx)).To(Succeed()) + g.Eventually(CRDs(t)).Should(HaveLen(0)) // Return the cluster to previous state - defer Cleanup() + defer Cleanup(t, ctx) - WithNewTestNamespace(t, func(ns string) { + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { namespaceArg := fmt.Sprintf("NAMESPACE=%s", ns) - ExpectExecSucceed(t, Make("setup-cluster", namespaceArg)) - ExpectExecSucceed(t, Make("setup", namespaceArg)) - ExpectExecSucceed(t, Make("platform", namespaceArg)) + ExpectExecSucceed(t, g, Make(t, "setup-cluster", namespaceArg)) + ExpectExecSucceed(t, g, Make(t, "setup", namespaceArg)) + ExpectExecSucceed(t, g, Make(t, "platform", namespaceArg)) // Skip default kamelets installation for faster test runs - ExpectExecSucceed(t, Make("operator", namespaceArg, "INSTALL_DEFAULT_KAMELETS=false")) - Eventually(OperatorPod(ns)).ShouldNot(BeNil()) - Eventually(OperatorPodPhase(ns), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) + ExpectExecSucceed(t, g, Make(t, "operator", namespaceArg, "INSTALL_DEFAULT_KAMELETS=false")) + g.Eventually(OperatorPod(t, ctx, ns)).ShouldNot(BeNil()) + g.Eventually(OperatorPodPhase(t, ctx, ns), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) // Do uninstall - ExpectExecSucceed(t, Make("uninstall", namespaceArg)) + ExpectExecSucceed(t, g, Make(t, "uninstall", namespaceArg)) // Refresh the test client to account for the newly installed CRDs - SyncClient() + RefreshClient(t) - Eventually(OperatorPod(ns)).Should(BeNil()) - Eventually(Platform(ns)).Should(BeNil()) + g.Eventually(OperatorPod(t, ctx, ns)).Should(BeNil()) + g.Eventually(Platform(t, ctx, ns)).Should(BeNil()) // The operator can dynamically create a for its builders // so, in case there is a build strategy "pod", expect this to have 1 role - Eventually(Role(ns)).Should(BeNil()) - Eventually(ClusterRole()).Should(BeNil()) + g.Eventually(Role(t, ctx, ns)).Should(BeNil()) + g.Eventually(ClusterRole(t, ctx)).Should(BeNil()) // CRDs should be still there - Eventually(CRDs()).Should(HaveLen(ExpectedCRDs)) + g.Eventually(CRDs(t)).Should(HaveLen(GetExpectedCRDs(defaults.Version))) // Do uninstall all - ExpectExecSucceed(t, Make("uninstall", namespaceArg, "UNINSTALL_ALL=true")) + ExpectExecSucceed(t, g, Make(t, "uninstall", namespaceArg, "UNINSTALL_ALL=true")) - Eventually(CRDs()).Should(BeNil()) + g.Eventually(CRDs(t)).Should(BeNil()) }) } func TestUninstallGlobal(t *testing.T) { - RegisterTestingT(t) + ctx := TestContext() + g := NewWithT(t) makeDir := testutil.MakeTempCopyDir(t, "../../../install") os.Setenv("CAMEL_K_TEST_MAKE_DIR", makeDir) // Ensure no CRDs are already installed - UninstallAll() - Eventually(CRDs()).Should(HaveLen(0)) + g.Expect(UninstallAll(t, ctx)).To(Succeed()) + g.Eventually(CRDs(t)).Should(HaveLen(0)) // Return the cluster to previous state - defer Cleanup() + defer Cleanup(t, ctx) - WithNewTestNamespace(t, func(ns string) { + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { namespaceArg := fmt.Sprintf("NAMESPACE=%s", ns) - ExpectExecSucceed(t, Make("setup-cluster", namespaceArg)) - ExpectExecSucceed(t, Make("setup", namespaceArg, "GLOBAL=true")) - ExpectExecSucceed(t, Make("platform", namespaceArg)) + ExpectExecSucceed(t, g, Make(t, "setup-cluster", namespaceArg)) + ExpectExecSucceed(t, g, Make(t, "setup", namespaceArg, "GLOBAL=true")) + ExpectExecSucceed(t, g, Make(t, "platform", namespaceArg)) // Skip default kamelets installation for faster test runs - ExpectExecSucceed(t, Make("operator", namespaceArg, "GLOBAL=true", "INSTALL_DEFAULT_KAMELETS=false")) - Eventually(OperatorPod(ns)).ShouldNot(BeNil()) - Eventually(OperatorPodPhase(ns), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) + ExpectExecSucceed(t, g, Make(t, "operator", namespaceArg, "GLOBAL=true", "INSTALL_DEFAULT_KAMELETS=false")) + g.Eventually(OperatorPod(t, ctx, ns)).ShouldNot(BeNil()) + g.Eventually(OperatorPodPhase(t, ctx, ns), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) // Do uninstall - ExpectExecSucceed(t, Make("uninstall", namespaceArg)) + ExpectExecSucceed(t, g, Make(t, "uninstall", namespaceArg)) // Refresh the test client to account for the newly installed CRDs - SyncClient() + RefreshClient(t) - Eventually(OperatorPod(ns)).Should(BeNil()) - Eventually(Platform(ns)).Should(BeNil()) - Eventually(Role(ns)).Should(BeNil()) - Eventually(ClusterRole()).Should(BeNil()) + g.Eventually(OperatorPod(t, ctx, ns)).Should(BeNil()) + g.Eventually(Platform(t, ctx, ns)).Should(BeNil()) + g.Eventually(Role(t, ctx, ns)).Should(BeNil()) + g.Eventually(ClusterRole(t, ctx)).Should(BeNil()) // CRDs should be still there - Eventually(CRDs()).Should(HaveLen(ExpectedCRDs)) + g.Eventually(CRDs(t)).Should(HaveLen(GetExpectedCRDs(defaults.Version))) // Do uninstall all - ExpectExecSucceed(t, Make("uninstall", namespaceArg, "UNINSTALL_ALL=true")) + ExpectExecSucceed(t, g, Make(t, "uninstall", namespaceArg, "UNINSTALL_ALL=true")) - Eventually(CRDs()).Should(BeNil()) + g.Eventually(CRDs(t)).Should(BeNil()) }) } diff --git a/e2e/install/olm/olm_install_test.go b/e2e/install/olm/olm_install_test.go index ac8fe9e2fe..01482b4f7d 100644 --- a/e2e/install/olm/olm_install_test.go +++ b/e2e/install/olm/olm_install_test.go @@ -23,13 +23,14 @@ limitations under the License. package olm import ( + "context" "fmt" "os" "testing" . "github.com/apache/camel-k/v2/e2e/support" . "github.com/onsi/gomega" - "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" @@ -53,21 +54,21 @@ func TestOLMInstallation(t *testing.T) { t.Skip("OLM fresh install test requires the CAMEL_K_NEW_IIB environment variable") } - WithNewTestNamespace(t, func(ns string) { - Expect(CreateOrUpdateCatalogSource(ns, installCatalogSourceName, newIIB)).To(Succeed()) + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + g.Expect(CreateOrUpdateCatalogSource(t, ctx, ns, installCatalogSourceName, newIIB)).To(Succeed()) - ocp, err := openshift.IsOpenShift(TestClient()) - assert.Nil(t, err) + ocp, err := openshift.IsOpenShift(TestClient(t)) + require.NoError(t, err) if ocp { // Wait for pull secret to be created in namespace // eg. test-camel-k-source-dockercfg-zlltn secretPrefix := fmt.Sprintf("%s-dockercfg-", installCatalogSourceName) - Eventually(SecretByName(ns, secretPrefix), TestTimeoutLong).Should(Not(BeNil())) + g.Eventually(SecretByName(t, ctx, ns, secretPrefix), TestTimeoutLong).Should(Not(BeNil())) } - Eventually(CatalogSourcePodRunning(ns, installCatalogSourceName), TestTimeoutMedium).Should(BeNil()) - Eventually(CatalogSourcePhase(ns, installCatalogSourceName), TestTimeoutLong).Should(Equal("READY")) + g.Eventually(CatalogSourcePodRunning(t, ctx, ns, installCatalogSourceName), TestTimeoutMedium).Should(BeNil()) + g.Eventually(CatalogSourcePhase(t, ctx, ns, installCatalogSourceName), TestTimeoutLong).Should(Equal("READY")) args := []string{"install", "-n", ns, "--olm=true", "--olm-source", installCatalogSourceName, "--olm-source-namespace", ns} @@ -75,39 +76,39 @@ func TestOLMInstallation(t *testing.T) { args = append(args, "--olm-channel", newUpdateChannel) } - Expect(Kamel(args...).Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, args...).Execute()).To(Succeed()) // Find the only one Camel K CSV noAdditionalConditions := func(csv olm.ClusterServiceVersion) bool { return true } - Eventually(ClusterServiceVersionPhase(noAdditionalConditions, ns), TestTimeoutMedium).Should(Equal(olm.CSVPhaseSucceeded)) + g.Eventually(ClusterServiceVersionPhase(t, ctx, noAdditionalConditions, ns), TestTimeoutMedium).Should(Equal(olm.CSVPhaseSucceeded)) // Refresh the test client to account for the newly installed CRDs - SyncClient() + RefreshClient(t) - csvVersion := ClusterServiceVersion(noAdditionalConditions, ns)().Spec.Version + csvVersion := ClusterServiceVersion(t, ctx, noAdditionalConditions, ns)().Spec.Version ipVersionPrefix := fmt.Sprintf("%d.%d", csvVersion.Version.Major, csvVersion.Version.Minor) t.Logf("CSV Version installed: %s", csvVersion.Version.String()) // Check the operator pod is running - Eventually(OperatorPodPhase(ns), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) - Eventually(OperatorImage(ns), TestTimeoutShort).Should(Equal(defaults.OperatorImage())) + g.Eventually(OperatorPodPhase(t, ctx, ns), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) + g.Eventually(OperatorImage(t, ctx, ns), TestTimeoutShort).Should(Equal(defaults.OperatorImage())) // Check the IntegrationPlatform has been reconciled - Eventually(PlatformVersion(ns)).Should(ContainSubstring(ipVersionPrefix)) + g.Eventually(PlatformVersion(t, ctx, ns)).Should(ContainSubstring(ipVersionPrefix)) // Check if restricted security context has been applyed - operatorPod := OperatorPod(ns)() - Expect(operatorPod.Spec.Containers[0].SecurityContext.RunAsNonRoot).To(Equal(kubernetes.DefaultOperatorSecurityContext().RunAsNonRoot)) - Expect(operatorPod.Spec.Containers[0].SecurityContext.Capabilities).To(Equal(kubernetes.DefaultOperatorSecurityContext().Capabilities)) - Expect(operatorPod.Spec.Containers[0].SecurityContext.SeccompProfile).To(Equal(kubernetes.DefaultOperatorSecurityContext().SeccompProfile)) - Expect(operatorPod.Spec.Containers[0].SecurityContext.AllowPrivilegeEscalation).To(Equal(kubernetes.DefaultOperatorSecurityContext().AllowPrivilegeEscalation)) + operatorPod := OperatorPod(t, ctx, ns)() + g.Expect(operatorPod.Spec.Containers[0].SecurityContext.RunAsNonRoot).To(Equal(kubernetes.DefaultOperatorSecurityContext().RunAsNonRoot)) + g.Expect(operatorPod.Spec.Containers[0].SecurityContext.Capabilities).To(Equal(kubernetes.DefaultOperatorSecurityContext().Capabilities)) + g.Expect(operatorPod.Spec.Containers[0].SecurityContext.SeccompProfile).To(Equal(kubernetes.DefaultOperatorSecurityContext().SeccompProfile)) + g.Expect(operatorPod.Spec.Containers[0].SecurityContext.AllowPrivilegeEscalation).To(Equal(kubernetes.DefaultOperatorSecurityContext().AllowPrivilegeEscalation)) // Clean up - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) - Expect(Kamel("uninstall", "-n", ns).Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "uninstall", "-n", ns).Execute()).To(Succeed()) // Clean up cluster-wide resources that are not removed by OLM - Expect(Kamel("uninstall", "--all", "-n", ns, "--olm=false").Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "uninstall", "--all", "-n", ns, "--olm=false").Execute()).To(Succeed()) }) } diff --git a/e2e/install/upgrade/cli_upgrade_test.go b/e2e/install/upgrade/cli_upgrade_test.go index 9f87f753aa..90da1cb5ab 100644 --- a/e2e/install/upgrade/cli_upgrade_test.go +++ b/e2e/install/upgrade/cli_upgrade_test.go @@ -23,6 +23,7 @@ limitations under the License. package upgrade import ( + "context" "os" "testing" "time" @@ -30,6 +31,7 @@ import ( . "github.com/onsi/gomega" corev1 "k8s.io/api/core/v1" + kerrors "k8s.io/apimachinery/pkg/api/errors" . "github.com/apache/camel-k/v2/e2e/support" v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" @@ -38,94 +40,97 @@ import ( // WARNING: this test is not OLM specific but needs certain setting we provide in OLM installation scenario func TestCLIOperatorUpgrade(t *testing.T) { - WithNewTestNamespace(t, func(ns string) { + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { version, ok := os.LookupEnv("KAMEL_K_TEST_RELEASE_VERSION") - Expect(ok).To(BeTrue()) + g.Expect(ok).To(BeTrue()) image, ok := os.LookupEnv("KAMEL_K_TEST_OPERATOR_CURRENT_IMAGE") - Expect(ok).To(BeTrue()) + g.Expect(ok).To(BeTrue()) kamel, ok := os.LookupEnv("RELEASED_KAMEL_BIN") - Expect(ok).To(BeTrue()) + g.Expect(ok).To(BeTrue()) // Set KAMEL_BIN only for this test - don't override the ENV variable for all tests - Expect(os.Setenv("KAMEL_BIN", kamel)).To(Succeed()) + g.Expect(os.Setenv("KAMEL_BIN", kamel)).To(Succeed()) + + if len(CRDs(t)()) > 0 { + // Clean up old installation - maybe leftover from another test + if err := UninstallAll(t, ctx); err != nil && !kerrors.IsNotFound(err) { + t.Error(err) + t.FailNow() + } + } + g.Eventually(CRDs(t)).Should(HaveLen(0)) // Should both install the CRDs and kamel in the given namespace - Expect(Kamel( - "install", - "-n", - ns, - "--olm=false", - "--force", - "--base-image", - defaults.BaseImage(), - ).Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "install", "-n", ns, "--olm=false", "--force", "--base-image", defaults.BaseImage()).Execute()).To(Succeed()) // Check the operator pod is running - Eventually(OperatorPodPhase(ns), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) + g.Eventually(OperatorPodPhase(t, ctx, ns), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) // Refresh the test client to account for the newly installed CRDs - SyncClient() + RefreshClient(t) // Check the IntegrationPlatform has been reconciled - Eventually(PlatformVersion(ns), TestTimeoutMedium).Should(Equal(version)) + g.Eventually(PlatformVersion(t, ctx, ns), TestTimeoutMedium).Should(Equal(version)) // Run the Integration name := RandomizedSuffixName("yaml") - Expect(Kamel("run", "-n", ns, "--name", name, "files/yaml.yaml").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutLong).Should(Equal(corev1.ConditionTrue)) + g.Expect(Kamel(t, ctx, "run", "-n", ns, "--name", name, "files/yaml.yaml").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutLong).Should(Equal(corev1.ConditionTrue)) // Check the Integration version - Eventually(IntegrationVersion(ns, name)).Should(Equal(version)) + g.Eventually(IntegrationVersion(t, ctx, ns, name)).Should(Equal(version)) // Clear the KAMEL_BIN environment variable so that the current version is used from now on - Expect(os.Setenv("KAMEL_BIN", "")).To(Succeed()) + g.Expect(os.Setenv("KAMEL_BIN", "")).To(Succeed()) // Upgrade the operator by installing the current version - Expect(KamelInstall(ns, "--olm=false", "--force", "--operator-image", image, "--base-image", defaults.BaseImage()).Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "install", "-n", ns, "--olm=false", "--skip-default-kamelets-setup", "--force", "--operator-image", image, "--base-image", defaults.BaseImage()).Execute()).To(Succeed()) // Check the operator image is the current built one - Eventually(OperatorImage(ns)).Should(Equal(image)) + g.Eventually(OperatorImage(t, ctx, ns)).Should(Equal(image)) // Check the operator pod is running - Eventually(OperatorPodPhase(ns), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) + g.Eventually(OperatorPodPhase(t, ctx, ns), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) // Check the IntegrationPlatform has been reconciled - Eventually(PlatformPhase(ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) - Eventually(PlatformVersion(ns), TestTimeoutMedium).Should(Equal(defaults.Version)) + g.Eventually(PlatformPhase(t, ctx, ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + g.Eventually(PlatformVersion(t, ctx, ns), TestTimeoutMedium).Should(Equal(defaults.Version)) // Check the Integration hasn't been upgraded - Consistently(IntegrationVersion(ns, name), 5*time.Second, 1*time.Second).Should(Equal(version)) + g.Consistently(IntegrationVersion(t, ctx, ns, name), 5*time.Second, 1*time.Second).Should(Equal(version)) // Force the Integration upgrade - Expect(Kamel("rebuild", name, "-n", ns).Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "rebuild", name, "-n", ns).Execute()).To(Succeed()) // A catalog should be created with the new configuration - Eventually(DefaultCamelCatalogPhase(ns), TestTimeoutMedium).Should(Equal(v1.CamelCatalogPhaseReady)) + g.Eventually(DefaultCamelCatalogPhase(t, ctx, ns), TestTimeoutMedium).Should(Equal(v1.CamelCatalogPhaseReady)) // Check the Integration version has been upgraded - Eventually(IntegrationVersion(ns, name), TestTimeoutMedium).Should(Equal(defaults.Version)) + g.Eventually(IntegrationVersion(t, ctx, ns, name), TestTimeoutMedium).Should(Equal(defaults.Version)) // Check the previous kit is not garbage collected - Eventually(Kits(ns, KitWithVersion(version))).Should(HaveLen(1)) + g.Eventually(Kits(t, ctx, ns, KitWithVersion(version))).Should(HaveLen(1)) // Check a new kit is created with the current version - Eventually(Kits(ns, KitWithVersion(defaults.Version))).Should(HaveLen(1)) + g.Eventually(Kits(t, ctx, ns, KitWithVersion(defaults.Version))).Should(HaveLen(1)) // Check the new kit is ready - Eventually(Kits(ns, KitWithVersion(defaults.Version), KitWithPhase(v1.IntegrationKitPhaseReady)), + g.Eventually(Kits(t, ctx, ns, KitWithVersion(defaults.Version), KitWithPhase(v1.IntegrationKitPhaseReady)), TestTimeoutMedium).Should(HaveLen(1)) - kit := Kits(ns, KitWithVersion(defaults.Version))()[0] + kit := Kits(t, ctx, ns, KitWithVersion(defaults.Version))()[0] // Check the Integration uses the new image - Eventually(IntegrationKit(ns, name), TestTimeoutMedium).Should(Equal(kit.Name)) + g.Eventually(IntegrationKit(t, ctx, ns, name), TestTimeoutMedium).Should(Equal(kit.Name)) // Check the Integration Pod uses the new kit - Eventually(IntegrationPodImage(ns, name)).Should(Equal(kit.Status.Image)) + g.Eventually(IntegrationPodImage(t, ctx, ns, name)).Should(Equal(kit.Status.Image)) // Check the Integration runs correctly - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) // Clean up - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) - Expect(Kamel("uninstall", "--all", "-n", ns, "--olm=false").Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + // Delete Integration Platform as it does not get removed with uninstall and might cause next tests to fail + DeletePlatform(t, ctx, ns)() + g.Expect(Kamel(t, ctx, "uninstall", "--all", "-n", ns, "--olm=false").Execute()).To(Succeed()) }) } diff --git a/e2e/install/upgrade/helm_upgrade_test.go b/e2e/install/upgrade/helm_upgrade_test.go index 17287386d6..4b95bc59a4 100644 --- a/e2e/install/upgrade/helm_upgrade_test.go +++ b/e2e/install/upgrade/helm_upgrade_test.go @@ -23,21 +23,26 @@ limitations under the License. package upgrade import ( + "context" "errors" "fmt" "os" "os/exec" "testing" - . "github.com/apache/camel-k/v2/e2e/support" - "github.com/apache/camel-k/v2/pkg/util/defaults" . "github.com/onsi/gomega" + corev1 "k8s.io/api/core/v1" + kerrors "k8s.io/apimachinery/pkg/api/errors" + + . "github.com/apache/camel-k/v2/e2e/support" + "github.com/apache/camel-k/v2/pkg/util/defaults" ) // WARNING: this test is not OLM specific but needs certain setting we provide in OLM installation scenario func TestHelmOperatorUpgrade(t *testing.T) { - RegisterTestingT(t) + ctx := TestContext() + g := NewWithT(t) KAMEL_INSTALL_REGISTRY := os.Getenv("KAMEL_INSTALL_REGISTRY") // need to add last release version @@ -51,16 +56,22 @@ func TestHelmOperatorUpgrade(t *testing.T) { customImage := fmt.Sprintf("%s/apache/camel-k", KAMEL_INSTALL_REGISTRY) - os.Setenv("CAMEL_K_TEST_MAKE_DIR", "../../../") - - // Ensure no CRDs are already installed - UninstallAll() - Eventually(CRDs()).Should(HaveLen(0)) + if err := os.Setenv("CAMEL_K_TEST_MAKE_DIR", "../../../"); err != nil { + t.Logf("Unable to set makefile directory envvar - %s", err.Error()) + } - WithNewTestNamespace(t, func(ns string) { + if len(CRDs(t)()) > 0 { + // Clean up old installation - maybe leftover from another test + if err := UninstallAll(t, ctx); err != nil && !kerrors.IsNotFound(err) { + t.Error(err) + t.FailNow() + } + } + g.Eventually(CRDs(t), TestTimeoutMedium).Should(HaveLen(0)) + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { // Install operator in last released version - ExpectExecSucceed(t, + ExpectExecSucceed(t, g, exec.Command( "helm", "install", @@ -75,20 +86,20 @@ func TestHelmOperatorUpgrade(t *testing.T) { ), ) - Eventually(OperatorPod(ns)).ShouldNot(BeNil()) - Eventually(OperatorImage(ns)).Should(ContainSubstring(releaseVersion)) - Eventually(CRDs()).Should(HaveLen(ExpectedCRDs)) + g.Eventually(OperatorPod(t, ctx, ns)).ShouldNot(BeNil()) + g.Eventually(OperatorImage(t, ctx, ns)).Should(ContainSubstring(releaseVersion)) + g.Eventually(CRDs(t)).Should(HaveLen(GetExpectedCRDs(releaseVersion))) - //Test a simple route + // Test a simple route t.Run("simple route", func(t *testing.T) { name := RandomizedSuffixName("yaml") - Expect(KamelRun(ns, "files/yaml.yaml", "--name", name).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + g.Expect(KamelRun(t, ctx, ns, "files/yaml.yaml", "--name", name).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) }) // Delete CRDs with kustomize - ExpectExecSucceed(t, + ExpectExecSucceed(t, g, exec.Command( "kubectl", "delete", @@ -101,7 +112,7 @@ func TestHelmOperatorUpgrade(t *testing.T) { ) // Re-Create CRDs with kustomize - ExpectExecSucceed(t, + ExpectExecSucceed(t, g, exec.Command( "kubectl", "create", @@ -113,9 +124,9 @@ func TestHelmOperatorUpgrade(t *testing.T) { ) // Upgrade operator to current version - ExpectExecSucceed(t, Make(fmt.Sprintf("CUSTOM_IMAGE=%s", customImage), "set-version")) - ExpectExecSucceed(t, Make("release-helm")) - ExpectExecSucceed(t, + ExpectExecSucceed(t, g, Make(t, fmt.Sprintf("CUSTOM_IMAGE=%s", customImage), "set-version")) + ExpectExecSucceed(t, g, Make(t, "release-helm")) + ExpectExecSucceed(t, g, exec.Command( "helm", "upgrade", @@ -131,19 +142,25 @@ func TestHelmOperatorUpgrade(t *testing.T) { ), ) - Eventually(OperatorPod(ns)).ShouldNot(BeNil()) - Eventually(OperatorImage(ns)).Should(ContainSubstring(defaults.Version)) + g.Eventually(OperatorPod(t, ctx, ns)).ShouldNot(BeNil()) + g.Eventually(OperatorImage(t, ctx, ns)).Should(ContainSubstring(defaults.Version)) - //Test again a simple route + // Test again a simple route t.Run("simple route upgraded", func(t *testing.T) { name := RandomizedSuffixName("yaml") - Expect(KamelRun(ns, "files/yaml.yaml", "--name", name).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + g.Expect(KamelRun(t, ctx, ns, "files/yaml.yaml", "--name", name).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) }) + // Clean up + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + + // Delete Integration Platform as it does not get removed with uninstall and might cause next tests to fail + DeletePlatform(t, ctx, ns)() + // Uninstall with helm - ExpectExecSucceed(t, + ExpectExecSucceed(t, g, exec.Command( "helm", "uninstall", @@ -152,11 +169,11 @@ func TestHelmOperatorUpgrade(t *testing.T) { ns, ), ) - Eventually(OperatorPod(ns)).Should(BeNil()) + g.Eventually(OperatorPod(t, ctx, ns)).Should(BeNil()) // helm does not remove the CRDs - Eventually(CRDs()).Should(HaveLen(ExpectedCRDs)) - ExpectExecSucceed(t, + g.Eventually(CRDs(t)).Should(HaveLen(GetExpectedCRDs(defaults.Version))) + ExpectExecSucceed(t, g, exec.Command( "kubectl", "delete", @@ -166,6 +183,6 @@ func TestHelmOperatorUpgrade(t *testing.T) { ns, ), ) - Eventually(CRDs()).Should(HaveLen(0)) + g.Eventually(CRDs(t)).Should(HaveLen(0)) }) } diff --git a/e2e/install/upgrade/olm_upgrade_test.go b/e2e/install/upgrade/olm_upgrade_test.go index 9d0c71787b..ac8bcf4721 100644 --- a/e2e/install/upgrade/olm_upgrade_test.go +++ b/e2e/install/upgrade/olm_upgrade_test.go @@ -23,6 +23,7 @@ limitations under the License. package upgrade import ( + "context" "fmt" "os" "testing" @@ -31,7 +32,8 @@ import ( . "github.com/apache/camel-k/v2/e2e/support" v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" . "github.com/onsi/gomega" - "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + kerrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/types" ctrl "sigs.k8s.io/controller-runtime/pkg/client" @@ -64,24 +66,32 @@ func TestOLMOperatorUpgrade(t *testing.T) { t.Logf("Testing cross-OLM channel upgrade %s -> %s", prevUpdateChannel, newUpdateChannel) } - WithNewTestNamespace(t, func(ns string) { - - Expect(CreateOrUpdateCatalogSource(ns, catalogSourceName, prevIIB)).To(Succeed()) - ocp, err := openshift.IsOpenShift(TestClient()) - assert.Nil(t, err) + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { + g.Expect(CreateOrUpdateCatalogSource(t, ctx, ns, catalogSourceName, prevIIB)).To(Succeed()) + ocp, err := openshift.IsOpenShift(TestClient(t)) + require.NoError(t, err) if ocp { // Wait for pull secret to be created in namespace - // eg. test-camel-k-source-dockercfg-zlltn + // e.g. test-camel-k-source-dockercfg-zlltn secretPrefix := fmt.Sprintf("%s-dockercfg-", catalogSourceName) - Eventually(SecretByName(ns, secretPrefix), TestTimeoutLong).Should(Not(BeNil())) + g.Eventually(SecretByName(t, ctx, ns, secretPrefix), TestTimeoutLong).Should(Not(BeNil())) } - Eventually(CatalogSourcePodRunning(ns, catalogSourceName), TestTimeoutMedium).Should(BeNil()) - Eventually(CatalogSourcePhase(ns, catalogSourceName), TestTimeoutMedium).Should(Equal("READY")) + g.Eventually(CatalogSourcePodRunning(t, ctx, ns, catalogSourceName), TestTimeoutMedium).Should(BeNil()) + g.Eventually(CatalogSourcePhase(t, ctx, ns, catalogSourceName), TestTimeoutMedium).Should(Equal("READY")) // Set KAMEL_BIN only for this test - don't override the ENV variable for all tests - Expect(os.Setenv("KAMEL_BIN", kamel)).To(Succeed()) + g.Expect(os.Setenv("KAMEL_BIN", kamel)).To(Succeed()) + + if len(CRDs(t)()) > 0 { + // Clean up old installation - maybe leftover from another test + if err := UninstallAll(t, ctx); err != nil && !kerrors.IsNotFound(err) { + t.Error(err) + t.FailNow() + } + } + g.Eventually(CRDs(t)).Should(HaveLen(0)) args := []string{ "install", @@ -96,17 +106,17 @@ func TestOLMOperatorUpgrade(t *testing.T) { args = append(args, "--olm-channel", prevUpdateChannel) } - Expect(Kamel(args...).Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, args...).Execute()).To(Succeed()) // Find the only one Camel K CSV noAdditionalConditions := func(csv olm.ClusterServiceVersion) bool { return true } - Eventually(ClusterServiceVersionPhase(noAdditionalConditions, ns), TestTimeoutMedium). + g.Eventually(ClusterServiceVersionPhase(t, ctx, noAdditionalConditions, ns), TestTimeoutMedium). Should(Equal(olm.CSVPhaseSucceeded)) // Refresh the test client to account for the newly installed CRDs - SyncClient() + RefreshClient(t) var prevCSVVersion version.OperatorVersion var newCSVVersion version.OperatorVersion @@ -116,134 +126,136 @@ func TestOLMOperatorUpgrade(t *testing.T) { var prevIPVersionPrefix string var newIPVersionMajorMinorPatch string - prevCSVVersion = ClusterServiceVersion(noAdditionalConditions, ns)().Spec.Version + prevCSVVersion = ClusterServiceVersion(t, ctx, noAdditionalConditions, ns)().Spec.Version prevIPVersionPrefix = fmt.Sprintf("%d.%d", prevCSVVersion.Version.Major, prevCSVVersion.Version.Minor) t.Logf("Using Previous CSV Version: %s", prevCSVVersion.Version.String()) // Check the operator pod is running - Eventually(OperatorPodPhase(ns), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) + g.Eventually(OperatorPodPhase(t, ctx, ns), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) // Check the IntegrationPlatform has been reconciled - Eventually(PlatformVersion(ns)).Should(ContainSubstring(prevIPVersionPrefix)) + g.Eventually(PlatformVersion(t, ctx, ns)).Should(ContainSubstring(prevIPVersionPrefix)) name := "yaml" - Expect(Kamel("run", "-n", ns, "files/yaml.yaml").Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "run", "-n", ns, "files/yaml.yaml").Execute()).To(Succeed()) kbindName := "timer-to-log" - Expect(KamelBind(ns, "timer-source?message=Hello", "log-sink", "--name", kbindName).Execute()).To(Succeed()) + g.Expect(KamelBind(t, ctx, ns, "timer-source?message=Hello", "log-sink", "--name", kbindName).Execute()).To(Succeed()) // Check the Integration runs correctly - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutLong). + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutLong). Should(Equal(corev1.ConditionTrue)) if prevCSVVersion.Version.String() >= "2" { // since 2.0 Pipe, previously KameletBinding - Eventually(PipeConditionStatus(ns, kbindName, v1.PipeConditionReady), TestTimeoutShort). + g.Eventually(PipeConditionStatus(t, ctx, ns, kbindName, v1.PipeConditionReady), TestTimeoutShort). Should(Equal(corev1.ConditionTrue)) } - Eventually(IntegrationPodPhase(ns, kbindName), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, kbindName, v1.IntegrationConditionReady), TestTimeoutLong).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationPodPhase(t, ctx, ns, kbindName), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, kbindName, v1.IntegrationConditionReady), TestTimeoutLong).Should(Equal(corev1.ConditionTrue)) // Check the Integration version matches that of the current operator - Expect(IntegrationVersion(ns, name)()).To(ContainSubstring(prevIPVersionPrefix)) - Expect(IntegrationVersion(ns, kbindName)()).To(ContainSubstring(prevIPVersionPrefix)) + g.Expect(IntegrationVersion(t, ctx, ns, name)()).To(ContainSubstring(prevIPVersionPrefix)) + g.Expect(IntegrationVersion(t, ctx, ns, kbindName)()).To(ContainSubstring(prevIPVersionPrefix)) t.Run("OLM upgrade", func(t *testing.T) { // Trigger Camel K operator upgrade by updating the CatalogSource with the new index image - Expect(CreateOrUpdateCatalogSource(ns, catalogSourceName, newIIB)).To(Succeed()) + g.Expect(CreateOrUpdateCatalogSource(t, ctx, ns, catalogSourceName, newIIB)).To(Succeed()) if crossChannelUpgrade { t.Log("Patching Camel K OLM subscription channel.") - subscription, err := GetSubscription(ns) - Expect(err).To(BeNil()) - Expect(subscription).NotTo(BeNil()) + subscription, err := GetSubscription(t, ctx, ns) + g.Expect(err).To(BeNil()) + g.Expect(subscription).NotTo(BeNil()) // Patch the Subscription to avoid conflicts with concurrent updates performed by OLM patch := fmt.Sprintf("{\"spec\":{\"channel\":%q}}", newUpdateChannel) - Expect( - TestClient().Patch(TestContext, subscription, ctrl.RawPatch(types.MergePatchType, []byte(patch))), + g.Expect( + TestClient(t).Patch(ctx, subscription, ctrl.RawPatch(types.MergePatchType, []byte(patch))), ).To(Succeed()) // Assert the response back from the API server - Expect(subscription.Spec.Channel).To(Equal(newUpdateChannel)) + g.Expect(subscription.Spec.Channel).To(Equal(newUpdateChannel)) } // The new CSV is installed - Eventually(ClusterServiceVersionPhase(func(csv olm.ClusterServiceVersion) bool { + g.Eventually(ClusterServiceVersionPhase(t, ctx, func(csv olm.ClusterServiceVersion) bool { return csv.Spec.Version.Version.String() != prevCSVVersion.Version.String() }, ns), TestTimeoutMedium).Should(Equal(olm.CSVPhaseSucceeded)) // The old CSV is gone - Eventually(ClusterServiceVersion(func(csv olm.ClusterServiceVersion) bool { + g.Eventually(ClusterServiceVersion(t, ctx, func(csv olm.ClusterServiceVersion) bool { return csv.Spec.Version.Version.String() == prevCSVVersion.Version.String() }, ns), TestTimeoutMedium).Should(BeNil()) - newCSVVersion = ClusterServiceVersion(noAdditionalConditions, ns)().Spec.Version + newCSVVersion = ClusterServiceVersion(t, ctx, noAdditionalConditions, ns)().Spec.Version newIPVersionMajorMinorPatch = fmt.Sprintf("%d.%d.%d", newCSVVersion.Version.Major, newCSVVersion.Version.Minor, newCSVVersion.Version.Patch) - Expect(prevCSVVersion.Version.String()).NotTo(Equal(newCSVVersion.Version.String())) + g.Expect(prevCSVVersion.Version.String()).NotTo(Equal(newCSVVersion.Version.String())) - Eventually(OperatorPodPhase(ns), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) - Eventually(OperatorImage(ns), TestTimeoutShort).Should(Equal(defaults.OperatorImage())) + g.Eventually(OperatorPodPhase(t, ctx, ns), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) + g.Eventually(OperatorImage(t, ctx, ns), TestTimeoutShort).Should(Equal(defaults.OperatorImage())) // Check the IntegrationPlatform has been reconciled - Eventually(PlatformVersion(ns)).Should(ContainSubstring(newIPVersionMajorMinorPatch)) + g.Eventually(PlatformVersion(t, ctx, ns)).Should(ContainSubstring(newIPVersionMajorMinorPatch)) }) t.Run("Integration upgrade", func(t *testing.T) { // Clear the KAMEL_BIN environment variable so that the current version is used from now on - Expect(os.Setenv("KAMEL_BIN", "")).To(Succeed()) + g.Expect(os.Setenv("KAMEL_BIN", "")).To(Succeed()) // Check the Integration hasn't been upgraded - Consistently(IntegrationVersion(ns, name), 5*time.Second, 1*time.Second). + g.Consistently(IntegrationVersion(t, ctx, ns, name), 5*time.Second, 1*time.Second). Should(ContainSubstring(prevIPVersionPrefix)) // Rebuild the Integration - Expect(Kamel("rebuild", "--all", "-n", ns).Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "rebuild", "--all", "-n", ns).Execute()).To(Succeed()) if prevCSVVersion.Version.String() >= "2" { - Eventually(PipeConditionStatus(ns, kbindName, v1.PipeConditionReady), TestTimeoutMedium). + g.Eventually(PipeConditionStatus(t, ctx, ns, kbindName, v1.PipeConditionReady), TestTimeoutMedium). Should(Equal(corev1.ConditionTrue)) } // Check the Integration runs correctly - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutMedium). + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutMedium). Should(Equal(corev1.ConditionTrue)) // Check the Integration version has been upgraded - Eventually(IntegrationVersion(ns, name)).Should(ContainSubstring(newIPVersionMajorMinorPatch)) - Eventually(IntegrationVersion(ns, kbindName)).Should(ContainSubstring(newIPVersionMajorMinorPatch)) + g.Eventually(IntegrationVersion(t, ctx, ns, name)).Should(ContainSubstring(newIPVersionMajorMinorPatch)) + g.Eventually(IntegrationVersion(t, ctx, ns, kbindName)).Should(ContainSubstring(newIPVersionMajorMinorPatch)) // Check the previous kit is not garbage collected (skip Build - present in case of respin) prevCSVVersionMajorMinorPatch := fmt.Sprintf("%d.%d.%d", prevCSVVersion.Version.Major, prevCSVVersion.Version.Minor, prevCSVVersion.Version.Patch) - Eventually(Kits(ns, KitWithVersion(prevCSVVersionMajorMinorPatch))).Should(HaveLen(2)) + g.Eventually(Kits(t, ctx, ns, KitWithVersion(prevCSVVersionMajorMinorPatch))).Should(HaveLen(2)) // Check a new kit is created with the current version - Eventually(Kits(ns, KitWithVersionPrefix(newIPVersionMajorMinorPatch))).Should(HaveLen(2)) + g.Eventually(Kits(t, ctx, ns, KitWithVersionPrefix(newIPVersionMajorMinorPatch))).Should(HaveLen(2)) // Check the new kit is ready - Eventually(Kits(ns, KitWithVersionPrefix(newIPVersionMajorMinorPatch), KitWithPhase(v1.IntegrationKitPhaseReady)), + g.Eventually(Kits(t, ctx, ns, KitWithVersionPrefix(newIPVersionMajorMinorPatch), KitWithPhase(v1.IntegrationKitPhaseReady)), TestTimeoutMedium).Should(HaveLen(2)) - kit := Kits(ns, KitWithVersionPrefix(newIPVersionMajorMinorPatch), KitWithLabels(map[string]string{"camel.apache.org/created.by.name": name}))()[0] - kitKbind := Kits(ns, KitWithVersionPrefix(newIPVersionMajorMinorPatch), KitWithLabels(map[string]string{"camel.apache.org/created.by.name": kbindName}))()[0] + kit := Kits(t, ctx, ns, KitWithVersionPrefix(newIPVersionMajorMinorPatch), KitWithLabels(map[string]string{"camel.apache.org/created.by.name": name}))()[0] + kitKbind := Kits(t, ctx, ns, KitWithVersionPrefix(newIPVersionMajorMinorPatch), KitWithLabels(map[string]string{"camel.apache.org/created.by.name": kbindName}))()[0] // Check the Integration uses the new kit - Eventually(IntegrationKit(ns, name), TestTimeoutMedium).Should(Equal(kit.Name)) - Eventually(IntegrationKit(ns, kbindName), TestTimeoutMedium).Should(Equal(kitKbind.Name)) + g.Eventually(IntegrationKit(t, ctx, ns, name), TestTimeoutMedium).Should(Equal(kit.Name)) + g.Eventually(IntegrationKit(t, ctx, ns, kbindName), TestTimeoutMedium).Should(Equal(kitKbind.Name)) // Check the Integration Pod uses the new image - Eventually(IntegrationPodImage(ns, name)).Should(Equal(kit.Status.Image)) - Eventually(IntegrationPodImage(ns, kbindName)).Should(Equal(kitKbind.Status.Image)) + g.Eventually(IntegrationPodImage(t, ctx, ns, name)).Should(Equal(kit.Status.Image)) + g.Eventually(IntegrationPodImage(t, ctx, ns, kbindName)).Should(Equal(kitKbind.Status.Image)) // Check the Integration runs correctly - Eventually(IntegrationPodPhase(ns, name)).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationPodPhase(ns, kbindName)).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutLong). + g.Eventually(IntegrationPodPhase(t, ctx, ns, name)).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationPodPhase(t, ctx, ns, kbindName)).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutLong). Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationConditionStatus(ns, kbindName, v1.IntegrationConditionReady), TestTimeoutLong). + g.Eventually(IntegrationConditionStatus(t, ctx, ns, kbindName, v1.IntegrationConditionReady), TestTimeoutLong). Should(Equal(corev1.ConditionTrue)) // Clean up - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) - Expect(Kamel("uninstall", "-n", ns).Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) + // Delete Integration Platform as it does not get removed with uninstall and might cause next tests to fail + DeletePlatform(t, ctx, ns)() + g.Expect(Kamel(t, ctx, "uninstall", "-n", ns).Execute()).To(Succeed()) // Clean up cluster-wide resources that are not removed by OLM - Expect(Kamel("uninstall", "--all", "-n", ns, "--olm=false").Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "uninstall", "--all", "-n", ns, "--olm=false").Execute()).To(Succeed()) }) }) } diff --git a/e2e/knative/default.go b/e2e/knative/default.go index 20fe113af7..1def627793 100644 --- a/e2e/knative/default.go +++ b/e2e/knative/default.go @@ -20,7 +20,10 @@ limitations under the License. package knative -import "github.com/apache/camel-k/v2/e2e/support" +import ( + "github.com/apache/camel-k/v2/e2e/support" + "github.com/apache/camel-k/v2/pkg/platform" +) -var ns = support.GetEnvOrDefault("CAMEL_K_TEST_NAMESPACE", support.GetCIProcessID()) -var operatorID = support.GetEnvOrDefault("CAMEL_K_OPERATOR_ID", support.GetCIProcessID()) +var ns = support.GetEnvOrDefault("CAMEL_K_TEST_NAMESPACE", support.TestDefaultNamespace) +var operatorID = support.GetEnvOrDefault("CAMEL_K_OPERATOR_ID", platform.DefaultPlatformName) diff --git a/e2e/knative/kamelet_test.go b/e2e/knative/kamelet_test.go index 379bf0e70c..5a495f7330 100644 --- a/e2e/knative/kamelet_test.go +++ b/e2e/knative/kamelet_test.go @@ -38,58 +38,45 @@ import ( // Test that a Pipe can be changed and the changes are propagated to the Integration func TestKameletChange(t *testing.T) { - RegisterTestingT(t) + ctx := TestContext() + g := NewWithT(t) timerPipe := "timer-binding" knChannel := "test-kamelet-messages" knChannelConf := fmt.Sprintf("%s:InMemoryChannel:%s", messaging.SchemeGroupVersion.String(), knChannel) timerSource := "my-timer-source" - Expect(CreateTimerKamelet(ns, timerSource)()).To(Succeed()) - Expect(CreateKnativeChannel(ns, knChannel)()).To(Succeed()) + g.Expect(CreateTimerKamelet(t, ctx, operatorID, ns, timerSource)()).To(Succeed()) + g.Expect(CreateKnativeChannel(t, ctx, ns, knChannel)()).To(Succeed()) // Consumer route that will read from the KNative channel - Expect(KamelRunWithID(operatorID, ns, "files/test-kamelet-display.groovy", "-w").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "test-kamelet-display")).Should(Equal(corev1.PodRunning)) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/test-kamelet-display.groovy", "-w").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "test-kamelet-display")).Should(Equal(corev1.PodRunning)) // Create the Pipe - Expect(KamelBindWithID(operatorID, ns, - timerSource, - knChannelConf, - "-p", "source.message=HelloKNative!", - "--annotation", "trait.camel.apache.org/health.enabled=true", - "--annotation", "trait.camel.apache.org/health.readiness-initial-delay=10", - "--name", timerPipe, - ).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, timerPipe)).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, timerPipe, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Expect(KamelBindWithID(t, ctx, operatorID, ns, timerSource, knChannelConf, "-p", "source.message=HelloKNative!", "--annotation", "trait.camel.apache.org/health.enabled=true", "--annotation", "trait.camel.apache.org/health.readiness-initial-delay=10", "--name", timerPipe).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, timerPipe)).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, timerPipe, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) // Consume the message - Eventually(IntegrationLogs(ns, "test-kamelet-display"), TestTimeoutShort).Should(ContainSubstring("HelloKNative!")) + g.Eventually(IntegrationLogs(t, ctx, ns, "test-kamelet-display"), TestTimeoutShort).Should(ContainSubstring("HelloKNative!")) - Eventually(PipeCondition(ns, timerPipe, v1.PipeConditionReady), TestTimeoutMedium).Should(And( + g.Eventually(PipeCondition(t, ctx, ns, timerPipe, v1.PipeConditionReady), TestTimeoutMedium).Should(And( WithTransform(PipeConditionStatusExtract, Equal(corev1.ConditionTrue)), WithTransform(PipeConditionReason, Equal(v1.IntegrationConditionDeploymentReadyReason)), WithTransform(PipeConditionMessage, Equal(fmt.Sprintf("1/1 ready replicas"))), )) // Update the Pipe - Expect(KamelBindWithID(operatorID, ns, - timerSource, - knChannelConf, - "-p", "source.message=message is Hi", - "--annotation", "trait.camel.apache.org/health.enabled=true", - "--annotation", "trait.camel.apache.org/health.readiness-initial-delay=10", - "--name", timerPipe, - ).Execute()).To(Succeed()) - - Eventually(IntegrationPodPhase(ns, timerPipe), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, timerPipe, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "test-kamelet-display"), TestTimeoutShort).Should(ContainSubstring("message is Hi")) - - Eventually(PipeCondition(ns, timerPipe, v1.PipeConditionReady), TestTimeoutMedium). + g.Expect(KamelBindWithID(t, ctx, operatorID, ns, timerSource, knChannelConf, "-p", "source.message=message is Hi", "--annotation", "trait.camel.apache.org/health.enabled=true", "--annotation", "trait.camel.apache.org/health.readiness-initial-delay=10", "--name", timerPipe).Execute()).To(Succeed()) + + g.Eventually(IntegrationPodPhase(t, ctx, ns, timerPipe), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, timerPipe, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "test-kamelet-display"), TestTimeoutShort).Should(ContainSubstring("message is Hi")) + + g.Eventually(PipeCondition(t, ctx, ns, timerPipe, v1.PipeConditionReady), TestTimeoutMedium). Should(And( WithTransform(PipeConditionStatusExtract, Equal(corev1.ConditionTrue)), WithTransform(PipeConditionReason, Equal(v1.IntegrationConditionDeploymentReadyReason)), WithTransform(PipeConditionMessage, Equal("1/1 ready replicas")), )) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) } diff --git a/e2e/knative/knative_platform_test.go b/e2e/knative/knative_platform_test.go index 90b2d6704a..a6223495ee 100644 --- a/e2e/knative/knative_platform_test.go +++ b/e2e/knative/knative_platform_test.go @@ -23,13 +23,13 @@ limitations under the License. package knative import ( + "context" "strings" "testing" . "github.com/onsi/gomega" - "github.com/stretchr/testify/assert" - + "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" . "github.com/apache/camel-k/v2/e2e/support" @@ -39,54 +39,54 @@ import ( ) func TestKnativePlatformDetection(t *testing.T) { - RegisterTestingT(t) + g := NewWithT(t) - installed, err := knative.IsServingInstalled(TestClient()) - Expect(err).NotTo(HaveOccurred()) + installed, err := knative.IsServingInstalled(TestClient(t)) + g.Expect(err).NotTo(HaveOccurred()) if !installed { t.Error("Knative not installed in the cluster") t.FailNow() } - WithNewTestNamespace(t, func(ns string) { + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { operatorID := "camel-k-knative" - // Install withouth profile (should automatically detect the presence of KNative) - Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed()) - Eventually(PlatformPhase(ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) - Eventually(PlatformProfile(ns), TestTimeoutShort).Should(Equal(v1.TraitProfile(""))) - cluster := Platform(ns)().Status.Cluster + // Install without profile (should automatically detect the presence of Knative) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) + g.Eventually(PlatformPhase(t, ctx, ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + g.Eventually(PlatformProfile(t, ctx, ns), TestTimeoutShort).Should(Equal(v1.TraitProfile(""))) + cluster := Platform(t, ctx, ns)().Status.Cluster t.Run("run yaml on cluster profile", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "files/yaml.yaml", "--profile", string(cluster)).Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "yaml"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns, "yaml"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) - Eventually(IntegrationTraitProfile(ns, "yaml"), TestTimeoutShort).Should(Equal(v1.TraitProfile(string(cluster)))) - // Change something in the integration to produce a redeploy - Expect(UpdateIntegration(ns, "yaml", func(it *v1.Integration) { + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/yaml.yaml", "--profile", string(cluster)).Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "yaml"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, "yaml"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + g.Eventually(IntegrationTraitProfile(t, ctx, ns, "yaml"), TestTimeoutShort).Should(Equal(v1.TraitProfile(string(cluster)))) + // Change something in the integration to produce a redeployment + g.Expect(UpdateIntegration(t, ctx, ns, "yaml", func(it *v1.Integration) { it.Spec.Profile = "" content, err := dsl.ToYamlDSL(it.Spec.Flows) - assert.NoError(t, err) + require.NoError(t, err) newData := strings.ReplaceAll(string(content), "string!", "string!!!") newFlows, err := dsl.FromYamlDSLString(newData) - assert.NoError(t, err) + require.NoError(t, err) it.Spec.Flows = newFlows })).To(Succeed()) // Spec profile should be reset by "kamel run" - Eventually(IntegrationSpecProfile(ns, "yaml")).Should(Equal(v1.TraitProfile(""))) + g.Eventually(IntegrationSpecProfile(t, ctx, ns, "yaml")).Should(Equal(v1.TraitProfile(""))) // When integration is running again ... - Eventually(IntegrationPhase(ns, "yaml")).Should(Equal(v1.IntegrationPhaseRunning)) - Eventually(IntegrationLogs(ns, "yaml"), TestTimeoutShort).Should(ContainSubstring("Magicstring!!!")) + g.Eventually(IntegrationPhase(t, ctx, ns, "yaml")).Should(Equal(v1.IntegrationPhaseRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, "yaml"), TestTimeoutShort).Should(ContainSubstring("Magicstring!!!")) // It should keep the old profile saved in status - Eventually(IntegrationTraitProfile(ns, "yaml"), TestTimeoutMedium).Should(Equal(v1.TraitProfile(cluster))) + g.Eventually(IntegrationTraitProfile(t, ctx, ns, "yaml"), TestTimeoutMedium).Should(Equal(v1.TraitProfile(cluster))) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) t.Run("run yaml on automatic profile", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "files/yaml.yaml").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "yaml"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationTraitProfile(ns, "yaml"), TestTimeoutShort).Should(Equal(v1.TraitProfileKnative)) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/yaml.yaml").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "yaml"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationTraitProfile(t, ctx, ns, "yaml"), TestTimeoutShort).Should(Equal(v1.TraitProfileKnative)) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) }) } diff --git a/e2e/knative/knative_test.go b/e2e/knative/knative_test.go index 889eacc1d4..8cb1e624fa 100644 --- a/e2e/knative/knative_test.go +++ b/e2e/knative/knative_test.go @@ -23,6 +23,7 @@ limitations under the License. package knative import ( + "context" "fmt" "testing" "time" @@ -36,120 +37,120 @@ import ( ) func TestKnative(t *testing.T) { - RegisterTestingT(t) + ctx := TestContext() + g := NewWithT(t) knChannelMessages := "messages" knChannelWords := "words" - Expect(CreateKnativeChannel(ns, knChannelMessages)()).To(Succeed()) - Expect(CreateKnativeChannel(ns, knChannelWords)()).To(Succeed()) + g.Expect(CreateKnativeChannel(t, ctx, ns, knChannelMessages)()).To(Succeed()) + g.Expect(CreateKnativeChannel(t, ctx, ns, knChannelWords)()).To(Succeed()) t.Run("Service combo", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "files/knative2.groovy").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "knative2"), TestTimeoutLong).Should(Equal(v1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "knative2", camelv1.IntegrationConditionReady), TestTimeoutMedium).Should(Equal(v1.ConditionTrue)) - Expect(KamelRunWithID(operatorID, ns, "files/knative3.groovy").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "knative3"), TestTimeoutLong).Should(Equal(v1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "knative3", camelv1.IntegrationConditionReady), TestTimeoutMedium).Should(Equal(v1.ConditionTrue)) - Expect(KamelRunWithID(operatorID, ns, "files/knative1.groovy").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "knative1"), TestTimeoutLong).Should(Equal(v1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "knative1", camelv1.IntegrationConditionReady), TestTimeoutMedium).Should(Equal(v1.ConditionTrue)) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/knative2.groovy").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "knative2"), TestTimeoutLong).Should(Equal(v1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "knative2", camelv1.IntegrationConditionReady), TestTimeoutMedium).Should(Equal(v1.ConditionTrue)) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/knative3.groovy").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "knative3"), TestTimeoutLong).Should(Equal(v1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "knative3", camelv1.IntegrationConditionReady), TestTimeoutMedium).Should(Equal(v1.ConditionTrue)) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/knative1.groovy").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "knative1"), TestTimeoutLong).Should(Equal(v1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "knative1", camelv1.IntegrationConditionReady), TestTimeoutMedium).Should(Equal(v1.ConditionTrue)) // Correct logs - Eventually(IntegrationLogs(ns, "knative1"), TestTimeoutMedium).Should(ContainSubstring("Received from 2: Hello from knative2")) - Eventually(IntegrationLogs(ns, "knative1"), TestTimeoutMedium).Should(ContainSubstring("Received from 3: Hello from knative3")) + g.Eventually(IntegrationLogs(t, ctx, ns, "knative1"), TestTimeoutMedium).Should(ContainSubstring("Received from 2: Hello from knative2")) + g.Eventually(IntegrationLogs(t, ctx, ns, "knative1"), TestTimeoutMedium).Should(ContainSubstring("Received from 3: Hello from knative3")) // Incorrect logs - Consistently(IntegrationLogs(ns, "knative1"), 10*time.Second).ShouldNot(ContainSubstring("Received from 2: Hello from knative3")) - Consistently(IntegrationLogs(ns, "knative1"), 10*time.Second).ShouldNot(ContainSubstring("Received from 3: Hello from knative2")) + g.Consistently(IntegrationLogs(t, ctx, ns, "knative1"), 10*time.Second).ShouldNot(ContainSubstring("Received from 2: Hello from knative3")) + g.Consistently(IntegrationLogs(t, ctx, ns, "knative1"), 10*time.Second).ShouldNot(ContainSubstring("Received from 3: Hello from knative2")) // Clean up - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) t.Run("Channel combo v1beta1", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "files/knativech2.groovy").Execute()).To(Succeed()) - Expect(KamelRunWithID(operatorID, ns, "files/knativech1.groovy").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "knativech2"), TestTimeoutLong).Should(Equal(v1.PodRunning)) - Eventually(IntegrationPodPhase(ns, "knativech1"), TestTimeoutLong).Should(Equal(v1.PodRunning)) - Eventually(IntegrationLogs(ns, "knativech2"), TestTimeoutMedium).Should(ContainSubstring("Received: Hello from knativech1")) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/knativech2.groovy").Execute()).To(Succeed()) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/knativech1.groovy").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "knativech2"), TestTimeoutLong).Should(Equal(v1.PodRunning)) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "knativech1"), TestTimeoutLong).Should(Equal(v1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, "knativech2"), TestTimeoutMedium).Should(ContainSubstring("Received: Hello from knativech1")) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) t.Run("Channel combo get to post", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "files/knativegetpost2.groovy").Execute()).To(Succeed()) - Expect(KamelRunWithID(operatorID, ns, "files/knativegetpost1.groovy").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "knativegetpost2"), TestTimeoutLong).Should(Equal(v1.PodRunning)) - Eventually(IntegrationPodPhase(ns, "knativegetpost1"), TestTimeoutLong).Should(Equal(v1.PodRunning)) - Eventually(IntegrationLogs(ns, "knativegetpost2"), TestTimeoutMedium).Should(ContainSubstring(`Received ""`)) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/knativegetpost2.groovy").Execute()).To(Succeed()) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/knativegetpost1.groovy").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "knativegetpost2"), TestTimeoutLong).Should(Equal(v1.PodRunning)) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "knativegetpost1"), TestTimeoutLong).Should(Equal(v1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, "knativegetpost2"), TestTimeoutMedium).Should(ContainSubstring(`Received ""`)) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) t.Run("Multi channel chain", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "files/knativemultihop3.groovy").Execute()).To(Succeed()) - Expect(KamelRunWithID(operatorID, ns, "files/knativemultihop2.groovy").Execute()).To(Succeed()) - Expect(KamelRunWithID(operatorID, ns, "files/knativemultihop1.groovy").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "knativemultihop3"), TestTimeoutLong).Should(Equal(v1.PodRunning)) - Eventually(IntegrationPodPhase(ns, "knativemultihop2"), TestTimeoutLong).Should(Equal(v1.PodRunning)) - Eventually(IntegrationPodPhase(ns, "knativemultihop1"), TestTimeoutLong).Should(Equal(v1.PodRunning)) - Eventually(IntegrationLogs(ns, "knativemultihop3"), TestTimeoutMedium).Should(ContainSubstring(`From messages: message`)) - Eventually(IntegrationLogs(ns, "knativemultihop3"), TestTimeoutMedium).Should(ContainSubstring(`From words: word`)) - Eventually(IntegrationLogs(ns, "knativemultihop3"), TestTimeoutMedium).Should(ContainSubstring(`From words: transformed message`)) - Eventually(IntegrationLogs(ns, "knativemultihop3"), 10*time.Second).ShouldNot(ContainSubstring(`From messages: word`)) - Eventually(IntegrationLogs(ns, "knativemultihop3"), 10*time.Second).ShouldNot(ContainSubstring(`From words: message`)) - Eventually(IntegrationLogs(ns, "knativemultihop3"), 10*time.Second).ShouldNot(ContainSubstring(`From messages: transformed message`)) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/knativemultihop3.groovy").Execute()).To(Succeed()) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/knativemultihop2.groovy").Execute()).To(Succeed()) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/knativemultihop1.groovy").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "knativemultihop3"), TestTimeoutLong).Should(Equal(v1.PodRunning)) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "knativemultihop2"), TestTimeoutLong).Should(Equal(v1.PodRunning)) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "knativemultihop1"), TestTimeoutLong).Should(Equal(v1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, "knativemultihop3"), TestTimeoutMedium).Should(ContainSubstring(`From messages: message`)) + g.Eventually(IntegrationLogs(t, ctx, ns, "knativemultihop3"), TestTimeoutMedium).Should(ContainSubstring(`From words: word`)) + g.Eventually(IntegrationLogs(t, ctx, ns, "knativemultihop3"), TestTimeoutMedium).Should(ContainSubstring(`From words: transformed message`)) + g.Eventually(IntegrationLogs(t, ctx, ns, "knativemultihop3"), 10*time.Second).ShouldNot(ContainSubstring(`From messages: word`)) + g.Eventually(IntegrationLogs(t, ctx, ns, "knativemultihop3"), 10*time.Second).ShouldNot(ContainSubstring(`From words: message`)) + g.Eventually(IntegrationLogs(t, ctx, ns, "knativemultihop3"), 10*time.Second).ShouldNot(ContainSubstring(`From messages: transformed message`)) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) t.Run("Flow", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "files/flow.yaml").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "flow"), TestTimeoutLong).Should(Equal(v1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "flow", camelv1.IntegrationConditionReady), TestTimeoutLong).Should(Equal(v1.ConditionTrue)) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/flow.yaml").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "flow"), TestTimeoutLong).Should(Equal(v1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "flow", camelv1.IntegrationConditionReady), TestTimeoutLong).Should(Equal(v1.ConditionTrue)) t.Run("Scale to zero", func(t *testing.T) { - Eventually(IntegrationPod(ns, "flow"), TestTimeoutLong).Should(BeNil()) + g.Eventually(IntegrationPod(t, ctx, ns, "flow"), TestTimeoutLong).Should(BeNil()) }) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) t.Run("Knative-service disabled", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "files/http_out.groovy", "-t", "knative-service.enabled=false").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "http-out"), TestTimeoutLong).Should(Equal(v1.PodRunning)) - Eventually(Service(ns, "http-out"), TestTimeoutShort).ShouldNot(BeNil()) - Consistently(KnativeService(ns, "http-out"), TestTimeoutShort).Should(BeNil()) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/http_out.groovy", "-t", "knative-service.enabled=false").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "http-out"), TestTimeoutLong).Should(Equal(v1.PodRunning)) + g.Eventually(Service(t, ctx, ns, "http-out"), TestTimeoutShort).ShouldNot(BeNil()) + g.Consistently(KnativeService(t, ctx, ns, "http-out"), TestTimeoutShort).Should(BeNil()) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) t.Run("Knative-service priority", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "files/http_out.groovy").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "http-out"), TestTimeoutLong).Should(Equal(v1.PodRunning)) - Eventually(KnativeService(ns, "http-out"), TestTimeoutShort).ShouldNot(BeNil()) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/http_out.groovy").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "http-out"), TestTimeoutLong).Should(Equal(v1.PodRunning)) + g.Eventually(KnativeService(t, ctx, ns, "http-out"), TestTimeoutShort).ShouldNot(BeNil()) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) t.Run("Knative-service annotation", func(t *testing.T) { - Expect(KamelRunWithID(operatorID, ns, "files/knative2.groovy", - "-t", "knative-service.annotations.'haproxy.router.openshift.io/balance'=roundrobin").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "knative2"), TestTimeoutLong).Should(Equal(v1.PodRunning)) - Eventually(KnativeService(ns, "knative2"), TestTimeoutShort).ShouldNot(BeNil()) - ks := KnativeService(ns, "knative2")() + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/knative2.groovy", "-t", "knative-service.annotations.'haproxy.router.openshift.io/balance'=roundrobin").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "knative2"), TestTimeoutLong).Should(Equal(v1.PodRunning)) + g.Eventually(KnativeService(t, ctx, ns, "knative2"), TestTimeoutShort).ShouldNot(BeNil()) + ks := KnativeService(t, ctx, ns, "knative2")() annotations := ks.ObjectMeta.Annotations - Expect(annotations["haproxy.router.openshift.io/balance"]).To(Equal("roundrobin")) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + g.Expect(annotations["haproxy.router.openshift.io/balance"]).To(Equal("roundrobin")) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) } func TestRunBroker(t *testing.T) { - RegisterTestingT(t) - - WithNewTestNamespaceWithKnativeBroker(t, func(ns string) { + WithNewTestNamespaceWithKnativeBroker(t, func(ctx context.Context, g *WithT, ns string) { operatorID := fmt.Sprintf("camel-k-%s", ns) - Expect(KamelInstallWithID(operatorID, ns, "--trait-profile", "knative").Execute()).To(Succeed()) - - Expect(KamelRunWithID(operatorID, ns, "files/knativeevt1.groovy").Execute()).To(Succeed()) - Expect(KamelRunWithID(operatorID, ns, "files/knativeevt2.groovy").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "knativeevt1"), TestTimeoutLong).Should(Equal(v1.PodRunning)) - Eventually(IntegrationPodPhase(ns, "knativeevt2"), TestTimeoutLong).Should(Equal(v1.PodRunning)) - Eventually(IntegrationLogs(ns, "knativeevt2"), TestTimeoutMedium).Should(ContainSubstring("Received 1: Hello 1")) - Eventually(IntegrationLogs(ns, "knativeevt2"), TestTimeoutMedium).Should(ContainSubstring("Received 2: Hello 2")) - Eventually(IntegrationLogs(ns, "knativeevt2")).ShouldNot(ContainSubstring("Received 1: Hello 2")) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns, "--trait-profile", "knative")).To(Succeed()) + + g.Eventually(SelectedPlatformPhase(t, ctx, ns, operatorID), TestTimeoutMedium).Should(Equal(camelv1.IntegrationPlatformPhaseReady)) + + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/knativeevt1.groovy").Execute()).To(Succeed()) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/knativeevt2.groovy").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "knativeevt1"), TestTimeoutLong).Should(Equal(v1.PodRunning)) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "knativeevt2"), TestTimeoutLong).Should(Equal(v1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, "knativeevt2"), TestTimeoutMedium).Should(ContainSubstring("Received 1: Hello 1")) + g.Eventually(IntegrationLogs(t, ctx, ns, "knativeevt2"), TestTimeoutMedium).Should(ContainSubstring("Received 2: Hello 2")) + g.Eventually(IntegrationLogs(t, ctx, ns, "knativeevt2")).ShouldNot(ContainSubstring("Received 1: Hello 2")) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) } diff --git a/e2e/knative/openapi_test.go b/e2e/knative/openapi_test.go index d26bba8896..a8f8457187 100644 --- a/e2e/knative/openapi_test.go +++ b/e2e/knative/openapi_test.go @@ -27,34 +27,31 @@ import ( . "github.com/apache/camel-k/v2/e2e/support" . "github.com/onsi/gomega" - "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "io/ioutil" ) func TestOpenAPIService(t *testing.T) { - RegisterTestingT(t) + ctx := TestContext() + g := NewWithT(t) openapiContent, err := ioutil.ReadFile("./files/petstore-api.yaml") - assert.Nil(t, err) + require.NoError(t, err) var cmDataProps = make(map[string]string) cmDataProps["petstore-api.yaml"] = string(openapiContent) - CreatePlainTextConfigmap(ns, "my-openapi-knative", cmDataProps) + CreatePlainTextConfigmap(t, ctx, ns, "my-openapi-knative", cmDataProps) - Expect(KamelRunWithID(operatorID, ns, - "--name", "petstore", - "--open-api", "configmap:my-openapi-knative", - "files/petstore.groovy", - ).Execute()).To(Succeed()) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "--name", "petstore", "--open-api", "configmap:my-openapi-knative", "files/petstore.groovy").Execute()).To(Succeed()) - Eventually(KnativeService(ns, "petstore"), TestTimeoutLong). + g.Eventually(KnativeService(t, ctx, ns, "petstore"), TestTimeoutLong). Should(Not(BeNil())) - Eventually(IntegrationLogs(ns, "petstore"), TestTimeoutMedium). + g.Eventually(IntegrationLogs(t, ctx, ns, "petstore"), TestTimeoutMedium). Should(ContainSubstring("Started listPets (rest://get:/v1:/pets)")) - Eventually(IntegrationLogs(ns, "petstore"), TestTimeoutMedium). + g.Eventually(IntegrationLogs(t, ctx, ns, "petstore"), TestTimeoutMedium). Should(ContainSubstring("Started createPets (rest://post:/v1:/pets)")) - Eventually(IntegrationLogs(ns, "petstore"), TestTimeoutMedium). + g.Eventually(IntegrationLogs(t, ctx, ns, "petstore"), TestTimeoutMedium). Should(ContainSubstring("Started showPetById (rest://get:/v1:/pets/%7BpetId%7D)")) - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) } diff --git a/e2e/knative/pod_test.go b/e2e/knative/pod_test.go index bb7d4e083a..de84434d45 100644 --- a/e2e/knative/pod_test.go +++ b/e2e/knative/pod_test.go @@ -34,16 +34,16 @@ import ( ) func TestPodTraitWithKnative(t *testing.T) { - RegisterTestingT(t) - - Expect(KamelRunWithID(operatorID, ns, "files/podtest-knative2.groovy", - "--pod-template", "files/template-knative.yaml").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "podtest-knative2"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "podtest-knative2", v1.IntegrationConditionReady), TestTimeoutMedium).Should(Equal(corev1.ConditionTrue)) - Expect(KamelRunWithID(operatorID, ns, "files/podtest-knative1.groovy").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "podtest-knative1"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationConditionStatus(ns, "podtest-knative1", v1.IntegrationConditionReady), TestTimeoutMedium).Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, "podtest-knative1"), TestTimeoutShort).Should(ContainSubstring("hello from the template")) - - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + ctx := TestContext() + g := NewWithT(t) + + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/podtest-knative2.groovy", "--pod-template", "files/template-knative.yaml").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "podtest-knative2"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "podtest-knative2", v1.IntegrationConditionReady), TestTimeoutMedium).Should(Equal(corev1.ConditionTrue)) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/podtest-knative1.groovy").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "podtest-knative1"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, "podtest-knative1", v1.IntegrationConditionReady), TestTimeoutMedium).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, "podtest-knative1"), TestTimeoutShort).Should(ContainSubstring("hello from the template")) + + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) } diff --git a/e2e/knative/support/startup_test.go b/e2e/knative/support/startup_test.go deleted file mode 100644 index da04425dbe..0000000000 --- a/e2e/knative/support/startup_test.go +++ /dev/null @@ -1,51 +0,0 @@ -//go:build integration -// +build integration - -// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration" - -/* -Licensed to the Apache Software Foundation (ASF) under one or more -contributor license agreements. See the NOTICE file distributed with -this work for additional information regarding copyright ownership. -The ASF licenses this file to You under the Apache License, Version 2.0 -(the "License"); you may not use this file except in compliance with -the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package support - -import ( - "testing" - - . "github.com/onsi/gomega" - corev1 "k8s.io/api/core/v1" - - . "github.com/apache/camel-k/v2/e2e/support" - v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" -) - -func TestKNativeCamelKInstallStartup(t *testing.T) { - RegisterTestingT(t) - - ns := NewTestNamespace(false) - Expect(ns).ShouldNot(BeNil()) - // the namespace is dynamic if there is some collision - // we store this value as it will be used for cleaning in the teardown process - SaveCIProcessID(ns.GetName()) - // fail fast if something did not work writing the resource - Expect(GetCIProcessID()).ShouldNot(Equal("")) - - Expect(KamelInstallWithIDAndKameletCatalog(ns.GetName(), ns.GetName(), "--trait-profile", "knative").Execute()).To(Succeed()) - Eventually(OperatorPod(ns.GetName())).ShouldNot(BeNil()) - Eventually(Platform(ns.GetName())).ShouldNot(BeNil()) - Eventually(PlatformConditionStatus(ns.GetName(), v1.IntegrationPlatformConditionTypeCreated), TestTimeoutShort). - Should(Equal(corev1.ConditionTrue)) -} diff --git a/e2e/knative/support/teardown_test.go b/e2e/knative/support/teardown_test.go deleted file mode 100644 index af4f0c9d8a..0000000000 --- a/e2e/knative/support/teardown_test.go +++ /dev/null @@ -1,40 +0,0 @@ -//go:build integration -// +build integration - -// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration" - -/* -Licensed to the Apache Software Foundation (ASF) under one or more -contributor license agreements. See the NOTICE file distributed with -this work for additional information regarding copyright ownership. -The ASF licenses this file to You under the Apache License, Version 2.0 -(the "License"); you may not use this file except in compliance with -the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package support - -import ( - "testing" - - . "github.com/onsi/gomega" - - . "github.com/apache/camel-k/v2/e2e/support" -) - -func TestKNativeCamelKInstallTeardown(t *testing.T) { - RegisterTestingT(t) - - ns := GetCIProcessID() - Expect(ns).ShouldNot(Equal("")) - Expect(DeleteNamespace(t, ns)).To(Succeed()) - DeleteCIProcessID() -} diff --git a/e2e/native/native_binding_test.go b/e2e/native/native_binding_test.go index 4ee9ad92d9..b4af7a4b2c 100644 --- a/e2e/native/native_binding_test.go +++ b/e2e/native/native_binding_test.go @@ -23,6 +23,7 @@ limitations under the License. package native import ( + "context" . "github.com/apache/camel-k/v2/e2e/support" v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" . "github.com/onsi/gomega" @@ -31,44 +32,34 @@ import ( ) func TestNativeBinding(t *testing.T) { - WithNewTestNamespace(t, func(ns string) { + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { operatorID := "camel-k-native-binding" - Expect(KamelInstallWithIDAndKameletCatalog(operatorID, ns, - "--build-timeout", "90m0s", - "--maven-cli-option", "-Dquarkus.native.native-image-xmx=6g", - ).Execute()).To(Succeed()) - Eventually(PlatformPhase(ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + g.Expect(KamelInstallWithIDAndKameletCatalog(t, ctx, operatorID, ns, "--build-timeout", "90m0s", "--maven-cli-option", "-Dquarkus.native.native-image-xmx=6g")).To(Succeed()) + g.Eventually(PlatformPhase(t, ctx, ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) message := "Magicstring!" t.Run("binding with native build", func(t *testing.T) { bindingName := "native-binding" - Expect(KamelBindWithID(operatorID, ns, - "timer-source", - "log-sink", - "-p", "source.message="+message, - "--annotation", "trait.camel.apache.org/quarkus.build-mode=native", - "--annotation", "trait.camel.apache.org/builder.tasks-limit-memory=quarkus-native:6.5Gi", - "--name", bindingName, - ).Execute()).To(Succeed()) + g.Expect(KamelBindWithID(t, ctx, operatorID, ns, "timer-source", "log-sink", "-p", "source.message="+message, "--annotation", "trait.camel.apache.org/quarkus.build-mode=native", "--annotation", "trait.camel.apache.org/builder.tasks-limit-memory=quarkus-native:6.5Gi", "--name", bindingName).Execute()).To(Succeed()) // ==================================== // !!! THE MOST TIME-CONSUMING PART !!! // ==================================== - Eventually(Kits(ns, withNativeLayout, KitWithPhase(v1.IntegrationKitPhaseReady)), + g.Eventually(Kits(t, ctx, ns, withNativeLayout, KitWithPhase(v1.IntegrationKitPhaseReady)), TestTimeoutVeryLong).Should(HaveLen(1)) - nativeKit := Kits(ns, withNativeLayout, KitWithPhase(v1.IntegrationKitPhaseReady))()[0] - Eventually(IntegrationKit(ns, bindingName), TestTimeoutShort).Should(Equal(nativeKit.Name)) + nativeKit := Kits(t, ctx, ns, withNativeLayout, KitWithPhase(v1.IntegrationKitPhaseReady))()[0] + g.Eventually(IntegrationKit(t, ctx, ns, bindingName), TestTimeoutShort).Should(Equal(nativeKit.Name)) - Eventually(IntegrationPodPhase(ns, bindingName), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns, bindingName), TestTimeoutShort).Should(ContainSubstring(message)) + g.Eventually(IntegrationPodPhase(t, ctx, ns, bindingName), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, bindingName), TestTimeoutShort).Should(ContainSubstring(message)) - Eventually(IntegrationPod(ns, bindingName), TestTimeoutShort). + g.Eventually(IntegrationPod(t, ctx, ns, bindingName), TestTimeoutShort). Should(WithTransform(getContainerCommand(), MatchRegexp(".*camel-k-integration-\\d+\\.\\d+\\.\\d+[-A-Za-z]*-runner.*"))) // Clean up - Expect(Kamel("delete", bindingName, "-n", ns).Execute()).To(Succeed()) - Expect(DeleteKits(ns)).To(Succeed()) + g.Expect(Kamel(t, ctx, "delete", bindingName, "-n", ns).Execute()).To(Succeed()) + g.Expect(DeleteKits(t, ctx, ns)).To(Succeed()) }) }) } diff --git a/e2e/native/native_test.go b/e2e/native/native_test.go index b4d0cc8b67..ac726c04fc 100644 --- a/e2e/native/native_test.go +++ b/e2e/native/native_test.go @@ -23,6 +23,7 @@ limitations under the License. package native import ( + "context" "testing" . "github.com/onsi/gomega" @@ -35,130 +36,114 @@ import ( ) func TestNativeIntegrations(t *testing.T) { - WithNewTestNamespace(t, func(ns string) { + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { operatorID := "camel-k-quarkus-native" - Expect(KamelInstallWithID(operatorID, ns, - "--build-timeout", "90m0s", - "--maven-cli-option", "-Dquarkus.native.native-image-xmx=6g", - ).Execute()).To(Succeed()) - Eventually(PlatformPhase(ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns, "--build-timeout", "90m0s", "--maven-cli-option", "-Dquarkus.native.native-image-xmx=6g")).To(Succeed()) + g.Eventually(PlatformPhase(t, ctx, ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) t.Run("unsupported integration source language", func(t *testing.T) { name := RandomizedSuffixName("unsupported-js") - Expect(KamelRunWithID(operatorID, ns, "files/JavaScript.js", "--name", name, - "-t", "quarkus.build-mode=native", - "-t", "builder.tasks-limit-memory=quarkus-native:6.5Gi", - ).Execute()).To(Succeed()) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/JavaScript.js", "--name", name, "-t", "quarkus.build-mode=native", "-t", "builder.tasks-limit-memory=quarkus-native:6.5Gi").Execute()).To(Succeed()) - Eventually(IntegrationPhase(ns, name)).Should(Equal(v1.IntegrationPhaseError)) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionKitAvailable)). + g.Eventually(IntegrationPhase(t, ctx, ns, name)).Should(Equal(v1.IntegrationPhaseError)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionKitAvailable)). Should(Equal(corev1.ConditionFalse)) // check integration schema does not contains unwanted default trait value. - Eventually(UnstructuredIntegration(ns, name)).ShouldNot(BeNil()) - unstructuredIntegration := UnstructuredIntegration(ns, name)() + g.Eventually(UnstructuredIntegration(t, ctx, ns, name)).ShouldNot(BeNil()) + unstructuredIntegration := UnstructuredIntegration(t, ctx, ns, name)() quarkusTrait, _, _ := unstructured.NestedMap(unstructuredIntegration.Object, "spec", "traits", "quarkus") - Expect(quarkusTrait).ToNot(BeNil()) - Expect(len(quarkusTrait)).To(Equal(1)) - Expect(quarkusTrait["buildMode"]).ToNot(BeNil()) + g.Expect(quarkusTrait).ToNot(BeNil()) + g.Expect(len(quarkusTrait)).To(Equal(1)) + g.Expect(quarkusTrait["buildMode"]).ToNot(BeNil()) // Clean up - Expect(Kamel("delete", name, "-n", ns).Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "delete", name, "-n", ns).Execute()).To(Succeed()) }) t.Run("xml native support", func(t *testing.T) { name := RandomizedSuffixName("xml-native") - Expect(KamelRunWithID(operatorID, ns, "files/Xml.xml", "--name", name, - "-t", "quarkus.build-mode=native", - "-t", "builder.tasks-limit-memory=quarkus-native:6.5Gi", - ).Execute()).To(Succeed()) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Xml.xml", "--name", name, "-t", "quarkus.build-mode=native", "-t", "builder.tasks-limit-memory=quarkus-native:6.5Gi").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutVeryLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationPod(ns, name), TestTimeoutShort). + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutVeryLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationPod(t, ctx, ns, name), TestTimeoutShort). Should(WithTransform(getContainerCommand(), MatchRegexp(".*camel-k-integration-\\d+\\.\\d+\\.\\d+[-A-Za-z]*-runner.*"))) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort). + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort). Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("XML Magicstring!")) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("XML Magicstring!")) // Clean up - Expect(Kamel("delete", name, "-n", ns).Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "delete", name, "-n", ns).Execute()).To(Succeed()) }) t.Run("automatic rollout deployment from jvm to native kit", func(t *testing.T) { // Let's make sure we start from a clean state - Expect(DeleteKits(ns)).To(Succeed()) + g.Expect(DeleteKits(t, ctx, ns)).To(Succeed()) name := RandomizedSuffixName("yaml-native") - Expect(KamelRunWithID(operatorID, ns, "files/yaml.yaml", "--name", name, - "-t", "quarkus.build-mode=jvm", - "-t", "quarkus.build-mode=native", - "-t", "builder.tasks-limit-memory=quarkus-native:6.5Gi", - ).Execute()).To(Succeed()) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/yaml.yaml", "--name", name, "-t", "quarkus.build-mode=jvm", "-t", "quarkus.build-mode=native", "-t", "builder.tasks-limit-memory=quarkus-native:6.5Gi").Execute()).To(Succeed()) // Check that two Kits are created with distinct layout - Eventually(Kits(ns, withFastJarLayout)).Should(HaveLen(1)) - Eventually(Kits(ns, withNativeLayout)).Should(HaveLen(1)) + g.Eventually(Kits(t, ctx, ns, withFastJarLayout)).Should(HaveLen(1)) + g.Eventually(Kits(t, ctx, ns, withNativeLayout)).Should(HaveLen(1)) // Check the fast-jar Kit is ready - Eventually(Kits(ns, withFastJarLayout, KitWithPhase(v1.IntegrationKitPhaseReady)), + g.Eventually(Kits(t, ctx, ns, withFastJarLayout, KitWithPhase(v1.IntegrationKitPhaseReady)), TestTimeoutLong).Should(HaveLen(1)) - fastJarKit := Kits(ns, withFastJarLayout, KitWithPhase(v1.IntegrationKitPhaseReady))()[0] + fastJarKit := Kits(t, ctx, ns, withFastJarLayout, KitWithPhase(v1.IntegrationKitPhaseReady))()[0] // Check the Integration uses the fast-jar Kit - Eventually(IntegrationKit(ns, name), TestTimeoutShort).Should(Equal(fastJarKit.Name)) + g.Eventually(IntegrationKit(t, ctx, ns, name), TestTimeoutShort).Should(Equal(fastJarKit.Name)) // Check the Integration Pod uses the fast-jar Kit - Eventually(IntegrationPodImage(ns, name)).Should(Equal(fastJarKit.Status.Image)) + g.Eventually(IntegrationPodImage(t, ctx, ns, name)).Should(Equal(fastJarKit.Status.Image)) // Check the Integration is ready - Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationPod(ns, name), TestTimeoutShort). + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationPod(t, ctx, ns, name), TestTimeoutShort). Should(WithTransform(getContainerCommand(), ContainSubstring("java"))) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort). + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort). Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutMedium).Should(ContainSubstring("Magicstring!")) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutMedium).Should(ContainSubstring("Magicstring!")) // ==================================== // !!! THE MOST TIME-CONSUMING PART !!! // ==================================== // Check the native Kit is ready - Eventually(Kits(ns, withNativeLayout, KitWithPhase(v1.IntegrationKitPhaseReady)), + g.Eventually(Kits(t, ctx, ns, withNativeLayout, KitWithPhase(v1.IntegrationKitPhaseReady)), TestTimeoutVeryLong).Should(HaveLen(1)) - nativeKit := Kits(ns, withNativeLayout, KitWithPhase(v1.IntegrationKitPhaseReady))()[0] + nativeKit := Kits(t, ctx, ns, withNativeLayout, KitWithPhase(v1.IntegrationKitPhaseReady))()[0] // Check the Integration uses the native Kit - Eventually(IntegrationKit(ns, name), TestTimeoutShort).Should(Equal(nativeKit.Name)) + g.Eventually(IntegrationKit(t, ctx, ns, name), TestTimeoutShort).Should(Equal(nativeKit.Name)) // Check the Integration Pod uses the native Kit - Eventually(IntegrationPodImage(ns, name)).Should(Equal(nativeKit.Status.Image)) + g.Eventually(IntegrationPodImage(t, ctx, ns, name)).Should(Equal(nativeKit.Status.Image)) // Check the Integration is still ready - Eventually(IntegrationPodPhase(ns, name), TestTimeoutVeryLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationPod(ns, name), TestTimeoutShort). + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutVeryLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationPod(t, ctx, ns, name), TestTimeoutShort). Should(WithTransform(getContainerCommand(), MatchRegexp(".*camel-k-integration-\\d+\\.\\d+\\.\\d+[-A-Za-z]*-runner.*"))) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort). + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort). Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) t.Run("yaml native should not rebuild", func(t *testing.T) { name := RandomizedSuffixName("yaml-native-2") - Expect(KamelRunWithID(operatorID, ns, "files/yaml2.yaml", "--name", name, - "-t", "quarkus.build-mode=native", - "-t", "builder.tasks-limit-memory=quarkus-native:6.5Gi", - ).Execute()).To(Succeed()) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/yaml2.yaml", "--name", name, "-t", "quarkus.build-mode=native", "-t", "builder.tasks-limit-memory=quarkus-native:6.5Gi").Execute()).To(Succeed()) // This one should run quickly as it suppose to reuse an IntegrationKit - Eventually(IntegrationPodPhase(ns, name), TestTimeoutShort).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationPod(ns, name), TestTimeoutShort). + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutShort).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationPod(t, ctx, ns, name), TestTimeoutShort). Should(WithTransform(getContainerCommand(), MatchRegexp(".*camel-k-integration-\\d+\\.\\d+\\.\\d+[-A-Za-z]*-runner.*"))) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort). + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort). Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!2")) - Eventually(IntegrationKit(ns, "yaml-native-2")).Should(Equal(IntegrationKit(ns, "yaml-native")())) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!2")) + g.Eventually(IntegrationKit(t, ctx, ns, "yaml-native-2")).Should(Equal(IntegrationKit(t, ctx, ns, "yaml-native")())) }) // Clean up - Expect(Kamel("delete", name, "-n", ns).Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "delete", name, "-n", ns).Execute()).To(Succeed()) }) }) diff --git a/e2e/native/native_with_sources_test.go b/e2e/native/native_with_sources_test.go index c3a868852e..989f612c19 100644 --- a/e2e/native/native_with_sources_test.go +++ b/e2e/native/native_with_sources_test.go @@ -23,6 +23,7 @@ limitations under the License. package native import ( + "context" "testing" . "github.com/onsi/gomega" @@ -33,13 +34,10 @@ import ( ) func TestNativeHighMemoryIntegrations(t *testing.T) { - WithNewTestNamespace(t, func(ns string) { + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { operatorID := "camel-k-quarkus-high-memory-native" - Expect(KamelInstallWithID(operatorID, ns, - "--build-timeout", "90m0s", - "--maven-cli-option", "-Dquarkus.native.native-image-xmx=9g", - ).Execute()).To(Succeed()) - Eventually(PlatformPhase(ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns, "--build-timeout", "90m0s", "--maven-cli-option", "-Dquarkus.native.native-image-xmx=9g")).To(Succeed()) + g.Eventually(PlatformPhase(t, ctx, ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) javaNativeName := RandomizedSuffixName("java-native") javaNativeCloneName := RandomizedSuffixName("java-native-clone") @@ -47,91 +45,76 @@ func TestNativeHighMemoryIntegrations(t *testing.T) { t.Run("java native support", func(t *testing.T) { name := javaNativeName - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", "--name", name, - "-t", "quarkus.build-mode=native", - "-t", "builder.tasks-limit-memory=quarkus-native:9.5Gi", - ).Execute()).To(Succeed()) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", name, "-t", "quarkus.build-mode=native", "-t", "builder.tasks-limit-memory=quarkus-native:9.5Gi").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutVeryLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationPod(ns, name), TestTimeoutShort). + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutVeryLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationPod(t, ctx, ns, name), TestTimeoutShort). Should(WithTransform(getContainerCommand(), MatchRegexp(".*camel-k-integration-\\d+\\.\\d+\\.\\d+[-A-Za-z]*-runner.*"))) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort). + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort). Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Java Magicstring!")) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Java Magicstring!")) t.Run("java native same should not rebuild", func(t *testing.T) { name := javaNativeCloneName - Expect(KamelRunWithID(operatorID, ns, "files/Java.java", "--name", name, - "-t", "quarkus.build-mode=native", - "-t", "builder.tasks-limit-memory=quarkus-native:9.5Gi", - ).Execute()).To(Succeed()) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java.java", "--name", name, "-t", "quarkus.build-mode=native", "-t", "builder.tasks-limit-memory=quarkus-native:9.5Gi").Execute()).To(Succeed()) // This one should run quickly as it suppose to reuse an IntegrationKit - Eventually(IntegrationPodPhase(ns, name), TestTimeoutShort).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationPod(ns, name), TestTimeoutShort). + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutShort).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationPod(t, ctx, ns, name), TestTimeoutShort). Should(WithTransform(getContainerCommand(), MatchRegexp(".*camel-k-integration-\\d+\\.\\d+\\.\\d+[-A-Za-z]*-runner.*"))) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort). + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort). Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Java Magicstring!")) - Eventually(IntegrationKit(ns, javaNativeCloneName)).Should(Equal(IntegrationKit(ns, javaNativeName)())) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Java Magicstring!")) + g.Eventually(IntegrationKit(t, ctx, ns, javaNativeCloneName)).Should(Equal(IntegrationKit(t, ctx, ns, javaNativeName)())) }) t.Run("java native should rebuild", func(t *testing.T) { name := javaNative2Name - Expect(KamelRunWithID(operatorID, ns, "files/Java2.java", "--name", name, - "-t", "quarkus.build-mode=native", - "-t", "builder.tasks-limit-memory=quarkus-native:9.5Gi", - ).Execute()).To(Succeed()) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Java2.java", "--name", name, "-t", "quarkus.build-mode=native", "-t", "builder.tasks-limit-memory=quarkus-native:9.5Gi").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutVeryLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationPod(ns, name), TestTimeoutShort). + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutVeryLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationPod(t, ctx, ns, name), TestTimeoutShort). Should(WithTransform(getContainerCommand(), MatchRegexp(".*camel-k-integration-\\d+\\.\\d+\\.\\d+[-A-Za-z]*-runner.*"))) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort). + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort). Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Java Magic2string!")) - Eventually(IntegrationKit(ns, javaNative2Name)).ShouldNot(Equal(IntegrationKit(ns, javaNativeName)())) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Java Magic2string!")) + g.Eventually(IntegrationKit(t, ctx, ns, javaNative2Name)).ShouldNot(Equal(IntegrationKit(t, ctx, ns, javaNativeName)())) }) // Clean up - Expect(Kamel("delete", name, "-n", ns).Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "delete", name, "-n", ns).Execute()).To(Succeed()) }) t.Run("groovy native support", func(t *testing.T) { name := RandomizedSuffixName("groovy-native") - Expect(KamelRunWithID(operatorID, ns, "files/Groovy.groovy", "--name", name, - "-t", "quarkus.build-mode=native", - "-t", "builder.tasks-limit-memory=quarkus-native:9.5Gi", - ).Execute()).To(Succeed()) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Groovy.groovy", "--name", name, "-t", "quarkus.build-mode=native", "-t", "builder.tasks-limit-memory=quarkus-native:9.5Gi").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutVeryLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationPod(ns, name), TestTimeoutShort). + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutVeryLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationPod(t, ctx, ns, name), TestTimeoutShort). Should(WithTransform(getContainerCommand(), MatchRegexp(".*camel-k-integration-\\d+\\.\\d+\\.\\d+[-A-Za-z]*-runner.*"))) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort). + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort). Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Groovy Magicstring!")) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Groovy Magicstring!")) // Clean up - Expect(Kamel("delete", name, "-n", ns).Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "delete", name, "-n", ns).Execute()).To(Succeed()) }) t.Run("kotlin native support", func(t *testing.T) { name := RandomizedSuffixName("kotlin-native") - Expect(KamelRunWithID(operatorID, ns, "files/Kotlin.kts", "--name", name, - "-t", "quarkus.build-mode=native", - "-t", "builder.tasks-limit-memory=quarkus-native:9.5Gi", - ).Execute()).To(Succeed()) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/Kotlin.kts", "--name", name, "-t", "quarkus.build-mode=native", "-t", "builder.tasks-limit-memory=quarkus-native:9.5Gi").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, name), TestTimeoutVeryLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationPod(ns, name), TestTimeoutShort). + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutVeryLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationPod(t, ctx, ns, name), TestTimeoutShort). Should(WithTransform(getContainerCommand(), MatchRegexp(".*camel-k-integration-\\d+\\.\\d+\\.\\d+[-A-Za-z]*-runner.*"))) - Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort). + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort). Should(Equal(corev1.ConditionTrue)) - Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Kotlin Magicstring!")) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Kotlin Magicstring!")) // Clean up - Expect(Kamel("delete", name, "-n", ns).Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "delete", name, "-n", ns).Execute()).To(Succeed()) }) }) } diff --git a/e2e/support/csv.go b/e2e/support/csv.go index 194fb140a8..c4bb04eae4 100644 --- a/e2e/support/csv.go +++ b/e2e/support/csv.go @@ -23,8 +23,10 @@ limitations under the License. package support import ( + "context" "fmt" "strings" + "testing" "time" "unsafe" @@ -40,10 +42,10 @@ import ( "github.com/apache/camel-k/v2/pkg/util/log" ) -func ClusterServiceVersion(conditions func(olm.ClusterServiceVersion) bool, ns string) func() *olm.ClusterServiceVersion { +func ClusterServiceVersion(t *testing.T, ctx context.Context, conditions func(olm.ClusterServiceVersion) bool, ns string) func() *olm.ClusterServiceVersion { return func() *olm.ClusterServiceVersion { lst := olm.ClusterServiceVersionList{} - if err := TestClient().List(TestContext, &lst, ctrl.InNamespace(ns)); err != nil { + if err := TestClient(t).List(ctx, &lst, ctrl.InNamespace(ns)); err != nil { panic(err) } for _, s := range lst.Items { @@ -55,16 +57,16 @@ func ClusterServiceVersion(conditions func(olm.ClusterServiceVersion) bool, ns s } } -func ClusterServiceVersionPhase(conditions func(olm.ClusterServiceVersion) bool, ns string) func() olm.ClusterServiceVersionPhase { +func ClusterServiceVersionPhase(t *testing.T, ctx context.Context, conditions func(olm.ClusterServiceVersion) bool, ns string) func() olm.ClusterServiceVersionPhase { return func() olm.ClusterServiceVersionPhase { - if csv := ClusterServiceVersion(conditions, ns)(); csv != nil && unsafe.Sizeof(csv.Status) > 0 { + if csv := ClusterServiceVersion(t, ctx, conditions, ns)(); csv != nil && unsafe.Sizeof(csv.Status) > 0 { return csv.Status.Phase } return "" } } -func CreateOrUpdateCatalogSource(ns, name, image string) error { +func CreateOrUpdateCatalogSource(t *testing.T, ctx context.Context, ns, name, image string) error { catalogSource := &olm.CatalogSource{ ObjectMeta: metav1.ObjectMeta{ Namespace: ns, @@ -72,7 +74,7 @@ func CreateOrUpdateCatalogSource(ns, name, image string) error { }, } - _, err := ctrlutil.CreateOrUpdate(TestContext, TestClient(), catalogSource, func() error { + _, err := ctrlutil.CreateOrUpdate(ctx, TestClient(t), catalogSource, func() error { catalogSource.Spec = olm.CatalogSourceSpec{ Image: image, SourceType: "grpc", @@ -85,7 +87,7 @@ func CreateOrUpdateCatalogSource(ns, name, image string) error { return err } -func CatalogSource(ns, name string) func() *olm.CatalogSource { +func CatalogSource(t *testing.T, ctx context.Context, ns, name string) func() *olm.CatalogSource { return func() *olm.CatalogSource { cs := &olm.CatalogSource{ TypeMeta: metav1.TypeMeta{ @@ -97,7 +99,7 @@ func CatalogSource(ns, name string) func() *olm.CatalogSource { Name: name, }, } - if err := TestClient().Get(TestContext, ctrl.ObjectKeyFromObject(cs), cs); err != nil && k8serrors.IsNotFound(err) { + if err := TestClient(t).Get(ctx, ctrl.ObjectKeyFromObject(cs), cs); err != nil && k8serrors.IsNotFound(err) { return nil } else if err != nil { log.Errorf(err, "Error while retrieving CatalogSource %s", name) @@ -107,18 +109,18 @@ func CatalogSource(ns, name string) func() *olm.CatalogSource { } } -func CatalogSourcePhase(ns, name string) func() string { +func CatalogSourcePhase(t *testing.T, ctx context.Context, ns, name string) func() string { return func() string { - if source := CatalogSource(ns, name)(); source != nil && source.Status.GRPCConnectionState != nil { - return CatalogSource(ns, name)().Status.GRPCConnectionState.LastObservedState + if source := CatalogSource(t, ctx, ns, name)(); source != nil && source.Status.GRPCConnectionState != nil { + return CatalogSource(t, ctx, ns, name)().Status.GRPCConnectionState.LastObservedState } return "" } } -func CatalogSourcePod(ns, csName string) func() *corev1.Pod { +func CatalogSourcePod(t *testing.T, ctx context.Context, ns, csName string) func() *corev1.Pod { return func() *corev1.Pod { - podList, err := TestClient().CoreV1().Pods(ns).List(TestContext, metav1.ListOptions{}) + podList, err := TestClient(t).CoreV1().Pods(ns).List(ctx, metav1.ListOptions{}) if err != nil && k8serrors.IsNotFound(err) { return nil } else if err != nil { @@ -139,8 +141,8 @@ func CatalogSourcePod(ns, csName string) func() *corev1.Pod { } } -func CatalogSourcePodRunning(ns, csName string) error { - podFunc := CatalogSourcePod(ns, csName) +func CatalogSourcePodRunning(t *testing.T, ctx context.Context, ns, csName string) error { + podFunc := CatalogSourcePod(t, ctx, ns, csName) for i := 1; i < 5; i++ { csPod := podFunc() @@ -150,7 +152,7 @@ func CatalogSourcePodRunning(ns, csName string) error { if i == 2 { fmt.Println("Catalog Source Pod still not ready so delete & allow it to be redeployed ...") - if err := TestClient().Delete(TestContext, csPod); err != nil { + if err := TestClient(t).Delete(ctx, csPod); err != nil { return err } } @@ -162,9 +164,9 @@ func CatalogSourcePodRunning(ns, csName string) error { return fmt.Errorf("Catalog Source Pod failed to reach a 'running' state") } -func GetSubscription(ns string) (*olm.Subscription, error) { +func GetSubscription(t *testing.T, ctx context.Context, ns string) (*olm.Subscription, error) { lst := olm.SubscriptionList{} - if err := TestClient().List(TestContext, &lst, ctrl.InNamespace(ns)); err != nil { + if err := TestClient(t).List(ctx, &lst, ctrl.InNamespace(ns)); err != nil { return nil, err } for _, s := range lst.Items { diff --git a/e2e/support/test_nexus_hooks.go b/e2e/support/test_nexus_hooks.go index 81aaeb988f..83dbde5753 100644 --- a/e2e/support/test_nexus_hooks.go +++ b/e2e/support/test_nexus_hooks.go @@ -53,7 +53,7 @@ func init() { Name: nexusService, } - if err := TestClient().Get(TestContext, key, &svc); err != nil { + if err := TestClient(nil).Get(TestContext(), key, &svc); err != nil { svcExists = false } svcChecked = true diff --git a/e2e/support/test_support.go b/e2e/support/test_support.go index 1a46a12a10..4f527a3eed 100644 --- a/e2e/support/test_support.go +++ b/e2e/support/test_support.go @@ -36,11 +36,12 @@ import ( "regexp" "runtime/debug" "strings" + "sync" "testing" "time" consoleV1 "github.com/openshift/api/console/v1" - "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/google/uuid" "github.com/onsi/gomega" @@ -98,10 +99,10 @@ const kubeConfigEnvVar = "KUBECONFIG" const ciPID = "/tmp/ci-k8s-pid" // v1.Build, v1.Integration -// v1.IntegrationKit, v1.IntegrationPlatform +// v1.IntegrationKit, v1.IntegrationPlatform, v1.IntegrationProfile // v1.Kamelet, v1.Pipe, // v1alpha1.Kamelet, v1alpha1.KameletBinding -const ExpectedCRDs = 8 +const ExpectedCRDs = 9 // camel-k-operator, // camel-k-operator-events, @@ -124,6 +125,8 @@ const ExpectedOSPromoteRoles = 1 // camel-k-operator-console-openshift const ExpectedOSClusterRoles = 1 +var TestDefaultNamespace = "default" + var TestTimeoutShort = 1 * time.Minute var TestTimeoutMedium = 5 * time.Minute var TestTimeoutLong = 15 * time.Minute @@ -133,46 +136,56 @@ var TestTimeoutVeryLong = 60 * time.Minute var NoOlmOperatorImage string -var TestContext context.Context +var testContext = context.TODO() var testClient client.Client +var clientMutex = sync.Mutex{} -var testLocus *testing.T - -func setTestLocus(t *testing.T) { - testLocus = t -} +var testSetupMutex = sync.Mutex{} +var kamelInstallMutex = sync.Mutex{} // Only panic the test if absolutely necessary and there is // no test locus. In most cases, the test should fail gracefully // using the test locus to error out and fail now. -func failTest(err error) { - if testLocus != nil { - testLocus.Helper() - testLocus.Error(err) - testLocus.FailNow() +func failTest(t *testing.T, err error) { + if t != nil { + t.Helper() + t.Error(err) + t.FailNow() } else { panic(err) } } -func TestClient() client.Client { +func TestContext() context.Context { + return testContext +} + +func TestClient(t *testing.T) client.Client { + clientMutex.Lock() + defer clientMutex.Unlock() + if testClient != nil { return testClient } + var err error testClient, err = NewTestClient() if err != nil { - failTest(err) + failTest(t, err) } return testClient } -func SyncClient() client.Client { +func RefreshClient(t *testing.T) client.Client { + clientMutex.Lock() + defer clientMutex.Unlock() + var err error testClient, err = NewTestClient() if err != nil { - failTest(err) + failTest(t, err) } + testContext = context.TODO() return testClient } @@ -195,7 +208,6 @@ func init() { client.FastMapperAllowedAPIGroups["policy"] = true var err error - TestContext = context.TODO() // Defaults for testing imageName := os.Getenv("CAMEL_K_TEST_IMAGE_NAME") @@ -251,29 +263,32 @@ func NewTestClient() (client.Client, error) { return client.NewOutOfClusterClient(os.Getenv(kubeConfigEnvVar)) } -func Kamel(args ...string) *cobra.Command { - return KamelWithContext(TestContext, args...) +func Kamel(t *testing.T, ctx context.Context, args ...string) *cobra.Command { + return KamelWithContext(t, ctx, args...) } -func KamelInstall(namespace string, args ...string) *cobra.Command { - return KamelInstallWithID(platform.DefaultPlatformName, namespace, args...) +func KamelInstall(t *testing.T, ctx context.Context, namespace string, args ...string) error { + return KamelInstallWithID(t, ctx, platform.DefaultPlatformName, namespace, args...) } -func KamelInstallWithID(operatorID string, namespace string, args ...string) *cobra.Command { - return kamelInstallWithContext(TestContext, operatorID, namespace, true, args...) +func KamelInstallWithID(t *testing.T, ctx context.Context, operatorID string, namespace string, args ...string) error { + return kamelInstallWithContext(t, ctx, operatorID, namespace, true, args...) } -func KamelInstallWithIDAndKameletCatalog(operatorID string, namespace string, args ...string) *cobra.Command { - return kamelInstallWithContext(TestContext, operatorID, namespace, false, args...) +func KamelInstallWithIDAndKameletCatalog(t *testing.T, ctx context.Context, operatorID string, namespace string, args ...string) error { + return kamelInstallWithContext(t, ctx, operatorID, namespace, false, args...) } -func kamelInstallWithContext(ctx context.Context, operatorID string, namespace string, skipKameletCatalog bool, args ...string) *cobra.Command { +func kamelInstallWithContext(t *testing.T, ctx context.Context, operatorID string, namespace string, skipKameletCatalog bool, args ...string) error { + kamelInstallMutex.Lock() + defer kamelInstallMutex.Unlock() + var installArgs []string - installArgs = []string{"install", "-n", namespace, "--operator-id", operatorID} + installArgs = []string{"install", "-n", namespace, "--operator-id", operatorID, "--skip-cluster-setup"} if skipKameletCatalog { - installArgs = append(installArgs, "--operator-env-vars", "KAMEL_INSTALL_DEFAULT_KAMELETS=false") + installArgs = append(installArgs, "--skip-default-kamelets-setup") } logLevel := os.Getenv("CAMEL_K_TEST_LOG_LEVEL") @@ -297,6 +312,16 @@ func kamelInstallWithContext(ctx context.Context, operatorID string, namespace s } } + runtimeVersion := os.Getenv("CAMEL_K_TEST_RUNTIME_VERSION") + if runtimeVersion != "" { + fmt.Printf("Setting runtime version to %s\n", runtimeVersion) + installArgs = append(installArgs, "--runtime-version", runtimeVersion) + } + baseImage := os.Getenv("CAMEL_K_TEST_BASE_IMAGE") + if baseImage != "" { + fmt.Printf("Setting base image to %s\n", baseImage) + installArgs = append(installArgs, "--base-image", baseImage) + } opImage := os.Getenv("CAMEL_K_TEST_OPERATOR_IMAGE") if opImage != "" { fmt.Printf("Setting operator image to %s\n", opImage) @@ -309,34 +334,35 @@ func kamelInstallWithContext(ctx context.Context, operatorID string, namespace s } installArgs = append(installArgs, args...) - return KamelWithContext(ctx, installArgs...) + installCommand := KamelWithContext(t, ctx, installArgs...) + return installCommand.Execute() } -func KamelRun(namespace string, args ...string) *cobra.Command { - return KamelRunWithID(platform.DefaultPlatformName, namespace, args...) +func KamelRun(t *testing.T, ctx context.Context, namespace string, args ...string) *cobra.Command { + return KamelRunWithID(t, ctx, platform.DefaultPlatformName, namespace, args...) } -func KamelRunWithID(operatorID string, namespace string, args ...string) *cobra.Command { - return KamelRunWithContext(TestContext, operatorID, namespace, args...) +func KamelRunWithID(t *testing.T, ctx context.Context, operatorID string, namespace string, args ...string) *cobra.Command { + return KamelRunWithContext(t, ctx, operatorID, namespace, args...) } -func KamelRunWithContext(ctx context.Context, operatorID string, namespace string, args ...string) *cobra.Command { - return KamelCommandWithContext(ctx, "run", operatorID, namespace, args...) +func KamelRunWithContext(t *testing.T, ctx context.Context, operatorID string, namespace string, args ...string) *cobra.Command { + return KamelCommandWithContext(t, ctx, "run", operatorID, namespace, args...) } -func KamelBind(namespace string, args ...string) *cobra.Command { - return KamelBindWithID(platform.DefaultPlatformName, namespace, args...) +func KamelBind(t *testing.T, ctx context.Context, namespace string, args ...string) *cobra.Command { + return KamelBindWithID(t, ctx, platform.DefaultPlatformName, namespace, args...) } -func KamelBindWithID(operatorID string, namespace string, args ...string) *cobra.Command { - return KamelBindWithContext(TestContext, operatorID, namespace, args...) +func KamelBindWithID(t *testing.T, ctx context.Context, operatorID string, namespace string, args ...string) *cobra.Command { + return KamelBindWithContext(t, ctx, operatorID, namespace, args...) } -func KamelBindWithContext(ctx context.Context, operatorID string, namespace string, args ...string) *cobra.Command { - return KamelCommandWithContext(ctx, "bind", operatorID, namespace, args...) +func KamelBindWithContext(t *testing.T, ctx context.Context, operatorID string, namespace string, args ...string) *cobra.Command { + return KamelCommandWithContext(t, ctx, "bind", operatorID, namespace, args...) } -func KamelCommandWithContext(ctx context.Context, command string, operatorID string, namespace string, args ...string) *cobra.Command { +func KamelCommandWithContext(t *testing.T, ctx context.Context, command string, operatorID string, namespace string, args ...string) *cobra.Command { // This line prevents controller-runtime from complaining about log.SetLogger never being called logf.SetLogger(zap.New(zap.UseDevMode(true))) var cmdArgs []string @@ -344,24 +370,10 @@ func KamelCommandWithContext(ctx context.Context, command string, operatorID str cmdArgs = []string{command, "-n", namespace, "--operator-id", operatorID} cmdArgs = append(cmdArgs, args...) - return KamelWithContext(ctx, cmdArgs...) -} - -func verifyGlobalOperator() error { - opns := os.Getenv("CAMEL_K_GLOBAL_OPERATOR_NS") - if opns == "" { - return errors.New("no operator namespace defined in CAMEL_K_GLOBAL_OPERATOR_NS") - } - - oppod := OperatorPod(opns)() - if oppod == nil { - return fmt.Errorf("no operator pod detected in namespace %s. Operator install is a pre-requisite of the test", opns) - } - - return nil + return KamelWithContext(t, ctx, cmdArgs...) } -func KamelWithContext(ctx context.Context, args ...string) *cobra.Command { +func KamelWithContext(t *testing.T, ctx context.Context, args ...string) *cobra.Command { var c *cobra.Command var err error @@ -378,7 +390,7 @@ func KamelWithContext(ctx context.Context, args ...string) *cobra.Command { kamelBin := os.Getenv("KAMEL_BIN") if kamelBin != "" { if _, e := os.Stat(kamelBin); e != nil && os.IsNotExist(e) { - failTest(e) + failTest(t, e) } fmt.Printf("Using external kamel binary on path %s\n", kamelBin) c = &cobra.Command{ @@ -388,11 +400,11 @@ func KamelWithContext(ctx context.Context, args ...string) *cobra.Command { var stdout, stderr io.Reader stdout, err = externalBin.StdoutPipe() if err != nil { - failTest(err) + failTest(t, err) } stderr, err = externalBin.StderrPipe() if err != nil { - failTest(err) + failTest(t, err) } err := externalBin.Start() if err != nil { @@ -417,8 +429,9 @@ func KamelWithContext(ctx context.Context, args ...string) *cobra.Command { // Use modeline CLI as it's closer to the real usage c, args, err = cmd.NewKamelWithModelineCommand(ctx, append([]string{"kamel"}, args...)) } + if err != nil { - failTest(err) + failTest(t, err) } for _, hook := range KamelHooks { args = hook(args) @@ -427,11 +440,11 @@ func KamelWithContext(ctx context.Context, args ...string) *cobra.Command { return c } -func Make(rule string, args ...string) *exec.Cmd { - return MakeWithContext(TestContext, rule, args...) +func Make(t *testing.T, rule string, args ...string) *exec.Cmd { + return MakeWithContext(t, rule, args...) } -func MakeWithContext(ctx context.Context, rule string, args ...string) *exec.Cmd { +func MakeWithContext(t *testing.T, rule string, args ...string) *exec.Cmd { makeArgs := os.Getenv("CAMEL_K_TEST_MAKE_ARGS") defaultArgs := strings.Fields(makeArgs) args = append(defaultArgs, args...) @@ -445,9 +458,9 @@ func MakeWithContext(ctx context.Context, rule string, args ...string) *exec.Cmd } if fi, e := os.Stat(makeDir); e != nil && os.IsNotExist(e) { - failTest(e) + failTest(t, e) } else if !fi.Mode().IsDir() { - failTest(e) + failTest(t, e) } args = append([]string{"-C", makeDir, rule}, args...) @@ -456,10 +469,10 @@ func MakeWithContext(ctx context.Context, rule string, args ...string) *exec.Cmd } func Kubectl(args ...string) *exec.Cmd { - return KubectlWithContext(TestContext, args...) + return KubectlWithContext(args...) } -func KubectlWithContext(ctx context.Context, args ...string) *exec.Cmd { +func KubectlWithContext(args ...string) *exec.Cmd { return exec.Command("kubectl", args...) } @@ -467,9 +480,9 @@ func KubectlWithContext(ctx context.Context, args ...string) *exec.Cmd { // Curried utility functions for testing // ============================================================================= -func IntegrationLogs(ns, name string) func() string { +func IntegrationLogs(t *testing.T, ctx context.Context, ns, name string) func() string { return func() string { - pod := IntegrationPod(ns, name)() + pod := IntegrationPod(t, ctx, ns, name)() if pod == nil { return "" } @@ -478,28 +491,35 @@ func IntegrationLogs(ns, name string) func() string { TailLines: pointer.Int64(100), } + for _, container := range pod.Status.ContainerStatuses { + if !container.Ready || container.State.Waiting != nil { + // avoid logs watch fail due to container creating state + return "" + } + } + if len(pod.Spec.Containers) > 1 { options.Container = pod.Spec.Containers[0].Name } - return Logs(ns, pod.Name, options)() + return Logs(t, ctx, ns, pod.Name, options)() } } -// Retrieve the Logs from the Pod defined by its name in the given namespace ns. The number of lines numLines from the end of the logs to show. -func TailedLogs(ns, name string, numLines int64) func() string { +// TailedLogs Retrieve the Logs from the Pod defined by its name in the given namespace ns. The number of lines numLines from the end of the logs to show. +func TailedLogs(t *testing.T, ctx context.Context, ns, name string, numLines int64) func() string { return func() string { options := corev1.PodLogOptions{ TailLines: pointer.Int64(numLines), } - return Logs(ns, name, options)() + return Logs(t, ctx, ns, name, options)() } } -func Logs(ns, podName string, options corev1.PodLogOptions) func() string { +func Logs(t *testing.T, ctx context.Context, ns, podName string, options corev1.PodLogOptions) func() string { return func() string { - byteReader, err := TestClient().CoreV1().Pods(ns).GetLogs(podName, &options).Stream(TestContext) + byteReader, err := TestClient(t).CoreV1().Pods(ns).GetLogs(podName, &options).Stream(ctx) if err != nil { log.Error(err, "Error while reading container logs") return "" @@ -510,18 +530,18 @@ func Logs(ns, podName string, options corev1.PodLogOptions) func() string { } }() - bytes, err := io.ReadAll(byteReader) + logBytes, err := io.ReadAll(byteReader) if err != nil { log.Error(err, "Error while reading container logs") return "" } - return string(bytes) + return string(logBytes) } } -func StructuredLogs(ns, podName string, options *corev1.PodLogOptions, ignoreParseErrors bool) ([]util.LogEntry, error) { +func StructuredLogs(t *testing.T, ctx context.Context, ns, podName string, options *corev1.PodLogOptions, ignoreParseErrors bool) ([]util.LogEntry, error) { - stream, err := TestClient().CoreV1().Pods(ns).GetLogs(podName, options).Stream(TestContext) + stream, err := TestClient(t).CoreV1().Pods(ns).GetLogs(podName, options).Stream(ctx) if err != nil { msg := "Error while reading container logs" log.Error(err, msg) @@ -568,9 +588,9 @@ func StructuredLogs(ns, podName string, options *corev1.PodLogOptions, ignorePar return entries, nil } -func IntegrationPodPhase(ns string, name string) func() corev1.PodPhase { +func IntegrationPodPhase(t *testing.T, ctx context.Context, ns string, name string) func() corev1.PodPhase { return func() corev1.PodPhase { - pod := IntegrationPod(ns, name)() + pod := IntegrationPod(t, ctx, ns, name)() if pod == nil { return "" } @@ -578,9 +598,9 @@ func IntegrationPodPhase(ns string, name string) func() corev1.PodPhase { } } -func IntegrationPodImage(ns string, name string) func() string { +func IntegrationPodImage(t *testing.T, ctx context.Context, ns string, name string) func() string { return func() string { - pod := IntegrationPod(ns, name)() + pod := IntegrationPod(t, ctx, ns, name)() if pod == nil || len(pod.Spec.Containers) == 0 { return "" } @@ -588,9 +608,9 @@ func IntegrationPodImage(ns string, name string) func() string { } } -func IntegrationPod(ns string, name string) func() *corev1.Pod { +func IntegrationPod(t *testing.T, ctx context.Context, ns string, name string) func() *corev1.Pod { return func() *corev1.Pod { - pods := IntegrationPods(ns, name)() + pods := IntegrationPods(t, ctx, ns, name)() if len(pods) == 0 { return nil } @@ -598,9 +618,9 @@ func IntegrationPod(ns string, name string) func() *corev1.Pod { } } -func IntegrationPodHas(ns string, name string, predicate func(pod *corev1.Pod) bool) func() bool { +func IntegrationPodHas(t *testing.T, ctx context.Context, ns string, name string, predicate func(pod *corev1.Pod) bool) func() bool { return func() bool { - pod := IntegrationPod(ns, name)() + pod := IntegrationPod(t, ctx, ns, name)() if pod == nil { return false } @@ -608,7 +628,7 @@ func IntegrationPodHas(ns string, name string, predicate func(pod *corev1.Pod) b } } -func IntegrationPods(ns string, name string) func() []corev1.Pod { +func IntegrationPods(t *testing.T, ctx context.Context, ns string, name string) func() []corev1.Pod { return func() []corev1.Pod { lst := corev1.PodList{ TypeMeta: metav1.TypeMeta{ @@ -616,28 +636,28 @@ func IntegrationPods(ns string, name string) func() []corev1.Pod { APIVersion: corev1.SchemeGroupVersion.String(), }, } - err := TestClient().List(TestContext, &lst, + err := TestClient(t).List(ctx, &lst, ctrl.InNamespace(ns), ctrl.MatchingLabels{ v1.IntegrationLabel: name, }) if err != nil { - failTest(err) + failTest(t, err) } return lst.Items } } -func IntegrationPodsNumbers(ns string, name string) func() *int32 { +func IntegrationPodsNumbers(t *testing.T, ctx context.Context, ns string, name string) func() *int32 { return func() *int32 { - i := int32(len(IntegrationPods(ns, name)())) + i := int32(len(IntegrationPods(t, ctx, ns, name)())) return &i } } -func IntegrationSpecReplicas(ns string, name string) func() *int32 { +func IntegrationSpecReplicas(t *testing.T, ctx context.Context, ns string, name string) func() *int32 { return func() *int32 { - it := Integration(ns, name)() + it := Integration(t, ctx, ns, name)() if it == nil { return nil } @@ -645,9 +665,9 @@ func IntegrationSpecReplicas(ns string, name string) func() *int32 { } } -func IntegrationGeneration(ns string, name string) func() *int64 { +func IntegrationGeneration(t *testing.T, ctx context.Context, ns string, name string) func() *int64 { return func() *int64 { - it := Integration(ns, name)() + it := Integration(t, ctx, ns, name)() if it == nil { return nil } @@ -655,9 +675,9 @@ func IntegrationGeneration(ns string, name string) func() *int64 { } } -func IntegrationObservedGeneration(ns string, name string) func() *int64 { +func IntegrationObservedGeneration(t *testing.T, ctx context.Context, ns string, name string) func() *int64 { return func() *int64 { - it := Integration(ns, name)() + it := Integration(t, ctx, ns, name)() if it == nil { return nil } @@ -665,9 +685,9 @@ func IntegrationObservedGeneration(ns string, name string) func() *int64 { } } -func IntegrationStatusReplicas(ns string, name string) func() *int32 { +func IntegrationStatusReplicas(t *testing.T, ctx context.Context, ns string, name string) func() *int32 { return func() *int32 { - it := Integration(ns, name)() + it := Integration(t, ctx, ns, name)() if it == nil { return nil } @@ -675,9 +695,9 @@ func IntegrationStatusReplicas(ns string, name string) func() *int32 { } } -func IntegrationStatusImage(ns string, name string) func() string { +func IntegrationStatusImage(t *testing.T, ctx context.Context, ns string, name string) func() string { return func() string { - it := Integration(ns, name)() + it := Integration(t, ctx, ns, name)() if it == nil { return "" } @@ -685,9 +705,9 @@ func IntegrationStatusImage(ns string, name string) func() string { } } -func IntegrationAnnotations(ns string, name string) func() map[string]string { +func IntegrationAnnotations(t *testing.T, ctx context.Context, ns string, name string) func() map[string]string { return func() map[string]string { - it := Integration(ns, name)() + it := Integration(t, ctx, ns, name)() if it == nil { return map[string]string{} } @@ -695,9 +715,9 @@ func IntegrationAnnotations(ns string, name string) func() map[string]string { } } -func IntegrationCondition(ns string, name string, conditionType v1.IntegrationConditionType) func() *v1.IntegrationCondition { +func IntegrationCondition(t *testing.T, ctx context.Context, ns string, name string, conditionType v1.IntegrationConditionType) func() *v1.IntegrationCondition { return func() *v1.IntegrationCondition { - it := Integration(ns, name)() + it := Integration(t, ctx, ns, name)() if it == nil { return nil } @@ -753,16 +773,16 @@ func HealthCheckData(r *v1.HealthCheckResponse) (map[string]interface{}, error) } var data map[string]interface{} - if err := json.Unmarshal(r.Data, data); err != nil { + if err := json.Unmarshal(r.Data, &data); err != nil { return nil, err } return data, nil } -func IntegrationConditionStatus(ns string, name string, conditionType v1.IntegrationConditionType) func() corev1.ConditionStatus { +func IntegrationConditionStatus(t *testing.T, ctx context.Context, ns string, name string, conditionType v1.IntegrationConditionType) func() corev1.ConditionStatus { return func() corev1.ConditionStatus { - c := IntegrationCondition(ns, name, conditionType)() + c := IntegrationCondition(t, ctx, ns, name, conditionType)() if c == nil { return "Unknown" } @@ -770,14 +790,14 @@ func IntegrationConditionStatus(ns string, name string, conditionType v1.Integra } } -func AssignIntegrationToOperator(ns, name, operator string) error { - it := Integration(ns, name)() +func AssignIntegrationToOperator(t *testing.T, ctx context.Context, ns, name, operator string) error { + it := Integration(t, ctx, ns, name)() if it == nil { return fmt.Errorf("cannot assign integration %q to operator: integration not found", name) } it.SetOperatorID(operator) - return TestClient().Update(TestContext, it) + return TestClient(t).Update(ctx, it) } func Annotations(object metav1.Object) map[string]string { @@ -788,24 +808,24 @@ func IntegrationSpec(it *v1.Integration) *v1.IntegrationSpec { return &it.Spec } -func Lease(ns string, name string) func() *coordination.Lease { +func Lease(t *testing.T, ctx context.Context, ns string, name string) func() *coordination.Lease { return func() *coordination.Lease { lease := coordination.Lease{} key := ctrl.ObjectKey{ Namespace: ns, Name: name, } - err := TestClient().Get(TestContext, key, &lease) + err := TestClient(t).Get(ctx, key, &lease) if err != nil && k8serrors.IsNotFound(err) { return nil } else if err != nil { - failTest(err) + failTest(t, err) } return &lease } } -func Nodes() func() []corev1.Node { +func Nodes(t *testing.T, ctx context.Context) func() []corev1.Node { return func() []corev1.Node { nodes := &corev1.NodeList{ TypeMeta: metav1.TypeMeta{ @@ -813,14 +833,14 @@ func Nodes() func() []corev1.Node { APIVersion: corev1.SchemeGroupVersion.String(), }, } - if err := TestClient().List(TestContext, nodes); err != nil { - failTest(err) + if err := TestClient(t).List(ctx, nodes); err != nil { + failTest(t, err) } return nodes.Items } } -func Node(name string) func() *corev1.Node { +func Node(t *testing.T, ctx context.Context, name string) func() *corev1.Node { return func() *corev1.Node { node := &corev1.Node{ TypeMeta: metav1.TypeMeta{ @@ -831,34 +851,34 @@ func Node(name string) func() *corev1.Node { Name: name, }, } - err := TestClient().Get(TestContext, ctrl.ObjectKeyFromObject(node), node) + err := TestClient(t).Get(ctx, ctrl.ObjectKeyFromObject(node), node) if err != nil { - failTest(err) + failTest(t, err) } return node } } -func Service(ns string, name string) func() *corev1.Service { +func Service(t *testing.T, ctx context.Context, ns string, name string) func() *corev1.Service { return func() *corev1.Service { svc := corev1.Service{} key := ctrl.ObjectKey{ Namespace: ns, Name: name, } - err := TestClient().Get(TestContext, key, &svc) + err := TestClient(t).Get(ctx, key, &svc) if err != nil && k8serrors.IsNotFound(err) { return nil } else if err != nil { - failTest(err) + failTest(t, err) } return &svc } } -func ServiceType(ns string, name string) func() corev1.ServiceType { +func ServiceType(t *testing.T, ctx context.Context, ns string, name string) func() corev1.ServiceType { return func() corev1.ServiceType { - svc := Service(ns, name)() + svc := Service(t, ctx, ns, name)() if svc == nil { return "" } @@ -866,16 +886,16 @@ func ServiceType(ns string, name string) func() corev1.ServiceType { } } -// Find the service in the given namespace with the given type -func ServicesByType(ns string, svcType corev1.ServiceType) func() []corev1.Service { +// ServicesByType Find the service in the given namespace with the given type +func ServicesByType(t *testing.T, ctx context.Context, ns string, svcType corev1.ServiceType) func() []corev1.Service { return func() []corev1.Service { svcs := []corev1.Service{} - svcList, err := TestClient().CoreV1().Services(ns).List(TestContext, metav1.ListOptions{}) + svcList, err := TestClient(t).CoreV1().Services(ns).List(ctx, metav1.ListOptions{}) if err != nil && k8serrors.IsNotFound(err) { return svcs } else if err != nil { - failTest(err) + failTest(t, err) } if len(svcList.Items) == 0 { @@ -892,24 +912,24 @@ func ServicesByType(ns string, svcType corev1.ServiceType) func() []corev1.Servi } } -func Route(ns string, name string) func() *routev1.Route { +func Route(t *testing.T, ctx context.Context, ns string, name string) func() *routev1.Route { return func() *routev1.Route { route := routev1.Route{} key := ctrl.ObjectKey{ Namespace: ns, Name: name, } - err := TestClient().Get(TestContext, key, &route) + err := TestClient(t).Get(ctx, key, &route) if err != nil && k8serrors.IsNotFound(err) { return nil } else if err != nil { - failTest(err) + failTest(t, err) } return &route } } -func RouteFull(ns string, name string) func() *routev1.Route { +func RouteFull(t *testing.T, ctx context.Context, ns string, name string) func() *routev1.Route { return func() *routev1.Route { answer := routev1.Route{ TypeMeta: metav1.TypeMeta{ @@ -925,19 +945,19 @@ func RouteFull(ns string, name string) func() *routev1.Route { Namespace: ns, Name: name, } - err := TestClient().Get(TestContext, key, &answer) + err := TestClient(t).Get(ctx, key, &answer) if err != nil && k8serrors.IsNotFound(err) { return nil } else if err != nil { - failTest(err) + failTest(t, err) } return &answer } } -func RouteStatus(ns string, name string) func() string { +func RouteStatus(t *testing.T, ctx context.Context, ns string, name string) func() string { return func() string { - route := Route(ns, name)() + route := Route(t, ctx, ns, name)() if route == nil || len(route.Status.Ingress) == 0 { return "" } @@ -945,7 +965,7 @@ func RouteStatus(ns string, name string) func() string { } } -func IntegrationCronJob(ns string, name string) func() *batchv1.CronJob { +func IntegrationCronJob(t *testing.T, ctx context.Context, ns string, name string) func() *batchv1.CronJob { return func() *batchv1.CronJob { lst := batchv1.CronJobList{ TypeMeta: metav1.TypeMeta{ @@ -953,12 +973,12 @@ func IntegrationCronJob(ns string, name string) func() *batchv1.CronJob { APIVersion: batchv1.SchemeGroupVersion.String(), }, } - if err := TestClient().List(TestContext, &lst, + if err := TestClient(t).List(ctx, &lst, ctrl.InNamespace(ns), ctrl.MatchingLabels{ "camel.apache.org/integration": name, }); err != nil { - failTest(err) + failTest(t, err) } if len(lst.Items) == 0 { return nil @@ -967,33 +987,33 @@ func IntegrationCronJob(ns string, name string) func() *batchv1.CronJob { } } -func Integrations(ns string) func() *v1.IntegrationList { +func Integrations(t *testing.T, ctx context.Context, ns string) func() *v1.IntegrationList { return func() *v1.IntegrationList { lst := v1.NewIntegrationList() - if err := TestClient().List(TestContext, &lst, ctrl.InNamespace(ns)); err != nil { - failTest(err) + if err := TestClient(t).List(ctx, &lst, ctrl.InNamespace(ns)); err != nil { + failTest(t, err) } return &lst } } -func NumIntegrations(ns string) func() int { +func NumIntegrations(t *testing.T, ctx context.Context, ns string) func() int { return func() int { - lst := Integrations(ns)() + lst := Integrations(t, ctx, ns)() return len(lst.Items) } } -func Integration(ns string, name string) func() *v1.Integration { +func Integration(t *testing.T, ctx context.Context, ns string, name string) func() *v1.Integration { return func() *v1.Integration { it := v1.NewIntegration(ns, name) key := ctrl.ObjectKey{ Namespace: ns, Name: name, } - if err := TestClient().Get(TestContext, key, &it); err != nil && !k8serrors.IsNotFound(err) { - failTest(err) + if err := TestClient(t).Get(ctx, key, &it); err != nil && !k8serrors.IsNotFound(err) { + failTest(t, err) } else if err != nil && k8serrors.IsNotFound(err) { return nil } @@ -1001,21 +1021,21 @@ func Integration(ns string, name string) func() *v1.Integration { } } -func UnstructuredIntegration(ns string, name string) func() *unstructured.Unstructured { +func UnstructuredIntegration(t *testing.T, ctx context.Context, ns string, name string) func() *unstructured.Unstructured { return func() *unstructured.Unstructured { gvk := schema.GroupVersionKind{Group: v1.SchemeGroupVersion.Group, Version: v1.SchemeGroupVersion.Version, Kind: v1.IntegrationKind} - return UnstructuredObject(ns, name, gvk)() + return UnstructuredObject(t, ctx, ns, name, gvk)() } } -func UnstructuredObject(ns string, name string, gvk schema.GroupVersionKind) func() *unstructured.Unstructured { +func UnstructuredObject(t *testing.T, ctx context.Context, ns string, name string, gvk schema.GroupVersionKind) func() *unstructured.Unstructured { return func() *unstructured.Unstructured { object := &unstructured.Unstructured{} object.SetNamespace(ns) object.SetName(name) object.SetGroupVersionKind(gvk) - if err := TestClient().Get(TestContext, ctrl.ObjectKeyFromObject(object), object); err != nil && !k8serrors.IsNotFound(err) { - failTest(err) + if err := TestClient(t).Get(ctx, ctrl.ObjectKeyFromObject(object), object); err != nil && !k8serrors.IsNotFound(err) { + failTest(t, err) } else if err != nil && k8serrors.IsNotFound(err) { return nil } @@ -1023,9 +1043,9 @@ func UnstructuredObject(ns string, name string, gvk schema.GroupVersionKind) fun } } -func IntegrationVersion(ns string, name string) func() string { +func IntegrationVersion(t *testing.T, ctx context.Context, ns string, name string) func() string { return func() string { - it := Integration(ns, name)() + it := Integration(t, ctx, ns, name)() if it == nil { return "" } @@ -1033,9 +1053,9 @@ func IntegrationVersion(ns string, name string) func() string { } } -func IntegrationTraitProfile(ns string, name string) func() v1.TraitProfile { +func IntegrationTraitProfile(t *testing.T, ctx context.Context, ns string, name string) func() v1.TraitProfile { return func() v1.TraitProfile { - it := Integration(ns, name)() + it := Integration(t, ctx, ns, name)() if it == nil { return "" } @@ -1043,9 +1063,9 @@ func IntegrationTraitProfile(ns string, name string) func() v1.TraitProfile { } } -func IntegrationPhase(ns string, name string) func() v1.IntegrationPhase { +func IntegrationPhase(t *testing.T, ctx context.Context, ns string, name string) func() v1.IntegrationPhase { return func() v1.IntegrationPhase { - it := Integration(ns, name)() + it := Integration(t, ctx, ns, name)() if it == nil { return "" } @@ -1053,9 +1073,9 @@ func IntegrationPhase(ns string, name string) func() v1.IntegrationPhase { } } -func IntegrationSpecProfile(ns string, name string) func() v1.TraitProfile { +func IntegrationSpecProfile(t *testing.T, ctx context.Context, ns string, name string) func() v1.TraitProfile { return func() v1.TraitProfile { - it := Integration(ns, name)() + it := Integration(t, ctx, ns, name)() if it == nil { return "" } @@ -1063,9 +1083,9 @@ func IntegrationSpecProfile(ns string, name string) func() v1.TraitProfile { } } -func IntegrationStatusCapabilities(ns string, name string) func() []string { +func IntegrationStatusCapabilities(t *testing.T, ctx context.Context, ns string, name string) func() []string { return func() []string { - it := Integration(ns, name)() + it := Integration(t, ctx, ns, name)() if it == nil || &it.Status == nil { return nil } @@ -1073,9 +1093,9 @@ func IntegrationStatusCapabilities(ns string, name string) func() []string { } } -func IntegrationSpecSA(ns string, name string) func() string { +func IntegrationSpecSA(t *testing.T, ctx context.Context, ns string, name string) func() string { return func() string { - it := Integration(ns, name)() + it := Integration(t, ctx, ns, name)() if it == nil { return "" } @@ -1083,9 +1103,9 @@ func IntegrationSpecSA(ns string, name string) func() string { } } -func IntegrationKit(ns string, name string) func() string { +func IntegrationKit(t *testing.T, ctx context.Context, ns string, name string) func() string { return func() string { - it := Integration(ns, name)() + it := Integration(t, ctx, ns, name)() if it == nil { return "" } @@ -1096,9 +1116,9 @@ func IntegrationKit(ns string, name string) func() string { } } -func IntegrationKitNamespace(integrationNamespace string, name string) func() string { +func IntegrationKitNamespace(t *testing.T, ctx context.Context, integrationNamespace string, name string) func() string { return func() string { - it := Integration(integrationNamespace, name)() + it := Integration(t, ctx, integrationNamespace, name)() if it == nil { return "" } @@ -1109,11 +1129,11 @@ func IntegrationKitNamespace(integrationNamespace string, name string) func() st } } -func Kit(ns, name string) func() *v1.IntegrationKit { +func Kit(t *testing.T, ctx context.Context, ns, name string) func() *v1.IntegrationKit { return func() *v1.IntegrationKit { kit := v1.NewIntegrationKit(ns, name) - if err := TestClient().Get(TestContext, ctrl.ObjectKeyFromObject(kit), kit); err != nil && !k8serrors.IsNotFound(err) { - failTest(err) + if err := TestClient(t).Get(ctx, ctrl.ObjectKeyFromObject(kit), kit); err != nil && !k8serrors.IsNotFound(err) { + failTest(t, err) } else if err != nil && k8serrors.IsNotFound(err) { return nil } @@ -1121,9 +1141,9 @@ func Kit(ns, name string) func() *v1.IntegrationKit { } } -func KitPhase(ns, name string) func() v1.IntegrationKitPhase { +func KitPhase(t *testing.T, ctx context.Context, ns, name string) func() v1.IntegrationKitPhase { return func() v1.IntegrationKitPhase { - kit := Kit(ns, name)() + kit := Kit(t, ctx, ns, name)() if kit == nil { return v1.IntegrationKitPhaseNone } @@ -1131,9 +1151,9 @@ func KitPhase(ns, name string) func() v1.IntegrationKitPhase { } } -func KitCondition(ns string, name string, conditionType v1.IntegrationKitConditionType) func() *v1.IntegrationKitCondition { +func KitCondition(t *testing.T, ctx context.Context, ns string, name string, conditionType v1.IntegrationKitConditionType) func() *v1.IntegrationKitCondition { return func() *v1.IntegrationKitCondition { - kt := Kit(ns, name)() + kt := Kit(t, ctx, ns, name)() if kt == nil { return nil } @@ -1141,18 +1161,18 @@ func KitCondition(ns string, name string, conditionType v1.IntegrationKitConditi } } -func UpdateIntegration(ns string, name string, mutate func(it *v1.Integration)) error { - it := Integration(ns, name)() +func UpdateIntegration(t *testing.T, ctx context.Context, ns string, name string, mutate func(it *v1.Integration)) error { + it := Integration(t, ctx, ns, name)() if it == nil { return fmt.Errorf("no integration named %s found", name) } target := it.DeepCopy() mutate(target) - return TestClient().Update(TestContext, target) + return TestClient(t).Update(ctx, target) } -func PatchIntegration(ns string, name string, mutate func(it *v1.Integration)) error { - it := Integration(ns, name)() +func PatchIntegration(t *testing.T, ctx context.Context, ns string, name string, mutate func(it *v1.Integration)) error { + it := Integration(t, ctx, ns, name)() if it == nil { return fmt.Errorf("no integration named %s found", name) } @@ -1164,24 +1184,24 @@ func PatchIntegration(ns string, name string, mutate func(it *v1.Integration)) e } else if len(p) == 0 { return nil } - return TestClient().Patch(TestContext, target, ctrl.RawPatch(types.MergePatchType, p)) + return TestClient(t).Patch(ctx, target, ctrl.RawPatch(types.MergePatchType, p)) } -func ScaleIntegration(ns string, name string, replicas int32) error { - return PatchIntegration(ns, name, func(it *v1.Integration) { +func ScaleIntegration(t *testing.T, ctx context.Context, ns string, name string, replicas int32) error { + return PatchIntegration(t, ctx, ns, name, func(it *v1.Integration) { it.Spec.Replicas = &replicas }) } -func Pipe(ns string, name string) func() *v1.Pipe { +func Pipe(t *testing.T, ctx context.Context, ns string, name string) func() *v1.Pipe { return func() *v1.Pipe { klb := v1.NewPipe(ns, name) key := ctrl.ObjectKey{ Namespace: ns, Name: name, } - if err := TestClient().Get(TestContext, key, &klb); err != nil && !k8serrors.IsNotFound(err) { - failTest(err) + if err := TestClient(t).Get(ctx, key, &klb); err != nil && !k8serrors.IsNotFound(err) { + failTest(t, err) } else if err != nil && k8serrors.IsNotFound(err) { return nil } @@ -1189,9 +1209,9 @@ func Pipe(ns string, name string) func() *v1.Pipe { } } -func PipePhase(ns string, name string) func() v1.PipePhase { +func PipePhase(t *testing.T, ctx context.Context, ns string, name string) func() v1.PipePhase { return func() v1.PipePhase { - klb := Pipe(ns, name)() + klb := Pipe(t, ctx, ns, name)() if klb == nil { return "" } @@ -1199,9 +1219,9 @@ func PipePhase(ns string, name string) func() v1.PipePhase { } } -func PipeSpecReplicas(ns string, name string) func() *int32 { +func PipeSpecReplicas(t *testing.T, ctx context.Context, ns string, name string) func() *int32 { return func() *int32 { - klb := Pipe(ns, name)() + klb := Pipe(t, ctx, ns, name)() if klb == nil { return nil } @@ -1209,9 +1229,9 @@ func PipeSpecReplicas(ns string, name string) func() *int32 { } } -func PipeStatusReplicas(ns string, name string) func() *int32 { +func PipeStatusReplicas(t *testing.T, ctx context.Context, ns string, name string) func() *int32 { return func() *int32 { - klb := Pipe(ns, name)() + klb := Pipe(t, ctx, ns, name)() if klb == nil { return nil } @@ -1219,9 +1239,9 @@ func PipeStatusReplicas(ns string, name string) func() *int32 { } } -func PipeCondition(ns string, name string, conditionType v1.PipeConditionType) func() *v1.PipeCondition { +func PipeCondition(t *testing.T, ctx context.Context, ns string, name string, conditionType v1.PipeConditionType) func() *v1.PipeCondition { return func() *v1.PipeCondition { - kb := Pipe(ns, name)() + kb := Pipe(t, ctx, ns, name)() if kb == nil { return nil } @@ -1254,9 +1274,9 @@ func PipeConditionMessage(c *v1.PipeCondition) string { return c.Message } -func PipeConditionStatus(ns string, name string, conditionType v1.PipeConditionType) func() corev1.ConditionStatus { +func PipeConditionStatus(t *testing.T, ctx context.Context, ns string, name string, conditionType v1.PipeConditionType) func() corev1.ConditionStatus { return func() corev1.ConditionStatus { - klb := Pipe(ns, name)() + klb := Pipe(t, ctx, ns, name)() if klb == nil { return "PipeMissing" } @@ -1268,37 +1288,37 @@ func PipeConditionStatus(ns string, name string, conditionType v1.PipeConditionT } } -func UpdatePipe(ns string, name string, upd func(it *v1.Pipe)) error { - klb := Pipe(ns, name)() +func UpdatePipe(t *testing.T, ctx context.Context, ns string, name string, upd func(it *v1.Pipe)) error { + klb := Pipe(t, ctx, ns, name)() if klb == nil { return fmt.Errorf("no Pipe named %s found", name) } target := klb.DeepCopy() upd(target) - // For some reasons, full patch fails on some clusters + // For some reason, full patch fails on some clusters p, err := patch.MergePatch(klb, target) if err != nil { return err } else if len(p) == 0 { return nil } - return TestClient().Patch(TestContext, target, ctrl.RawPatch(types.MergePatchType, p)) + return TestClient(t).Patch(ctx, target, ctrl.RawPatch(types.MergePatchType, p)) } -func ScalePipe(ns string, name string, replicas int32) error { - return UpdatePipe(ns, name, func(klb *v1.Pipe) { +func ScalePipe(t *testing.T, ctx context.Context, ns string, name string, replicas int32) error { + return UpdatePipe(t, ctx, ns, name, func(klb *v1.Pipe) { klb.Spec.Replicas = &replicas }) } -func AssignPipeToOperator(ns, name, operator string) error { - klb := Pipe(ns, name)() +func AssignPipeToOperator(t *testing.T, ctx context.Context, ns, name, operator string) error { + klb := Pipe(t, ctx, ns, name)() if klb == nil { return fmt.Errorf("cannot assign Pipe %q to operator:Pipe not found", name) } klb.SetOperatorID(operator) - return TestClient().Update(TestContext, klb) + return TestClient(t).Update(ctx, klb) } type KitFilter interface { @@ -1343,7 +1363,7 @@ func (f *kitFilter) Match(kit *v1.IntegrationKit) bool { return f.filter(kit) } -func Kits(ns string, options ...interface{}) func() []v1.IntegrationKit { +func Kits(t *testing.T, ctx context.Context, ns string, options ...interface{}) func() []v1.IntegrationKit { filters := make([]KitFilter, 0) listOptions := []ctrl.ListOption{ctrl.InNamespace(ns)} for _, option := range options { @@ -1353,14 +1373,14 @@ func Kits(ns string, options ...interface{}) func() []v1.IntegrationKit { case ctrl.ListOption: listOptions = append(listOptions, o) default: - failTest(fmt.Errorf("unsupported kits option %q", o)) + failTest(t, fmt.Errorf("unsupported kits option %q", o)) } } return func() []v1.IntegrationKit { list := v1.NewIntegrationKitList() - if err := TestClient().List(TestContext, &list, listOptions...); err != nil { - failTest(err) + if err := TestClient(t).List(ctx, &list, listOptions...); err != nil { + failTest(t, err) } var kits []v1.IntegrationKit @@ -1378,13 +1398,13 @@ func Kits(ns string, options ...interface{}) func() []v1.IntegrationKit { } } -func DeleteKits(ns string) error { - kits := Kits(ns)() +func DeleteKits(t *testing.T, ctx context.Context, ns string) error { + kits := Kits(t, ctx, ns)() if len(kits) == 0 { return nil } for _, kit := range kits { - if err := TestClient().Delete(TestContext, &kit); err != nil { + if err := TestClient(t).Delete(ctx, &kit); err != nil { return err } } @@ -1392,24 +1412,24 @@ func DeleteKits(ns string) error { return nil } -func DeleteIntegrations(ns string) func() (int, error) { +func DeleteIntegrations(t *testing.T, ctx context.Context, ns string) func() (int, error) { return func() (int, error) { - integrations := Integrations(ns)() + integrations := Integrations(t, ctx, ns)() if len(integrations.Items) == 0 { return 0, nil } - if err := Kamel("delete", "--all", "-n", ns).Execute(); err != nil { + if err := Kamel(t, ctx, "delete", "--all", "-n", ns).Execute(); err != nil { return 0, err } - return NumIntegrations(ns)(), nil + return NumIntegrations(t, ctx, ns)(), nil } } -func OperatorImage(ns string) func() string { +func OperatorImage(t *testing.T, ctx context.Context, ns string) func() string { return func() string { - pod := OperatorPod(ns)() + pod := OperatorPod(t, ctx, ns)() if pod != nil { if len(pod.Spec.Containers) > 0 { return pod.Spec.Containers[0].Image @@ -1419,9 +1439,9 @@ func OperatorImage(ns string) func() string { } } -func OperatorPodSecurityContext(ns string) func() *corev1.SecurityContext { +func OperatorPodSecurityContext(t *testing.T, ctx context.Context, ns string) func() *corev1.SecurityContext { return func() *corev1.SecurityContext { - pod := OperatorPod(ns)() + pod := OperatorPod(t, ctx, ns)() if pod == nil || pod.Spec.Containers == nil || len(pod.Spec.Containers) == 0 { return nil } @@ -1429,9 +1449,9 @@ func OperatorPodSecurityContext(ns string) func() *corev1.SecurityContext { } } -func OperatorPodHas(ns string, predicate func(pod *corev1.Pod) bool) func() bool { +func OperatorPodHas(t *testing.T, ctx context.Context, ns string, predicate func(pod *corev1.Pod) bool) func() bool { return func() bool { - pod := OperatorPod(ns)() + pod := OperatorPod(t, ctx, ns)() if pod == nil { return false } @@ -1439,9 +1459,9 @@ func OperatorPodHas(ns string, predicate func(pod *corev1.Pod) bool) func() bool } } -func OperatorPodPhase(ns string) func() corev1.PodPhase { +func OperatorPodPhase(t *testing.T, ctx context.Context, ns string) func() corev1.PodPhase { return func() corev1.PodPhase { - pod := OperatorPod(ns)() + pod := OperatorPod(t, ctx, ns)() if pod == nil { return "" } @@ -1449,9 +1469,9 @@ func OperatorPodPhase(ns string) func() corev1.PodPhase { } } -func OperatorEnvVarValue(ns string, key string) func() string { +func OperatorEnvVarValue(t *testing.T, ctx context.Context, ns string, key string) func() string { return func() string { - pod := OperatorPod(ns)() + pod := OperatorPod(t, ctx, ns)() if pod == nil || len(pod.Spec.Containers) == 0 { return "" } @@ -1466,7 +1486,7 @@ func OperatorEnvVarValue(ns string, key string) func() string { } } -func Configmap(ns string, name string) func() *corev1.ConfigMap { +func Configmap(t *testing.T, ctx context.Context, ns string, name string) func() *corev1.ConfigMap { return func() *corev1.ConfigMap { cm := corev1.ConfigMap{ TypeMeta: metav1.TypeMeta{ @@ -1482,7 +1502,7 @@ func Configmap(ns string, name string) func() *corev1.ConfigMap { Namespace: ns, Name: name, } - if err := TestClient().Get(TestContext, key, &cm); err != nil && k8serrors.IsNotFound(err) { + if err := TestClient(t).Get(ctx, key, &cm); err != nil && k8serrors.IsNotFound(err) { return nil } else if err != nil { log.Error(err, "Error while retrieving configmap "+name) @@ -1492,7 +1512,7 @@ func Configmap(ns string, name string) func() *corev1.ConfigMap { } } -func BuilderPod(ns string, name string) func() *corev1.Pod { +func BuilderPod(t *testing.T, ctx context.Context, ns string, name string) func() *corev1.Pod { return func() *corev1.Pod { pod := corev1.Pod{ TypeMeta: metav1.TypeMeta{ @@ -1508,7 +1528,7 @@ func BuilderPod(ns string, name string) func() *corev1.Pod { Namespace: ns, Name: name, } - if err := TestClient().Get(TestContext, key, &pod); err != nil && k8serrors.IsNotFound(err) { + if err := TestClient(t).Get(ctx, key, &pod); err != nil && k8serrors.IsNotFound(err) { return nil } else if err != nil { log.Error(err, "Error while retrieving pod "+name) @@ -1518,9 +1538,9 @@ func BuilderPod(ns string, name string) func() *corev1.Pod { } } -func BuilderPodPhase(ns string, name string) func() corev1.PodPhase { +func BuilderPodPhase(t *testing.T, ctx context.Context, ns string, name string) func() corev1.PodPhase { return func() corev1.PodPhase { - pod := BuilderPod(ns, name)() + pod := BuilderPod(t, ctx, ns, name)() if pod == nil { return "" } @@ -1528,7 +1548,7 @@ func BuilderPodPhase(ns string, name string) func() corev1.PodPhase { } } -func BuilderPodsCount(ns string) func() int { +func BuilderPodsCount(t *testing.T, ctx context.Context, ns string) func() int { return func() int { lst := corev1.PodList{ TypeMeta: metav1.TypeMeta{ @@ -1536,18 +1556,18 @@ func BuilderPodsCount(ns string) func() int { APIVersion: corev1.SchemeGroupVersion.String(), }, } - if err := TestClient().List(TestContext, &lst, + if err := TestClient(t).List(ctx, &lst, ctrl.InNamespace(ns), ctrl.MatchingLabels{ "camel.apache.org/component": "builder", }); err != nil { - failTest(err) + failTest(t, err) } return len(lst.Items) } } -func AutogeneratedConfigmapsCount(ns string) func() int { +func AutogeneratedConfigmapsCount(t *testing.T, ctx context.Context, ns string) func() int { return func() int { lst := corev1.ConfigMapList{ TypeMeta: metav1.TypeMeta{ @@ -1555,22 +1575,22 @@ func AutogeneratedConfigmapsCount(ns string) func() int { APIVersion: corev1.SchemeGroupVersion.String(), }, } - if err := TestClient().List(TestContext, &lst, + if err := TestClient(t).List(ctx, &lst, ctrl.InNamespace(ns), ctrl.MatchingLabels{ kubernetes.ConfigMapAutogenLabel: "true", }); err != nil { - failTest(err) + failTest(t, err) } return len(lst.Items) } } -func CreatePlainTextConfigmap(ns string, name string, data map[string]string) error { - return CreatePlainTextConfigmapWithLabels(ns, name, data, map[string]string{}) +func CreatePlainTextConfigmap(t *testing.T, ctx context.Context, ns string, name string, data map[string]string) error { + return CreatePlainTextConfigmapWithLabels(t, ctx, ns, name, data, map[string]string{}) } -func CreatePlainTextConfigmapWithLabels(ns string, name string, data map[string]string, labels map[string]string) error { +func CreatePlainTextConfigmapWithLabels(t *testing.T, ctx context.Context, ns string, name string, data map[string]string, labels map[string]string) error { cm := corev1.ConfigMap{ TypeMeta: metav1.TypeMeta{ Kind: "ConfigMap", @@ -1583,10 +1603,10 @@ func CreatePlainTextConfigmapWithLabels(ns string, name string, data map[string] }, Data: data, } - return TestClient().Create(TestContext, &cm) + return TestClient(t).Create(ctx, &cm) } -func CreatePlainTextConfigmapWithOwnerRefWithLabels(ns string, name string, data map[string]string, orname string, uid types.UID, labels map[string]string) error { +func CreatePlainTextConfigmapWithOwnerRefWithLabels(t *testing.T, ctx context.Context, ns string, name string, data map[string]string, orname string, uid types.UID, labels map[string]string) error { cm := corev1.ConfigMap{ TypeMeta: metav1.TypeMeta{ Kind: "ConfigMap", @@ -1608,14 +1628,14 @@ func CreatePlainTextConfigmapWithOwnerRefWithLabels(ns string, name string, data }, Data: data, } - return TestClient().Create(TestContext, &cm) + return TestClient(t).Create(ctx, &cm) } -func UpdatePlainTextConfigmap(ns string, name string, data map[string]string) error { - return UpdatePlainTextConfigmapWithLabels(ns, name, data, nil) +func UpdatePlainTextConfigmap(t *testing.T, ctx context.Context, ns string, name string, data map[string]string) error { + return UpdatePlainTextConfigmapWithLabels(t, ctx, ns, name, data, nil) } -func UpdatePlainTextConfigmapWithLabels(ns string, name string, data map[string]string, labels map[string]string) error { +func UpdatePlainTextConfigmapWithLabels(t *testing.T, ctx context.Context, ns string, name string, data map[string]string, labels map[string]string) error { cm := corev1.ConfigMap{ TypeMeta: metav1.TypeMeta{ Kind: "ConfigMap", @@ -1628,10 +1648,10 @@ func UpdatePlainTextConfigmapWithLabels(ns string, name string, data map[string] }, Data: data, } - return TestClient().Update(TestContext, &cm) + return TestClient(t).Update(ctx, &cm) } -func CreateBinaryConfigmap(ns string, name string, data map[string][]byte) error { +func CreateBinaryConfigmap(t *testing.T, ctx context.Context, ns string, name string, data map[string][]byte) error { cm := corev1.ConfigMap{ TypeMeta: metav1.TypeMeta{ Kind: "ConfigMap", @@ -1643,10 +1663,10 @@ func CreateBinaryConfigmap(ns string, name string, data map[string][]byte) error }, BinaryData: data, } - return TestClient().Create(TestContext, &cm) + return TestClient(t).Create(ctx, &cm) } -func DeleteConfigmap(ns string, name string) error { +func DeleteConfigmap(t *testing.T, ctx context.Context, ns string, name string) error { cm := corev1.ConfigMap{ TypeMeta: metav1.TypeMeta{ Kind: "ConfigMap", @@ -1657,18 +1677,18 @@ func DeleteConfigmap(ns string, name string) error { Name: name, }, } - return TestClient().Delete(TestContext, &cm) + return TestClient(t).Delete(ctx, &cm) } -func CreatePlainTextSecret(ns string, name string, data map[string]string) error { - return CreatePlainTextSecretWithLabels(ns, name, data, map[string]string{}) +func CreatePlainTextSecret(t *testing.T, ctx context.Context, ns string, name string, data map[string]string) error { + return CreatePlainTextSecretWithLabels(t, ctx, ns, name, data, map[string]string{}) } -func UpdatePlainTextSecret(ns string, name string, data map[string]string) error { - return UpdatePlainTextSecretWithLabels(ns, name, data, nil) +func UpdatePlainTextSecret(t *testing.T, ctx context.Context, ns string, name string, data map[string]string) error { + return UpdatePlainTextSecretWithLabels(t, ctx, ns, name, data, nil) } -func UpdatePlainTextSecretWithLabels(ns string, name string, data map[string]string, labels map[string]string) error { +func UpdatePlainTextSecretWithLabels(t *testing.T, ctx context.Context, ns string, name string, data map[string]string, labels map[string]string) error { sec := corev1.Secret{ TypeMeta: metav1.TypeMeta{ Kind: "Secret", @@ -1681,10 +1701,10 @@ func UpdatePlainTextSecretWithLabels(ns string, name string, data map[string]str }, StringData: data, } - return TestClient().Update(TestContext, &sec) + return TestClient(t).Update(ctx, &sec) } -func CreatePlainTextSecretWithLabels(ns string, name string, data map[string]string, labels map[string]string) error { +func CreatePlainTextSecretWithLabels(t *testing.T, ctx context.Context, ns string, name string, data map[string]string, labels map[string]string) error { sec := corev1.Secret{ TypeMeta: metav1.TypeMeta{ Kind: "Secret", @@ -1697,17 +1717,17 @@ func CreatePlainTextSecretWithLabels(ns string, name string, data map[string]str }, StringData: data, } - return TestClient().Create(TestContext, &sec) + return TestClient(t).Create(ctx, &sec) } -// Finds a secret in the given namespace by name or prefix of name -func SecretByName(ns string, prefix string) func() *corev1.Secret { +// SecretByName Finds a secret in the given namespace by name or prefix of name +func SecretByName(t *testing.T, ctx context.Context, ns string, prefix string) func() *corev1.Secret { return func() *corev1.Secret { - secretList, err := TestClient().CoreV1().Secrets(ns).List(TestContext, metav1.ListOptions{}) + secretList, err := TestClient(t).CoreV1().Secrets(ns).List(ctx, metav1.ListOptions{}) if err != nil && k8serrors.IsNotFound(err) { return nil } else if err != nil { - failTest(err) + failTest(t, err) } if len(secretList.Items) == 0 { @@ -1724,7 +1744,7 @@ func SecretByName(ns string, prefix string) func() *corev1.Secret { } } -func DeleteSecret(ns string, name string) error { +func DeleteSecret(t *testing.T, ctx context.Context, ns string, name string) error { sec := corev1.Secret{ TypeMeta: metav1.TypeMeta{ Kind: "Secret", @@ -1735,10 +1755,10 @@ func DeleteSecret(ns string, name string) error { Name: name, }, } - return TestClient().Delete(TestContext, &sec) + return TestClient(t).Delete(ctx, &sec) } -func KnativeService(ns string, name string) func() *servingv1.Service { +func KnativeService(t *testing.T, ctx context.Context, ns string, name string) func() *servingv1.Service { return func() *servingv1.Service { answer := servingv1.Service{ TypeMeta: metav1.TypeMeta{ @@ -1754,7 +1774,7 @@ func KnativeService(ns string, name string) func() *servingv1.Service { Namespace: ns, Name: name, } - if err := TestClient().Get(TestContext, key, &answer); err != nil && k8serrors.IsNotFound(err) { + if err := TestClient(t).Get(ctx, key, &answer); err != nil && k8serrors.IsNotFound(err) { return nil } else if err != nil { log.Errorf(err, "Error while retrieving knative service %s", name) @@ -1763,7 +1783,7 @@ func KnativeService(ns string, name string) func() *servingv1.Service { return &answer } } -func DeploymentWithIntegrationLabel(ns string, label string) func() *appsv1.Deployment { +func DeploymentWithIntegrationLabel(t *testing.T, ctx context.Context, ns string, label string) func() *appsv1.Deployment { return func() *appsv1.Deployment { lst := appsv1.DeploymentList{ TypeMeta: metav1.TypeMeta{ @@ -1771,7 +1791,7 @@ func DeploymentWithIntegrationLabel(ns string, label string) func() *appsv1.Depl APIVersion: appsv1.SchemeGroupVersion.String(), }, } - if err := TestClient().List(TestContext, &lst, ctrl.InNamespace(ns), ctrl.MatchingLabels{v1.IntegrationLabel: label}); err != nil && k8serrors.IsNotFound(err) { + if err := TestClient(t).List(ctx, &lst, ctrl.InNamespace(ns), ctrl.MatchingLabels{v1.IntegrationLabel: label}); err != nil && k8serrors.IsNotFound(err) { return nil } else if err != nil { log.Errorf(err, "Error while retrieving deployment %s", label) @@ -1784,7 +1804,7 @@ func DeploymentWithIntegrationLabel(ns string, label string) func() *appsv1.Depl } } -func Deployment(ns string, name string) func() *appsv1.Deployment { +func Deployment(t *testing.T, ctx context.Context, ns string, name string) func() *appsv1.Deployment { return func() *appsv1.Deployment { answer := appsv1.Deployment{ TypeMeta: metav1.TypeMeta{ @@ -1800,7 +1820,7 @@ func Deployment(ns string, name string) func() *appsv1.Deployment { Namespace: ns, Name: name, } - if err := TestClient().Get(TestContext, key, &answer); err != nil && k8serrors.IsNotFound(err) { + if err := TestClient(t).Get(ctx, key, &answer); err != nil && k8serrors.IsNotFound(err) { return nil } else if err != nil { log.Errorf(err, "Error while retrieving deployment %s", name) @@ -1810,9 +1830,9 @@ func Deployment(ns string, name string) func() *appsv1.Deployment { } } -func DeploymentCondition(ns string, name string, conditionType appsv1.DeploymentConditionType) func() appsv1.DeploymentCondition { +func DeploymentCondition(t *testing.T, ctx context.Context, ns string, name string, conditionType appsv1.DeploymentConditionType) func() appsv1.DeploymentCondition { return func() appsv1.DeploymentCondition { - deployment := Deployment(ns, name)() + deployment := Deployment(t, ctx, ns, name)() condition := appsv1.DeploymentCondition{ Status: corev1.ConditionUnknown, @@ -1829,10 +1849,10 @@ func DeploymentCondition(ns string, name string, conditionType appsv1.Deployment } } -func Build(ns, name string) func() *v1.Build { +func Build(t *testing.T, ctx context.Context, ns, name string) func() *v1.Build { return func() *v1.Build { build := v1.NewBuild(ns, name) - if err := TestClient().Get(TestContext, ctrl.ObjectKeyFromObject(build), build); err != nil && k8serrors.IsNotFound(err) { + if err := TestClient(t).Get(ctx, ctrl.ObjectKeyFromObject(build), build); err != nil && k8serrors.IsNotFound(err) { return nil } else if err != nil { log.Error(err, "Error while retrieving build "+name) @@ -1842,9 +1862,9 @@ func Build(ns, name string) func() *v1.Build { } } -func BuildConfig(ns, name string) func() v1.BuildConfiguration { +func BuildConfig(t *testing.T, ctx context.Context, ns, name string) func() v1.BuildConfiguration { return func() v1.BuildConfiguration { - build := Build(ns, name)() + build := Build(t, ctx, ns, name)() if build != nil { return *build.BuilderConfiguration() } @@ -1852,9 +1872,9 @@ func BuildConfig(ns, name string) func() v1.BuildConfiguration { } } -func BuildPhase(ns, name string) func() v1.BuildPhase { +func BuildPhase(t *testing.T, ctx context.Context, ns, name string) func() v1.BuildPhase { return func() v1.BuildPhase { - build := Build(ns, name)() + build := Build(t, ctx, ns, name)() if build != nil { return build.Status.Phase } @@ -1862,9 +1882,9 @@ func BuildPhase(ns, name string) func() v1.BuildPhase { } } -func BuildConditions(ns, name string) func() []v1.BuildCondition { +func BuildConditions(t *testing.T, ctx context.Context, ns, name string) func() []v1.BuildCondition { return func() []v1.BuildCondition { - build := Build(ns, name)() + build := Build(t, ctx, ns, name)() if build != nil && &build.Status != nil && build.Status.Conditions != nil { return build.Status.Conditions } @@ -1872,9 +1892,9 @@ func BuildConditions(ns, name string) func() []v1.BuildCondition { } } -func BuildCondition(ns string, name string, conditionType v1.BuildConditionType) func() *v1.BuildCondition { +func BuildCondition(t *testing.T, ctx context.Context, ns string, name string, conditionType v1.BuildConditionType) func() *v1.BuildCondition { return func() *v1.BuildCondition { - build := Build(ns, name)() + build := Build(t, ctx, ns, name)() if build != nil && &build.Status != nil && build.Status.Conditions != nil { return build.Status.GetCondition(conditionType) } @@ -1882,9 +1902,9 @@ func BuildCondition(ns string, name string, conditionType v1.BuildConditionType) } } -func BuildFailureRecovery(ns, name string) func() int { +func BuildFailureRecovery(t *testing.T, ctx context.Context, ns, name string) func() int { return func() int { - build := Build(ns, name)() + build := Build(t, ctx, ns, name)() if build != nil { return build.Status.Failure.Recovery.Attempt } @@ -1904,37 +1924,37 @@ func BuildsRunning(predicates ...func() v1.BuildPhase) func() int { } } -func HasPlatform(ns string) func() bool { +func HasPlatform(t *testing.T, ctx context.Context, ns string) func() bool { return func() bool { lst := v1.NewIntegrationPlatformList() - if err := TestClient().List(TestContext, &lst, ctrl.InNamespace(ns)); err != nil { + if err := TestClient(t).List(ctx, &lst, ctrl.InNamespace(ns)); err != nil { return false } return len(lst.Items) > 0 } } -func Platform(ns string) func() *v1.IntegrationPlatform { +func Platform(t *testing.T, ctx context.Context, ns string) func() *v1.IntegrationPlatform { return func() *v1.IntegrationPlatform { lst := v1.NewIntegrationPlatformList() - if err := TestClient().List(TestContext, &lst, ctrl.InNamespace(ns)); err != nil { - failTest(err) + if err := TestClient(t).List(ctx, &lst, ctrl.InNamespace(ns)); err != nil { + failTest(t, err) } if len(lst.Items) == 0 { return nil } if len(lst.Items) > 1 { - failTest(fmt.Errorf("multiple integration platforms found in namespace %q", ns)) + failTest(t, fmt.Errorf("multiple integration platforms found in namespace %q", ns)) } return &lst.Items[0] } } -func PlatformByName(ns string, name string) func() *v1.IntegrationPlatform { +func PlatformByName(t *testing.T, ctx context.Context, ns string, name string) func() *v1.IntegrationPlatform { return func() *v1.IntegrationPlatform { lst := v1.NewIntegrationPlatformList() - if err := TestClient().List(TestContext, &lst, ctrl.InNamespace(ns)); err != nil { - failTest(err) + if err := TestClient(t).List(ctx, &lst, ctrl.InNamespace(ns)); err != nil { + failTest(t, err) } for _, p := range lst.Items { if p.Name == name { @@ -1945,10 +1965,48 @@ func PlatformByName(ns string, name string) func() *v1.IntegrationPlatform { } } -func CopyCamelCatalog(ns, operatorID string) error { +func CopyIntegrationKits(t *testing.T, ctx context.Context, ns, operatorID string) error { + opns := GetEnvOrDefault("CAMEL_K_GLOBAL_OPERATOR_NS", TestDefaultNamespace) + + lst := v1.NewIntegrationKitList() + if err := TestClient(t).List(ctx, &lst, ctrl.InNamespace(opns)); err != nil { + failTest(t, err) + } + for _, kit := range lst.Items { + if kit.Status.Image != "" { + copyKit := v1.IntegrationKit{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: ns, + Name: kit.Name, + }, + Spec: *kit.Spec.DeepCopy(), + } + + if copyKit.Labels == nil { + copyKit.Labels = make(map[string]string) + } + + copyKit.Labels[v1.IntegrationKitTypeLabel] = v1.IntegrationKitTypeExternal + copyKit.Spec.Image = kit.Status.Image + + v1.SetAnnotation(©Kit.ObjectMeta, v1.OperatorIDAnnotation, operatorID) + fmt.Printf("Copy integration kit %s from namespace %s\n", kit.Name, opns) + if err := CreateIntegrationKit(t, ctx, ©Kit)(); err != nil { + return err + } + } + } + + return nil +} + +func CopyCamelCatalog(t *testing.T, ctx context.Context, ns, operatorID string) error { catalogName := fmt.Sprintf("camel-catalog-%s", strings.ToLower(defaults.DefaultRuntimeVersion)) - defaultCatalog := CamelCatalog("default", catalogName)() + opns := GetEnvOrDefault("CAMEL_K_GLOBAL_OPERATOR_NS", TestDefaultNamespace) + + defaultCatalog := CamelCatalog(t, ctx, opns, catalogName)() if defaultCatalog != nil { + fmt.Printf("Copy catalog %s from namespace %s\n", catalogName, opns) catalog := v1.CamelCatalog{ ObjectMeta: metav1.ObjectMeta{ Namespace: ns, @@ -1957,17 +2015,17 @@ func CopyCamelCatalog(ns, operatorID string) error { Spec: *defaultCatalog.Spec.DeepCopy(), } v1.SetAnnotation(&catalog.ObjectMeta, v1.OperatorIDAnnotation, operatorID) - return CreateCamelCatalog(&catalog)() + return CreateCamelCatalog(t, ctx, &catalog)() } return nil } -func IntegrationProfileByName(ns string, name string) func() *v1.IntegrationProfile { +func IntegrationProfileByName(t *testing.T, ctx context.Context, ns string, name string) func() *v1.IntegrationProfile { return func() *v1.IntegrationProfile { lst := v1.NewIntegrationProfileList() - if err := TestClient().List(TestContext, &lst, ctrl.InNamespace(ns)); err != nil { - failTest(err) + if err := TestClient(t).List(ctx, &lst, ctrl.InNamespace(ns)); err != nil { + failTest(t, err) } for _, pc := range lst.Items { if pc.Name == name { @@ -1978,15 +2036,15 @@ func IntegrationProfileByName(ns string, name string) func() *v1.IntegrationProf } } -func CamelCatalog(ns, name string) func() *v1.CamelCatalog { +func CamelCatalog(t *testing.T, ctx context.Context, ns, name string) func() *v1.CamelCatalog { return func() *v1.CamelCatalog { cat := v1.CamelCatalog{} key := ctrl.ObjectKey{ Namespace: ns, Name: name, } - if err := TestClient().Get(TestContext, key, &cat); err != nil && !k8serrors.IsNotFound(err) { - failTest(err) + if err := TestClient(t).Get(ctx, key, &cat); err != nil && !k8serrors.IsNotFound(err) { + failTest(t, err) } else if err != nil && k8serrors.IsNotFound(err) { return nil } @@ -1994,28 +2052,28 @@ func CamelCatalog(ns, name string) func() *v1.CamelCatalog { } } -func IntegrationProfile(ns string) func() *v1.IntegrationProfile { +func IntegrationProfile(t *testing.T, ctx context.Context, ns string) func() *v1.IntegrationProfile { return func() *v1.IntegrationProfile { lst := v1.NewIntegrationProfileList() - if err := TestClient().List(TestContext, &lst, ctrl.InNamespace(ns)); err != nil { - failTest(err) + if err := TestClient(t).List(ctx, &lst, ctrl.InNamespace(ns)); err != nil { + failTest(t, err) } if len(lst.Items) == 0 { return nil } if len(lst.Items) > 1 { - failTest(fmt.Errorf("multiple integration profiles found in namespace %q", ns)) + failTest(t, fmt.Errorf("multiple integration profiles found in namespace %q", ns)) } return &lst.Items[0] } } -func CreateIntegrationProfile(profile *v1.IntegrationProfile) error { - return TestClient().Create(TestContext, profile) +func CreateIntegrationProfile(t *testing.T, ctx context.Context, profile *v1.IntegrationProfile) error { + return TestClient(t).Create(ctx, profile) } -func UpdateIntegrationProfile(ns string, upd func(ipr *v1.IntegrationProfile)) error { - ipr := IntegrationProfile(ns)() +func UpdateIntegrationProfile(t *testing.T, ctx context.Context, ns string, upd func(ipr *v1.IntegrationProfile)) error { + ipr := IntegrationProfile(t, ctx, ns)() if ipr == nil { return fmt.Errorf("unable to locate Integration Profile in %s", ns) } @@ -2028,32 +2086,42 @@ func UpdateIntegrationProfile(ns string, upd func(ipr *v1.IntegrationProfile)) e } else if len(p) == 0 { return nil } - return TestClient().Patch(TestContext, target, ctrl.RawPatch(types.MergePatchType, p)) + return TestClient(t).Patch(ctx, target, ctrl.RawPatch(types.MergePatchType, p)) +} + +func CreateCamelCatalog(t *testing.T, ctx context.Context, catalog *v1.CamelCatalog) func() error { + return func() error { + testSetupMutex.Lock() + defer testSetupMutex.Unlock() + return TestClient(t).Create(ctx, catalog) + } } -func CreateCamelCatalog(catalog *v1.CamelCatalog) func() error { +func CreateIntegrationKit(t *testing.T, ctx context.Context, kit *v1.IntegrationKit) func() error { return func() error { - return TestClient().Create(TestContext, catalog) + testSetupMutex.Lock() + defer testSetupMutex.Unlock() + return TestClient(t).Create(ctx, kit) } } -func DeleteCamelCatalog(ns, name string) func() bool { +func DeleteCamelCatalog(t *testing.T, ctx context.Context, ns, name string) func() bool { return func() bool { - cat := CamelCatalog(ns, name)() + cat := CamelCatalog(t, ctx, ns, name)() if cat == nil { return true } - if err := TestClient().Delete(TestContext, cat); err != nil { + if err := TestClient(t).Delete(ctx, cat); err != nil { log.Error(err, "Got error while deleting the catalog") } return true } } -func DefaultCamelCatalogPhase(ns string) func() v1.CamelCatalogPhase { +func DefaultCamelCatalogPhase(t *testing.T, ctx context.Context, ns string) func() v1.CamelCatalogPhase { return func() v1.CamelCatalogPhase { catalogName := fmt.Sprintf("camel-catalog-%s", strings.ToLower(defaults.DefaultRuntimeVersion)) - c := CamelCatalog(ns, catalogName)() + c := CamelCatalog(t, ctx, ns, catalogName)() if c == nil { return "" } @@ -2061,9 +2129,9 @@ func DefaultCamelCatalogPhase(ns string) func() v1.CamelCatalogPhase { } } -func CamelCatalogPhase(ns, name string) func() v1.CamelCatalogPhase { +func CamelCatalogPhase(t *testing.T, ctx context.Context, ns, name string) func() v1.CamelCatalogPhase { return func() v1.CamelCatalogPhase { - c := CamelCatalog(ns, name)() + c := CamelCatalog(t, ctx, ns, name)() if c == nil { return "" } @@ -2071,9 +2139,9 @@ func CamelCatalogPhase(ns, name string) func() v1.CamelCatalogPhase { } } -func CamelCatalogCondition(ns, name string, conditionType v1.CamelCatalogConditionType) func() *v1.CamelCatalogCondition { +func CamelCatalogCondition(t *testing.T, ctx context.Context, ns, name string, conditionType v1.CamelCatalogConditionType) func() *v1.CamelCatalogCondition { return func() *v1.CamelCatalogCondition { - c := CamelCatalog(ns, name)() + c := CamelCatalog(t, ctx, ns, name)() if c == nil { return nil } @@ -2086,9 +2154,9 @@ func CamelCatalogCondition(ns, name string, conditionType v1.CamelCatalogConditi } } -func CamelCatalogImage(ns, name string) func() string { +func CamelCatalogImage(t *testing.T, ctx context.Context, ns, name string) func() string { return func() string { - c := CamelCatalog(ns, name)() + c := CamelCatalog(t, ctx, ns, name)() if c == nil { return "" } @@ -2096,32 +2164,49 @@ func CamelCatalogImage(ns, name string) func() string { } } -func CamelCatalogList(ns string) func() []v1.CamelCatalog { +func CamelCatalogList(t *testing.T, ctx context.Context, ns string) func() []v1.CamelCatalog { return func() []v1.CamelCatalog { lst := v1.NewCamelCatalogList() - if err := TestClient().List(TestContext, &lst, ctrl.InNamespace(ns)); err != nil { - failTest(err) + if err := TestClient(t).List(ctx, &lst, ctrl.InNamespace(ns)); err != nil { + failTest(t, err) } return lst.Items } } -func DeletePlatform(ns string) func() bool { +func DeletePlatform(t *testing.T, ctx context.Context, ns string) func() bool { return func() bool { - pl := Platform(ns)() + pl := Platform(t, ctx, ns)() if pl == nil { return true } - if err := TestClient().Delete(TestContext, pl); err != nil { + if err := TestClient(t).Delete(ctx, pl); err != nil { log.Error(err, "Got error while deleting the platform") } return false } } -func PlatformVersion(ns string) func() string { +func UpdatePlatform(t *testing.T, ctx context.Context, ns string, name string, upd func(ip *v1.IntegrationPlatform)) error { + ip := PlatformByName(t, ctx, ns, name)() + if ip == nil { + return fmt.Errorf("unable to locate Integration Platform %s in %s", name, ns) + } + target := ip.DeepCopy() + upd(target) + // For some reason, full patch fails on some clusters + p, err := patch.MergePatch(ip, target) + if err != nil { + return err + } else if len(p) == 0 { + return nil + } + return TestClient(t).Patch(ctx, target, ctrl.RawPatch(types.MergePatchType, p)) +} + +func PlatformVersion(t *testing.T, ctx context.Context, ns string) func() string { return func() string { - p := Platform(ns)() + p := Platform(t, ctx, ns)() if p == nil { return "" } @@ -2129,9 +2214,9 @@ func PlatformVersion(ns string) func() string { } } -func PlatformPhase(ns string) func() v1.IntegrationPlatformPhase { +func PlatformPhase(t *testing.T, ctx context.Context, ns string) func() v1.IntegrationPlatformPhase { return func() v1.IntegrationPlatformPhase { - p := Platform(ns)() + p := Platform(t, ctx, ns)() if p == nil { return "" } @@ -2139,9 +2224,9 @@ func PlatformPhase(ns string) func() v1.IntegrationPlatformPhase { } } -func SelectedPlatformPhase(ns string, name string) func() v1.IntegrationPlatformPhase { +func SelectedPlatformPhase(t *testing.T, ctx context.Context, ns string, name string) func() v1.IntegrationPlatformPhase { return func() v1.IntegrationPlatformPhase { - p := PlatformByName(ns, name)() + p := PlatformByName(t, ctx, ns, name)() if p == nil { return "" } @@ -2149,9 +2234,9 @@ func SelectedPlatformPhase(ns string, name string) func() v1.IntegrationPlatform } } -func SelectedIntegrationProfilePhase(ns string, name string) func() v1.IntegrationProfilePhase { +func SelectedIntegrationProfilePhase(t *testing.T, ctx context.Context, ns string, name string) func() v1.IntegrationProfilePhase { return func() v1.IntegrationProfilePhase { - pc := IntegrationProfileByName(ns, name)() + pc := IntegrationProfileByName(t, ctx, ns, name)() if pc == nil { return "" } @@ -2159,9 +2244,9 @@ func SelectedIntegrationProfilePhase(ns string, name string) func() v1.Integrati } } -func PlatformHas(ns string, predicate func(pl *v1.IntegrationPlatform) bool) func() bool { +func PlatformHas(t *testing.T, ctx context.Context, ns string, predicate func(pl *v1.IntegrationPlatform) bool) func() bool { return func() bool { - pl := Platform(ns)() + pl := Platform(t, ctx, ns)() if pl == nil { return false } @@ -2169,12 +2254,9 @@ func PlatformHas(ns string, predicate func(pl *v1.IntegrationPlatform) bool) fun } } -func PlatformCondition( - ns string, - conditionType v1.IntegrationPlatformConditionType, -) func() *v1.IntegrationPlatformCondition { +func PlatformCondition(t *testing.T, ctx context.Context, ns string, conditionType v1.IntegrationPlatformConditionType) func() *v1.IntegrationPlatformCondition { return func() *v1.IntegrationPlatformCondition { - p := Platform(ns)() + p := Platform(t, ctx, ns)() if p == nil { return nil } @@ -2182,12 +2264,9 @@ func PlatformCondition( } } -func PlatformConditionStatus( - ns string, - conditionType v1.IntegrationPlatformConditionType, -) func() corev1.ConditionStatus { +func PlatformConditionStatus(t *testing.T, ctx context.Context, ns string, conditionType v1.IntegrationPlatformConditionType) func() corev1.ConditionStatus { return func() corev1.ConditionStatus { - c := PlatformCondition(ns, conditionType)() + c := PlatformCondition(t, ctx, ns, conditionType)() if c == nil { return "Unknown" } @@ -2195,9 +2274,9 @@ func PlatformConditionStatus( } } -func PlatformProfile(ns string) func() v1.TraitProfile { +func PlatformProfile(t *testing.T, ctx context.Context, ns string) func() v1.TraitProfile { return func() v1.TraitProfile { - p := Platform(ns)() + p := Platform(t, ctx, ns)() if p == nil { return "" } @@ -2205,9 +2284,9 @@ func PlatformProfile(ns string) func() v1.TraitProfile { } } -func PlatformTimeout(ns string) func() *metav1.Duration { +func PlatformTimeout(t *testing.T, ctx context.Context, ns string) func() *metav1.Duration { return func() *metav1.Duration { - p := Platform(ns)() + p := Platform(t, ctx, ns)() if p == nil { return &metav1.Duration{} } @@ -2215,17 +2294,28 @@ func PlatformTimeout(ns string) func() *metav1.Duration { } } -func AssignPlatformToOperator(ns, operator string) error { - pl := Platform(ns)() +func AssignPlatformToOperator(t *testing.T, ctx context.Context, ns, operator string) error { + pl := Platform(t, ctx, ns)() if pl == nil { return errors.New("cannot assign platform to operator: no platform found") } pl.SetOperatorID(operator) - return TestClient().Update(TestContext, pl) + return TestClient(t).Update(ctx, pl) } -func CRDs() func() []metav1.APIResource { +func GetExpectedCRDs(releaseVersion string) int { + switch releaseVersion { + case "2.2.0": + return 8 + case defaults.Version: + return ExpectedCRDs + } + + return ExpectedCRDs +} + +func CRDs(t *testing.T) func() []metav1.APIResource { return func() []metav1.APIResource { kinds := []string{ @@ -2233,6 +2323,7 @@ func CRDs() func() []metav1.APIResource { reflect.TypeOf(v1.Integration{}).Name(), reflect.TypeOf(v1.IntegrationKit{}).Name(), reflect.TypeOf(v1.IntegrationPlatform{}).Name(), + reflect.TypeOf(v1.IntegrationProfile{}).Name(), reflect.TypeOf(v1.Kamelet{}).Name(), reflect.TypeOf(v1.Pipe{}).Name(), reflect.TypeOf(v1alpha1.KameletBinding{}).Name(), @@ -2242,11 +2333,11 @@ func CRDs() func() []metav1.APIResource { present := []metav1.APIResource{} for _, version := range versions { - lst, err := TestClient().Discovery().ServerResourcesForGroupVersion("camel.apache.org/" + version) + lst, err := TestClient(t).Discovery().ServerResourcesForGroupVersion("camel.apache.org/" + version) if err != nil && k8serrors.IsNotFound(err) { return nil } else if err != nil { - failTest(err) + failTest(t, err) } for _, res := range lst.APIResources { @@ -2266,11 +2357,11 @@ func CRDs() func() []metav1.APIResource { } } -func ConsoleCLIDownload(name string) func() *consoleV1.ConsoleCLIDownload { +func ConsoleCLIDownload(t *testing.T, ctx context.Context, name string) func() *consoleV1.ConsoleCLIDownload { return func() *consoleV1.ConsoleCLIDownload { cliDownload := consoleV1.ConsoleCLIDownload{} - if err := TestClient().Get(TestContext, ctrl.ObjectKey{Name: name}, &cliDownload); err != nil && !k8serrors.IsNotFound(err) { - failTest(err) + if err := TestClient(t).Get(ctx, ctrl.ObjectKey{Name: name}, &cliDownload); err != nil && !k8serrors.IsNotFound(err) { + failTest(t, err) } else if err != nil && k8serrors.IsNotFound(err) { return nil } @@ -2278,7 +2369,7 @@ func ConsoleCLIDownload(name string) func() *consoleV1.ConsoleCLIDownload { } } -func OperatorPod(ns string) func() *corev1.Pod { +func OperatorPod(t *testing.T, ctx context.Context, ns string) func() *corev1.Pod { return func() *corev1.Pod { lst := corev1.PodList{ TypeMeta: metav1.TypeMeta{ @@ -2286,12 +2377,12 @@ func OperatorPod(ns string) func() *corev1.Pod { APIVersion: v1.SchemeGroupVersion.String(), }, } - if err := TestClient().List(TestContext, &lst, + if err := TestClient(t).List(ctx, &lst, ctrl.InNamespace(ns), ctrl.MatchingLabels{ "camel.apache.org/component": "operator", }); err != nil { - failTest(err) + failTest(t, err) } if len(lst.Items) == 0 { return nil @@ -2300,8 +2391,8 @@ func OperatorPod(ns string) func() *corev1.Pod { } } -// Find one Pod filtered by namespace ns and label app.kubernetes.io/name value appName. -func Pod(ns string, appName string) func() (*corev1.Pod, error) { +// Pod Find one pod filtered by namespace ns and label app.kubernetes.io/name value appName. +func Pod(t *testing.T, ctx context.Context, ns string, appName string) func() (*corev1.Pod, error) { return func() (*corev1.Pod, error) { lst := corev1.PodList{ TypeMeta: metav1.TypeMeta{ @@ -2309,7 +2400,7 @@ func Pod(ns string, appName string) func() (*corev1.Pod, error) { APIVersion: v1.SchemeGroupVersion.String(), }, } - if err := TestClient().List(TestContext, &lst, + if err := TestClient(t).List(ctx, &lst, ctrl.InNamespace(ns), ctrl.MatchingLabels{ "app.kubernetes.io/name": appName, @@ -2323,34 +2414,34 @@ func Pod(ns string, appName string) func() (*corev1.Pod, error) { } } -func OperatorTryPodForceKill(ns string, timeSeconds int) { - pod := OperatorPod(ns)() +func OperatorTryPodForceKill(t *testing.T, ctx context.Context, ns string, timeSeconds int) { + pod := OperatorPod(t, ctx, ns)() if pod != nil { - if err := TestClient().Delete(TestContext, pod, ctrl.GracePeriodSeconds(timeSeconds)); err != nil { + if err := TestClient(t).Delete(ctx, pod, ctrl.GracePeriodSeconds(timeSeconds)); err != nil { log.Error(err, "cannot forcefully kill the pod") } } } -func ScaleOperator(ns string, replicas int32) error { - operator, err := TestClient().AppsV1().Deployments(ns).Get(TestContext, "camel-k-operator", metav1.GetOptions{}) +func ScaleOperator(t *testing.T, ctx context.Context, ns string, replicas int32) error { + operator, err := TestClient(t).AppsV1().Deployments(ns).Get(ctx, "camel-k-operator", metav1.GetOptions{}) if err != nil { return err } operator.Spec.Replicas = &replicas - _, err = TestClient().AppsV1().Deployments(ns).Update(TestContext, operator, metav1.UpdateOptions{}) + _, err = TestClient(t).AppsV1().Deployments(ns).Update(ctx, operator, metav1.UpdateOptions{}) if err != nil { return err } if replicas == 0 { // speedup scale down by killing the pod - OperatorTryPodForceKill(ns, 10) + OperatorTryPodForceKill(t, ctx, ns, 10) } return nil } -func ClusterRole() func() []rbacv1.ClusterRole { +func ClusterRole(t *testing.T, ctx context.Context) func() []rbacv1.ClusterRole { return func() []rbacv1.ClusterRole { lst := rbacv1.ClusterRoleList{ TypeMeta: metav1.TypeMeta{ @@ -2358,11 +2449,11 @@ func ClusterRole() func() []rbacv1.ClusterRole { APIVersion: rbacv1.SchemeGroupVersion.String(), }, } - if err := TestClient().List(TestContext, &lst, + if err := TestClient(t).List(ctx, &lst, ctrl.MatchingLabels{ "app": "camel-k", }); err != nil { - failTest(err) + failTest(t, err) } if len(lst.Items) == 0 { return nil @@ -2371,7 +2462,7 @@ func ClusterRole() func() []rbacv1.ClusterRole { } } -func Role(ns string) func() []rbacv1.Role { +func Role(t *testing.T, ctx context.Context, ns string) func() []rbacv1.Role { return func() []rbacv1.Role { lst := rbacv1.RoleList{ TypeMeta: metav1.TypeMeta{ @@ -2379,12 +2470,12 @@ func Role(ns string) func() []rbacv1.Role { APIVersion: rbacv1.SchemeGroupVersion.String(), }, } - if err := TestClient().List(TestContext, &lst, + if err := TestClient(t).List(ctx, &lst, ctrl.InNamespace(ns), ctrl.MatchingLabels{ "app": "camel-k", }); err != nil { - failTest(err) + failTest(t, err) } if len(lst.Items) == 0 { return nil @@ -2393,7 +2484,7 @@ func Role(ns string) func() []rbacv1.Role { } } -func RoleBinding(ns string) func() *rbacv1.RoleBinding { +func RoleBinding(t *testing.T, ctx context.Context, ns string) func() *rbacv1.RoleBinding { return func() *rbacv1.RoleBinding { lst := rbacv1.RoleBindingList{ TypeMeta: metav1.TypeMeta{ @@ -2401,12 +2492,12 @@ func RoleBinding(ns string) func() *rbacv1.RoleBinding { APIVersion: metav1.SchemeGroupVersion.String(), }, } - if err := TestClient().List(TestContext, &lst, + if err := TestClient(t).List(ctx, &lst, ctrl.InNamespace(ns), ctrl.MatchingLabels{ "app": "camel-k", }); err != nil { - failTest(err) + failTest(t, err) } if len(lst.Items) == 0 { return nil @@ -2415,7 +2506,7 @@ func RoleBinding(ns string) func() *rbacv1.RoleBinding { } } -func ServiceAccount(ns, name string) func() *corev1.ServiceAccount { +func ServiceAccount(t *testing.T, ctx context.Context, ns, name string) func() *corev1.ServiceAccount { return func() *corev1.ServiceAccount { lst := corev1.ServiceAccountList{ TypeMeta: metav1.TypeMeta{ @@ -2423,12 +2514,12 @@ func ServiceAccount(ns, name string) func() *corev1.ServiceAccount { APIVersion: corev1.SchemeGroupVersion.String(), }, } - if err := TestClient().List(TestContext, &lst, + if err := TestClient(t).List(ctx, &lst, ctrl.InNamespace(ns), ctrl.MatchingLabels{ "app": "camel-k", }); err != nil { - failTest(err) + failTest(t, err) } if len(lst.Items) == 0 { return nil @@ -2437,25 +2528,25 @@ func ServiceAccount(ns, name string) func() *corev1.ServiceAccount { } } -func KameletList(ns string) func() []v1.Kamelet { +func KameletList(t *testing.T, ctx context.Context, ns string) func() []v1.Kamelet { return func() []v1.Kamelet { lst := v1.NewKameletList() - if err := TestClient().List(TestContext, &lst, ctrl.InNamespace(ns)); err != nil { - failTest(err) + if err := TestClient(t).List(ctx, &lst, ctrl.InNamespace(ns)); err != nil { + failTest(t, err) } return lst.Items } } -func Kamelet(name string, ns string) func() *v1.Kamelet { +func Kamelet(t *testing.T, ctx context.Context, name string, ns string) func() *v1.Kamelet { return func() *v1.Kamelet { it := v1.NewKamelet(ns, name) key := ctrl.ObjectKey{ Namespace: ns, Name: name, } - if err := TestClient().Get(TestContext, key, &it); err != nil && !k8serrors.IsNotFound(err) { - failTest(err) + if err := TestClient(t).Get(ctx, key, &it); err != nil && !k8serrors.IsNotFound(err) { + failTest(t, err) } else if err != nil && k8serrors.IsNotFound(err) { return nil } @@ -2470,12 +2561,12 @@ func KameletLabels(kamelet *v1.Kamelet) map[string]string { return kamelet.GetLabels() } -func ClusterDomainName() (string, error) { +func ClusterDomainName(t *testing.T, ctx context.Context) (string, error) { dns := configv1.DNS{} key := ctrl.ObjectKey{ Name: "cluster", } - err := TestClient().Get(TestContext, key, &dns) + err := TestClient(t).Get(ctx, key, &dns) if err != nil { return "", err } @@ -2486,14 +2577,14 @@ func ClusterDomainName() (string, error) { Tekton */ -func CreateOperatorServiceAccount(ns string) error { - return install.Resource(TestContext, TestClient(), ns, true, install.IdentityResourceCustomizer, "/config/manager/operator-service-account.yaml") +func CreateOperatorServiceAccount(t *testing.T, ctx context.Context, ns string) error { + return install.Resource(ctx, TestClient(t), ns, true, install.IdentityResourceCustomizer, "/config/manager/operator-service-account.yaml") } -func CreateOperatorRole(ns string) (err error) { - oc, err := openshift.IsOpenShift(TestClient()) +func CreateOperatorRole(t *testing.T, ctx context.Context, ns string) (err error) { + oc, err := openshift.IsOpenShift(TestClient(t)) if err != nil { - failTest(err) + failTest(t, err) } customizer := install.IdentityResourceCustomizer if oc { @@ -2501,32 +2592,32 @@ func CreateOperatorRole(ns string) (err error) { // This should ideally be removed from the common RBAC manifest. customizer = install.RemoveIngressRoleCustomizer } - err = install.Resource(TestContext, TestClient(), ns, true, customizer, "/config/rbac/namespaced/operator-role.yaml") + err = install.Resource(ctx, TestClient(t), ns, true, customizer, "/config/rbac/namespaced/operator-role.yaml") if err != nil { return err } if oc { - return install.Resource(TestContext, TestClient(), ns, true, install.IdentityResourceCustomizer, "/config/rbac/openshift/namespaced/operator-role-openshift.yaml") + return install.Resource(ctx, TestClient(t), ns, true, install.IdentityResourceCustomizer, "/config/rbac/openshift/namespaced/operator-role-openshift.yaml") } return nil } -func CreateOperatorRoleBinding(ns string) error { - oc, err := openshift.IsOpenShift(TestClient()) +func CreateOperatorRoleBinding(t *testing.T, ctx context.Context, ns string) error { + oc, err := openshift.IsOpenShift(TestClient(t)) if err != nil { - failTest(err) + failTest(t, err) } - err = install.Resource(TestContext, TestClient(), ns, true, install.IdentityResourceCustomizer, "/config/rbac/namespaced/operator-role-binding.yaml") + err = install.Resource(ctx, TestClient(t), ns, true, install.IdentityResourceCustomizer, "/config/rbac/namespaced/operator-role-binding.yaml") if err != nil { return err } if oc { - return install.Resource(TestContext, TestClient(), ns, true, install.IdentityResourceCustomizer, "/config/rbac/openshift/namespaced/operator-role-binding-openshift.yaml") + return install.Resource(ctx, TestClient(t), ns, true, install.IdentityResourceCustomizer, "/config/rbac/openshift/namespaced/operator-role-binding-openshift.yaml") } return nil } -func CreateKamelPod(ns string, name string, command ...string) error { +func CreateKamelPod(t *testing.T, ctx context.Context, ns string, name string, command ...string) error { args := command for _, hook := range KamelHooks { args = hook(args) @@ -2552,14 +2643,14 @@ func CreateKamelPod(ns string, name string, command ...string) error { }, }, } - return TestClient().Create(TestContext, &pod) + return TestClient(t).Create(ctx, &pod) } /* Knative */ -func CreateKnativeChannel(ns string, name string) func() error { +func CreateKnativeChannel(t *testing.T, ctx context.Context, ns string, name string) func() error { return func() error { channel := messaging.InMemoryChannel{ TypeMeta: metav1.TypeMeta{ @@ -2571,11 +2662,11 @@ func CreateKnativeChannel(ns string, name string) func() error { Name: name, }, } - return TestClient().Create(TestContext, &channel) + return TestClient(t).Create(ctx, &channel) } } -func CreateKnativeBroker(ns string, name string) func() error { +func CreateKnativeBroker(t *testing.T, ctx context.Context, ns string, name string) func() error { return func() error { broker := eventing.Broker{ TypeMeta: metav1.TypeMeta{ @@ -2587,7 +2678,7 @@ func CreateKnativeBroker(ns string, name string) func() error { Name: name, }, } - return TestClient().Create(TestContext, &broker) + return TestClient(t).Create(ctx, &broker) } } @@ -2595,7 +2686,7 @@ func CreateKnativeBroker(ns string, name string) func() error { Kamelets */ -func CreateKamelet(ns string, name string, template map[string]interface{}, properties map[string]v1.JSONSchemaProp, labels map[string]string) func() error { +func CreateKamelet(t *testing.T, operatorID string, ctx context.Context, ns string, name string, template map[string]interface{}, properties map[string]v1.JSONSchemaProp, labels map[string]string) func() error { return func() error { kamelet := v1.Kamelet{ ObjectMeta: metav1.ObjectMeta{ @@ -2607,14 +2698,16 @@ func CreateKamelet(ns string, name string, template map[string]interface{}, prop Definition: &v1.JSONSchemaProps{ Properties: properties, }, - Template: asTemplate(template), + Template: asTemplate(t, template), }, } - return TestClient().Create(TestContext, &kamelet) + + kamelet.SetOperatorID(operatorID) + return TestClient(t).Create(ctx, &kamelet) } } -func CreateTimerKamelet(ns string, name string) func() error { +func CreateTimerKamelet(t *testing.T, ctx context.Context, operatorID string, ns string, name string) func() error { props := map[string]v1.JSONSchemaProp{ "message": { Type: "string", @@ -2637,23 +2730,23 @@ func CreateTimerKamelet(ns string, name string) func() error { }, } - return CreateKamelet(ns, name, flow, props, nil) + return CreateKamelet(t, operatorID, ctx, ns, name, flow, props, nil) } -func DeleteKamelet(ns string, name string) error { +func DeleteKamelet(t *testing.T, ctx context.Context, ns string, name string) error { kamelet := v1.Kamelet{ ObjectMeta: metav1.ObjectMeta{ Namespace: ns, Name: name, }, } - return TestClient().Delete(TestContext, &kamelet) + return TestClient(t).Delete(ctx, &kamelet) } -func asTemplate(source map[string]interface{}) *v1.Template { +func asTemplate(t *testing.T, source map[string]interface{}) *v1.Template { bytes, err := json.Marshal(source) if err != nil { - failTest(err) + failTest(t, err) } return &v1.Template{ RawMessage: bytes, @@ -2661,10 +2754,10 @@ func asTemplate(source map[string]interface{}) *v1.Template { } // nolint: staticcheck -func AsTraitConfiguration(props map[string]string) *traitv1.Configuration { +func AsTraitConfiguration(t *testing.T, props map[string]string) *traitv1.Configuration { bytes, err := json.Marshal(props) if err != nil { - failTest(err) + failTest(t, err) } return &traitv1.Configuration{ RawMessage: bytes, @@ -2675,7 +2768,7 @@ func AsTraitConfiguration(props map[string]string) *traitv1.Configuration { Namespace testing functions */ -func Pods(ns string) func() []corev1.Pod { +func Pods(t *testing.T, ctx context.Context, ns string) func() []corev1.Pod { return func() []corev1.Pod { lst := corev1.PodList{ TypeMeta: metav1.TypeMeta{ @@ -2683,7 +2776,7 @@ func Pods(ns string) func() []corev1.Pod { APIVersion: v1.SchemeGroupVersion.String(), }, } - if err := TestClient().List(TestContext, &lst, ctrl.InNamespace(ns)); err != nil { + if err := TestClient(t).List(ctx, &lst, ctrl.InNamespace(ns)); err != nil { if !k8serrors.IsUnauthorized(err) { log.Error(err, "Error while listing the pods") } @@ -2693,36 +2786,33 @@ func Pods(ns string) func() []corev1.Pod { } } -func WithNewTestNamespace(t *testing.T, doRun func(string)) { - setTestLocus(t) - ns := NewTestNamespace(false) - defer deleteTestNamespace(t, ns) +func WithNewTestNamespace(t *testing.T, doRun func(context.Context, *gomega.WithT, string)) { + ns := NewTestNamespace(t, testContext, false) + defer deleteTestNamespace(t, testContext, ns) defer userCleanup(t) - invokeUserTestCode(t, ns.GetName(), doRun) + invokeUserTestCode(t, testContext, ns.GetName(), doRun) } -func WithGlobalOperatorNamespace(t *testing.T, test func(string)) { - setTestLocus(t) - ocp, err := openshift.IsOpenShift(TestClient()) - assert.Nil(t, err) +func WithGlobalOperatorNamespace(t *testing.T, test func(context.Context, *gomega.WithT, string)) { + ocp, err := openshift.IsOpenShift(TestClient(t)) + require.NoError(t, err) if ocp { // global operators are always installed in the openshift-operators namespace - invokeUserTestCode(t, "openshift-operators", test) + invokeUserTestCode(t, testContext, "openshift-operators", test) } else { // create new namespace for the global operator WithNewTestNamespace(t, test) } } -func WithNewTestNamespaceWithKnativeBroker(t *testing.T, doRun func(string)) { - setTestLocus(t) - ns := NewTestNamespace(true) - defer deleteTestNamespace(t, ns) - defer deleteKnativeBroker(ns) +func WithNewTestNamespaceWithKnativeBroker(t *testing.T, doRun func(context.Context, *gomega.WithT, string)) { + ns := NewTestNamespace(t, testContext, true) + defer deleteTestNamespace(t, testContext, ns) + defer deleteKnativeBroker(t, testContext, ns) defer userCleanup(t) - invokeUserTestCode(t, ns.GetName(), doRun) + invokeUserTestCode(t, testContext, ns.GetName(), doRun) } func userCleanup(t *testing.T) { @@ -2741,17 +2831,17 @@ func userCleanup(t *testing.T) { } } -func invokeUserTestCode(t *testing.T, ns string, doRun func(string)) { +func invokeUserTestCode(t *testing.T, ctx context.Context, ns string, doRun func(context.Context, *gomega.WithT, string)) { defer func() { - DumpNamespace(t, ns) + DumpNamespace(t, ctx, ns) osns := os.Getenv("CAMEL_K_GLOBAL_OPERATOR_NS") // Try to clean up namespace - if ns != osns && HasPlatform(ns)() { + if ns != osns && HasPlatform(t, ctx, ns)() { t.Logf("Clean up test namespace: %s", ns) - if err := Kamel("uninstall", "-n", ns, "--skip-crd", "--skip-cluster-roles").Execute(); err != nil { + if err := Kamel(t, ctx, "uninstall", "-n", ns, "--skip-crd", "--skip-cluster-roles").Execute(); err != nil { t.Logf("Error while cleaning up namespace %s: %v\n", ns, err) } @@ -2759,11 +2849,11 @@ func invokeUserTestCode(t *testing.T, ns string, doRun func(string)) { } }() - gomega.RegisterTestingT(t) - doRun(ns) + g := gomega.NewWithT(t) + doRun(ctx, g, ns) } -func deleteKnativeBroker(ns metav1.Object) { +func deleteKnativeBroker(t *testing.T, ctx context.Context, ns metav1.Object) { nsRef := corev1.Namespace{ TypeMeta: metav1.TypeMeta{ APIVersion: v1.SchemeGroupVersion.String(), @@ -2774,13 +2864,13 @@ func deleteKnativeBroker(ns metav1.Object) { }, } nsKey := ctrl.ObjectKeyFromObject(&nsRef) - if err := TestClient().Get(TestContext, nsKey, &nsRef); err != nil { - failTest(err) + if err := TestClient(t).Get(ctx, nsKey, &nsRef); err != nil { + failTest(t, err) } nsRef.SetLabels(make(map[string]string, 0)) - if err := TestClient().Update(TestContext, &nsRef); err != nil { - failTest(err) + if err := TestClient(t).Update(ctx, &nsRef); err != nil { + failTest(t, err) } broker := eventing.Broker{ TypeMeta: metav1.TypeMeta{ @@ -2789,25 +2879,25 @@ func deleteKnativeBroker(ns metav1.Object) { }, ObjectMeta: metav1.ObjectMeta{ Namespace: ns.GetName(), - Name: "default", + Name: TestDefaultNamespace, }, } - if err := TestClient().Delete(TestContext, &broker); err != nil { - failTest(err) + if err := TestClient(t).Delete(ctx, &broker); err != nil { + failTest(t, err) } } -func deleteTestNamespace(t *testing.T, ns ctrl.Object) { +func deleteTestNamespace(t *testing.T, ctx context.Context, ns ctrl.Object) { value, saveNS := os.LookupEnv("CAMEL_K_TEST_SAVE_FAILED_TEST_NAMESPACE") - if t.Failed() && saveNS && value == "true" { + if t != nil && t.Failed() && saveNS && value == "true" { t.Logf("Warning: retaining failed test project %q", ns.GetName()) return } var oc bool var err error - if oc, err = openshift.IsOpenShift(TestClient()); err != nil { - failTest(err) + if oc, err = openshift.IsOpenShift(TestClient(t)); err != nil { + failTest(t, err) } else if oc { prj := &projectv1.Project{ TypeMeta: metav1.TypeMeta{ @@ -2818,20 +2908,20 @@ func deleteTestNamespace(t *testing.T, ns ctrl.Object) { Name: ns.GetName(), }, } - if err := TestClient().Delete(TestContext, prj); err != nil { + if err := TestClient(t).Delete(ctx, prj); err != nil { t.Logf("Warning: cannot delete test project %q", prj.Name) } } else { - if err := TestClient().Delete(TestContext, ns); err != nil { + if err := TestClient(t).Delete(ctx, ns); err != nil { t.Logf("Warning: cannot delete test namespace %q", ns.GetName()) } } // Wait for all pods to be deleted - pods := Pods(ns.GetName())() + pods := Pods(t, ctx, ns.GetName())() for i := 0; len(pods) > 0 && i < 60; i++ { time.Sleep(1 * time.Second) - pods = Pods(ns.GetName())() + pods = Pods(t, ctx, ns.GetName())() } if len(pods) > 0 { names := []string{} @@ -2843,8 +2933,8 @@ func deleteTestNamespace(t *testing.T, ns ctrl.Object) { } } -func testNamespaceExists(ns string) (bool, error) { - _, err := TestClient().CoreV1().Namespaces().Get(TestContext, ns, metav1.GetOptions{}) +func testNamespaceExists(t *testing.T, ctx context.Context, ns string) (bool, error) { + _, err := TestClient(t).CoreV1().Namespaces().Get(ctx, ns, metav1.GetOptions{}) if err != nil { if k8serrors.IsNotFound(err) { return false, nil @@ -2856,52 +2946,57 @@ func testNamespaceExists(ns string) (bool, error) { return true, nil } -func DumpNamespace(t *testing.T, ns string) { +func DumpNamespace(t *testing.T, ctx context.Context, ns string) { if t.Failed() { - if err := util.Dump(TestContext, TestClient(), ns, t); err != nil { + if err := util.Dump(ctx, TestClient(t), ns, t); err != nil { t.Logf("Error while dumping namespace %s: %v\n", ns, err) } } } -func DeleteNamespace(t *testing.T, ns string) error { - nsObj, err := TestClient().CoreV1().Namespaces().Get(TestContext, ns, metav1.GetOptions{}) +func DeleteNamespace(t *testing.T, ctx context.Context, ns string) error { + nsObj, err := TestClient(t).CoreV1().Namespaces().Get(ctx, ns, metav1.GetOptions{}) if err != nil { return err } - deleteTestNamespace(t, nsObj) + deleteTestNamespace(t, ctx, nsObj) return nil } -func NewTestNamespace(injectKnativeBroker bool) ctrl.Object { - brokerLabel := "eventing.knative.dev/injection" +func NewTestNamespace(t *testing.T, ctx context.Context, injectKnativeBroker bool) ctrl.Object { name := os.Getenv("CAMEL_K_TEST_NS") if name == "" { name = "test-" + uuid.New().String() } - c := TestClient() - if exists, err := testNamespaceExists(name); err != nil { - failTest(err) + if exists, err := testNamespaceExists(t, ctx, name); err != nil { + failTest(t, err) } else if exists { fmt.Println("Warning: namespace ", name, " already exists so using different namespace name") name = fmt.Sprintf("%s-%d", name, time.Now().Second()) } - if oc, err := openshift.IsOpenShift(TestClient()); err != nil { - failTest(err) + return NewNamedTestNamespace(t, ctx, name, injectKnativeBroker) +} + +func NewNamedTestNamespace(t *testing.T, ctx context.Context, name string, injectKnativeBroker bool) ctrl.Object { + brokerLabel := "eventing.knative.dev/injection" + c := TestClient(t) + + if oc, err := openshift.IsOpenShift(TestClient(t)); err != nil { + failTest(t, err) } else if oc { httpCli, err := rest.HTTPClientFor(c.GetConfig()) if err != nil { - failTest(err) + failTest(t, err) } rest, err := apiutil.RESTClientForGVK( schema.GroupVersionKind{Group: projectv1.GroupName, Version: projectv1.GroupVersion.Version}, false, c.GetConfig(), serializer.NewCodecFactory(c.GetScheme()), httpCli) if err != nil { - failTest(err) + failTest(t, err) } request := &projectv1.ProjectRequest{ TypeMeta: metav1.TypeMeta{ @@ -2921,23 +3016,23 @@ func NewTestNamespace(injectKnativeBroker bool) ctrl.Object { err = rest.Post(). Resource("projectrequests"). Body(request). - Do(TestContext). + Do(ctx). Into(project) if err != nil { - failTest(err) + failTest(t, err) } // workaround https://github.com/openshift/origin/issues/3819 if injectKnativeBroker { // use Kubernetes API - https://access.redhat.com/solutions/2677921 - if namespace, err := TestClient().CoreV1().Namespaces().Get(TestContext, name, metav1.GetOptions{}); err != nil { - failTest(err) + if namespace, err := TestClient(t).CoreV1().Namespaces().Get(ctx, name, metav1.GetOptions{}); err != nil { + failTest(t, err) } else { if _, ok := namespace.GetLabels()[brokerLabel]; !ok { namespace.SetLabels(map[string]string{ brokerLabel: "enabled", }) - if err = TestClient().Update(TestContext, namespace); err != nil { - failTest(errors.New("Unable to label project with knative-eventing-injection. This operation needs update permission on the project.")) + if err = TestClient(t).Update(ctx, namespace); err != nil { + failTest(t, errors.New("Unable to label project with knative-eventing-injection. This operation needs update permission on the project.")) } } } @@ -2958,8 +3053,8 @@ func NewTestNamespace(injectKnativeBroker bool) ctrl.Object { brokerLabel: "enabled", }) } - if err := TestClient().Create(TestContext, namespace); err != nil { - failTest(err) + if err := TestClient(t).Create(ctx, namespace); err != nil { + failTest(t, err) } return namespace } @@ -2988,7 +3083,7 @@ func GetOutputStringAsync(cmd *cobra.Command) func() string { } } -func CreateLogKamelet(ns string, name string) func() error { +func CreateLogKamelet(t *testing.T, ctx context.Context, operatorID string, ns string, name string) func() error { flow := map[string]interface{}{ "from": map[string]interface{}{ "uri": "kamelet:source", @@ -3006,7 +3101,7 @@ func CreateLogKamelet(ns string, name string) func() error { }, } - return CreateKamelet(ns, name, flow, props, nil) + return CreateKamelet(t, operatorID, ctx, ns, name, flow, props, nil) } func GetCIProcessID() string { diff --git a/e2e/support/test_util.go b/e2e/support/test_util.go index 61fbc3f2f6..d110c34f81 100644 --- a/e2e/support/test_util.go +++ b/e2e/support/test_util.go @@ -23,6 +23,8 @@ limitations under the License. package support import ( + "context" + "github.com/apache/camel-k/v2/pkg/util/log" "os" "os/exec" "strings" @@ -33,6 +35,7 @@ import ( . "github.com/onsi/gomega/gstruct" "github.com/onsi/gomega/types" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func init() { @@ -56,7 +59,7 @@ func GetEnvOrDefault(key string, deflt string) string { } } -func ExpectExecSucceed(t *testing.T, command *exec.Cmd) { +func ExpectExecSucceed(t *testing.T, g *WithT, command *exec.Cmd) { t.Helper() var cmdOut strings.Builder @@ -69,15 +72,16 @@ func ExpectExecSucceed(t *testing.T, command *exec.Cmd) { } }() + RegisterTestingT(t) session, err := gexec.Start(command, &cmdOut, &cmdErr) session.Wait() - Eventually(session).Should(gexec.Exit(0)) - assert.NoError(t, err) + g.Eventually(session).Should(gexec.Exit(0)) + require.NoError(t, err) assert.NotContains(t, strings.ToUpper(cmdErr.String()), "ERROR") } -// Expect a command error with an exit code of 1 -func ExpectExecError(t *testing.T, command *exec.Cmd) { +// ExpectExecError Expect a command error with an exit code of 1 +func ExpectExecError(t *testing.T, g *WithT, command *exec.Cmd) { t.Helper() var cmdOut strings.Builder @@ -92,21 +96,30 @@ func ExpectExecError(t *testing.T, command *exec.Cmd) { session, err := gexec.Start(command, &cmdOut, &cmdErr) session.Wait() - Eventually(session).ShouldNot(gexec.Exit(0)) - assert.NoError(t, err) + g.Eventually(session).ShouldNot(gexec.Exit(0)) + require.NoError(t, err) assert.Contains(t, strings.ToUpper(cmdErr.String()), "ERROR") } -// Clean up the cluster ready for the next set of tests -func Cleanup() { +// Cleanup Clean up the cluster ready for the next set of tests +func Cleanup(t *testing.T, ctx context.Context) { // Remove the locally installed operator - UninstallAll() + if err := UninstallAll(t, ctx); err != nil { + log.Error(err, "Failed to uninstall Camel K") + } // Ensure the CRDs & ClusterRoles are reinstalled if not already - Kamel("install", "--olm=false", "--cluster-setup").Execute() + if err := Kamel(t, ctx, "install", "--olm=false", "--cluster-setup").Execute(); err != nil { + log.Error(err, "Failed to perform Camel K cluster setup") + } +} + +// UninstallAll Removes all items +func UninstallAll(t *testing.T, ctx context.Context) error { + return Kamel(t, ctx, "uninstall", "--olm=false", "--all").Execute() } -// Removes all items -func UninstallAll() { - Kamel("uninstall", "--olm=false", "--all").Execute() +// UninstallFromNamespace Removes operator from given namespace +func UninstallFromNamespace(t *testing.T, ctx context.Context, ns string) error { + return Kamel(t, ctx, "uninstall", "--olm=false", "-n", ns).Execute() } diff --git a/e2e/support/util/dump.go b/e2e/support/util/dump.go index c170cf6aad..a5741e697f 100644 --- a/e2e/support/util/dump.go +++ b/e2e/support/util/dump.go @@ -258,7 +258,7 @@ func Dump(ctx context.Context, c client.Client, ns string, t *testing.T) error { // OLM CSV csvs := olm.ClusterServiceVersionList{} err = c.List(ctx, &csvs, ctrl.InNamespace(ns)) - if err != nil { + if err != nil && !kubernetes.IsUnknownAPIError(err) { return err } t.Logf("\nFound %d OLM CSVs:\n", len(csvs.Items)) diff --git a/e2e/support/util/structured_log_test.go b/e2e/support/util/structured_log_test.go index 067cb7774c..66f0481d88 100644 --- a/e2e/support/util/structured_log_test.go +++ b/e2e/support/util/structured_log_test.go @@ -22,13 +22,14 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestJSONFormat(t *testing.T) { logLine := `{"level":"info","ts":"2023-08-30T08:07:19Z","logger":"camel-k.cmd","msg":"maxprocs: Leaving GOMAXPROCS=[2]: CPU quota undefined"}` entry := LogEntry{} err := json.Unmarshal([]byte(logLine), &entry) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "2023-08-30 08:07:19 +0000 UTC", entry.Timestamp.String()) assert.Equal(t, "maxprocs: Leaving GOMAXPROCS=[2]: CPU quota undefined", entry.Message) } diff --git a/e2e/telemetry/telemetry_test.go b/e2e/telemetry/telemetry_test.go index b327300923..ec3d494c26 100644 --- a/e2e/telemetry/telemetry_test.go +++ b/e2e/telemetry/telemetry_test.go @@ -23,6 +23,7 @@ limitations under the License. package telemetry import ( + "context" "fmt" "testing" @@ -35,49 +36,43 @@ import ( ) func TestTelemetryTrait(t *testing.T) { - WithNewTestNamespace(t, func(ns string) { + WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { operatorID := "camel-k-trait-telemetry" - Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed()) + g.Expect(KamelInstallWithID(t, ctx, operatorID, ns)).To(Succeed()) // Check service is available - Eventually(ServicesByType("otlp", corev1.ServiceTypeClusterIP), TestTimeoutLong).ShouldNot(BeEmpty()) + g.Eventually(ServicesByType(t, ctx, "otlp", corev1.ServiceTypeClusterIP), TestTimeoutLong).ShouldNot(BeEmpty()) // Create integration and activate traces by telemetry trait - Expect(KamelRunWithID(operatorID, ns, "files/rest-consumer.yaml", - "--name", "rest-consumer", - "-t", "telemetry.enabled=true", - "-t", "telemetry.endpoint=http://opentelemetrycollector.otlp.svc.cluster.local:4317").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "rest-consumer"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/rest-consumer.yaml", "--name", "rest-consumer", "-t", "telemetry.enabled=true", "-t", "telemetry.endpoint=http://opentelemetrycollector.otlp.svc.cluster.local:4317").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "rest-consumer"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) name := "Bob" - Expect(KamelRunWithID(operatorID, ns, "files/rest-producer.yaml", - "-p", "serviceName=rest-consumer", - "-p", "name="+name, - "--name", "rest-producer").Execute()).To(Succeed()) - Eventually(IntegrationPodPhase(ns, "rest-producer"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - Eventually(IntegrationLogs(ns, "rest-consumer"), TestTimeoutLong).Should(ContainSubstring(fmt.Sprintf("get %s", name))) - Eventually(IntegrationLogs(ns, "rest-producer"), TestTimeoutLong).Should(ContainSubstring(fmt.Sprintf("%s Doe", name))) - - // Find opentelemetrycollector pod : the exporter is configured to log traces with detailed verborsity. - pod, err := Pod("otlp", "opentelemetrycollector")() - Expect(err).To(BeNil()) - Expect(pod).NotTo(BeNil()) - - // Ensured logs in opentelemetrycollector pod are present - Eventually(TailedLogs(pod.Namespace, pod.Name, 100), TestTimeoutLong).Should(ContainSubstring(fmt.Sprintf("http.target: Str(/customers/%s)", name))) - Eventually(TailedLogs(pod.Namespace, pod.Name, 100), TestTimeoutLong).Should(ContainSubstring(fmt.Sprintf("http.url: Str(http://rest-consumer/customers/%s)", name))) + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "files/rest-producer.yaml", "-p", "serviceName=rest-consumer", "-p", "name="+name, "--name", "rest-producer").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, "rest-producer"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationLogs(t, ctx, ns, "rest-consumer"), TestTimeoutLong).Should(ContainSubstring(fmt.Sprintf("get %s", name))) + g.Eventually(IntegrationLogs(t, ctx, ns, "rest-producer"), TestTimeoutLong).Should(ContainSubstring(fmt.Sprintf("%s Doe", name))) + + // Find opentelemetry collector pod : the exporter is configured to log traces with detailed verbosity. + pod, err := Pod(t, ctx, "otlp", "opentelemetrycollector")() + g.Expect(err).To(BeNil()) + g.Expect(pod).NotTo(BeNil()) + + // Ensured logs in opentelemetry collector pod are present + g.Eventually(TailedLogs(t, ctx, pod.Namespace, pod.Name, 100), TestTimeoutLong).Should(ContainSubstring(fmt.Sprintf("http.target: Str(/customers/%s)", name))) + g.Eventually(TailedLogs(t, ctx, pod.Namespace, pod.Name, 100), TestTimeoutLong).Should(ContainSubstring(fmt.Sprintf("http.url: Str(http://rest-consumer/customers/%s)", name))) // check integration schema does not contains unwanted default trait value. - Eventually(UnstructuredIntegration(ns, "rest-consumer")).ShouldNot(BeNil()) - unstructuredIntegration := UnstructuredIntegration(ns, "rest-consumer")() + g.Eventually(UnstructuredIntegration(t, ctx, ns, "rest-consumer")).ShouldNot(BeNil()) + unstructuredIntegration := UnstructuredIntegration(t, ctx, ns, "rest-consumer")() builderTrait, _, _ := unstructured.NestedMap(unstructuredIntegration.Object, "spec", "traits", "addons", "telemetry") - Expect(builderTrait).NotTo(BeNil()) - Expect(len(builderTrait)).To(Equal(2)) - Expect(builderTrait["enabled"]).To(Equal(true)) - Expect(builderTrait["endpoint"]).To(Equal("http://opentelemetrycollector.otlp.svc.cluster.local:4317")) + g.Expect(builderTrait).NotTo(BeNil()) + g.Expect(len(builderTrait)).To(Equal(2)) + g.Expect(builderTrait["enabled"]).To(Equal(true)) + g.Expect(builderTrait["endpoint"]).To(Equal("http://opentelemetrycollector.otlp.svc.cluster.local:4317")) // Clean up - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) }) } diff --git a/go.mod b/go.mod index 828bfcbd92..099bcc01c8 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/apache/camel-k/v2 -go 1.20 +go 1.21 require ( github.com/Masterminds/semver v1.5.0 @@ -16,14 +16,14 @@ require ( github.com/magiconair/properties v1.8.7 github.com/mattn/go-shellwords v1.0.12 github.com/mitchellh/mapstructure v1.5.0 - github.com/onsi/gomega v1.31.1 + github.com/onsi/gomega v1.32.0 // go get github.com/openshift/api@release-4.12 github.com/openshift/api v0.0.0-20230817133225-564be9ddb58e github.com/operator-framework/api v0.20.0 github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.67.1 github.com/prometheus/client_golang v1.19.0 github.com/prometheus/client_model v0.6.0 - github.com/prometheus/common v0.48.0 + github.com/prometheus/common v0.51.1 github.com/redhat-developer/service-binding-operator v1.4.0 github.com/rs/xid v1.5.0 github.com/sirupsen/logrus v1.9.3 @@ -31,13 +31,13 @@ require ( github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.18.2 github.com/stoewer/go-strcase v1.3.0 - github.com/stretchr/testify v1.8.4 + github.com/stretchr/testify v1.9.0 go.uber.org/automaxprocs v1.5.3 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.0 - golang.org/x/oauth2 v0.17.0 + golang.org/x/oauth2 v0.18.0 golang.org/x/sync v0.6.0 - golang.org/x/term v0.17.0 + golang.org/x/term v0.18.0 golang.org/x/text v0.14.0 golang.org/x/time v0.5.0 gopkg.in/yaml.v2 v2.4.0 @@ -68,13 +68,13 @@ require ( github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/cloudevents/sdk-go/sql/v2 v2.13.0 // indirect - github.com/cloudevents/sdk-go/v2 v2.13.0 // indirect + github.com/cloudevents/sdk-go/v2 v2.15.2 // indirect github.com/cloudflare/circl v1.3.7 // indirect github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/docker/cli v24.0.7+incompatible // indirect github.com/docker/distribution v2.8.2+incompatible // indirect - github.com/docker/docker v24.0.7+incompatible // indirect + github.com/docker/docker v24.0.9+incompatible // indirect github.com/docker/docker-credential-helpers v0.7.0 // indirect github.com/emicklei/go-restful/v3 v3.10.2 // indirect github.com/evanphx/json-patch/v5 v5.7.0 // indirect @@ -125,11 +125,11 @@ require ( github.com/subosito/gotenv v1.6.0 // indirect github.com/vbatts/tar-split v0.11.3 // indirect go.opencensus.io v0.24.0 // indirect - golang.org/x/crypto v0.19.0 // indirect + golang.org/x/crypto v0.21.0 // indirect golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect golang.org/x/mod v0.14.0 // indirect - golang.org/x/net v0.21.0 // indirect - golang.org/x/sys v0.17.0 // indirect + golang.org/x/net v0.22.0 // indirect + golang.org/x/sys v0.18.0 // indirect golang.org/x/tools v0.16.1 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect google.golang.org/api v0.153.0 // indirect @@ -138,7 +138,7 @@ require ( google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f // indirect google.golang.org/grpc v1.59.0 // indirect - google.golang.org/protobuf v1.32.0 // indirect + google.golang.org/protobuf v1.33.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 1326fb743b..cddc1e07e3 100644 --- a/go.sum +++ b/go.sum @@ -53,6 +53,7 @@ github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kd github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 h1:yL7+Jz0jTC6yykIK/Wh74gnTJnrGr5AyrNMXuA0gves= github.com/antlr/antlr4/runtime/Go/antlr v1.4.10/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= @@ -78,8 +79,8 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudevents/sdk-go/sql/v2 v2.13.0 h1:gMJvQ3XFkygY9JmrusgK80d9yRAb8+J3X8IA1OC+oc0= github.com/cloudevents/sdk-go/sql/v2 v2.13.0/go.mod h1:XZRQBCgRreddIpQrdjBJQUrRg3BCs3aikplJQkHrK44= -github.com/cloudevents/sdk-go/v2 v2.13.0 h1:2zxDS8RyY1/wVPULGGbdgniGXSzLaRJVl136fLXGsYw= -github.com/cloudevents/sdk-go/v2 v2.13.0/go.mod h1:xDmKfzNjM8gBvjaF8ijFjM1VYOVUEeUfapHMUX1T5To= +github.com/cloudevents/sdk-go/v2 v2.15.2 h1:54+I5xQEnI73RBhWHxbI1XJcqOFOVJN85vb41+8mHUc= +github.com/cloudevents/sdk-go/v2 v2.15.2/go.mod h1:lL7kSWAE/V8VI4Wh0jbL2v/jvqsm6tjmaQBSvxcv4uE= github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I= github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= @@ -101,8 +102,8 @@ github.com/docker/cli v24.0.7+incompatible h1:wa/nIwYFW7BVTGa7SWPVyyXU9lgORqUb1x github.com/docker/cli v24.0.7+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v24.0.7+incompatible h1:Wo6l37AuwP3JaMnZa226lzVXGA3F9Ig1seQen0cKYlM= -github.com/docker/docker v24.0.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v24.0.9+incompatible h1:HPGzNmwfLZWdxHqK9/II92pyi1EpYKsAqcl4G0Of9v0= +github.com/docker/docker v24.0.9+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A= github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= @@ -120,6 +121,7 @@ github.com/evanphx/json-patch/v5 v5.7.0 h1:nJqP7uwL84RJInrohHfW0Fx3awjbm8qZeFv0n github.com/evanphx/json-patch/v5 v5.7.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= @@ -154,11 +156,13 @@ github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/ github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= +github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -172,6 +176,7 @@ github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -229,6 +234,7 @@ github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= @@ -278,6 +284,7 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -311,14 +318,17 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.15.0 h1:79HwNRBAZHOEwrczrgSOPy+eFTTlIGELKy5as+ClttY= +github.com/onsi/ginkgo/v2 v2.15.0/go.mod h1:HlxMHtYF57y6Dpf+mc5529KKmSq9h2FpCF+/ZkwUxKM= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.31.1 h1:KYppCUK+bUgAZwHOu7EXVBKyQA6ILvOESHkn/tgoqvo= -github.com/onsi/gomega v1.31.1/go.mod h1:y40C95dwAD1Nz36SsEnxvfFe8FFfNxzI5eJ0EYGyAy0= +github.com/onsi/gomega v1.32.0 h1:JRYU78fJ1LPxlckP6Txi/EYqJvjtMrDC04/MM5XRHPk= +github.com/onsi/gomega v1.32.0/go.mod h1:a4x4gW6Pz2yK1MAmvluYme5lvYTn61afQ2ETw/8n4Lg= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.0-rc3 h1:fzg1mXZFj8YdPeNkRXMg+zb88BFV0Ys52cJydRwBkb8= @@ -337,6 +347,7 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g= +github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.67.1 h1:u1Mw9irznvsBPxQxjUmCel1ufP3UgzA1CILj7/2tpNw= github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.67.1/go.mod h1:KZHvrby65G+rA4V/vMTUXDV22TI+GgLIrCigYClpjzk= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= @@ -360,8 +371,8 @@ github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9 github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.35.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= -github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE= -github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= +github.com/prometheus/common v0.51.1 h1:eIjN50Bwglz6a/c3hAgSMcofL3nD+nFQkV6Dd4DsQCw= +github.com/prometheus/common v0.51.1/go.mod h1:lrWtQx+iDfn2mbH5GUzlH9TSHyfZpHkSiG1W7y3sF2Q= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= @@ -383,6 +394,7 @@ github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzG github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -426,13 +438,15 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stvp/go-udp-testing v0.0.0-20201019212854-469649b16807/go.mod h1:7jxmlfBCDBXRzr0eAQJ48XC1hBu1np4CS5+cHEYfwpc= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/urfave/cli v1.22.12/go.mod h1:sSBEIC79qR6OvcmsD4U3KABeOTxDqQtdDnaFuUN30b8= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/vbatts/tar-split v0.11.3 h1:hLFqsOLQ1SsppQNTMpkpPXClLDfC2A3Zgy9OUU+RVck= github.com/vbatts/tar-split v0.11.3/go.mod h1:9QlHN18E+fEH7RdG+QAJJcuya3rqT7eXSTY7wGrAokY= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= @@ -458,6 +472,7 @@ go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8= go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -473,8 +488,8 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -549,8 +564,8 @@ golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= +golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -558,8 +573,8 @@ golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.17.0 h1:6m3ZPmLEFdVxKKWnKq4VqZ60gutO35zm+zrAHVmHyDQ= -golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA= +golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI= +golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -623,12 +638,12 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220906165534-d0df966e6959/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U= -golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= +golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -795,8 +810,8 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= -google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -827,6 +842,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= +gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/helm/camel-k/crds/crd-build.yaml b/helm/camel-k/crds/crd-build.yaml index ae2925cd2d..31635f79dd 100644 --- a/helm/camel-k/crds/crd-build.yaml +++ b/helm/camel-k/crds/crd-build.yaml @@ -117,6 +117,12 @@ spec: - fifo - sequential type: string + platforms: + description: The list of platforms used in order to build a container + image. + items: + type: string + type: array requestCPU: description: The minimum amount of CPU required. Only used for `pod` strategy @@ -196,6 +202,12 @@ spec: - fifo - sequential type: string + platforms: + description: The list of platforms used in order to + build a container image. + items: + type: string + type: array requestCPU: description: The minimum amount of CPU required. Only used for `pod` strategy @@ -300,6 +312,12 @@ spec: - fifo - sequential type: string + platforms: + description: The list of platforms used in order to + build a container image. + items: + type: string + type: array requestCPU: description: The minimum amount of CPU required. Only used for `pod` strategy @@ -638,10 +656,27 @@ spec: capabilities: additionalProperties: description: Capability is a particular feature which - requires a well known set of dependencies which - are specified in the runtime catalog. + requires a well known set of dependencies and other + properties which are specified in the runtime catalog. properties: + buildTimeProperties: + description: Set of required Camel build time + properties + items: + description: CamelProperty represents a Camel + property that may end up in an application.properties + file. + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array dependencies: + description: List of required Maven dependencies items: description: MavenArtifact defines a GAV (Group:Artifact:Type:Version:Classifier) Maven artifact. @@ -666,8 +701,26 @@ spec: - groupId type: object type: array - required: - - dependencies + metadata: + additionalProperties: + type: string + description: Set of generic metadata + type: object + runtimeProperties: + description: Set of required Camel runtime properties + items: + description: CamelProperty represents a Camel + property that may end up in an application.properties + file. + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array type: object description: features offered by this runtime type: object @@ -835,6 +888,12 @@ spec: - fifo - sequential type: string + platforms: + description: The list of platforms used in order to + build a container image. + items: + type: string + type: array requestCPU: description: The minimum amount of CPU required. Only used for `pod` strategy @@ -910,6 +969,12 @@ spec: - fifo - sequential type: string + platforms: + description: The list of platforms used in order to + build a container image. + items: + type: string + type: array requestCPU: description: The minimum amount of CPU required. Only used for `pod` strategy @@ -1013,6 +1078,12 @@ spec: - fifo - sequential type: string + platforms: + description: The list of platforms used in order to + build a container image. + items: + type: string + type: array requestCPU: description: The minimum amount of CPU required. Only used for `pod` strategy @@ -1115,6 +1186,12 @@ spec: - fifo - sequential type: string + platforms: + description: The list of platforms used in order to + build a container image. + items: + type: string + type: array requestCPU: description: The minimum amount of CPU required. Only used for `pod` strategy @@ -1453,10 +1530,27 @@ spec: capabilities: additionalProperties: description: Capability is a particular feature which - requires a well known set of dependencies which - are specified in the runtime catalog. + requires a well known set of dependencies and other + properties which are specified in the runtime catalog. properties: + buildTimeProperties: + description: Set of required Camel build time + properties + items: + description: CamelProperty represents a Camel + property that may end up in an application.properties + file. + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array dependencies: + description: List of required Maven dependencies items: description: MavenArtifact defines a GAV (Group:Artifact:Type:Version:Classifier) Maven artifact. @@ -1481,8 +1575,26 @@ spec: - groupId type: object type: array - required: - - dependencies + metadata: + additionalProperties: + type: string + description: Set of generic metadata + type: object + runtimeProperties: + description: Set of required Camel runtime properties + items: + description: CamelProperty represents a Camel + property that may end up in an application.properties + file. + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array type: object description: features offered by this runtime type: object @@ -1641,6 +1753,12 @@ spec: - fifo - sequential type: string + platforms: + description: The list of platforms used in order to + build a container image. + items: + type: string + type: array requestCPU: description: The minimum amount of CPU required. Only used for `pod` strategy @@ -1712,6 +1830,12 @@ spec: - fifo - sequential type: string + platforms: + description: The list of platforms used in order to + build a container image. + items: + type: string + type: array requestCPU: description: The minimum amount of CPU required. Only used for `pod` strategy diff --git a/helm/camel-k/crds/crd-camel-catalog.yaml b/helm/camel-k/crds/crd-camel-catalog.yaml index 4f75f02b6a..e76c6bb594 100644 --- a/helm/camel-k/crds/crd-camel-catalog.yaml +++ b/helm/camel-k/crds/crd-camel-catalog.yaml @@ -372,10 +372,25 @@ spec: capabilities: additionalProperties: description: Capability is a particular feature which requires - a well known set of dependencies which are specified in the - runtime catalog. + a well known set of dependencies and other properties which + are specified in the runtime catalog. properties: + buildTimeProperties: + description: Set of required Camel build time properties + items: + description: CamelProperty represents a Camel property + that may end up in an application.properties file. + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array dependencies: + description: List of required Maven dependencies items: description: MavenArtifact defines a GAV (Group:Artifact:Type:Version:Classifier) Maven artifact. @@ -400,8 +415,25 @@ spec: - groupId type: object type: array - required: - - dependencies + metadata: + additionalProperties: + type: string + description: Set of generic metadata + type: object + runtimeProperties: + description: Set of required Camel runtime properties + items: + description: CamelProperty represents a Camel property + that may end up in an application.properties file. + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array type: object description: features offered by this runtime type: object diff --git a/helm/camel-k/crds/crd-integration-kit.yaml b/helm/camel-k/crds/crd-integration-kit.yaml index 8a16efffcb..1d5bfb5378 100644 --- a/helm/camel-k/crds/crd-integration-kit.yaml +++ b/helm/camel-k/crds/crd-integration-kit.yaml @@ -88,6 +88,11 @@ spec: spec: description: the desired configuration properties: + capabilities: + description: features offered by the IntegrationKit + items: + type: string + type: array configuration: description: 'Deprecated: Use camel trait (camel.properties) to manage properties Use mount trait (mount.configs) to manage configs Use @@ -258,6 +263,12 @@ spec: - fifo - sequential type: string + platforms: + description: The list of manifest platforms to use to build + a container image (default `linux/amd64`). + items: + type: string + type: array properties: description: A list of properties to be provided to the build task @@ -402,8 +413,9 @@ spec: type: array type: object registry: - description: The Registry trait sets up Maven to use the Image - registry as a Maven repository. + description: 'The Registry trait sets up Maven to use the Image + registry as a Maven repository. Deprecated: use jvm trait or + read documentation.' properties: configuration: description: 'Legacy trait configuration parameters. Deprecated: @@ -539,236 +551,6 @@ spec: runtimeVersion: description: the runtime version for which this kit was configured type: string - traits: - description: generated traits executed by the kit - properties: - addons: - additionalProperties: - description: AddonTrait represents the configuration of an addon - trait. - type: object - x-kubernetes-preserve-unknown-fields: true - description: The collection of addon trait configurations - type: object - builder: - description: The builder trait is internally used to determine - the best strategy to build and configure IntegrationKits. - properties: - annotations: - additionalProperties: - type: string - description: When using `pod` strategy, annotation to use - for the builder pod. - type: object - baseImage: - description: Specify a base image - type: string - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: 'Deprecated: no longer in use.' - type: boolean - incrementalImageBuild: - description: Use the incremental image build option, to reuse - existing containers (default `true`) - type: boolean - limitCPU: - description: 'When using `pod` strategy, the maximum amount - of CPU required by the pod builder. Deprecated: use TasksRequestCPU - instead with task name `builder`.' - type: string - limitMemory: - description: 'When using `pod` strategy, the maximum amount - of memory required by the pod builder. Deprecated: use TasksRequestCPU - instead with task name `builder`.' - type: string - mavenProfiles: - description: 'A list of references pointing to configmaps/secrets - that contains a maven profile. The content of the maven - profile is expected to be a text containing a valid maven - profile starting with `` and ending with `` - that will be integrated as an inline profile in the POM. - Syntax: [configmap|secret]:name[/key], where name represents - the resource name, key optionally represents the resource - key to be filtered (default key value = profile.xml).' - items: - type: string - type: array - nodeSelector: - additionalProperties: - type: string - description: Defines a set of nodes the builder pod is eligible - to be scheduled on, based on labels on the node. - type: object - orderStrategy: - description: The build order strategy to use, either `dependencies`, - `fifo` or `sequential` (default `sequential`) - enum: - - dependencies - - fifo - - sequential - type: string - properties: - description: A list of properties to be provided to the build - task - items: - type: string - type: array - requestCPU: - description: 'When using `pod` strategy, the minimum amount - of CPU required by the pod builder. Deprecated: use TasksRequestCPU - instead with task name `builder`.' - type: string - requestMemory: - description: 'When using `pod` strategy, the minimum amount - of memory required by the pod builder. Deprecated: use TasksRequestCPU - instead with task name `builder`.' - type: string - strategy: - description: The strategy to use, either `pod` or `routine` - (default `routine`) - enum: - - pod - - routine - type: string - tasks: - description: A list of tasks to be executed (available only - when using `pod` strategy) with format `;;`. - items: - type: string - type: array - tasksFilter: - description: A list of tasks sorted by the order of execution - in a csv format, ie, `,,...`. Mind - that you must include also the operator tasks (`builder`, - `quarkus-native`, `package`, `jib`, `spectrum`, `s2i`) if - you need to execute them. Useful only with `pod` strategy. - type: string - tasksLimitCPU: - description: A list of limit cpu configuration for the specific - task with format `:`. - items: - type: string - type: array - tasksLimitMemory: - description: A list of limit memory configuration for the - specific task with format `:`. - items: - type: string - type: array - tasksRequestCPU: - description: A list of request cpu configuration for the specific - task with format `:`. - items: - type: string - type: array - tasksRequestMemory: - description: A list of request memory configuration for the - specific task with format `:`. - items: - type: string - type: array - verbose: - description: Enable verbose logging on build components that - support it (e.g. Kaniko build pod). Deprecated no longer - in use - type: boolean - type: object - camel: - description: The Camel trait sets up Camel configuration. - properties: - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: 'Deprecated: no longer in use.' - type: boolean - properties: - description: A list of properties to be provided to the Integration - runtime - items: - type: string - type: array - runtimeVersion: - description: The camel-k-runtime version to use for the integration. - It overrides the default version set in the Integration - Platform. - type: string - type: object - quarkus: - description: 'The Quarkus trait configures the Quarkus runtime. - It''s enabled by default. NOTE: Compiling to a native executable, - requires at least 4GiB of memory, so the Pod running the native - build must have enough memory available.' - properties: - buildMode: - description: 'The Quarkus mode to run: either `jvm` or `native` - (default `jvm`). In case both `jvm` and `native` are specified, - two `IntegrationKit` resources are created, with the `native` - kit having precedence over the `jvm` one once ready.' - items: - description: QuarkusMode is the type of Quarkus build packaging. - enum: - - jvm - - native - type: string - type: array - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: 'Deprecated: no longer in use.' - type: boolean - nativeBaseImage: - description: The base image to use when running a native build - (default `quay.io/quarkus/quarkus-micro-image:2.0`) - type: string - nativeBuilderImage: - description: The image containing the tooling required for - a native build (by default it will use the one provided - in the runtime catalog) - type: string - packageTypes: - description: 'The Quarkus package types, `fast-jar` or `native` - (default `fast-jar`). In case both `fast-jar` and `native` - are specified, two `IntegrationKit` resources are created, - with the native kit having precedence over the `fast-jar` - one once ready. The order influences the resolution of the - current kit for the integration. The kit corresponding to - the first package type will be assigned to the integration - in case no existing kit that matches the integration exists. - Deprecated: use `build-mode` instead.' - items: - description: 'QuarkusPackageType is the type of Quarkus - build packaging. Deprecated: use `QuarkusMode` instead.' - enum: - - fast-jar - - native - type: string - type: array - type: object - registry: - description: The Registry trait sets up Maven to use the Image - registry as a Maven repository. - properties: - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: Can be used to enable or disable a trait. All - traits share this common property. - type: boolean - type: object - type: object version: description: the Camel K operator version for which this kit was configured type: string diff --git a/helm/camel-k/crds/crd-integration-platform.yaml b/helm/camel-k/crds/crd-integration-platform.yaml index a76be34402..2ab9010acf 100644 --- a/helm/camel-k/crds/crd-integration-platform.yaml +++ b/helm/camel-k/crds/crd-integration-platform.yaml @@ -136,6 +136,12 @@ spec: - fifo - sequential type: string + platforms: + description: The list of platforms used in order to build + a container image. + items: + type: string + type: array requestCPU: description: The minimum amount of CPU required. Only used for `pod` strategy @@ -573,6 +579,12 @@ spec: - fifo - sequential type: string + platforms: + description: The list of manifest platforms to use to build + a container image (default `linux/amd64`). + items: + type: string + type: array properties: description: A list of properties to be provided to the build task @@ -852,20 +864,26 @@ spec: format: int32 type: integer rollingUpdateMaxSurge: + anyOf: + - type: integer + - type: string description: 'The maximum number of pods that can be scheduled above the desired number of pods. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). This can not be 0 if MaxUnavailable is 0. Absolute number is calculated from percentage by rounding up. Defaults to `25%`.' - type: integer + x-kubernetes-int-or-string: true rollingUpdateMaxUnavailable: + anyOf: + - type: integer + - type: string description: 'The maximum number of pods that can be unavailable during the update. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). Absolute number is calculated from percentage by rounding down. This can not be 0 if MaxSurge is 0. Defaults to `25%`.' - type: integer + x-kubernetes-int-or-string: true strategy: description: The deployment strategy to use to replace existing pods with new ones. @@ -1483,7 +1501,8 @@ spec: description: Enable "hot reload" when a secret/configmap mounted is edited (default `false`). The configmap/secret must be marked with `camel.apache.org/integration` label to be taken - in account. + in account. The resource will be watched for any kind change, + also for changes in metadata. type: boolean resources: description: 'A list of resources (text or binary content) @@ -1497,6 +1516,14 @@ spec: items: type: string type: array + scanKameletsImplicitLabelSecrets: + description: 'Deprecated: include your properties in an explicit + property file backed by a secret. Let the operator to scan + for secret labeled with `camel.apache.org/kamelet` and `camel.apache.org/kamelet.configuration`. + These secrets are mounted to the application and treated + as plain properties file with their key/value list (ie .spec.data["camel.my-property"] + = my-value) (default `true`).' + type: boolean volumes: description: 'A list of Persistent Volume Claims to be mounted. Syntax: [pvcname:/container/path]' @@ -1717,7 +1744,8 @@ spec: type: array type: object registry: - description: The configuration of Registry trait + description: 'The configuration of Registry trait Deprecated: + use jvm trait or read documentation.' properties: configuration: description: 'Legacy trait configuration parameters. Deprecated: @@ -1969,6 +1997,12 @@ spec: - fifo - sequential type: string + platforms: + description: The list of platforms used in order to build + a container image. + items: + type: string + type: array requestCPU: description: The minimum amount of CPU required. Only used for `pod` strategy @@ -2454,6 +2488,12 @@ spec: - fifo - sequential type: string + platforms: + description: The list of manifest platforms to use to build + a container image (default `linux/amd64`). + items: + type: string + type: array properties: description: A list of properties to be provided to the build task @@ -2733,20 +2773,26 @@ spec: format: int32 type: integer rollingUpdateMaxSurge: + anyOf: + - type: integer + - type: string description: 'The maximum number of pods that can be scheduled above the desired number of pods. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). This can not be 0 if MaxUnavailable is 0. Absolute number is calculated from percentage by rounding up. Defaults to `25%`.' - type: integer + x-kubernetes-int-or-string: true rollingUpdateMaxUnavailable: + anyOf: + - type: integer + - type: string description: 'The maximum number of pods that can be unavailable during the update. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). Absolute number is calculated from percentage by rounding down. This can not be 0 if MaxSurge is 0. Defaults to `25%`.' - type: integer + x-kubernetes-int-or-string: true strategy: description: The deployment strategy to use to replace existing pods with new ones. @@ -3364,7 +3410,8 @@ spec: description: Enable "hot reload" when a secret/configmap mounted is edited (default `false`). The configmap/secret must be marked with `camel.apache.org/integration` label to be taken - in account. + in account. The resource will be watched for any kind change, + also for changes in metadata. type: boolean resources: description: 'A list of resources (text or binary content) @@ -3378,6 +3425,14 @@ spec: items: type: string type: array + scanKameletsImplicitLabelSecrets: + description: 'Deprecated: include your properties in an explicit + property file backed by a secret. Let the operator to scan + for secret labeled with `camel.apache.org/kamelet` and `camel.apache.org/kamelet.configuration`. + These secrets are mounted to the application and treated + as plain properties file with their key/value list (ie .spec.data["camel.my-property"] + = my-value) (default `true`).' + type: boolean volumes: description: 'A list of Persistent Volume Claims to be mounted. Syntax: [pvcname:/container/path]' @@ -3598,7 +3653,8 @@ spec: type: array type: object registry: - description: The configuration of Registry trait + description: 'The configuration of Registry trait Deprecated: + use jvm trait or read documentation.' properties: configuration: description: 'Legacy trait configuration parameters. Deprecated: diff --git a/helm/camel-k/crds/crd-integration-profile.yaml b/helm/camel-k/crds/crd-integration-profile.yaml index 3e997b3cea..21e0c93340 100644 --- a/helm/camel-k/crds/crd-integration-profile.yaml +++ b/helm/camel-k/crds/crd-integration-profile.yaml @@ -455,6 +455,12 @@ spec: - fifo - sequential type: string + platforms: + description: The list of manifest platforms to use to build + a container image (default `linux/amd64`). + items: + type: string + type: array properties: description: A list of properties to be provided to the build task @@ -734,20 +740,26 @@ spec: format: int32 type: integer rollingUpdateMaxSurge: + anyOf: + - type: integer + - type: string description: 'The maximum number of pods that can be scheduled above the desired number of pods. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). This can not be 0 if MaxUnavailable is 0. Absolute number is calculated from percentage by rounding up. Defaults to `25%`.' - type: integer + x-kubernetes-int-or-string: true rollingUpdateMaxUnavailable: + anyOf: + - type: integer + - type: string description: 'The maximum number of pods that can be unavailable during the update. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). Absolute number is calculated from percentage by rounding down. This can not be 0 if MaxSurge is 0. Defaults to `25%`.' - type: integer + x-kubernetes-int-or-string: true strategy: description: The deployment strategy to use to replace existing pods with new ones. @@ -1358,7 +1370,8 @@ spec: description: Enable "hot reload" when a secret/configmap mounted is edited (default `false`). The configmap/secret must be marked with `camel.apache.org/integration` label to be taken - in account. + in account. The resource will be watched for any kind change, + also for changes in metadata. type: boolean resources: description: 'A list of resources (text or binary content) @@ -1372,6 +1385,14 @@ spec: items: type: string type: array + scanKameletsImplicitLabelSecrets: + description: 'Deprecated: include your properties in an explicit + property file backed by a secret. Let the operator to scan + for secret labeled with `camel.apache.org/kamelet` and `camel.apache.org/kamelet.configuration`. + These secrets are mounted to the application and treated + as plain properties file with their key/value list (ie .spec.data["camel.my-property"] + = my-value) (default `true`).' + type: boolean volumes: description: 'A list of Persistent Volume Claims to be mounted. Syntax: [pvcname:/container/path]' @@ -1592,7 +1613,8 @@ spec: type: array type: object registry: - description: The configuration of Registry trait + description: 'The configuration of Registry trait Deprecated: + use jvm trait or read documentation.' properties: configuration: description: 'Legacy trait configuration parameters. Deprecated: @@ -2218,6 +2240,12 @@ spec: - fifo - sequential type: string + platforms: + description: The list of manifest platforms to use to build + a container image (default `linux/amd64`). + items: + type: string + type: array properties: description: A list of properties to be provided to the build task @@ -2497,20 +2525,26 @@ spec: format: int32 type: integer rollingUpdateMaxSurge: + anyOf: + - type: integer + - type: string description: 'The maximum number of pods that can be scheduled above the desired number of pods. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). This can not be 0 if MaxUnavailable is 0. Absolute number is calculated from percentage by rounding up. Defaults to `25%`.' - type: integer + x-kubernetes-int-or-string: true rollingUpdateMaxUnavailable: + anyOf: + - type: integer + - type: string description: 'The maximum number of pods that can be unavailable during the update. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). Absolute number is calculated from percentage by rounding down. This can not be 0 if MaxSurge is 0. Defaults to `25%`.' - type: integer + x-kubernetes-int-or-string: true strategy: description: The deployment strategy to use to replace existing pods with new ones. @@ -3121,7 +3155,8 @@ spec: description: Enable "hot reload" when a secret/configmap mounted is edited (default `false`). The configmap/secret must be marked with `camel.apache.org/integration` label to be taken - in account. + in account. The resource will be watched for any kind change, + also for changes in metadata. type: boolean resources: description: 'A list of resources (text or binary content) @@ -3135,6 +3170,14 @@ spec: items: type: string type: array + scanKameletsImplicitLabelSecrets: + description: 'Deprecated: include your properties in an explicit + property file backed by a secret. Let the operator to scan + for secret labeled with `camel.apache.org/kamelet` and `camel.apache.org/kamelet.configuration`. + These secrets are mounted to the application and treated + as plain properties file with their key/value list (ie .spec.data["camel.my-property"] + = my-value) (default `true`).' + type: boolean volumes: description: 'A list of Persistent Volume Claims to be mounted. Syntax: [pvcname:/container/path]' @@ -3355,7 +3398,8 @@ spec: type: array type: object registry: - description: The configuration of Registry trait + description: 'The configuration of Registry trait Deprecated: + use jvm trait or read documentation.' properties: configuration: description: 'Legacy trait configuration parameters. Deprecated: diff --git a/helm/camel-k/crds/crd-integration.yaml b/helm/camel-k/crds/crd-integration.yaml index 3c343c6bbb..db212a24e7 100644 --- a/helm/camel-k/crds/crd-integration.yaml +++ b/helm/camel-k/crds/crd-integration.yaml @@ -6474,6 +6474,12 @@ spec: - fifo - sequential type: string + platforms: + description: The list of manifest platforms to use to build + a container image (default `linux/amd64`). + items: + type: string + type: array properties: description: A list of properties to be provided to the build task @@ -6753,20 +6759,26 @@ spec: format: int32 type: integer rollingUpdateMaxSurge: + anyOf: + - type: integer + - type: string description: 'The maximum number of pods that can be scheduled above the desired number of pods. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). This can not be 0 if MaxUnavailable is 0. Absolute number is calculated from percentage by rounding up. Defaults to `25%`.' - type: integer + x-kubernetes-int-or-string: true rollingUpdateMaxUnavailable: + anyOf: + - type: integer + - type: string description: 'The maximum number of pods that can be unavailable during the update. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). Absolute number is calculated from percentage by rounding down. This can not be 0 if MaxSurge is 0. Defaults to `25%`.' - type: integer + x-kubernetes-int-or-string: true strategy: description: The deployment strategy to use to replace existing pods with new ones. @@ -7384,7 +7396,8 @@ spec: description: Enable "hot reload" when a secret/configmap mounted is edited (default `false`). The configmap/secret must be marked with `camel.apache.org/integration` label to be taken - in account. + in account. The resource will be watched for any kind change, + also for changes in metadata. type: boolean resources: description: 'A list of resources (text or binary content) @@ -7398,6 +7411,14 @@ spec: items: type: string type: array + scanKameletsImplicitLabelSecrets: + description: 'Deprecated: include your properties in an explicit + property file backed by a secret. Let the operator to scan + for secret labeled with `camel.apache.org/kamelet` and `camel.apache.org/kamelet.configuration`. + These secrets are mounted to the application and treated + as plain properties file with their key/value list (ie .spec.data["camel.my-property"] + = my-value) (default `true`).' + type: boolean volumes: description: 'A list of Persistent Volume Claims to be mounted. Syntax: [pvcname:/container/path]' @@ -7618,7 +7639,8 @@ spec: type: array type: object registry: - description: The configuration of Registry trait + description: 'The configuration of Registry trait Deprecated: + use jvm trait or read documentation.' properties: configuration: description: 'Legacy trait configuration parameters. Deprecated: @@ -8079,1462 +8101,6 @@ spec: selector: description: label selector type: string - traits: - description: the traits generated and executed for this Integration - properties: - 3scale: - description: 'Deprecated: for backward compatibility.' - properties: - configuration: - description: TraitConfiguration parameters configuration - type: object - x-kubernetes-preserve-unknown-fields: true - required: - - configuration - type: object - addons: - additionalProperties: - description: AddonTrait represents the configuration of an addon - trait. - type: object - x-kubernetes-preserve-unknown-fields: true - description: The extension point with addon traits - type: object - affinity: - description: The configuration of Affinity trait - properties: - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: Can be used to enable or disable a trait. All - traits share this common property. - type: boolean - nodeAffinityLabels: - description: Defines a set of nodes the integration pod(s) - are eligible to be scheduled on, based on labels on the - node. - items: - type: string - type: array - podAffinity: - description: Always co-locates multiple replicas of the integration - in the same node (default `false`). - type: boolean - podAffinityLabels: - description: Defines a set of pods (namely those matching - the label selector, relative to the given namespace) that - the integration pod(s) should be co-located with. - items: - type: string - type: array - podAntiAffinity: - description: Never co-locates multiple replicas of the integration - in the same node (default `false`). - type: boolean - podAntiAffinityLabels: - description: Defines a set of pods (namely those matching - the label selector, relative to the given namespace) that - the integration pod(s) should not be co-located with. - items: - type: string - type: array - type: object - builder: - description: The configuration of Builder trait - properties: - annotations: - additionalProperties: - type: string - description: When using `pod` strategy, annotation to use - for the builder pod. - type: object - baseImage: - description: Specify a base image - type: string - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: 'Deprecated: no longer in use.' - type: boolean - incrementalImageBuild: - description: Use the incremental image build option, to reuse - existing containers (default `true`) - type: boolean - limitCPU: - description: 'When using `pod` strategy, the maximum amount - of CPU required by the pod builder. Deprecated: use TasksRequestCPU - instead with task name `builder`.' - type: string - limitMemory: - description: 'When using `pod` strategy, the maximum amount - of memory required by the pod builder. Deprecated: use TasksRequestCPU - instead with task name `builder`.' - type: string - mavenProfiles: - description: 'A list of references pointing to configmaps/secrets - that contains a maven profile. The content of the maven - profile is expected to be a text containing a valid maven - profile starting with `` and ending with `` - that will be integrated as an inline profile in the POM. - Syntax: [configmap|secret]:name[/key], where name represents - the resource name, key optionally represents the resource - key to be filtered (default key value = profile.xml).' - items: - type: string - type: array - nodeSelector: - additionalProperties: - type: string - description: Defines a set of nodes the builder pod is eligible - to be scheduled on, based on labels on the node. - type: object - orderStrategy: - description: The build order strategy to use, either `dependencies`, - `fifo` or `sequential` (default `sequential`) - enum: - - dependencies - - fifo - - sequential - type: string - properties: - description: A list of properties to be provided to the build - task - items: - type: string - type: array - requestCPU: - description: 'When using `pod` strategy, the minimum amount - of CPU required by the pod builder. Deprecated: use TasksRequestCPU - instead with task name `builder`.' - type: string - requestMemory: - description: 'When using `pod` strategy, the minimum amount - of memory required by the pod builder. Deprecated: use TasksRequestCPU - instead with task name `builder`.' - type: string - strategy: - description: The strategy to use, either `pod` or `routine` - (default `routine`) - enum: - - pod - - routine - type: string - tasks: - description: A list of tasks to be executed (available only - when using `pod` strategy) with format `;;`. - items: - type: string - type: array - tasksFilter: - description: A list of tasks sorted by the order of execution - in a csv format, ie, `,,...`. Mind - that you must include also the operator tasks (`builder`, - `quarkus-native`, `package`, `jib`, `spectrum`, `s2i`) if - you need to execute them. Useful only with `pod` strategy. - type: string - tasksLimitCPU: - description: A list of limit cpu configuration for the specific - task with format `:`. - items: - type: string - type: array - tasksLimitMemory: - description: A list of limit memory configuration for the - specific task with format `:`. - items: - type: string - type: array - tasksRequestCPU: - description: A list of request cpu configuration for the specific - task with format `:`. - items: - type: string - type: array - tasksRequestMemory: - description: A list of request memory configuration for the - specific task with format `:`. - items: - type: string - type: array - verbose: - description: Enable verbose logging on build components that - support it (e.g. Kaniko build pod). Deprecated no longer - in use - type: boolean - type: object - camel: - description: The configuration of Camel trait - properties: - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: 'Deprecated: no longer in use.' - type: boolean - properties: - description: A list of properties to be provided to the Integration - runtime - items: - type: string - type: array - runtimeVersion: - description: The camel-k-runtime version to use for the integration. - It overrides the default version set in the Integration - Platform. - type: string - type: object - container: - description: The configuration of Container trait - properties: - auto: - description: To automatically enable the trait - type: boolean - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: 'Deprecated: no longer in use.' - type: boolean - expose: - description: Can be used to enable/disable exposure via kubernetes - Service. - type: boolean - image: - description: The main container image - type: string - imagePullPolicy: - description: 'The pull policy: Always|Never|IfNotPresent' - enum: - - Always - - Never - - IfNotPresent - type: string - limitCPU: - description: The maximum amount of CPU required. - type: string - limitMemory: - description: The maximum amount of memory required. - type: string - name: - description: The main container name. It's named `integration` - by default. - type: string - port: - description: To configure a different port exposed by the - container (default `8080`). - type: integer - portName: - description: To configure a different port name for the port - exposed by the container. It defaults to `http` only when - the `expose` parameter is true. - type: string - requestCPU: - description: The minimum amount of CPU required. - type: string - requestMemory: - description: The minimum amount of memory required. - type: string - servicePort: - description: To configure under which service port the container - port is to be exposed (default `80`). - type: integer - servicePortName: - description: To configure under which service port name the - container port is to be exposed (default `http`). - type: string - type: object - cron: - description: The configuration of Cron trait - properties: - activeDeadlineSeconds: - description: Specifies the duration in seconds, relative to - the start time, that the job may be continuously active - before it is considered to be failed. It defaults to 60s. - format: int64 - type: integer - auto: - description: "Automatically deploy the integration as CronJob - when all routes are either starting from a periodic consumer - (only `cron`, `timer` and `quartz` are supported) or a passive - consumer (e.g. `direct` is a passive consumer). \n It's - required that all periodic consumers have the same period, - and it can be expressed as cron schedule (e.g. `1m` can - be expressed as `0/1 * * * *`, while `35m` or `50s` cannot)." - type: boolean - backoffLimit: - description: Specifies the number of retries before marking - the job failed. It defaults to 2. - format: int32 - type: integer - components: - description: "A comma separated list of the Camel components - that need to be customized in order for them to work when - the schedule is triggered externally by Kubernetes. A specific - customizer is activated for each specified component. E.g. - for the `timer` component, the `cron-timer` customizer is - activated (it's present in the `org.apache.camel.k:camel-k-cron` - library). \n Supported components are currently: `cron`, - `timer` and `quartz`." - type: string - concurrencyPolicy: - description: 'Specifies how to treat concurrent executions - of a Job. Valid values are: - "Allow": allows CronJobs to - run concurrently; - "Forbid" (default): forbids concurrent - runs, skipping next run if previous run hasn''t finished - yet; - "Replace": cancels currently running job and replaces - it with a new one' - enum: - - Allow - - Forbid - - Replace - type: string - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: Can be used to enable or disable a trait. All - traits share this common property. - type: boolean - fallback: - description: Use the default Camel implementation of the `cron` - endpoint (`quartz`) instead of trying to materialize the - integration as Kubernetes CronJob. - type: boolean - schedule: - description: The CronJob schedule for the whole integration. - If multiple routes are declared, they must have the same - schedule for this mechanism to work correctly. - type: string - startingDeadlineSeconds: - description: Optional deadline in seconds for starting the - job if it misses scheduled time for any reason. Missed - jobs executions will be counted as failed ones. - format: int64 - type: integer - type: object - dependencies: - description: The configuration of Dependencies trait - properties: - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: 'Deprecated: no longer in use.' - type: boolean - type: object - deployer: - description: The configuration of Deployer trait - properties: - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: 'Deprecated: no longer in use.' - type: boolean - kind: - description: Allows to explicitly select the desired deployment - kind between `deployment`, `cron-job` or `knative-service` - when creating the resources for running the integration. - enum: - - deployment - - cron-job - - knative-service - type: string - useSSA: - description: Use server-side apply to update the owned resources - (default `true`). Note that it automatically falls back - to client-side patching, if SSA is not available, e.g., - on old Kubernetes clusters. - type: boolean - type: object - deployment: - description: The configuration of Deployment trait - properties: - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: 'Deprecated: no longer in use.' - type: boolean - progressDeadlineSeconds: - description: The maximum time in seconds for the deployment - to make progress before it is considered to be failed. It - defaults to `60s`. - format: int32 - type: integer - rollingUpdateMaxSurge: - description: 'The maximum number of pods that can be scheduled - above the desired number of pods. Value can be an absolute - number (ex: 5) or a percentage of desired pods (ex: 10%). - This can not be 0 if MaxUnavailable is 0. Absolute number - is calculated from percentage by rounding up. Defaults to - `25%`.' - type: integer - rollingUpdateMaxUnavailable: - description: 'The maximum number of pods that can be unavailable - during the update. Value can be an absolute number (ex: - 5) or a percentage of desired pods (ex: 10%). Absolute number - is calculated from percentage by rounding down. This can - not be 0 if MaxSurge is 0. Defaults to `25%`.' - type: integer - strategy: - description: The deployment strategy to use to replace existing - pods with new ones. - enum: - - Recreate - - RollingUpdate - type: string - type: object - environment: - description: The configuration of Environment trait - properties: - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - containerMeta: - description: Enables injection of `NAMESPACE` and `POD_NAME` - environment variables (default `true`) - type: boolean - enabled: - description: 'Deprecated: no longer in use.' - type: boolean - httpProxy: - description: Propagates the `HTTP_PROXY`, `HTTPS_PROXY` and - `NO_PROXY` environment variables (default `true`) - type: boolean - vars: - description: A list of environment variables to be added to - the integration container. The syntax is KEY=VALUE, e.g., - `MY_VAR="my value"`. These take precedence over the previously - defined environment variables. - items: - type: string - type: array - type: object - error-handler: - description: The configuration of Error Handler trait - properties: - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: 'Deprecated: no longer in use.' - type: boolean - ref: - description: The error handler ref name provided or found - in application properties - type: string - type: object - gc: - description: The configuration of GC trait - properties: - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - discoveryCache: - description: 'Discovery client cache to be used, either `disabled`, - `disk` or `memory` (default `memory`). Deprecated: to be - removed from trait configuration.' - enum: - - disabled - - disk - - memory - type: string - enabled: - description: Can be used to enable or disable a trait. All - traits share this common property. - type: boolean - type: object - health: - description: The configuration of Health trait - properties: - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: Can be used to enable or disable a trait. All - traits share this common property. - type: boolean - livenessFailureThreshold: - description: Minimum consecutive failures for the liveness - probe to be considered failed after having succeeded. - format: int32 - type: integer - livenessInitialDelay: - description: Number of seconds after the container has started - before the liveness probe is initiated. - format: int32 - type: integer - livenessPeriod: - description: How often to perform the liveness probe. - format: int32 - type: integer - livenessProbeEnabled: - description: Configures the liveness probe for the integration - container (default `false`). - type: boolean - livenessScheme: - description: Scheme to use when connecting to the liveness - probe (default `HTTP`). - type: string - livenessSuccessThreshold: - description: Minimum consecutive successes for the liveness - probe to be considered successful after having failed. - format: int32 - type: integer - livenessTimeout: - description: Number of seconds after which the liveness probe - times out. - format: int32 - type: integer - readinessFailureThreshold: - description: Minimum consecutive failures for the readiness - probe to be considered failed after having succeeded. - format: int32 - type: integer - readinessInitialDelay: - description: Number of seconds after the container has started - before the readiness probe is initiated. - format: int32 - type: integer - readinessPeriod: - description: How often to perform the readiness probe. - format: int32 - type: integer - readinessProbeEnabled: - description: Configures the readiness probe for the integration - container (default `true`). - type: boolean - readinessScheme: - description: Scheme to use when connecting to the readiness - probe (default `HTTP`). - type: string - readinessSuccessThreshold: - description: Minimum consecutive successes for the readiness - probe to be considered successful after having failed. - format: int32 - type: integer - readinessTimeout: - description: Number of seconds after which the readiness probe - times out. - format: int32 - type: integer - startupFailureThreshold: - description: Minimum consecutive failures for the startup - probe to be considered failed after having succeeded. - format: int32 - type: integer - startupInitialDelay: - description: Number of seconds after the container has started - before the startup probe is initiated. - format: int32 - type: integer - startupPeriod: - description: How often to perform the startup probe. - format: int32 - type: integer - startupProbeEnabled: - description: Configures the startup probe for the integration - container (default `false`). - type: boolean - startupScheme: - description: Scheme to use when connecting to the startup - probe (default `HTTP`). - type: string - startupSuccessThreshold: - description: Minimum consecutive successes for the startup - probe to be considered successful after having failed. - format: int32 - type: integer - startupTimeout: - description: Number of seconds after which the startup probe - times out. - format: int32 - type: integer - type: object - ingress: - description: The configuration of Ingress trait - properties: - annotations: - additionalProperties: - type: string - description: 'The annotations added to the ingress. This can - be used to set controller specific annotations, e.g., when - using the NGINX Ingress controller: See https://github.com/kubernetes/ingress-nginx/blob/main/docs/user-guide/nginx-configuration/annotations.md' - type: object - auto: - description: To automatically add an ingress whenever the - integration uses an HTTP endpoint consumer. - type: boolean - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: Can be used to enable or disable a trait. All - traits share this common property. - type: boolean - host: - description: To configure the host exposed by the ingress. - type: string - path: - description: To configure the path exposed by the ingress - (default `/`). - type: string - pathType: - description: To configure the path type exposed by the ingress. - One of `Exact`, `Prefix`, `ImplementationSpecific` (default - to `Prefix`). - enum: - - Exact - - Prefix - - ImplementationSpecific - type: string - type: object - istio: - description: The configuration of Istio trait - properties: - allow: - description: Configures a (comma-separated) list of CIDR subnets - that should not be intercepted by the Istio proxy (`10.0.0.0/8,172.16.0.0/12,192.168.0.0/16` - by default). - type: string - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: Can be used to enable or disable a trait. All - traits share this common property. - type: boolean - inject: - description: Forces the value for labels `sidecar.istio.io/inject`. - By default the label is set to `true` on deployment and - not set on Knative Service. - type: boolean - type: object - jolokia: - description: The configuration of Jolokia trait - properties: - CACert: - description: The PEM encoded CA certification file path, used - to verify client certificates, applicable when `protocol` - is `https` and `use-ssl-client-authentication` is `true` - (default `/var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt` - for OpenShift). - type: string - clientPrincipal: - description: The principal(s) which must be given in a client - certificate to allow access to the Jolokia endpoint, applicable - when `protocol` is `https` and `use-ssl-client-authentication` - is `true` (default `clientPrincipal=cn=system:master-proxy`, - `cn=hawtio-online.hawtio.svc` and `cn=fuse-console.fuse.svc` - for OpenShift). - items: - type: string - type: array - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - discoveryEnabled: - description: Listen for multicast requests (default `false`) - type: boolean - enabled: - description: Can be used to enable or disable a trait. All - traits share this common property. - type: boolean - extendedClientCheck: - description: Mandate the client certificate contains a client - flag in the extended key usage section, applicable when - `protocol` is `https` and `use-ssl-client-authentication` - is `true` (default `true` for OpenShift). - type: boolean - host: - description: The Host address to which the Jolokia agent should - bind to. If `"\*"` or `"0.0.0.0"` is given, the servers - binds to every network interface (default `"*"`). - type: string - options: - description: A list of additional Jolokia options as defined - in https://jolokia.org/reference/html/agents.html#agent-jvm-config[JVM - agent configuration options] - items: - type: string - type: array - password: - description: The password used for authentication, applicable - when the `user` option is set. - type: string - port: - description: The Jolokia endpoint port (default `8778`). - type: integer - protocol: - description: The protocol to use, either `http` or `https` - (default `https` for OpenShift) - type: string - useSSLClientAuthentication: - description: Whether client certificates should be used for - authentication (default `true` for OpenShift). - type: boolean - user: - description: The user to be used for authentication - type: string - type: object - jvm: - description: The configuration of JVM trait - properties: - classpath: - description: Additional JVM classpath (use `Linux` classpath - separator) - type: string - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - debug: - description: Activates remote debugging, so that a debugger - can be attached to the JVM, e.g., using port-forwarding - type: boolean - debugAddress: - description: Transport address at which to listen for the - newly launched JVM (default `*:5005`) - type: string - debugSuspend: - description: Suspends the target JVM immediately before the - main class is loaded - type: boolean - enabled: - description: Can be used to enable or disable a trait. All - traits share this common property. - type: boolean - options: - description: A list of JVM options - items: - type: string - type: array - printCommand: - description: Prints the command used the start the JVM in - the container logs (default `true`) - type: boolean - type: object - kamelets: - description: The configuration of Kamelets trait - properties: - auto: - description: Automatically inject all referenced Kamelets - and their default configuration (enabled by default) - type: boolean - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: Can be used to enable or disable a trait. All - traits share this common property. - type: boolean - list: - description: Comma separated list of Kamelet names to load - into the current integration - type: string - mountPoint: - description: The directory where the application mounts and - reads Kamelet spec (default `/etc/camel/kamelets`) - type: string - type: object - keda: - description: 'Deprecated: for backward compatibility.' - properties: - configuration: - description: TraitConfiguration parameters configuration - type: object - x-kubernetes-preserve-unknown-fields: true - required: - - configuration - type: object - knative: - description: The configuration of Knative trait - properties: - auto: - description: Enable automatic discovery of all trait properties. - type: boolean - channelSinks: - description: List of channels used as destination of integration - routes. Can contain simple channel names or full Camel URIs. - items: - type: string - type: array - channelSources: - description: List of channels used as source of integration - routes. Can contain simple channel names or full Camel URIs. - items: - type: string - type: array - config: - description: Can be used to inject a Knative complete configuration - in JSON format. - type: string - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: Can be used to enable or disable a trait. All - traits share this common property. - type: boolean - endpointSinks: - description: List of endpoints used as destination of integration - routes. Can contain simple endpoint names or full Camel - URIs. - items: - type: string - type: array - endpointSources: - description: List of channels used as source of integration - routes. - items: - type: string - type: array - eventSinks: - description: List of event types that the integration will - produce. Can contain simple event types or full Camel URIs - (to use a specific broker). - items: - type: string - type: array - eventSources: - description: List of event types that the integration will - be subscribed to. Can contain simple event types or full - Camel URIs (to use a specific broker different from "default"). - items: - type: string - type: array - filterSourceChannels: - description: Enables filtering on events based on the header - "ce-knativehistory". Since this header has been removed - in newer versions of Knative, filtering is disabled by default. - type: boolean - namespaceLabel: - description: 'Enables the camel-k-operator to set the "bindings.knative.dev/include=true" - label to the namespace As Knative requires this label to - perform injection of K_SINK URL into the service. If this - is false, the integration pod may start and fail, read the - SinkBinding Knative documentation. (default: true)' - type: boolean - sinkBinding: - description: Allows binding the integration to a sink via - a Knative SinkBinding resource. This can be used when the - integration targets a single sink. It's enabled by default - when the integration targets a single sink (except when - the integration is owned by a Knative source). - type: boolean - type: object - knative-service: - description: The configuration of Knative Service trait - properties: - annotations: - additionalProperties: - type: string - description: 'The annotations added to route. This can be - used to set knative service specific annotations CLI usage - example: -t "knative-service.annotations.''haproxy.router.openshift.io/balance''=true"' - type: object - auto: - description: "Automatically deploy the integration as Knative - service when all conditions hold: \n * Integration is using - the Knative profile * All routes are either starting from - an HTTP based consumer or a passive consumer (e.g. `direct` - is a passive consumer)" - type: boolean - autoscalingMetric: - description: "Configures the Knative autoscaling metric property - (e.g. to set `concurrency` based or `cpu` based autoscaling). - \n Refer to the Knative documentation for more information." - type: string - autoscalingTarget: - description: "Sets the allowed concurrency level or CPU percentage - (depending on the autoscaling metric) for each Pod. \n Refer - to the Knative documentation for more information." - type: integer - class: - description: "Configures the Knative autoscaling class property - (e.g. to set `hpa.autoscaling.knative.dev` or `kpa.autoscaling.knative.dev` - autoscaling). \n Refer to the Knative documentation for - more information." - enum: - - kpa.autoscaling.knative.dev - - hpa.autoscaling.knative.dev - type: string - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: Can be used to enable or disable a trait. All - traits share this common property. - type: boolean - maxScale: - description: "An upper bound for the number of Pods that can - be running in parallel for the integration. Knative has - its own cap value that depends on the installation. \n Refer - to the Knative documentation for more information." - type: integer - minScale: - description: "The minimum number of Pods that should be running - at any time for the integration. It's **zero** by default, - meaning that the integration is scaled down to zero when - not used for a configured amount of time. \n Refer to the - Knative documentation for more information." - type: integer - rolloutDuration: - description: Enables to gradually shift traffic to the latest - Revision and sets the rollout duration. It's disabled by - default and must be expressed as a Golang `time.Duration` - string representation, rounded to a second precision. - type: string - visibility: - description: "Setting `cluster-local`, Knative service becomes - a private service. Specifically, this option applies the - `networking.knative.dev/visibility` label to Knative service. - \n Refer to the Knative documentation for more information." - enum: - - cluster-local - type: string - type: object - logging: - description: The configuration of Logging trait - properties: - color: - description: Colorize the log output - type: boolean - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: Can be used to enable or disable a trait. All - traits share this common property. - type: boolean - format: - description: Logs message format - type: string - json: - description: Output the logs in JSON - type: boolean - jsonPrettyPrint: - description: Enable "pretty printing" of the JSON logs - type: boolean - level: - description: Adjust the logging level (defaults to `INFO`) - enum: - - FATAL - - WARN - - INFO - - DEBUG - - TRACE - type: string - type: object - master: - description: 'Deprecated: for backward compatibility.' - properties: - configuration: - description: TraitConfiguration parameters configuration - type: object - x-kubernetes-preserve-unknown-fields: true - required: - - configuration - type: object - mount: - description: The configuration of Mount trait - properties: - configs: - description: 'A list of configuration pointing to configmap/secret. - The configuration are expected to be UTF-8 resources as - they are processed by runtime Camel Context and tried to - be parsed as property files. They are also made available - on the classpath in order to ease their usage directly from - the Route. Syntax: [configmap|secret]:name[/key], where - name represents the resource name and key optionally represents - the resource key to be filtered' - items: - type: string - type: array - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: 'Deprecated: no longer in use.' - type: boolean - hotReload: - description: Enable "hot reload" when a secret/configmap mounted - is edited (default `false`). The configmap/secret must be - marked with `camel.apache.org/integration` label to be taken - in account. - type: boolean - resources: - description: 'A list of resources (text or binary content) - pointing to configmap/secret. The resources are expected - to be any resource type (text or binary content). The destination - path can be either a default location or any path specified - by the user. Syntax: [configmap|secret]:name[/key][@path], - where name represents the resource name, key optionally - represents the resource key to be filtered and path represents - the destination path' - items: - type: string - type: array - volumes: - description: 'A list of Persistent Volume Claims to be mounted. - Syntax: [pvcname:/container/path]' - items: - type: string - type: array - type: object - openapi: - description: The configuration of OpenAPI trait - properties: - configmaps: - description: The configmaps holding the spec of the OpenAPI - items: - type: string - type: array - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: 'Deprecated: no longer in use.' - type: boolean - type: object - owner: - description: The configuration of Owner trait - properties: - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: Can be used to enable or disable a trait. All - traits share this common property. - type: boolean - targetAnnotations: - description: The set of annotations to be transferred - items: - type: string - type: array - targetLabels: - description: The set of labels to be transferred - items: - type: string - type: array - type: object - pdb: - description: The configuration of PDB trait - properties: - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: Can be used to enable or disable a trait. All - traits share this common property. - type: boolean - maxUnavailable: - description: The number of pods for the Integration that can - be unavailable after an eviction. It can be either an absolute - number or a percentage (default `1` if `min-available` is - also not set). Only one of `max-unavailable` and `min-available` - can be specified. - type: string - minAvailable: - description: The number of pods for the Integration that must - still be available after an eviction. It can be either an - absolute number or a percentage. Only one of `min-available` - and `max-unavailable` can be specified. - type: string - type: object - platform: - description: The configuration of Platform trait - properties: - auto: - description: 'To automatically detect from the environment - if a default platform can be created (it will be created - on OpenShift or when a registry address is set). Deprecated: - Platform is auto generated by the operator install procedure - - maintained for backward compatibility' - type: boolean - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - createDefault: - description: 'To create a default (empty) platform when the - platform is missing. Deprecated: Platform is auto generated - by the operator install procedure - maintained for backward - compatibility' - type: boolean - enabled: - description: 'Deprecated: no longer in use.' - type: boolean - global: - description: 'Indicates if the platform should be created - globally in the case of global operator (default true). - Deprecated: Platform is auto generated by the operator install - procedure - maintained for backward compatibility' - type: boolean - type: object - pod: - description: The configuration of Pod trait - properties: - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: Can be used to enable or disable a trait. All - traits share this common property. - type: boolean - type: object - prometheus: - description: The configuration of Prometheus trait - properties: - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: Can be used to enable or disable a trait. All - traits share this common property. - type: boolean - podMonitor: - description: Whether a `PodMonitor` resource is created (default - `true`). - type: boolean - podMonitorLabels: - description: The `PodMonitor` resource labels, applicable - when `pod-monitor` is `true`. - items: - type: string - type: array - type: object - pull-secret: - description: The configuration of Pull Secret trait - properties: - auto: - description: Automatically configures the platform registry - secret on the pod if it is of type `kubernetes.io/dockerconfigjson`. - type: boolean - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: Can be used to enable or disable a trait. All - traits share this common property. - type: boolean - imagePullerDelegation: - description: When using a global operator with a shared platform, - this enables delegation of the `system:image-puller` cluster - role on the operator namespace to the integration service - account. - type: boolean - secretName: - description: The pull secret name to set on the Pod. If left - empty this is automatically taken from the `IntegrationPlatform` - registry configuration. - type: string - type: object - quarkus: - description: The configuration of Quarkus trait - properties: - buildMode: - description: 'The Quarkus mode to run: either `jvm` or `native` - (default `jvm`). In case both `jvm` and `native` are specified, - two `IntegrationKit` resources are created, with the `native` - kit having precedence over the `jvm` one once ready.' - items: - description: QuarkusMode is the type of Quarkus build packaging. - enum: - - jvm - - native - type: string - type: array - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: 'Deprecated: no longer in use.' - type: boolean - nativeBaseImage: - description: The base image to use when running a native build - (default `quay.io/quarkus/quarkus-micro-image:2.0`) - type: string - nativeBuilderImage: - description: The image containing the tooling required for - a native build (by default it will use the one provided - in the runtime catalog) - type: string - packageTypes: - description: 'The Quarkus package types, `fast-jar` or `native` - (default `fast-jar`). In case both `fast-jar` and `native` - are specified, two `IntegrationKit` resources are created, - with the native kit having precedence over the `fast-jar` - one once ready. The order influences the resolution of the - current kit for the integration. The kit corresponding to - the first package type will be assigned to the integration - in case no existing kit that matches the integration exists. - Deprecated: use `build-mode` instead.' - items: - description: 'QuarkusPackageType is the type of Quarkus - build packaging. Deprecated: use `QuarkusMode` instead.' - enum: - - fast-jar - - native - type: string - type: array - type: object - registry: - description: The configuration of Registry trait - properties: - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: Can be used to enable or disable a trait. All - traits share this common property. - type: boolean - type: object - route: - description: The configuration of Route trait - properties: - annotations: - additionalProperties: - type: string - description: 'The annotations added to route. This can be - used to set route specific annotations For annotations options - see https://docs.openshift.com/container-platform/3.11/architecture/networking/routes.html#route-specific-annotations - CLI usage example: -t "route.annotations.''haproxy.router.openshift.io/balance''=true"' - type: object - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: Can be used to enable or disable a trait. All - traits share this common property. - type: boolean - host: - description: To configure the host exposed by the route. - type: string - tlsCACertificate: - description: "The TLS CA certificate contents. \n Refer to - the OpenShift route documentation for additional information." - type: string - tlsCACertificateSecret: - description: "The secret name and key reference to the TLS - CA certificate. The format is \"secret-name[/key-name]\", - the value represents the secret name, if there is only one - key in the secret it will be read, otherwise you can set - a key name separated with a \"/\". \n Refer to the OpenShift - route documentation for additional information." - type: string - tlsCertificate: - description: "The TLS certificate contents. \n Refer to the - OpenShift route documentation for additional information." - type: string - tlsCertificateSecret: - description: "The secret name and key reference to the TLS - certificate. The format is \"secret-name[/key-name]\", the - value represents the secret name, if there is only one key - in the secret it will be read, otherwise you can set a key - name separated with a \"/\". \n Refer to the OpenShift route - documentation for additional information." - type: string - tlsDestinationCACertificate: - description: "The destination CA certificate provides the - contents of the ca certificate of the final destination. - \ When using reencrypt termination this file should be provided - in order to have routers use it for health checks on the - secure connection. If this field is not specified, the router - may provide its own destination CA and perform hostname - validation using the short service name (service.namespace.svc), - which allows infrastructure generated certificates to automatically - verify. \n Refer to the OpenShift route documentation for - additional information." - type: string - tlsDestinationCACertificateSecret: - description: "The secret name and key reference to the destination - CA certificate. The format is \"secret-name[/key-name]\", - the value represents the secret name, if there is only one - key in the secret it will be read, otherwise you can set - a key name separated with a \"/\". \n Refer to the OpenShift - route documentation for additional information." - type: string - tlsInsecureEdgeTerminationPolicy: - description: "To configure how to deal with insecure traffic, - e.g. `Allow`, `Disable` or `Redirect` traffic. \n Refer - to the OpenShift route documentation for additional information." - enum: - - None - - Allow - - Redirect - type: string - tlsKey: - description: "The TLS certificate key contents. \n Refer to - the OpenShift route documentation for additional information." - type: string - tlsKeySecret: - description: "The secret name and key reference to the TLS - certificate key. The format is \"secret-name[/key-name]\", - the value represents the secret name, if there is only one - key in the secret it will be read, otherwise you can set - a key name separated with a \"/\". \n Refer to the OpenShift - route documentation for additional information." - type: string - tlsTermination: - description: "The TLS termination type, like `edge`, `passthrough` - or `reencrypt`. \n Refer to the OpenShift route documentation - for additional information." - enum: - - edge - - reencrypt - - passthrough - type: string - type: object - service: - description: The configuration of Service trait - properties: - auto: - description: To automatically detect from the code if a Service - needs to be created. - type: boolean - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: Can be used to enable or disable a trait. All - traits share this common property. - type: boolean - nodePort: - description: 'Enable Service to be exposed as NodePort (default - `false`). Deprecated: Use service type instead.' - type: boolean - type: - description: The type of service to be used, either 'ClusterIP', - 'NodePort' or 'LoadBalancer'. - enum: - - ClusterIP - - NodePort - - LoadBalancer - type: string - type: object - service-binding: - description: The configuration of Service Binding trait - properties: - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: Can be used to enable or disable a trait. All - traits share this common property. - type: boolean - services: - description: List of Services in the form [[apigroup/]version:]kind:[namespace/]name - items: - type: string - type: array - type: object - strimzi: - description: 'Deprecated: for backward compatibility.' - properties: - configuration: - description: TraitConfiguration parameters configuration - type: object - x-kubernetes-preserve-unknown-fields: true - required: - - configuration - type: object - toleration: - description: The configuration of Toleration trait - properties: - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: Can be used to enable or disable a trait. All - traits share this common property. - type: boolean - taints: - description: The list of taints to tolerate, in the form `Key[=Value]:Effect[:Seconds]` - items: - type: string - type: array - type: object - tracing: - description: 'Deprecated: for backward compatibility.' - properties: - configuration: - description: TraitConfiguration parameters configuration - type: object - x-kubernetes-preserve-unknown-fields: true - required: - - configuration - type: object - type: object version: description: the operator version type: string diff --git a/helm/camel-k/crds/crd-kamelet-binding.yaml b/helm/camel-k/crds/crd-kamelet-binding.yaml index ea5c186bbf..137de07cee 100644 --- a/helm/camel-k/crds/crd-kamelet-binding.yaml +++ b/helm/camel-k/crds/crd-kamelet-binding.yaml @@ -6758,6 +6758,12 @@ spec: - fifo - sequential type: string + platforms: + description: The list of manifest platforms to use to + build a container image (default `linux/amd64`). + items: + type: string + type: array properties: description: A list of properties to be provided to the build task @@ -7040,20 +7046,26 @@ spec: format: int32 type: integer rollingUpdateMaxSurge: + anyOf: + - type: integer + - type: string description: 'The maximum number of pods that can be scheduled above the desired number of pods. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). This can not be 0 if MaxUnavailable is 0. Absolute number is calculated from percentage by rounding up. Defaults to `25%`.' - type: integer + x-kubernetes-int-or-string: true rollingUpdateMaxUnavailable: + anyOf: + - type: integer + - type: string description: 'The maximum number of pods that can be unavailable during the update. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). Absolute number is calculated from percentage by rounding down. This can not be 0 if MaxSurge is 0. Defaults to `25%`.' - type: integer + x-kubernetes-int-or-string: true strategy: description: The deployment strategy to use to replace existing pods with new ones. @@ -7681,7 +7693,8 @@ spec: description: Enable "hot reload" when a secret/configmap mounted is edited (default `false`). The configmap/secret must be marked with `camel.apache.org/integration` label - to be taken in account. + to be taken in account. The resource will be watched + for any kind change, also for changes in metadata. type: boolean resources: description: 'A list of resources (text or binary content) @@ -7695,6 +7708,16 @@ spec: items: type: string type: array + scanKameletsImplicitLabelSecrets: + description: 'Deprecated: include your properties in an + explicit property file backed by a secret. Let the operator + to scan for secret labeled with `camel.apache.org/kamelet` + and `camel.apache.org/kamelet.configuration`. These + secrets are mounted to the application and treated as + plain properties file with their key/value list (ie + .spec.data["camel.my-property"] = my-value) (default + `true`).' + type: boolean volumes: description: 'A list of Persistent Volume Claims to be mounted. Syntax: [pvcname:/container/path]' @@ -7918,7 +7941,8 @@ spec: type: array type: object registry: - description: The configuration of Registry trait + description: 'The configuration of Registry trait Deprecated: + use jvm trait or read documentation.' properties: configuration: description: 'Legacy trait configuration parameters. Deprecated: diff --git a/helm/camel-k/crds/crd-pipe.yaml b/helm/camel-k/crds/crd-pipe.yaml index 98d3d9ac8b..a5fa027a72 100644 --- a/helm/camel-k/crds/crd-pipe.yaml +++ b/helm/camel-k/crds/crd-pipe.yaml @@ -6756,6 +6756,12 @@ spec: - fifo - sequential type: string + platforms: + description: The list of manifest platforms to use to + build a container image (default `linux/amd64`). + items: + type: string + type: array properties: description: A list of properties to be provided to the build task @@ -7038,20 +7044,26 @@ spec: format: int32 type: integer rollingUpdateMaxSurge: + anyOf: + - type: integer + - type: string description: 'The maximum number of pods that can be scheduled above the desired number of pods. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). This can not be 0 if MaxUnavailable is 0. Absolute number is calculated from percentage by rounding up. Defaults to `25%`.' - type: integer + x-kubernetes-int-or-string: true rollingUpdateMaxUnavailable: + anyOf: + - type: integer + - type: string description: 'The maximum number of pods that can be unavailable during the update. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). Absolute number is calculated from percentage by rounding down. This can not be 0 if MaxSurge is 0. Defaults to `25%`.' - type: integer + x-kubernetes-int-or-string: true strategy: description: The deployment strategy to use to replace existing pods with new ones. @@ -7679,7 +7691,8 @@ spec: description: Enable "hot reload" when a secret/configmap mounted is edited (default `false`). The configmap/secret must be marked with `camel.apache.org/integration` label - to be taken in account. + to be taken in account. The resource will be watched + for any kind change, also for changes in metadata. type: boolean resources: description: 'A list of resources (text or binary content) @@ -7693,6 +7706,16 @@ spec: items: type: string type: array + scanKameletsImplicitLabelSecrets: + description: 'Deprecated: include your properties in an + explicit property file backed by a secret. Let the operator + to scan for secret labeled with `camel.apache.org/kamelet` + and `camel.apache.org/kamelet.configuration`. These + secrets are mounted to the application and treated as + plain properties file with their key/value list (ie + .spec.data["camel.my-property"] = my-value) (default + `true`).' + type: boolean volumes: description: 'A list of Persistent Volume Claims to be mounted. Syntax: [pvcname:/container/path]' @@ -7916,7 +7939,8 @@ spec: type: array type: object registry: - description: The configuration of Registry trait + description: 'The configuration of Registry trait Deprecated: + use jvm trait or read documentation.' properties: configuration: description: 'Legacy trait configuration parameters. Deprecated: diff --git a/pkg/apis/camel/v1/build_type_support_test.go b/pkg/apis/camel/v1/build_type_support_test.go index 704b53f490..7fba1de191 100644 --- a/pkg/apis/camel/v1/build_type_support_test.go +++ b/pkg/apis/camel/v1/build_type_support_test.go @@ -116,13 +116,13 @@ func TestMatchingBuildsPending(t *testing.T) { // buildA is completed, no need to check it matches, buildMatch := buildList.HasMatchingBuild(&buildB) - assert.Equal(t, true, matches) + assert.True(t, matches) assert.Equal(t, buildA.Name, buildMatch.Name) matches, buildMatch = buildList.HasMatchingBuild(&buildC) - assert.Equal(t, true, matches) + assert.True(t, matches) // The matching logic is returning the first matching build found assert.True(t, buildMatch.Name == buildA.Name || buildMatch.Name == buildB.Name) matches, buildMatch = buildList.HasMatchingBuild(&buildZ) - assert.Equal(t, false, matches) + assert.False(t, matches) assert.Nil(t, buildMatch) } diff --git a/pkg/apis/camel/v1/common_types.go b/pkg/apis/camel/v1/common_types.go index cb01b391f4..d5af69100f 100644 --- a/pkg/apis/camel/v1/common_types.go +++ b/pkg/apis/camel/v1/common_types.go @@ -59,6 +59,8 @@ type BuildConfiguration struct { NodeSelector map[string]string `property:"node-selector" json:"nodeSelector,omitempty"` // Annotation to use for the builder pod. Only used for `pod` strategy Annotations map[string]string `property:"annotations" json:"annotations,omitempty"` + // The list of platforms used in order to build a container image. + ImagePlatforms []string `property:"platforms" json:"platforms,omitempty"` } // BuildStrategy specifies how the Build should be executed. @@ -232,6 +234,7 @@ type Traits struct { // The configuration of Quarkus trait Quarkus *trait.QuarkusTrait `property:"quarkus" json:"quarkus,omitempty"` // The configuration of Registry trait + // Deprecated: use jvm trait or read documentation. Registry *trait.RegistryTrait `property:"registry" json:"registry,omitempty"` // The configuration of Route trait Route *trait.RouteTrait `property:"route" json:"route,omitempty"` @@ -341,10 +344,23 @@ type RuntimeSpec struct { Capabilities map[string]Capability `json:"capabilities,omitempty" yaml:"capabilities,omitempty"` } -// Capability is a particular feature which requires a well known set of dependencies +// Capability is a particular feature which requires a well known set of dependencies and other properties // which are specified in the runtime catalog. type Capability struct { - Dependencies []MavenArtifact `json:"dependencies" yaml:"dependencies"` + // List of required Maven dependencies + Dependencies []MavenArtifact `json:"dependencies,omitempty" yaml:"dependencies,omitempty"` + // Set of required Camel runtime properties + RuntimeProperties []CamelProperty `json:"runtimeProperties,omitempty" yaml:"runtimeProperties,omitempty"` + // Set of required Camel build time properties + BuildTimeProperties []CamelProperty `json:"buildTimeProperties,omitempty" yaml:"buildTimeProperties,omitempty"` + // Set of generic metadata + Metadata map[string]string `json:"metadata,omitempty" yaml:"metadata,omitempty"` +} + +// CamelProperty represents a Camel property that may end up in an application.properties file. +type CamelProperty struct { + Key string `json:"key" yaml:"key"` + Value string `json:"value,omitempty" yaml:"value,omitempty"` } const ( diff --git a/pkg/apis/camel/v1/common_types_support_test.go b/pkg/apis/camel/v1/common_types_support_test.go index 36c1f9e9e7..082696987d 100644 --- a/pkg/apis/camel/v1/common_types_support_test.go +++ b/pkg/apis/camel/v1/common_types_support_test.go @@ -236,7 +236,7 @@ func TestDecodeValueSourceInvalid(t *testing.T) { for i, tc := range testcases { t.Run(fmt.Sprintf("test-%d-%s", i, tc.name), func(t *testing.T) { res, err := DecodeValueSource(tc.input, tc.defaultKey, tc.errorMessage) - assert.NotNil(t, err) + require.Error(t, err) assert.Equal(t, ValueSource{}, res) assert.Equal(t, err.Error(), tc.errorMessage) }) diff --git a/pkg/apis/camel/v1/integration_types.go b/pkg/apis/camel/v1/integration_types.go index c72a96253f..9f293f6a63 100644 --- a/pkg/apis/camel/v1/integration_types.go +++ b/pkg/apis/camel/v1/integration_types.go @@ -118,8 +118,6 @@ type IntegrationStatus struct { Selector string `json:"selector,omitempty"` // features offered by the Integration Capabilities []string `json:"capabilities,omitempty"` - // the traits generated and executed for this Integration - Traits Traits `json:"traits,omitempty"` // the timestamp representing the last time when this integration was initialized. InitializationTimestamp *metav1.Time `json:"lastInitTimestamp,omitempty"` } diff --git a/pkg/apis/camel/v1/integration_types_support.go b/pkg/apis/camel/v1/integration_types_support.go index 3342be76a6..3705c5a050 100644 --- a/pkg/apis/camel/v1/integration_types_support.go +++ b/pkg/apis/camel/v1/integration_types_support.go @@ -116,6 +116,11 @@ func (in *IntegrationSpec) AddDependency(dependency string) { in.Dependencies = append(in.Dependencies, dependency) } +// AddConfigurationProperty adds a new configuration property. +func (in *IntegrationSpec) AddConfigurationProperty(confValue string) { + in.AddConfiguration("property", confValue) +} + // GetConfigurationProperty returns a configuration property. func (in *IntegrationSpec) GetConfigurationProperty(property string) string { for _, confSpec := range in.Configuration { @@ -155,21 +160,6 @@ func (in *IntegrationStatus) AddOrReplaceGeneratedSources(sources ...SourceSpec) in.GeneratedSources = append(in.GeneratedSources, newSources...) } -func (in *IntegrationStatus) AddConfigurationsIfMissing(configurations ...ConfigurationSpec) { - for _, config := range configurations { - alreadyPresent := false - for _, r := range in.Configuration { - if r.Type == config.Type && r.Value == config.Value { - alreadyPresent = true - break - } - } - if !alreadyPresent { - in.Configuration = append(in.Configuration, config) - } - } -} - func (in *IntegrationSpec) Configurations() []ConfigurationSpec { if in == nil { return []ConfigurationSpec{} diff --git a/pkg/apis/camel/v1/integration_types_support_test.go b/pkg/apis/camel/v1/integration_types_support_test.go index 81b1c59734..d2bbb87819 100644 --- a/pkg/apis/camel/v1/integration_types_support_test.go +++ b/pkg/apis/camel/v1/integration_types_support_test.go @@ -63,10 +63,10 @@ func TestLanguageAlreadySet(t *testing.T) { func TestAddDependency(t *testing.T) { integration := IntegrationSpec{} integration.AddDependency("camel:file") - assert.Equal(t, integration.Dependencies, []string{"camel:file"}) + assert.Equal(t, []string{"camel:file"}, integration.Dependencies) // adding the same dependency twice won't duplicate it in the list integration.AddDependency("camel:file") - assert.Equal(t, integration.Dependencies, []string{"camel:file"}) + assert.Equal(t, []string{"camel:file"}, integration.Dependencies) integration = IntegrationSpec{} integration.AddDependency("mvn:com.my:company") diff --git a/pkg/apis/camel/v1/integrationkit_types.go b/pkg/apis/camel/v1/integrationkit_types.go index 5311e7dd7b..d8b0864c4a 100644 --- a/pkg/apis/camel/v1/integrationkit_types.go +++ b/pkg/apis/camel/v1/integrationkit_types.go @@ -74,6 +74,8 @@ type IntegrationKitSpec struct { Repositories []string `json:"repositories,omitempty"` // the sources to add at build time Sources []SourceSpec `json:"sources,omitempty"` + // features offered by the IntegrationKit + Capabilities []string `json:"capabilities,omitempty"` } // IntegrationKitTraits defines traits assigned to an `IntegrationKit`. @@ -87,6 +89,7 @@ type IntegrationKitTraits struct { // NOTE: Compiling to a native executable, requires at least 4GiB of memory, so the Pod running the native build must have enough memory available. Quarkus *trait.QuarkusTrait `property:"quarkus" json:"quarkus,omitempty"` // The Registry trait sets up Maven to use the Image registry as a Maven repository. + // Deprecated: use jvm trait or read documentation. Registry *trait.RegistryTrait `property:"registry" json:"registry,omitempty"` // The collection of addon trait configurations Addons map[string]AddonTrait `json:"addons,omitempty"` @@ -120,8 +123,6 @@ type IntegrationKitStatus struct { Version string `json:"version,omitempty"` // a list of conditions which happened for the events related the kit Conditions []IntegrationKitCondition `json:"conditions,omitempty"` - // generated traits executed by the kit - Traits IntegrationKitTraits `json:"traits,omitempty"` } // +kubebuilder:object:root=true diff --git a/pkg/apis/camel/v1/integrationkit_types_support.go b/pkg/apis/camel/v1/integrationkit_types_support.go index 6bcde2c037..c1c8d2a5f0 100644 --- a/pkg/apis/camel/v1/integrationkit_types_support.go +++ b/pkg/apis/camel/v1/integrationkit_types_support.go @@ -106,6 +106,17 @@ func (in *IntegrationKit) IsExternal() bool { return in.Labels[IntegrationKitTypeLabel] == IntegrationKitTypeExternal } +// HasCapability returns true if the Kit is enabled with such a capability. +func (in *IntegrationKit) HasCapability(capability string) bool { + for _, cap := range in.Spec.Capabilities { + if cap == capability { + return true + } + } + + return false +} + // GetCondition returns the condition with the provided type. func (in *IntegrationKitStatus) GetCondition(condType IntegrationKitConditionType) *IntegrationKitCondition { for i := range in.Conditions { diff --git a/pkg/apis/camel/v1/kamelet_types_support.go b/pkg/apis/camel/v1/kamelet_types_support.go index a95f425f10..e8818cb9ef 100644 --- a/pkg/apis/camel/v1/kamelet_types_support.go +++ b/pkg/apis/camel/v1/kamelet_types_support.go @@ -214,3 +214,8 @@ func NewKameletList() KameletList { }, } } + +// SetOperatorID sets the given operator id as an annotation. +func (k *Kamelet) SetOperatorID(operatorID string) { + SetAnnotation(&k.ObjectMeta, OperatorIDAnnotation, operatorID) +} diff --git a/pkg/apis/camel/v1/knative/types_support_test.go b/pkg/apis/camel/v1/knative/types_support_test.go index 44e204c272..ddc228000d 100644 --- a/pkg/apis/camel/v1/knative/types_support_test.go +++ b/pkg/apis/camel/v1/knative/types_support_test.go @@ -22,6 +22,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestSetSinkBinding(t *testing.T) { @@ -34,7 +35,7 @@ func TestSetSinkBinding(t *testing.T) { "apiVersion", "InMemoryChannel", ) - assert.Nil(t, err) + require.NoError(t, err) camelEnv.Services = append(camelEnv.Services, svc1) svc := camelEnv.FindService("test", CamelEndpointKindSink, diff --git a/pkg/apis/camel/v1/maven_types_support_test.go b/pkg/apis/camel/v1/maven_types_support_test.go index 095b33a0a4..2763f6b066 100644 --- a/pkg/apis/camel/v1/maven_types_support_test.go +++ b/pkg/apis/camel/v1/maven_types_support_test.go @@ -24,6 +24,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestMarshalEmptyProperties(t *testing.T) { @@ -34,11 +35,11 @@ func TestMarshalEmptyProperties(t *testing.T) { Name: xml.Name{Local: "root"}, }) - assert.NoError(t, err) + require.NoError(t, err) err = e.Flush() - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, "", buf.String()) } @@ -54,11 +55,11 @@ func TestMarshalProperties(t *testing.T) { Name: xml.Name{Local: "root"}, }) - assert.NoError(t, err) + require.NoError(t, err) err = e.Flush() - assert.NoError(t, err) + require.NoError(t, err) result := buf.String() assert.True(t, strings.HasPrefix(result, "")) @@ -75,11 +76,11 @@ func TestMarshalEmptyPluginProperties(t *testing.T) { Name: xml.Name{Local: "root"}, }) - assert.NoError(t, err) + require.NoError(t, err) err = e.Flush() - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, "", buf.String()) } @@ -95,11 +96,11 @@ func TestMarshalPluginProperties(t *testing.T) { Name: xml.Name{Local: "root"}, }) - assert.NoError(t, err) + require.NoError(t, err) err = e.Flush() - assert.NoError(t, err) + require.NoError(t, err) result := buf.String() assert.True(t, strings.HasPrefix(result, "")) @@ -124,11 +125,11 @@ func TestMarshalPluginPropertiesWithNestedProps(t *testing.T) { Name: xml.Name{Local: "root"}, }) - assert.NoError(t, err) + require.NoError(t, err) err = e.Flush() - assert.NoError(t, err) + require.NoError(t, err) result := buf.String() assert.True(t, strings.HasPrefix(result, "")) diff --git a/pkg/apis/camel/v1/pipe_types_support_test.go b/pkg/apis/camel/v1/pipe_types_support_test.go index 334bd2d2af..7d1e69fb9f 100644 --- a/pkg/apis/camel/v1/pipe_types_support_test.go +++ b/pkg/apis/camel/v1/pipe_types_support_test.go @@ -22,6 +22,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestNumberConversion(t *testing.T) { @@ -33,12 +34,12 @@ func TestNumberConversion(t *testing.T) { "float64": float64(1111123.123), } ser, err := json.Marshal(props) - assert.NoError(t, err) + require.NoError(t, err) ep := EndpointProperties{ RawMessage: ser, } res, err := ep.GetPropertyMap() - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, "str", res["string"]) assert.Equal(t, "1000000", res["int32"]) assert.Equal(t, "10000000000", res["int64"]) diff --git a/pkg/apis/camel/v1/trait/builder.go b/pkg/apis/camel/v1/trait/builder.go index 0e626438e0..8c6ca571e9 100644 --- a/pkg/apis/camel/v1/trait/builder.go +++ b/pkg/apis/camel/v1/trait/builder.go @@ -72,4 +72,6 @@ type BuilderTrait struct { NodeSelector map[string]string `property:"node-selector" json:"nodeSelector,omitempty"` // When using `pod` strategy, annotation to use for the builder pod. Annotations map[string]string `property:"annotations" json:"annotations,omitempty"` + // The list of manifest platforms to use to build a container image (default `linux/amd64`). + ImagePlatforms []string `property:"platforms" json:"platforms,omitempty"` } diff --git a/pkg/apis/camel/v1/trait/cron.go b/pkg/apis/camel/v1/trait/cron.go index 55f2eb4967..e1e1773491 100644 --- a/pkg/apis/camel/v1/trait/cron.go +++ b/pkg/apis/camel/v1/trait/cron.go @@ -24,7 +24,7 @@ package trait // For such tasks, the cron trait can materialize the integration as a Kubernetes CronJob instead of a standard deployment, // in order to save resources when the integration does not need to be executed. // -// Integrations that start from the following components are evaluated by the cron trait: `timer`, `cron`, `quartz`. +// Integrations that start from the following components are evaluated by the cron trait: `timer`, `cron`, `quartz`. The trait does support multiple evaluated components only if they have the same schedule, else it will fallback to Camel implementation instead of instanciating a Kubernetes CronJob. // // WARNING: In case of native build-mode defined in xref:traits:quarkus.adoc[quarkus] trait, the component can't be customized. // diff --git a/pkg/apis/camel/v1/trait/deployment.go b/pkg/apis/camel/v1/trait/deployment.go index 3e8092df6c..2be4cab70b 100644 --- a/pkg/apis/camel/v1/trait/deployment.go +++ b/pkg/apis/camel/v1/trait/deployment.go @@ -19,6 +19,7 @@ package trait import ( appsv1 "k8s.io/api/apps/v1" + "k8s.io/apimachinery/pkg/util/intstr" ) // The Deployment trait is responsible for generating the Kubernetes deployment that will make sure @@ -38,12 +39,12 @@ type DeploymentTrait struct { // Absolute number is calculated from percentage by rounding down. // This can not be 0 if MaxSurge is 0. // Defaults to `25%`. - RollingUpdateMaxUnavailable *int `property:"rolling-update-max-unavailable" json:"rollingUpdateMaxUnavailable,omitempty"` + RollingUpdateMaxUnavailable *intstr.IntOrString `property:"rolling-update-max-unavailable" json:"rollingUpdateMaxUnavailable,omitempty"` // The maximum number of pods that can be scheduled above the desired number of // pods. // Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). // This can not be 0 if MaxUnavailable is 0. // Absolute number is calculated from percentage by rounding up. // Defaults to `25%`. - RollingUpdateMaxSurge *int `property:"rolling-update-max-surge" json:"rollingUpdateMaxSurge,omitempty"` + RollingUpdateMaxSurge *intstr.IntOrString `property:"rolling-update-max-surge" json:"rollingUpdateMaxSurge,omitempty"` } diff --git a/pkg/apis/camel/v1/trait/mount.go b/pkg/apis/camel/v1/trait/mount.go index a0bcb889a7..bfa710fa56 100644 --- a/pkg/apis/camel/v1/trait/mount.go +++ b/pkg/apis/camel/v1/trait/mount.go @@ -36,6 +36,12 @@ type MountTrait struct { // A list of Persistent Volume Claims to be mounted. Syntax: [pvcname:/container/path] Volumes []string `property:"volumes" json:"volumes,omitempty"` // Enable "hot reload" when a secret/configmap mounted is edited (default `false`). The configmap/secret must be - // marked with `camel.apache.org/integration` label to be taken in account. + // marked with `camel.apache.org/integration` label to be taken in account. The resource will be watched for any kind change, also for + // changes in metadata. HotReload *bool `property:"hot-reload" json:"hotReload,omitempty"` + // Deprecated: include your properties in an explicit property file backed by a secret. + // Let the operator to scan for secret labeled with `camel.apache.org/kamelet` and `camel.apache.org/kamelet.configuration`. + // These secrets are mounted to the application and treated as plain properties file with their key/value list + // (ie .spec.data["camel.my-property"] = my-value) (default `true`). + ScanKameletsImplicitLabelSecrets *bool `property:"scan-kamelets-implicit-label-secrets" json:"scanKameletsImplicitLabelSecrets,omitempty"` } diff --git a/pkg/apis/camel/v1/trait/registry.go b/pkg/apis/camel/v1/trait/registry.go index 2f9db1b0c0..d0d6c7d099 100644 --- a/pkg/apis/camel/v1/trait/registry.go +++ b/pkg/apis/camel/v1/trait/registry.go @@ -17,6 +17,8 @@ limitations under the License. package trait +// WARNING: The Registry trait is **deprecated** and will removed in future release versions. +// // The Registry trait sets up Maven to use the Image registry // as a Maven repository. // diff --git a/pkg/apis/camel/v1/trait/zz_generated.deepcopy.go b/pkg/apis/camel/v1/trait/zz_generated.deepcopy.go index a799bdc3f4..8bfa59a89f 100644 --- a/pkg/apis/camel/v1/trait/zz_generated.deepcopy.go +++ b/pkg/apis/camel/v1/trait/zz_generated.deepcopy.go @@ -7,6 +7,7 @@ package trait import ( "k8s.io/api/networking/v1" + "k8s.io/apimachinery/pkg/util/intstr" ) // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. @@ -113,6 +114,11 @@ func (in *BuilderTrait) DeepCopyInto(out *BuilderTrait) { (*out)[key] = val } } + if in.ImagePlatforms != nil { + in, out := &in.ImagePlatforms, &out.ImagePlatforms + *out = make([]string, len(*in)) + copy(*out, *in) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BuilderTrait. @@ -281,12 +287,12 @@ func (in *DeploymentTrait) DeepCopyInto(out *DeploymentTrait) { } if in.RollingUpdateMaxUnavailable != nil { in, out := &in.RollingUpdateMaxUnavailable, &out.RollingUpdateMaxUnavailable - *out = new(int) + *out = new(intstr.IntOrString) **out = **in } if in.RollingUpdateMaxSurge != nil { in, out := &in.RollingUpdateMaxSurge, &out.RollingUpdateMaxSurge - *out = new(int) + *out = new(intstr.IntOrString) **out = **in } } @@ -748,6 +754,11 @@ func (in *MountTrait) DeepCopyInto(out *MountTrait) { *out = new(bool) **out = **in } + if in.ScanKameletsImplicitLabelSecrets != nil { + in, out := &in.ScanKameletsImplicitLabelSecrets, &out.ScanKameletsImplicitLabelSecrets + *out = new(bool) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MountTrait. diff --git a/pkg/apis/camel/v1/zz_generated.deepcopy.go b/pkg/apis/camel/v1/zz_generated.deepcopy.go index ded77d34ba..8d1e9dc134 100644 --- a/pkg/apis/camel/v1/zz_generated.deepcopy.go +++ b/pkg/apis/camel/v1/zz_generated.deepcopy.go @@ -160,6 +160,11 @@ func (in *BuildConfiguration) DeepCopyInto(out *BuildConfiguration) { (*out)[key] = val } } + if in.ImagePlatforms != nil { + in, out := &in.ImagePlatforms, &out.ImagePlatforms + *out = make([]string, len(*in)) + copy(*out, *in) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BuildConfiguration. @@ -563,6 +568,21 @@ func (in *CamelLoader) DeepCopy() *CamelLoader { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CamelProperty) DeepCopyInto(out *CamelProperty) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CamelProperty. +func (in *CamelProperty) DeepCopy() *CamelProperty { + if in == nil { + return nil + } + out := new(CamelProperty) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CamelScheme) DeepCopyInto(out *CamelScheme) { *out = *in @@ -610,6 +630,23 @@ func (in *Capability) DeepCopyInto(out *Capability) { *out = make([]MavenArtifact, len(*in)) copy(*out, *in) } + if in.RuntimeProperties != nil { + in, out := &in.RuntimeProperties, &out.RuntimeProperties + *out = make([]CamelProperty, len(*in)) + copy(*out, *in) + } + if in.BuildTimeProperties != nil { + in, out := &in.BuildTimeProperties, &out.BuildTimeProperties + *out = make([]CamelProperty, len(*in)) + copy(*out, *in) + } + if in.Metadata != nil { + in, out := &in.Metadata, &out.Metadata + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Capability. @@ -1248,6 +1285,11 @@ func (in *IntegrationKitSpec) DeepCopyInto(out *IntegrationKitSpec) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.Capabilities != nil { + in, out := &in.Capabilities, &out.Capabilities + *out = make([]string, len(*in)) + copy(*out, *in) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IntegrationKitSpec. @@ -1280,7 +1322,6 @@ func (in *IntegrationKitStatus) DeepCopyInto(out *IntegrationKitStatus) { (*in)[i].DeepCopyInto(&(*out)[i]) } } - in.Traits.DeepCopyInto(&out.Traits) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IntegrationKitStatus. @@ -1812,7 +1853,6 @@ func (in *IntegrationStatus) DeepCopyInto(out *IntegrationStatus) { *out = make([]string, len(*in)) copy(*out, *in) } - in.Traits.DeepCopyInto(&out.Traits) if in.InitializationTimestamp != nil { in, out := &in.InitializationTimestamp, &out.InitializationTimestamp *out = (*in).DeepCopy() diff --git a/pkg/apis/camel/v1alpha1/kamelet_binding_types_support_test.go b/pkg/apis/camel/v1alpha1/kamelet_binding_types_support_test.go index 1f9b4d1433..5c0dbb76c5 100644 --- a/pkg/apis/camel/v1alpha1/kamelet_binding_types_support_test.go +++ b/pkg/apis/camel/v1alpha1/kamelet_binding_types_support_test.go @@ -24,6 +24,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestNumberConversion(t *testing.T) { @@ -35,12 +36,12 @@ func TestNumberConversion(t *testing.T) { "float64": float64(1111123.123), } ser, err := json.Marshal(props) - assert.NoError(t, err) + require.NoError(t, err) ep := EndpointProperties{ RawMessage: ser, } res, err := ep.GetPropertyMap() - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, "str", res["string"]) assert.Equal(t, "1000000", res["int32"]) assert.Equal(t, "10000000000", res["int64"]) diff --git a/pkg/builder/builder_test.go b/pkg/builder/builder_test.go index 8ff60bd54f..1f8c643b8b 100644 --- a/pkg/builder/builder_test.go +++ b/pkg/builder/builder_test.go @@ -22,6 +22,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" "github.com/apache/camel-k/v2/pkg/util/cancellable" @@ -35,7 +36,7 @@ type errorTestSteps struct { func TestFailure(t *testing.T) { c, err := test.NewFakeClient() - assert.Nil(t, err) + require.NoError(t, err) b := New(c) diff --git a/pkg/builder/image_test.go b/pkg/builder/image_test.go index f7a54725fc..e0fce1e5f4 100644 --- a/pkg/builder/image_test.go +++ b/pkg/builder/image_test.go @@ -21,6 +21,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -32,7 +33,7 @@ import ( func TestListPublishedImages(t *testing.T) { catalog, err := camel.DefaultCatalog() - assert.Nil(t, err) + require.NoError(t, err) c, err := test.NewFakeClient( &v1.IntegrationKit{ @@ -79,7 +80,7 @@ func TestListPublishedImages(t *testing.T) { }, ) - assert.Nil(t, err) + require.NoError(t, err) assert.NotNil(t, c) i, err := listPublishedImages(&builderContext{ @@ -88,7 +89,7 @@ func TestListPublishedImages(t *testing.T) { C: cancellable.NewContext(), }) - assert.Nil(t, err) + require.NoError(t, err) assert.Len(t, i, 1) assert.Equal(t, "image-2", i[0].Image) } diff --git a/pkg/builder/jib.go b/pkg/builder/jib.go index 129e978b01..0c2f071fa4 100644 --- a/pkg/builder/jib.go +++ b/pkg/builder/jib.go @@ -109,6 +109,10 @@ func (t *jibTask) Do(ctx context.Context) v1.BuildStatus { mavenArgs = append(mavenArgs, "-P", "jib") mavenArgs = append(mavenArgs, jib.JibMavenToImageParam+t.task.Image) mavenArgs = append(mavenArgs, jib.JibMavenFromImageParam+baseImage) + if t.task.Configuration.ImagePlatforms != nil { + platforms := strings.Join(t.task.Configuration.ImagePlatforms, ",") + mavenArgs = append(mavenArgs, jib.JibMavenFromPlatforms+platforms) + } if t.task.Registry.Insecure { mavenArgs = append(mavenArgs, jib.JibMavenInsecureRegistries+"true") } diff --git a/pkg/builder/project_test.go b/pkg/builder/project_test.go index d6db9edb46..00a948ef1b 100644 --- a/pkg/builder/project_test.go +++ b/pkg/builder/project_test.go @@ -22,6 +22,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -192,7 +193,7 @@ const expectedCustomSettingsWithExtraServers = ` 0 { + if _, err := f.WriteString("\n"); err != nil { + return err + } + } + // Fill with properties coming from user configuration + for k, v := range applicationProperties { + if _, err := f.WriteString(fmt.Sprintf("%s=%s\n", k, v)); err != nil { + return err + } + } + return nil +} + func computeQuarkusDependencies(ctx *builderContext) error { mc := maven.NewContext(filepath.Join(ctx.Path, "maven")) mc.GlobalSettings = ctx.Maven.GlobalSettings diff --git a/pkg/builder/quarkus_test.go b/pkg/builder/quarkus_test.go new file mode 100644 index 0000000000..4b994fd4cf --- /dev/null +++ b/pkg/builder/quarkus_test.go @@ -0,0 +1,314 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package builder + +import ( + "context" + "fmt" + "os" + "path/filepath" + "strings" + "testing" + + v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" + "github.com/apache/camel-k/v2/pkg/util/camel" + "github.com/apache/camel-k/v2/pkg/util/defaults" + "github.com/apache/camel-k/v2/pkg/util/test" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func TestGenerateQuarkusProjectCommon(t *testing.T) { + p := generateQuarkusProjectCommon("1.2.3", "4.5.6") + assert.Equal(t, "org.apache.camel.k.integration", p.GroupID) + assert.Equal(t, "camel-k-integration", p.ArtifactID) + assert.Equal(t, defaults.Version, p.Version) + assert.Equal(t, "fast-jar", p.Properties["quarkus.package.type"]) + assert.Equal(t, "org.apache.camel.k", p.DependencyManagement.Dependencies[0].GroupID) + assert.Equal(t, "camel-k-runtime-bom", p.DependencyManagement.Dependencies[0].ArtifactID) + assert.Equal(t, "1.2.3", p.DependencyManagement.Dependencies[0].Version) + assert.Equal(t, "pom", p.DependencyManagement.Dependencies[0].Type) + assert.Equal(t, "import", p.DependencyManagement.Dependencies[0].Scope) + assert.Equal(t, "io.quarkus", p.Build.Plugins[0].GroupID) + assert.Equal(t, "quarkus-maven-plugin", p.Build.Plugins[0].ArtifactID) + assert.Equal(t, "4.5.6", p.Build.Plugins[0].Version) +} + +func TestLoadCamelQuarkusCatalogMissing(t *testing.T) { + c, err := test.NewFakeClient() + require.NoError(t, err) + builderContext := builderContext{ + Client: c, + C: context.TODO(), + Namespace: "test", + Build: v1.BuilderTask{ + Runtime: v1.RuntimeSpec{ + Version: "1.2.3", + Provider: "Quarkus", + }, + }, + } + err = loadCamelQuarkusCatalog(&builderContext) + require.Error(t, err) + assert.Equal(t, "unable to find catalog matching version requirement: runtime=1.2.3, provider=Quarkus", err.Error()) +} + +func TestLoadCamelQuarkusCatalogOk(t *testing.T) { + runtimeCatalog := v1.RuntimeSpec{ + Version: "1.2.3", + Provider: "Quarkus", + Dependencies: make([]v1.MavenArtifact, 0), + } + c, err := test.NewFakeClient(&v1.CamelCatalog{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "my-fake-catalog", + }, + Spec: v1.CamelCatalogSpec{ + Runtime: runtimeCatalog, + }, + }) + require.NoError(t, err) + builderContext := builderContext{ + Client: c, + C: context.TODO(), + Namespace: "default", + Build: v1.BuilderTask{ + Runtime: v1.RuntimeSpec{ + Version: "1.2.3", + Provider: "Quarkus", + }, + }, + } + err = loadCamelQuarkusCatalog(&builderContext) + require.NoError(t, err) + assert.Equal(t, runtimeCatalog, builderContext.Catalog.Runtime) +} + +func TestGenerateQuarkusProjectWithBuildTimeProperties(t *testing.T) { + tmpDir, err := os.MkdirTemp("", "go-test-camel-k-quarkus-with-props") + require.NoError(t, err) + defaultCatalog, err := camel.DefaultCatalog() + require.NoError(t, err) + + mavenProps := v1.Properties{} + mavenProps.Add("quarkus.camel.hello", "world") + mavenProps.Add("quarkus.camel.\"shouldnt\"", "fail") + mavenProps.Add("my-build-time-var", "my-build-time-val") + mavenProps.Add("my-build-time\var2", "my-build-time-val2") + builderContext := builderContext{ + C: context.TODO(), + Path: tmpDir, + Namespace: "test", + Build: v1.BuilderTask{ + Runtime: defaultCatalog.Runtime, + Maven: v1.MavenBuildSpec{ + MavenSpec: v1.MavenSpec{ + Properties: mavenProps, + }, + }, + }, + } + if strings.Contains(defaults.DefaultRuntimeVersion, "SNAPSHOT") { + builderContext.Build.Maven.Repositories = []v1.Repository{ + { + ID: "APACHE-SNAPSHOT", + Name: "Apache Snapshot", + URL: "https://repository.apache.org/content/repositories/snapshots-group", + Snapshots: v1.RepositoryPolicy{ + Enabled: true, + UpdatePolicy: "always", + ChecksumPolicy: "ignore", + }, + Releases: v1.RepositoryPolicy{ + Enabled: false, + }, + }, + } + } + + err = generateQuarkusProject(&builderContext) + require.NoError(t, err) + // use local Maven executable in tests + t.Setenv("MAVEN_WRAPPER", "false") + _, ok := os.LookupEnv("MAVEN_CMD") + if !ok { + t.Setenv("MAVEN_CMD", "mvn") + } + err = buildQuarkusRunner(&builderContext) + require.NoError(t, err) + appProps, err := os.ReadFile(filepath.Join(tmpDir, "maven", "src", "main", "resources", "application.properties")) + require.NoError(t, err) + assert.Contains(t, string(appProps), "quarkus.camel.hello=world\n") + assert.Contains(t, string(appProps), "quarkus.camel.\"shouldnt\"=fail\n") + assert.Contains(t, string(appProps), "my-build-time-var=my-build-time-val\n") + assert.Contains(t, string(appProps), "my-build-time\var2=my-build-time-val2\n") + // At this stage a maven project should have been executed. Verify the package was created. + _, err = os.Stat(filepath.Join(tmpDir, "maven", "target", "camel-k-integration-"+defaults.Version+".jar")) + require.NoError(t, err) +} + +func TestGenerateQuarkusProjectWithNativeSources(t *testing.T) { + tmpDir, err := os.MkdirTemp("", "go-test-camel-k-quarkus-native") + require.NoError(t, err) + defaultCatalog, err := camel.DefaultCatalog() + require.NoError(t, err) + + builderContext := builderContext{ + C: context.TODO(), + Path: tmpDir, + Namespace: "test", + Build: v1.BuilderTask{ + Runtime: defaultCatalog.Runtime, + Maven: v1.MavenBuildSpec{ + MavenSpec: v1.MavenSpec{}, + }, + Sources: []v1.SourceSpec{v1.NewSourceSpec("Test.java", "bogus, irrelevant for test", v1.LanguageJavaSource)}, + }, + } + if strings.Contains(defaults.DefaultRuntimeVersion, "SNAPSHOT") { + builderContext.Build.Maven.Repositories = []v1.Repository{ + { + ID: "APACHE-SNAPSHOT", + Name: "Apache Snapshot", + URL: "https://repository.apache.org/content/repositories/snapshots-group", + Snapshots: v1.RepositoryPolicy{ + Enabled: true, + UpdatePolicy: "always", + ChecksumPolicy: "ignore", + }, + Releases: v1.RepositoryPolicy{ + Enabled: false, + }, + }, + } + } + + err = prepareProjectWithSources(&builderContext) + require.NoError(t, err) + err = generateQuarkusProject(&builderContext) + require.NoError(t, err) + // use local Maven executable in tests + t.Setenv("MAVEN_WRAPPER", "false") + _, ok := os.LookupEnv("MAVEN_CMD") + if !ok { + t.Setenv("MAVEN_CMD", "mvn") + } + err = buildQuarkusRunner(&builderContext) + require.NoError(t, err) + appProps, err := os.ReadFile(filepath.Join(tmpDir, "maven", "src", "main", "resources", "application.properties")) + require.NoError(t, err) + assert.Contains(t, string(appProps), "quarkus.camel.routes-discovery.enabled=false\n") + assert.Contains(t, string(appProps), "camel.main.routes-include-pattern = classpath:routes/Test.java\n") + materializedRoute, err := os.ReadFile(filepath.Join(tmpDir, "maven", "src", "main", "resources", "routes", "Test.java")) + require.NoError(t, err) + assert.Contains(t, string(materializedRoute), "bogus, irrelevant for test") + // At this stage a maven project should have been executed. Verify the package was created. + _, err = os.Stat(filepath.Join(tmpDir, "maven", "target", "camel-k-integration-"+defaults.Version+".jar")) + require.NoError(t, err) +} + +func TestBuildQuarkusRunner(t *testing.T) { + tmpDir, err := os.MkdirTemp("", "go-test-camel-k-quarkus") + require.NoError(t, err) + defaultCatalog, err := camel.DefaultCatalog() + require.NoError(t, err) + c, err := test.NewFakeClient(&v1.CamelCatalog{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "camel-catalog-" + defaults.DefaultRuntimeVersion, + }, + Spec: v1.CamelCatalogSpec{ + Runtime: defaultCatalog.Runtime, + }, + }) + require.NoError(t, err) + mavenProps := v1.Properties{} + mavenProps.Add("camel.hello", "world") + builderContext := builderContext{ + Client: c, + Catalog: defaultCatalog, + C: context.TODO(), + Path: tmpDir, + Namespace: "test", + Build: v1.BuilderTask{ + Runtime: defaultCatalog.Runtime, + Maven: v1.MavenBuildSpec{ + MavenSpec: v1.MavenSpec{ + Properties: mavenProps, + }, + }, + Dependencies: []string{"mvn:org.apache.camel.k:camel-k-runtime"}, + }, + } + if strings.Contains(defaults.DefaultRuntimeVersion, "SNAPSHOT") { + builderContext.Build.Maven.Repositories = []v1.Repository{ + { + ID: "APACHE-SNAPSHOT", + Name: "Apache Snapshot", + URL: "https://repository.apache.org/content/repositories/snapshots-group", + Snapshots: v1.RepositoryPolicy{ + Enabled: true, + UpdatePolicy: "always", + ChecksumPolicy: "ignore", + }, + Releases: v1.RepositoryPolicy{ + Enabled: false, + }, + }, + } + } + err = generateQuarkusProject(&builderContext) + require.NoError(t, err) + err = injectDependencies(&builderContext) + require.NoError(t, err) + err = sanitizeDependencies(&builderContext) + require.NoError(t, err) + // use local Maven executable in tests + t.Setenv("MAVEN_WRAPPER", "false") + _, ok := os.LookupEnv("MAVEN_CMD") + if !ok { + t.Setenv("MAVEN_CMD", "mvn") + } + err = buildQuarkusRunner(&builderContext) + require.NoError(t, err) + // Verify default application properties + appProps, err := os.ReadFile(filepath.Join(tmpDir, "maven", "src", "main", "resources", "application.properties")) + require.NoError(t, err) + assert.Contains(t, string(appProps), "camel.hello=world\n") + assert.Contains(t, string(appProps), "quarkus.banner.enabled=false\n") + assert.Contains(t, string(appProps), "quarkus.camel.service.discovery.include-patterns=META-INF/services/org/apache/camel/datatype/converter/*,META-INF/services/org/apache/camel/datatype/transformer/*,META-INF/services/org/apache/camel/transformer/*\n") + assert.Contains(t, string(appProps), "quarkus.class-loading.parent-first-artifacts=org.graalvm.regex:regex\n") + // At this stage a maven project should have been executed. Verify the package was created. + _, err = os.Stat(filepath.Join(tmpDir, "maven", "target", "camel-k-integration-"+defaults.Version+".jar")) + require.NoError(t, err) + + // We use this same unit test to verify dependencies generated + // (and spare some build time to avoid running another maven process) + err = computeQuarkusDependencies(&builderContext) + require.NoError(t, err) + assert.NotEmpty(t, builderContext.Artifacts) + camelRuntimeDepFound := false + expectedArtifact := fmt.Sprintf("org.apache.camel.k.camel-k-runtime-%s.jar", defaults.DefaultRuntimeVersion) + for _, artifact := range builderContext.Artifacts { + if artifact.ID == expectedArtifact { + camelRuntimeDepFound = true + break + } + } + assert.True(t, camelRuntimeDepFound, "Did not find expected artifact: %s", expectedArtifact) +} diff --git a/pkg/builder/types.go b/pkg/builder/types.go index e6835d4881..71f578e621 100644 --- a/pkg/builder/types.go +++ b/pkg/builder/types.go @@ -64,7 +64,7 @@ type Task interface { type Step interface { ID() string Phase() int32 - execute(*builderContext) error + execute(context *builderContext) error } type resource struct { diff --git a/pkg/client/camel/applyconfiguration/camel/v1/buildconfiguration.go b/pkg/client/camel/applyconfiguration/camel/v1/buildconfiguration.go index 1b1f99777e..494e39c0dc 100644 --- a/pkg/client/camel/applyconfiguration/camel/v1/buildconfiguration.go +++ b/pkg/client/camel/applyconfiguration/camel/v1/buildconfiguration.go @@ -36,6 +36,7 @@ type BuildConfigurationApplyConfiguration struct { LimitMemory *string `json:"limitMemory,omitempty"` NodeSelector map[string]string `json:"nodeSelector,omitempty"` Annotations map[string]string `json:"annotations,omitempty"` + ImagePlatforms []string `json:"platforms,omitempty"` } // BuildConfigurationApplyConfiguration constructs an declarative configuration of the BuildConfiguration type for use with @@ -135,3 +136,13 @@ func (b *BuildConfigurationApplyConfiguration) WithAnnotations(entries map[strin } return b } + +// WithImagePlatforms adds the given value to the ImagePlatforms field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the ImagePlatforms field. +func (b *BuildConfigurationApplyConfiguration) WithImagePlatforms(values ...string) *BuildConfigurationApplyConfiguration { + for i := range values { + b.ImagePlatforms = append(b.ImagePlatforms, values[i]) + } + return b +} diff --git a/pkg/client/camel/applyconfiguration/camel/v1/camelproperty.go b/pkg/client/camel/applyconfiguration/camel/v1/camelproperty.go new file mode 100644 index 0000000000..a93d9ab6cc --- /dev/null +++ b/pkg/client/camel/applyconfiguration/camel/v1/camelproperty.go @@ -0,0 +1,49 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1 + +// CamelPropertyApplyConfiguration represents an declarative configuration of the CamelProperty type for use +// with apply. +type CamelPropertyApplyConfiguration struct { + Key *string `json:"key,omitempty"` + Value *string `json:"value,omitempty"` +} + +// CamelPropertyApplyConfiguration constructs an declarative configuration of the CamelProperty type for use with +// apply. +func CamelProperty() *CamelPropertyApplyConfiguration { + return &CamelPropertyApplyConfiguration{} +} + +// WithKey sets the Key field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Key field is set to the value of the last call. +func (b *CamelPropertyApplyConfiguration) WithKey(value string) *CamelPropertyApplyConfiguration { + b.Key = &value + return b +} + +// WithValue sets the Value field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Value field is set to the value of the last call. +func (b *CamelPropertyApplyConfiguration) WithValue(value string) *CamelPropertyApplyConfiguration { + b.Value = &value + return b +} diff --git a/pkg/client/camel/applyconfiguration/camel/v1/capability.go b/pkg/client/camel/applyconfiguration/camel/v1/capability.go index 7d49027fad..28b155f38b 100644 --- a/pkg/client/camel/applyconfiguration/camel/v1/capability.go +++ b/pkg/client/camel/applyconfiguration/camel/v1/capability.go @@ -22,7 +22,10 @@ package v1 // CapabilityApplyConfiguration represents an declarative configuration of the Capability type for use // with apply. type CapabilityApplyConfiguration struct { - Dependencies []MavenArtifactApplyConfiguration `json:"dependencies,omitempty"` + Dependencies []MavenArtifactApplyConfiguration `json:"dependencies,omitempty"` + RuntimeProperties []CamelPropertyApplyConfiguration `json:"runtimeProperties,omitempty"` + BuildTimeProperties []CamelPropertyApplyConfiguration `json:"buildTimeProperties,omitempty"` + Metadata map[string]string `json:"metadata,omitempty"` } // CapabilityApplyConfiguration constructs an declarative configuration of the Capability type for use with @@ -43,3 +46,43 @@ func (b *CapabilityApplyConfiguration) WithDependencies(values ...*MavenArtifact } return b } + +// WithRuntimeProperties adds the given value to the RuntimeProperties field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the RuntimeProperties field. +func (b *CapabilityApplyConfiguration) WithRuntimeProperties(values ...*CamelPropertyApplyConfiguration) *CapabilityApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithRuntimeProperties") + } + b.RuntimeProperties = append(b.RuntimeProperties, *values[i]) + } + return b +} + +// WithBuildTimeProperties adds the given value to the BuildTimeProperties field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the BuildTimeProperties field. +func (b *CapabilityApplyConfiguration) WithBuildTimeProperties(values ...*CamelPropertyApplyConfiguration) *CapabilityApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithBuildTimeProperties") + } + b.BuildTimeProperties = append(b.BuildTimeProperties, *values[i]) + } + return b +} + +// WithMetadata puts the entries into the Metadata field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Metadata field, +// overwriting an existing map entries in Metadata field with the same key. +func (b *CapabilityApplyConfiguration) WithMetadata(entries map[string]string) *CapabilityApplyConfiguration { + if b.Metadata == nil && len(entries) > 0 { + b.Metadata = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.Metadata[k] = v + } + return b +} diff --git a/pkg/client/camel/applyconfiguration/camel/v1/integrationkitspec.go b/pkg/client/camel/applyconfiguration/camel/v1/integrationkitspec.go index 19bd2e613c..9d85a68297 100644 --- a/pkg/client/camel/applyconfiguration/camel/v1/integrationkitspec.go +++ b/pkg/client/camel/applyconfiguration/camel/v1/integrationkitspec.go @@ -33,6 +33,7 @@ type IntegrationKitSpecApplyConfiguration struct { Configuration []ConfigurationSpecApplyConfiguration `json:"configuration,omitempty"` Repositories []string `json:"repositories,omitempty"` Sources []SourceSpecApplyConfiguration `json:"sources,omitempty"` + Capabilities []string `json:"capabilities,omitempty"` } // IntegrationKitSpecApplyConfiguration constructs an declarative configuration of the IntegrationKitSpec type for use with @@ -110,3 +111,13 @@ func (b *IntegrationKitSpecApplyConfiguration) WithSources(values ...*SourceSpec } return b } + +// WithCapabilities adds the given value to the Capabilities field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Capabilities field. +func (b *IntegrationKitSpecApplyConfiguration) WithCapabilities(values ...string) *IntegrationKitSpecApplyConfiguration { + for i := range values { + b.Capabilities = append(b.Capabilities, values[i]) + } + return b +} diff --git a/pkg/client/camel/applyconfiguration/camel/v1/integrationkitstatus.go b/pkg/client/camel/applyconfiguration/camel/v1/integrationkitstatus.go index 931c92f89f..12650227af 100644 --- a/pkg/client/camel/applyconfiguration/camel/v1/integrationkitstatus.go +++ b/pkg/client/camel/applyconfiguration/camel/v1/integrationkitstatus.go @@ -39,7 +39,6 @@ type IntegrationKitStatusApplyConfiguration struct { Platform *string `json:"platform,omitempty"` Version *string `json:"version,omitempty"` Conditions []IntegrationKitConditionApplyConfiguration `json:"conditions,omitempty"` - Traits *IntegrationKitTraitsApplyConfiguration `json:"traits,omitempty"` } // IntegrationKitStatusApplyConfiguration constructs an declarative configuration of the IntegrationKitStatus type for use with @@ -161,11 +160,3 @@ func (b *IntegrationKitStatusApplyConfiguration) WithConditions(values ...*Integ } return b } - -// WithTraits sets the Traits field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Traits field is set to the value of the last call. -func (b *IntegrationKitStatusApplyConfiguration) WithTraits(value *IntegrationKitTraitsApplyConfiguration) *IntegrationKitStatusApplyConfiguration { - b.Traits = value - return b -} diff --git a/pkg/client/camel/applyconfiguration/camel/v1/integrationstatus.go b/pkg/client/camel/applyconfiguration/camel/v1/integrationstatus.go index 8ef4bdfcf5..d17acaa2b2 100644 --- a/pkg/client/camel/applyconfiguration/camel/v1/integrationstatus.go +++ b/pkg/client/camel/applyconfiguration/camel/v1/integrationstatus.go @@ -45,7 +45,6 @@ type IntegrationStatusApplyConfiguration struct { Replicas *int32 `json:"replicas,omitempty"` Selector *string `json:"selector,omitempty"` Capabilities []string `json:"capabilities,omitempty"` - Traits *TraitsApplyConfiguration `json:"traits,omitempty"` InitializationTimestamp *metav1.Time `json:"lastInitTimestamp,omitempty"` } @@ -210,14 +209,6 @@ func (b *IntegrationStatusApplyConfiguration) WithCapabilities(values ...string) return b } -// WithTraits sets the Traits field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Traits field is set to the value of the last call. -func (b *IntegrationStatusApplyConfiguration) WithTraits(value *TraitsApplyConfiguration) *IntegrationStatusApplyConfiguration { - b.Traits = value - return b -} - // WithInitializationTimestamp sets the InitializationTimestamp field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the InitializationTimestamp field is set to the value of the last call. diff --git a/pkg/client/camel/applyconfiguration/utils.go b/pkg/client/camel/applyconfiguration/utils.go index 737a3d5ebc..6632cd8230 100644 --- a/pkg/client/camel/applyconfiguration/utils.go +++ b/pkg/client/camel/applyconfiguration/utils.go @@ -68,6 +68,8 @@ func ForKind(kind schema.GroupVersionKind) interface{} { return &camelv1.CamelCatalogStatusApplyConfiguration{} case v1.SchemeGroupVersion.WithKind("CamelLoader"): return &camelv1.CamelLoaderApplyConfiguration{} + case v1.SchemeGroupVersion.WithKind("CamelProperty"): + return &camelv1.CamelPropertyApplyConfiguration{} case v1.SchemeGroupVersion.WithKind("CamelScheme"): return &camelv1.CamelSchemeApplyConfiguration{} case v1.SchemeGroupVersion.WithKind("CamelSchemeScope"): diff --git a/pkg/client/client.go b/pkg/client/client.go index 4325c65717..15fafbcb02 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -68,7 +68,7 @@ type Client interface { // Injectable identifies objects that can receive a Client. type Injectable interface { - InjectClient(Client) + InjectClient(client Client) } // Provider is used to provide a new instance of the Client each time it's required. diff --git a/pkg/cmd/bind.go b/pkg/cmd/bind.go index 57530a6738..938a023890 100644 --- a/pkg/cmd/bind.go +++ b/pkg/cmd/bind.go @@ -47,7 +47,7 @@ func newCmdBind(rootCmdOptions *RootCmdOptions) (*cobra.Command, *bindCmdOptions Use: "bind [source] [sink] ...", Short: "Bind Kubernetes resources, such as Kamelets, in an integration flow.", Long: "Bind Kubernetes resources, such as Kamelets, in an integration flow. Endpoints are expected in the format \"[[apigroup/]version:]kind:[namespace/]name\" or plain Camel URIs.", - PersistentPreRunE: decode(&options), + PersistentPreRunE: decode(&options, options.Flags), PreRunE: options.preRunE, RunE: options.runE, Annotations: make(map[string]string), diff --git a/pkg/cmd/bind_test.go b/pkg/cmd/bind_test.go index 1b50d9fe96..86756896ca 100644 --- a/pkg/cmd/bind_test.go +++ b/pkg/cmd/bind_test.go @@ -40,7 +40,7 @@ func initializeBindCmdOptions(t *testing.T) (*bindCmdOptions, *cobra.Command, Ro options, rootCmd := kamelTestPreAddCommandInitWithClient(fakeClient) bindCmdOptions := addTestBindCmd(*options, rootCmd) - kamelTestPostAddCommandInit(t, rootCmd) + kamelTestPostAddCommandInit(t, rootCmd, options) return bindCmdOptions, rootCmd, *options } @@ -58,7 +58,7 @@ func TestBindOutputJSON(t *testing.T) { output, err := test.ExecuteCommand(bindCmd, cmdBind, "my:src", "my:dst", "-o", "json") assert.Equal(t, "json", buildCmdOptions.OutputFormat) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, `{"kind":"Pipe","apiVersion":"camel.apache.org/v1","metadata":{"name":"my-to-my","creationTimestamp":null,"annotations":{"camel.apache.org/operator.id":"camel-k"}},"spec":{"source":{"uri":"my:src"},"sink":{"uri":"my:dst"}},"status":{}}`, output) } @@ -67,7 +67,7 @@ func TestBindOutputYAML(t *testing.T) { output, err := test.ExecuteCommand(bindCmd, cmdBind, "my:src", "my:dst", "-o", "yaml") assert.Equal(t, "yaml", buildCmdOptions.OutputFormat) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, `apiVersion: camel.apache.org/v1 kind: Pipe metadata: @@ -98,7 +98,7 @@ func TestBindErrorHandlerDLCKamelet(t *testing.T) { "--error-handler", "sink:my-kamelet", "-p", "error-handler.my-prop=value") assert.Equal(t, "yaml", buildCmdOptions.OutputFormat) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, `apiVersion: camel.apache.org/v1 kind: Pipe metadata: @@ -130,7 +130,7 @@ func TestBindErrorHandlerNone(t *testing.T) { "--error-handler", "none") assert.Equal(t, "yaml", buildCmdOptions.OutputFormat) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, `apiVersion: camel.apache.org/v1 kind: Pipe metadata: @@ -155,7 +155,7 @@ func TestBindErrorHandlerLog(t *testing.T) { "--error-handler", "log") assert.Equal(t, "yaml", buildCmdOptions.OutputFormat) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, `apiVersion: camel.apache.org/v1 kind: Pipe metadata: @@ -179,7 +179,7 @@ func TestBindTraits(t *testing.T) { output, err := test.ExecuteCommand(bindCmd, cmdBind, "my:src", "my:dst", "-o", "yaml", "-t", "mount.configs=configmap:my-cm", "-c", "my-service-binding") assert.Equal(t, "yaml", buildCmdOptions.OutputFormat) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, `apiVersion: camel.apache.org/v1 kind: Pipe metadata: @@ -212,7 +212,7 @@ func TestBindSteps(t *testing.T) { "-p", "step-2.var1=my-step2-var1", "-p", "step-2.var2=my-step2-var2") assert.Equal(t, "yaml", buildCmdOptions.OutputFormat) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, `apiVersion: camel.apache.org/v1 kind: Pipe metadata: @@ -244,7 +244,7 @@ func TestBindServiceAccountName(t *testing.T) { "-o", "yaml", "--service-account", "my-service-account") - assert.Nil(t, err) + require.NoError(t, err) assert.Contains(t, output, "serviceAccountName: my-service-account") } diff --git a/pkg/cmd/builder.go b/pkg/cmd/builder.go index 34dd2d9239..7609e3f187 100644 --- a/pkg/cmd/builder.go +++ b/pkg/cmd/builder.go @@ -33,7 +33,7 @@ func newCmdBuilder(rootCmdOptions *RootCmdOptions) (*cobra.Command, *builderCmdO Short: "Run the Camel K builder", Long: `Run the Camel K builder`, Hidden: true, - PreRunE: decode(&options), + PreRunE: decode(&options, options.Flags), Run: options.run, } diff --git a/pkg/cmd/builder_test.go b/pkg/cmd/builder_test.go index 3e390d6d0c..4f5ee39e30 100644 --- a/pkg/cmd/builder_test.go +++ b/pkg/cmd/builder_test.go @@ -23,6 +23,7 @@ import ( "github.com/apache/camel-k/v2/pkg/util/test" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) const cmdBuilder = "builder" @@ -33,7 +34,7 @@ func initializeBuilderCmdOptions(t *testing.T) (*builderCmdOptions, *cobra.Comma options, rootCmd := kamelTestPreAddCommandInit() builderCmdOptions := addTestBuilderCmd(*options, rootCmd) - kamelTestPostAddCommandInit(t, rootCmd) + kamelTestPostAddCommandInit(t, rootCmd, options) return builderCmdOptions, rootCmd, *options } @@ -55,19 +56,19 @@ func addTestBuilderCmd(options RootCmdOptions, rootCmd *cobra.Command) *builderC func TestBuilderNonExistingFlag(t *testing.T) { _, rootCmd, _ := initializeBuilderCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdBuilder, "--nonExistingFlag") - assert.NotNil(t, err) + require.Error(t, err) } func TestBuilderBuildNameFlag(t *testing.T) { builderCmdOptions, rootCmd, _ := initializeBuilderCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdBuilder, "--build-name", "someBuild") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "someBuild", builderCmdOptions.BuildName) } func TestBuilderTaskNameFlag(t *testing.T) { builderCmdOptions, rootCmd, _ := initializeBuilderCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdBuilder, "--task-name", "someTask") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "someTask", builderCmdOptions.TaskName) } diff --git a/pkg/cmd/config.go b/pkg/cmd/config.go index 0b361d1631..5665e0cb26 100644 --- a/pkg/cmd/config.go +++ b/pkg/cmd/config.go @@ -51,7 +51,7 @@ func newCmdConfig(rootCmdOptions *RootCmdOptions) (*cobra.Command, *configCmdOpt cmd := cobra.Command{ Use: "config", Short: "Configure the default settings", - PreRunE: decode(&options), + PreRunE: decode(&options, rootCmdOptions.Flags), Args: options.validateArgs, RunE: options.run, } diff --git a/pkg/cmd/config_test.go b/pkg/cmd/config_test.go index 7f9cd27fc9..606e27ed29 100644 --- a/pkg/cmd/config_test.go +++ b/pkg/cmd/config_test.go @@ -27,6 +27,7 @@ import ( "github.com/apache/camel-k/v2/pkg/util/test" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) const cmdConfig = "config" @@ -37,7 +38,7 @@ func initializeConfigCmdOptions(t *testing.T, mock bool) (*configCmdOptions, *co options, rootCmd := kamelTestPreAddCommandInit() configCmdOptions := addTestConfigCmd(*options, rootCmd, mock) - kamelTestPostAddCommandInit(t, rootCmd) + kamelTestPostAddCommandInit(t, rootCmd, options) return configCmdOptions, rootCmd, *options } @@ -58,41 +59,41 @@ func addTestConfigCmd(options RootCmdOptions, rootCmd *cobra.Command, mock bool) func TestConfigNonExistingFlag(t *testing.T) { _, rootCmd, _ := initializeConfigCmdOptions(t, true) _, err := test.ExecuteCommand(rootCmd, cmdConfig, "--nonExistingFlag") - assert.NotNil(t, err) + require.Error(t, err) } func TestConfigDefaultNamespaceFlag(t *testing.T) { configCmdOptions, rootCmd, _ := initializeConfigCmdOptions(t, true) _, err := test.ExecuteCommand(rootCmd, cmdConfig, "--default-namespace", "foo") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "foo", configCmdOptions.DefaultNamespace) } func TestConfigListFlag(t *testing.T) { _, rootCmd, _ := initializeConfigCmdOptions(t, false) output, err := test.ExecuteCommand(rootCmd, cmdConfig, "--list") - assert.Nil(t, err) + require.NoError(t, err) assert.True(t, strings.Contains(output, "No settings"), "The output is unexpected: "+output) } func TestConfigFolderFlagToUsed(t *testing.T) { _, rootCmd, _ := initializeConfigCmdOptions(t, false) output, err := test.ExecuteCommand(rootCmd, cmdConfig, "--list", "--folder", "used") - assert.Nil(t, err) + require.NoError(t, err) assert.True(t, strings.Contains(output, fmt.Sprintf(" %s", DefaultConfigLocation)), "The output is unexpected: "+output) } func TestConfigFolderFlagToSub(t *testing.T) { _, rootCmd, _ := initializeConfigCmdOptions(t, false) output, err := test.ExecuteCommand(rootCmd, cmdConfig, "--list", "--folder", "sub") - assert.Nil(t, err) + require.NoError(t, err) assert.True(t, strings.Contains(output, filepath.FromSlash(fmt.Sprintf(".kamel/%s", DefaultConfigLocation))), "The output is unexpected: "+output) } func TestConfigFolderFlagToHome(t *testing.T) { _, rootCmd, _ := initializeConfigCmdOptions(t, false) output, err := test.ExecuteCommand(rootCmd, cmdConfig, "--list", "--folder", "home") - assert.Nil(t, err) + require.NoError(t, err) assert.True(t, strings.Contains(output, filepath.FromSlash(fmt.Sprintf(".kamel/%s", DefaultConfigLocation))), "The output is unexpected: "+output) } @@ -101,7 +102,7 @@ func TestConfigFolderFlagToEnv(t *testing.T) { t.Cleanup(func() { os.Unsetenv("KAMEL_CONFIG_PATH") }) _, rootCmd, _ := initializeConfigCmdOptions(t, false) output, err := test.ExecuteCommand(rootCmd, cmdConfig, "--list", "--folder", "env") - assert.Nil(t, err) + require.NoError(t, err) assert.True(t, strings.Contains(output, filepath.FromSlash(fmt.Sprintf("foo/bar/%s", DefaultConfigLocation))), "The output is unexpected: "+output) } @@ -114,7 +115,7 @@ func TestConfigFolderFlagToEnvWithConfigName(t *testing.T) { }) _, rootCmd, _ := initializeConfigCmdOptions(t, false) output, err := test.ExecuteCommand(rootCmd, cmdConfig, "--list", "--folder", "env") - assert.Nil(t, err) + require.NoError(t, err) assert.True(t, strings.Contains(output, filepath.FromSlash("/foo/bar/config.yaml")), "The output is unexpected: "+output) } @@ -124,15 +125,15 @@ func TestConfigDefaultNamespace(t *testing.T) { _, rootCmd, _ := initializeConfigCmdOptions(t, false) t.Cleanup(func() { os.Remove(DefaultConfigLocation) }) _, err = test.ExecuteCommand(rootCmd, cmdConfig, "--default-namespace", "foo") - assert.Nil(t, err) + require.NoError(t, err) _, err = os.Stat(DefaultConfigLocation) - assert.Nil(t, err, "A file at "+DefaultConfigLocation+" was expected") + require.NoError(t, err, "A file at "+DefaultConfigLocation+" was expected") output, err := test.ExecuteCommand(rootCmd, cmdConfig, "--list") - assert.Nil(t, err) + require.NoError(t, err) assert.True(t, strings.Contains(output, "foo"), "The output is unexpected: "+output) _, rootCmd, _ = initializeInstallCmdOptions(t) _, err = test.ExecuteCommand(rootCmd, cmdInstall) - assert.Nil(t, err) + require.NoError(t, err) // Check default namespace is set assert.Equal(t, "foo", rootCmd.Flag("namespace").Value.String()) } diff --git a/pkg/cmd/debug.go b/pkg/cmd/debug.go index 214b2dad6b..997ecb2184 100644 --- a/pkg/cmd/debug.go +++ b/pkg/cmd/debug.go @@ -46,7 +46,7 @@ func newCmdDebug(rootCmdOptions *RootCmdOptions) (*cobra.Command, *debugCmdOptio Short: "Debug an integration running on Kubernetes", Long: `Set an integration running on the Kubernetes cluster in debug mode and forward ports in order to connect a remote debugger running on the local host.`, Args: options.validateArgs, - PreRunE: decode(&options), + PreRunE: decode(&options, options.Flags), RunE: options.run, } diff --git a/pkg/cmd/delete.go b/pkg/cmd/delete.go index 5ce21e727e..acf480b363 100644 --- a/pkg/cmd/delete.go +++ b/pkg/cmd/delete.go @@ -24,6 +24,7 @@ import ( "strconv" v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" + "github.com/apache/camel-k/v2/pkg/apis/camel/v1alpha1" "github.com/apache/camel-k/v2/pkg/client" "github.com/apache/camel-k/v2/pkg/util/kubernetes" @@ -41,7 +42,7 @@ func newCmdDelete(rootCmdOptions *RootCmdOptions) (*cobra.Command, *deleteCmdOpt cmd := cobra.Command{ Use: "delete [integration1] [integration2] ...", Short: "Delete integrations deployed on Kubernetes", - PreRunE: decode(&options), + PreRunE: decode(&options, options.Flags), RunE: func(cmd *cobra.Command, args []string) error { if err := options.validate(args); err != nil { return err @@ -136,13 +137,22 @@ func getIntegration(ctx context.Context, c client.Client, name string, namespace } func deleteIntegration(ctx context.Context, cmd *cobra.Command, c client.Client, integration *v1.Integration) error { - deleted, binding, err := deletePipeIfExists(ctx, c, integration) + deletedPipes, pipe, err := deletePipeIfExists(ctx, c, integration) if err != nil { return err } - if deleted { + if deletedPipes { // Deleting Pipe will automatically clean up the integration - fmt.Fprintln(cmd.OutOrStdout(), "Pipe "+binding+" deleted") + fmt.Fprintln(cmd.OutOrStdout(), "Pipe "+pipe+" deleted") + return nil + } + deletedKameletBindings, klb, err := deleteKameletBindingIfExists(ctx, c, integration) + if err != nil { + return err + } + if deletedKameletBindings { + // Deleting KameletBinding will automatically clean up the integration + fmt.Fprintln(cmd.OutOrStdout(), "KameletBinding "+klb+" deleted") return nil } return c.Delete(ctx, integration) @@ -172,6 +182,30 @@ func deletePipeIfExists(ctx context.Context, c client.Client, integration *v1.In return err == nil, name, err } +func deleteKameletBindingIfExists(ctx context.Context, c client.Client, integration *v1.Integration) (bool, string, error) { + kind, name := findCreator(integration) + if kind != v1alpha1.KameletBindingKind || name == "" { + return false, "", nil + } + + binding := v1alpha1.KameletBinding{ + TypeMeta: metav1.TypeMeta{ + Kind: kind, + APIVersion: v1.SchemeGroupVersion.String(), + }, + ObjectMeta: metav1.ObjectMeta{ + Namespace: integration.Namespace, + Name: name, + }, + } + err := c.Delete(ctx, &binding) + if k8errors.IsNotFound(err) { + // Simply skip if binding doesn't exist (could be deleted already) + return false, name, nil + } + return err == nil, name, err +} + func findCreator(integration *v1.Integration) (string, string) { kind := integration.GetLabels()[kubernetes.CamelCreatorLabelKind] name := integration.GetLabels()[kubernetes.CamelCreatorLabelName] diff --git a/pkg/cmd/delete_test.go b/pkg/cmd/delete_test.go index e2a1084234..5388c034e7 100644 --- a/pkg/cmd/delete_test.go +++ b/pkg/cmd/delete_test.go @@ -23,6 +23,7 @@ import ( "github.com/apache/camel-k/v2/pkg/util/test" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) const cmdDelete = "delete" @@ -33,7 +34,7 @@ func initializeDeleteCmdOptions(t *testing.T) (*deleteCmdOptions, *cobra.Command options, rootCmd := kamelTestPreAddCommandInit() deleteCmdOptions := addTestDeleteCmd(*options, rootCmd) - kamelTestPostAddCommandInit(t, rootCmd) + kamelTestPostAddCommandInit(t, rootCmd, options) return deleteCmdOptions, rootCmd, *options } @@ -55,12 +56,12 @@ func addTestDeleteCmd(options RootCmdOptions, rootCmd *cobra.Command) *deleteCmd func TestDeleteNonExistingFlag(t *testing.T) { _, rootCmd, _ := initializeDeleteCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdDelete, "--nonExistingFlag") - assert.NotNil(t, err) + require.Error(t, err) } func TestDeleteAllFlag(t *testing.T) { deleteCmdOptions, rootCmd, _ := initializeDeleteCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdDelete, "--all") - assert.Nil(t, err) - assert.Equal(t, true, deleteCmdOptions.DeleteAll) + require.NoError(t, err) + assert.True(t, deleteCmdOptions.DeleteAll) } diff --git a/pkg/cmd/describe_integration.go b/pkg/cmd/describe_integration.go index c18b219181..5917173b97 100644 --- a/pkg/cmd/describe_integration.go +++ b/pkg/cmd/describe_integration.go @@ -41,7 +41,7 @@ func newDescribeIntegrationCmd(rootCmdOptions *RootCmdOptions) (*cobra.Command, Aliases: []string{"it"}, Short: "Describe an Integration", Long: `Describe an Integration.`, - PreRunE: decode(&options), + PreRunE: decode(&options, options.Flags), RunE: func(cmd *cobra.Command, args []string) error { if err := options.validate(cmd, args); err != nil { return err diff --git a/pkg/cmd/describe_kamelet.go b/pkg/cmd/describe_kamelet.go index b8601b8b79..a0464c8e1f 100644 --- a/pkg/cmd/describe_kamelet.go +++ b/pkg/cmd/describe_kamelet.go @@ -42,7 +42,7 @@ func newDescribeKameletCmd(rootCmdOptions *RootCmdOptions) (*cobra.Command, *des Aliases: []string{"kl"}, Short: "Describe a Kamelet", Long: `Describe a Kamelet.`, - PreRunE: decode(&options), + PreRunE: decode(&options, options.Flags), RunE: func(cmd *cobra.Command, args []string) error { if err := options.validate(cmd, args); err != nil { return err diff --git a/pkg/cmd/describe_kit.go b/pkg/cmd/describe_kit.go index e5f01da736..ea5346e822 100644 --- a/pkg/cmd/describe_kit.go +++ b/pkg/cmd/describe_kit.go @@ -40,7 +40,7 @@ func newDescribeKitCmd(rootCmdOptions *RootCmdOptions) (*cobra.Command, *describ Aliases: []string{"ik"}, Short: "Describe an Integration Kit", Long: `Describe an Integration Kit.`, - PreRunE: decode(&options), + PreRunE: decode(&options, options.Flags), RunE: func(cmd *cobra.Command, args []string) error { if err := options.validate(cmd, args); err != nil { return err diff --git a/pkg/cmd/describe_platform.go b/pkg/cmd/describe_platform.go index 9b716d8a5f..72692e3b1e 100644 --- a/pkg/cmd/describe_platform.go +++ b/pkg/cmd/describe_platform.go @@ -40,7 +40,7 @@ func newDescribePlatformCmd(rootCmdOptions *RootCmdOptions) (*cobra.Command, *de Aliases: []string{"ip"}, Short: "Describe an Integration Platform", Long: `Describe an Integration Platform.`, - PreRunE: decode(&options), + PreRunE: decode(&options, options.Flags), RunE: func(cmd *cobra.Command, args []string) error { if err := options.validate(cmd, args); err != nil { return err diff --git a/pkg/cmd/dump.go b/pkg/cmd/dump.go index b67637f692..d9351d7f01 100644 --- a/pkg/cmd/dump.go +++ b/pkg/cmd/dump.go @@ -45,7 +45,7 @@ func newCmdDump(rootCmdOptions *RootCmdOptions) (*cobra.Command, *dumpCmdOptions Use: "dump [filename]", Short: "Dump the state of namespace", Long: `Dump the state of currently used namespace. If no filename will be specified, the output will be on stdout`, - PreRunE: decode(&options), + PreRunE: decode(&options, options.Flags), RunE: options.dump, } diff --git a/pkg/cmd/get.go b/pkg/cmd/get.go index a560a9ed7b..e6445069d3 100644 --- a/pkg/cmd/get.go +++ b/pkg/cmd/get.go @@ -42,7 +42,7 @@ func newCmdGet(rootCmdOptions *RootCmdOptions) (*cobra.Command, *getCmdOptions) Use: "get [integration]", Short: "Get integrations deployed on Kubernetes", Long: `Get the status of integrations deployed on Kubernetes.`, - PreRunE: decode(&options), + PreRunE: decode(&options, options.Flags), RunE: options.run, } diff --git a/pkg/cmd/install.go b/pkg/cmd/install.go index 80a0f66fe5..635d1a04d7 100644 --- a/pkg/cmd/install.go +++ b/pkg/cmd/install.go @@ -30,8 +30,6 @@ import ( platformutil "github.com/apache/camel-k/v2/pkg/platform" "github.com/spf13/cobra" - "github.com/spf13/viper" - "go.uber.org/multierr" corev1 "k8s.io/api/core/v1" @@ -277,7 +275,7 @@ func (o *installCmdOptions) tryInstallViaOLM( if err != nil { return false, err } - if olmAvailable, err := olm.IsAPIAvailable(o.Context, olmClient, o.Namespace); err != nil { + if olmAvailable, err := olm.IsAPIAvailable(olmClient); err != nil { return false, fmt.Errorf("error while checking OLM availability. Run with '--olm=false' to skip this check: %w", err) } else if !olmAvailable { @@ -313,7 +311,14 @@ func (o *installCmdOptions) tryInstallViaOLM( } func (o *installCmdOptions) installOperator(cmd *cobra.Command, output *kubernetes.Collection, olm bool) error { - operatorID, err := getOperatorID(o.EnvVars) + var operatorID string + var err error + if o.OperatorID != "" { + operatorID = o.OperatorID + } else { + operatorID, err = getOperatorID(o.EnvVars) + } + if err != nil { return err } @@ -669,25 +674,26 @@ func (o *installCmdOptions) postRun(cmd *cobra.Command, _ []string) error { func (o *installCmdOptions) decode(cmd *cobra.Command, _ []string) error { path := pathToRoot(cmd) - if err := decodeKey(o, path); err != nil { + + if err := decodeKey(o, path, o.Flags.AllSettings()); err != nil { return err } - o.registry.Address = viper.GetString(path + ".registry") - o.registry.Organization = viper.GetString(path + ".organization") - o.registry.Secret = viper.GetString(path + ".registry-secret") - o.registry.Insecure = viper.GetBool(path + ".registry-insecure") - o.registryAuth.Username = viper.GetString(path + ".registry-auth-username") - o.registryAuth.Password = viper.GetString(path + ".registry-auth-password") - o.registryAuth.Server = viper.GetString(path + ".registry-auth-server") + o.registry.Address = o.Flags.GetString(path + ".registry") + o.registry.Organization = o.Flags.GetString(path + ".organization") + o.registry.Secret = o.Flags.GetString(path + ".registry-secret") + o.registry.Insecure = o.Flags.GetBool(path + ".registry-insecure") + o.registryAuth.Username = o.Flags.GetString(path + ".registry-auth-username") + o.registryAuth.Password = o.Flags.GetString(path + ".registry-auth-password") + o.registryAuth.Server = o.Flags.GetString(path + ".registry-auth-server") - o.olmOptions.OperatorName = viper.GetString(path + ".olm-operator-name") - o.olmOptions.Package = viper.GetString(path + ".olm-package") - o.olmOptions.Channel = viper.GetString(path + ".olm-channel") - o.olmOptions.Source = viper.GetString(path + ".olm-source") - o.olmOptions.SourceNamespace = viper.GetString(path + ".olm-source-namespace") - o.olmOptions.StartingCSV = viper.GetString(path + ".olm-starting-csv") - o.olmOptions.GlobalNamespace = viper.GetString(path + ".olm-global-namespace") + o.olmOptions.OperatorName = o.Flags.GetString(path + ".olm-operator-name") + o.olmOptions.Package = o.Flags.GetString(path + ".olm-package") + o.olmOptions.Channel = o.Flags.GetString(path + ".olm-channel") + o.olmOptions.Source = o.Flags.GetString(path + ".olm-source") + o.olmOptions.SourceNamespace = o.Flags.GetString(path + ".olm-source-namespace") + o.olmOptions.StartingCSV = o.Flags.GetString(path + ".olm-starting-csv") + o.olmOptions.GlobalNamespace = o.Flags.GetString(path + ".olm-global-namespace") return nil } @@ -785,10 +791,6 @@ func (o *installCmdOptions) validate(_ *cobra.Command, _ []string) error { return result } -func decodeMavenSettings(mavenSettings string) (v1.ValueSource, error) { - return v1.DecodeValueSource(mavenSettings, "settings.xml", "illegal maven setting definition, syntax: configmap|secret:resource-name[/settings path]") -} - func decodeSecretKeySelector(secretKey string) (*corev1.SecretKeySelector, error) { r := regexp.MustCompile(`^([a-zA-Z0-9-]*)/([a-zA-Z0-9].*)$`) diff --git a/pkg/cmd/install_test.go b/pkg/cmd/install_test.go index 09f778bee2..6fed126d13 100644 --- a/pkg/cmd/install_test.go +++ b/pkg/cmd/install_test.go @@ -22,6 +22,7 @@ import ( "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" "github.com/apache/camel-k/v2/pkg/util/test" @@ -35,7 +36,7 @@ func initializeInstallCmdOptions(t *testing.T) (*installCmdOptions, *cobra.Comma options, rootCmd := kamelTestPreAddCommandInit() installCmdOptions := addTestInstallCmd(*options, rootCmd) - kamelTestPostAddCommandInit(t, rootCmd) + kamelTestPostAddCommandInit(t, rootCmd, options) return installCmdOptions, rootCmd, *options } @@ -57,18 +58,18 @@ func addTestInstallCmd(options RootCmdOptions, rootCmd *cobra.Command) *installC func TestInstallNoFlag(t *testing.T) { installCmdOptions, rootCmd, _ := initializeInstallCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdInstall) - assert.Nil(t, err) + require.NoError(t, err) // Check default expected values - assert.Equal(t, false, installCmdOptions.Wait) - assert.Equal(t, false, installCmdOptions.ClusterSetupOnly) - assert.Equal(t, false, installCmdOptions.SkipOperatorSetup) - assert.Equal(t, false, installCmdOptions.SkipClusterSetup) - assert.Equal(t, false, installCmdOptions.SkipDefaultKameletsSetup) - assert.Equal(t, false, installCmdOptions.ExampleSetup) - assert.Equal(t, false, installCmdOptions.Global) - assert.Equal(t, false, installCmdOptions.Save) - assert.Equal(t, false, installCmdOptions.Force) - assert.Equal(t, true, installCmdOptions.Olm) + assert.False(t, installCmdOptions.Wait) + assert.False(t, installCmdOptions.ClusterSetupOnly) + assert.False(t, installCmdOptions.SkipOperatorSetup) + assert.False(t, installCmdOptions.SkipClusterSetup) + assert.False(t, installCmdOptions.SkipDefaultKameletsSetup) + assert.False(t, installCmdOptions.ExampleSetup) + assert.False(t, installCmdOptions.Global) + assert.False(t, installCmdOptions.Save) + assert.False(t, installCmdOptions.Force) + assert.True(t, installCmdOptions.Olm) assert.Equal(t, "", installCmdOptions.olmOptions.OperatorName) assert.Equal(t, "", installCmdOptions.olmOptions.Package) assert.Equal(t, "", installCmdOptions.olmOptions.Channel) @@ -76,97 +77,97 @@ func TestInstallNoFlag(t *testing.T) { assert.Equal(t, "", installCmdOptions.olmOptions.SourceNamespace) assert.Equal(t, "", installCmdOptions.olmOptions.GlobalNamespace) assert.Equal(t, int32(8081), installCmdOptions.HealthPort) - assert.Equal(t, false, installCmdOptions.Monitoring) + assert.False(t, installCmdOptions.Monitoring) assert.Equal(t, int32(8080), installCmdOptions.MonitoringPort) } func TestInstallNonExistingFlag(t *testing.T) { _, rootCmd, _ := initializeInstallCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdInstall, "--nonExistingFlag") - assert.NotNil(t, err) + require.Error(t, err) } func TestInstallBaseImageFlag(t *testing.T) { installCmdOptions, rootCmd, _ := initializeInstallCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdInstall, "--base-image", "someString") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "someString", installCmdOptions.BaseImage) } func TestInstallBuildPublishStrategyFlag(t *testing.T) { installCmdOptions, rootCmd, _ := initializeInstallCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdInstall, "--build-publish-strategy", "someString") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "someString", installCmdOptions.BuildPublishStrategy) } func TestInstallBuildStrategyFlag(t *testing.T) { installCmdOptions, rootCmd, _ := initializeInstallCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdInstall, "--build-strategy", "someString") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "someString", installCmdOptions.BuildStrategy) } func TestInstallBuildOrderStrategyFlag(t *testing.T) { installCmdOptions, rootCmd, _ := initializeInstallCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdInstall, "--build-order-strategy", "someString") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "someString", installCmdOptions.BuildOrderStrategy) } func TestInstallBuildTimeoutFlag(t *testing.T) { installCmdOptions, rootCmd, _ := initializeInstallCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdInstall, "--build-timeout", "10") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "10", installCmdOptions.BuildTimeout) } func TestInstallClusterSetupFlag(t *testing.T) { installCmdOptions, rootCmd, _ := initializeInstallCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdInstall, "--cluster-setup") - assert.Nil(t, err) - assert.Equal(t, true, installCmdOptions.ClusterSetupOnly) + require.NoError(t, err) + assert.True(t, installCmdOptions.ClusterSetupOnly) } func TestInstallClusterTypeFlag(t *testing.T) { installCmdOptions, rootCmd, _ := initializeInstallCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdInstall, "--cluster-type", "Kubernetes") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "Kubernetes", installCmdOptions.ClusterType) } func TestInstallExampleFlag(t *testing.T) { installCmdOptions, rootCmd, _ := initializeInstallCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdInstall, "--example") - assert.Nil(t, err) - assert.Equal(t, true, installCmdOptions.ExampleSetup) + require.NoError(t, err) + assert.True(t, installCmdOptions.ExampleSetup) } func TestInstallForceFlag(t *testing.T) { installCmdOptions, rootCmd, _ := initializeInstallCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdInstall, "--force") - assert.Nil(t, err) - assert.Equal(t, true, installCmdOptions.Force) + require.NoError(t, err) + assert.True(t, installCmdOptions.Force) } func TestInstallGlobalFlag(t *testing.T) { installCmdOptions, rootCmd, _ := initializeInstallCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdInstall, "--global") - assert.Nil(t, err) - assert.Equal(t, true, installCmdOptions.Global) + require.NoError(t, err) + assert.True(t, installCmdOptions.Global) } func TestInstallHealthFlag(t *testing.T) { installCmdOptions, rootCmd, _ := initializeInstallCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdInstall, "--health-port", "7777") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, int32(7777), installCmdOptions.HealthPort) } func TestInstallLocalRepositoryFlag(t *testing.T) { installCmdOptions, rootCmd, _ := initializeInstallCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdInstall, "--maven-local-repository", "someString") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "someString", installCmdOptions.MavenLocalRepository) } @@ -175,7 +176,7 @@ func TestInstallMavenRepositoryFlag(t *testing.T) { _, err := test.ExecuteCommand(rootCmd, cmdInstall, "--maven-repository", "someString1", "--maven-repository", "someString2") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "someString1", installCmdOptions.MavenRepositories[0]) assert.Equal(t, "someString2", installCmdOptions.MavenRepositories[1]) } @@ -183,7 +184,7 @@ func TestInstallMavenRepositoryFlag(t *testing.T) { func TestInstallMavenSettingsFlag(t *testing.T) { installCmdOptions, rootCmd, _ := initializeInstallCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdInstall, "--maven-settings", "someString") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "someString", installCmdOptions.MavenSettings) } @@ -192,16 +193,16 @@ func TestInstallMonitoringFlag(t *testing.T) { _, err := test.ExecuteCommand(rootCmd, cmdInstall, "--monitoring", "--monitoring-port", "7777") - assert.Nil(t, err) - assert.Equal(t, true, installCmdOptions.Monitoring) + require.NoError(t, err) + assert.True(t, installCmdOptions.Monitoring) assert.Equal(t, int32(7777), installCmdOptions.MonitoringPort) } func TestInstallOlmFalseFlag(t *testing.T) { installCmdOptions, rootCmd, _ := initializeInstallCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdInstall, "--olm=false") - assert.Nil(t, err) - assert.Equal(t, false, installCmdOptions.Olm) + require.NoError(t, err) + assert.False(t, installCmdOptions.Olm) } func TestInstallOlmTrueNonDefaultFlag(t *testing.T) { @@ -214,8 +215,8 @@ func TestInstallOlmTrueNonDefaultFlag(t *testing.T) { "--olm-source", "olmSource", "--olm-source-namespace", "olmSourceNamespace", "--olm-starting-csv", "olmStartingCSV") - assert.Nil(t, err) - assert.Equal(t, true, installCmdOptions.Olm) + require.NoError(t, err) + assert.True(t, installCmdOptions.Olm) assert.Equal(t, "olmChannel", installCmdOptions.olmOptions.Channel) assert.Equal(t, "olmGlobalNamespace", installCmdOptions.olmOptions.GlobalNamespace) assert.Equal(t, "olmOperatorName", installCmdOptions.olmOptions.OperatorName) @@ -228,21 +229,21 @@ func TestInstallOlmTrueNonDefaultFlag(t *testing.T) { func TestInstallOperatorImageFlag(t *testing.T) { installCmdOptions, rootCmd, _ := initializeInstallCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdInstall, "--operator-image", "someString") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "someString", installCmdOptions.OperatorImage) } func TestInstallOperatorImagePullPolicyFlag(t *testing.T) { installCmdOptions, rootCmd, _ := initializeInstallCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdInstall, "--operator-image-pull-policy", "someString") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "someString", installCmdOptions.OperatorImagePullPolicy) } func TestInstallOutputFlag(t *testing.T) { installCmdOptions, rootCmd, _ := initializeInstallCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdInstall, "--output", "yaml") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "yaml", installCmdOptions.OutputFormat) } @@ -251,7 +252,7 @@ func TestInstallPropertyFlag(t *testing.T) { _, err := test.ExecuteCommand(rootCmd, cmdInstall, "--maven-property", "someString1", "--maven-property", "someString2") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "someString1", installCmdOptions.MavenProperties[0]) assert.Equal(t, "someString2", installCmdOptions.MavenProperties[1]) } @@ -263,10 +264,10 @@ func TestInstallRegistryFlag(t *testing.T) { "--organization", "organization", "--registry-insecure", "--registry-secret", "secret") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "registry", installCmdOptions.registry.Address) assert.Equal(t, "organization", installCmdOptions.registry.Organization) - assert.Equal(t, true, installCmdOptions.registry.Insecure) + assert.True(t, installCmdOptions.registry.Insecure) assert.Equal(t, "secret", installCmdOptions.registry.Secret) } @@ -276,7 +277,7 @@ func TestInstallRegistryWithAuthFlag(t *testing.T) { "--registry-auth-password", "authPassword", "--registry-auth-server", "authServer", "--registry-auth-username", "authUsername") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "authPassword", installCmdOptions.registryAuth.Password) assert.Equal(t, "authServer", installCmdOptions.registryAuth.Server) assert.Equal(t, "authUsername", installCmdOptions.registryAuth.Username) @@ -285,57 +286,57 @@ func TestInstallRegistryWithAuthFlag(t *testing.T) { func TestInstallRuntimeVersionFlag(t *testing.T) { installCmdOptions, rootCmd, _ := initializeInstallCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdInstall, "--runtime-version", "1.3.0") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "1.3.0", installCmdOptions.RuntimeVersion) } func TestInstallSaveFlag(t *testing.T) { installCmdOptions, rootCmd, _ := initializeInstallCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdInstall, "--save") - assert.Nil(t, err) - assert.Equal(t, true, installCmdOptions.Save) + require.NoError(t, err) + assert.True(t, installCmdOptions.Save) } func TestInstallSkipClusterSetupFlag(t *testing.T) { installCmdOptions, rootCmd, _ := initializeInstallCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdInstall, "--skip-cluster-setup") - assert.Nil(t, err) - assert.Equal(t, true, installCmdOptions.SkipClusterSetup) + require.NoError(t, err) + assert.True(t, installCmdOptions.SkipClusterSetup) } func TestInstallSkipOperatorSetupFlag(t *testing.T) { installCmdOptions, rootCmd, _ := initializeInstallCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdInstall, "--skip-operator-setup") - assert.Nil(t, err) - assert.Equal(t, true, installCmdOptions.SkipOperatorSetup) + require.NoError(t, err) + assert.True(t, installCmdOptions.SkipOperatorSetup) } func TestInstallSkipRegistrySetupFlag(t *testing.T) { installCmdOptions, rootCmd, _ := initializeInstallCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdInstall, "--skip-registry-setup") - assert.Nil(t, err) - assert.Equal(t, true, installCmdOptions.SkipRegistrySetup) + require.NoError(t, err) + assert.True(t, installCmdOptions.SkipRegistrySetup) } func TestInstallSkipDefaultKameletsSetupFlag(t *testing.T) { installCmdOptions, rootCmd, _ := initializeInstallCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdInstall, "--skip-default-kamelets-setup") - assert.Nil(t, err) - assert.Equal(t, true, installCmdOptions.SkipDefaultKameletsSetup) + require.NoError(t, err) + assert.True(t, installCmdOptions.SkipDefaultKameletsSetup) } func TestInstallTraitProfileFlag(t *testing.T) { installCmdOptions, rootCmd, _ := initializeInstallCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdInstall, "--trait-profile", "someString") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "someString", installCmdOptions.TraitProfile) } func TestInstallWaitFlag(t *testing.T) { installCmdOptions, rootCmd, _ := initializeInstallCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdInstall, "--wait") - assert.Nil(t, err) - assert.Equal(t, true, installCmdOptions.Wait) + require.NoError(t, err) + assert.True(t, installCmdOptions.Wait) } func TestDecodeMavenSettings(t *testing.T) { @@ -344,13 +345,13 @@ func TestDecodeMavenSettings(t *testing.T) { // ConfigMap val, err = decodeMavenSettings("configmap:maven-settings/s.xml") - assert.Nil(t, err) + require.NoError(t, err) assert.Nil(t, val.SecretKeyRef) assert.Equal(t, "maven-settings", val.ConfigMapKeyRef.Name) assert.Equal(t, "s.xml", val.ConfigMapKeyRef.Key) val, err = decodeMavenSettings("configmap:maven-settings") - assert.Nil(t, err) + require.NoError(t, err) assert.Nil(t, val.SecretKeyRef) assert.Equal(t, "maven-settings", val.ConfigMapKeyRef.Name) // Default name @@ -358,13 +359,13 @@ func TestDecodeMavenSettings(t *testing.T) { // Secrets val, err = decodeMavenSettings("secret:maven-settings-secret/s.xml") - assert.Nil(t, err) + require.NoError(t, err) assert.Nil(t, val.ConfigMapKeyRef) assert.Equal(t, "maven-settings-secret", val.SecretKeyRef.Name) assert.Equal(t, "s.xml", val.SecretKeyRef.Key) val, err = decodeMavenSettings("secret:maven-settings-secret") - assert.Nil(t, err) + require.NoError(t, err) assert.Nil(t, val.ConfigMapKeyRef) assert.Equal(t, "maven-settings-secret", val.SecretKeyRef.Name) // Default name @@ -372,9 +373,9 @@ func TestDecodeMavenSettings(t *testing.T) { // Errors _, err = decodeMavenSettings("something:maven-settings-secret/s.xml") - assert.NotNil(t, err) + require.Error(t, err) _, err = decodeMavenSettings("secret") - assert.NotNil(t, err) + require.Error(t, err) } func TestInstallTolerationFlag(t *testing.T) { @@ -382,7 +383,7 @@ func TestInstallTolerationFlag(t *testing.T) { _, err := test.ExecuteCommand(rootCmd, cmdInstall, "--toleration", "key1=value1:NoSchedule", "--toleration", "key2=value2:NoExecute") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "key1=value1:NoSchedule", installCmdOptions.Tolerations[0]) assert.Equal(t, "key2=value2:NoExecute", installCmdOptions.Tolerations[1]) } @@ -391,69 +392,73 @@ func TestInstallMavenExtension(t *testing.T) { installCmdOptions, rootCmd, _ := initializeInstallCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdInstall, "--maven-extension", "fi.yle.tools:aws-maven:1.4.2") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "fi.yle.tools:aws-maven:1.4.2", installCmdOptions.MavenExtensions[0]) } func TestInstallInfoLogging(t *testing.T) { installCmdOptions, rootCmd, _ := initializeInstallCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdInstall) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "info", installCmdOptions.LogLevel) } func TestInstallInfoLogging1(t *testing.T) { installCmdOptions, rootCmd, _ := initializeInstallCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdInstall, "-z", "0") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "0", installCmdOptions.LogLevel) } func TestInstallInfoLogging2(t *testing.T) { installCmdOptions, rootCmd, _ := initializeInstallCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdInstall, "--log-level", "0") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "0", installCmdOptions.LogLevel) } func TestInstallInfoLogging3(t *testing.T) { installCmdOptions, rootCmd, _ := initializeInstallCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdInstall, "-z", "info") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "info", installCmdOptions.LogLevel) } func TestInstallInfoLogging4(t *testing.T) { installCmdOptions, rootCmd, _ := initializeInstallCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdInstall, "--log-level", "info") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "info", installCmdOptions.LogLevel) } func TestInstallDebugLogging1(t *testing.T) { installCmdOptions, rootCmd, _ := initializeInstallCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdInstall, "-z", "1") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "1", installCmdOptions.LogLevel) } func TestInstallDebugLogging2(t *testing.T) { installCmdOptions, rootCmd, _ := initializeInstallCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdInstall, "--log-level", "1") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "1", installCmdOptions.LogLevel) } func TestInstallDebugLogging3(t *testing.T) { installCmdOptions, rootCmd, _ := initializeInstallCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdInstall, "-z", "debug") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "debug", installCmdOptions.LogLevel) } func TestInstallDebugLogging4(t *testing.T) { installCmdOptions, rootCmd, _ := initializeInstallCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdInstall, "--log-level", "debug") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "debug", installCmdOptions.LogLevel) } + +func decodeMavenSettings(mavenSettings string) (v1.ValueSource, error) { + return v1.DecodeValueSource(mavenSettings, "settings.xml", "illegal maven setting definition, syntax: configmap|secret:resource-name[/settings path]") +} diff --git a/pkg/cmd/kamelet_add_repo.go b/pkg/cmd/kamelet_add_repo.go index 870955cd73..2244764e1a 100644 --- a/pkg/cmd/kamelet_add_repo.go +++ b/pkg/cmd/kamelet_add_repo.go @@ -43,7 +43,7 @@ func newKameletAddRepoCmd(rootCmdOptions *RootCmdOptions) (*cobra.Command, *kame Use: "add-repo github:owner/repo[/path_to_kamelets_folder][@version] ...", Short: "Add a Kamelet repository", Long: `Add a Kamelet repository.`, - PreRunE: decode(&options), + PreRunE: decode(&options, options.Flags), RunE: func(cmd *cobra.Command, args []string) error { if err := options.validate(args); err != nil { return err diff --git a/pkg/cmd/kamelet_add_repo_test.go b/pkg/cmd/kamelet_add_repo_test.go index 6ce7199195..f2f2aa6f0d 100644 --- a/pkg/cmd/kamelet_add_repo_test.go +++ b/pkg/cmd/kamelet_add_repo_test.go @@ -21,7 +21,7 @@ import ( "testing" "github.com/spf13/cobra" - "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" "github.com/apache/camel-k/v2/pkg/util/test" @@ -35,7 +35,7 @@ func initializeKameletAddRepoCmdOptions(t *testing.T) (*kameletAddRepoCommandOpt options, rootCmd := kamelTestPreAddCommandInit() kameletAddRepoCommandOptions := addTestKameletAddRepoCmd(*options, rootCmd) - kamelTestPostAddCommandInit(t, rootCmd) + kamelTestPostAddCommandInit(t, rootCmd, options) return kameletAddRepoCommandOptions, rootCmd, *options } @@ -57,34 +57,34 @@ func addTestKameletAddRepoCmd(options RootCmdOptions, rootCmd *cobra.Command) *k func TestKameletAddRepoNoFlag(t *testing.T) { _, rootCmd, _ := initializeKameletAddRepoCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdKameletAddRepo, "foo") - assert.Nil(t, err) + require.NoError(t, err) } func TestKameletAddRepoNonExistingFlag(t *testing.T) { _, rootCmd, _ := initializeKameletAddRepoCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdKameletAddRepo, "--nonExistingFlag", "foo") - assert.NotNil(t, err) + require.Error(t, err) } func TestKameletAddRepoInvalidRepositoryURI(t *testing.T) { repositories := []v1.KameletRepositorySpec{} - assert.NotNil(t, checkURI("foo", repositories)) - assert.NotNil(t, checkURI("github", repositories)) - assert.NotNil(t, checkURI("github:", repositories)) - assert.NotNil(t, checkURI("github:foo", repositories)) - assert.NotNil(t, checkURI("github:foo/", repositories)) + require.Error(t, checkURI("foo", repositories)) + require.Error(t, checkURI("github", repositories)) + require.Error(t, checkURI("github:", repositories)) + require.Error(t, checkURI("github:foo", repositories)) + require.Error(t, checkURI("github:foo/", repositories)) } func TestKameletAddRepoValidRepositoryURI(t *testing.T) { repositories := []v1.KameletRepositorySpec{} - assert.Nil(t, checkURI("github:foo/bar", repositories)) - assert.Nil(t, checkURI("github:foo/bar/some/path", repositories)) - assert.Nil(t, checkURI("github:foo/bar@1.0", repositories)) - assert.Nil(t, checkURI("github:foo/bar/some/path@1.0", repositories)) + require.NoError(t, checkURI("github:foo/bar", repositories)) + require.NoError(t, checkURI("github:foo/bar/some/path", repositories)) + require.NoError(t, checkURI("github:foo/bar@1.0", repositories)) + require.NoError(t, checkURI("github:foo/bar/some/path@1.0", repositories)) } func TestKameletAddRepoDuplicateRepositoryURI(t *testing.T) { repositories := []v1.KameletRepositorySpec{{URI: "github:foo/bar"}} - assert.NotNil(t, checkURI("github:foo/bar", repositories)) - assert.Nil(t, checkURI("github:foo/bar2", repositories)) + require.Error(t, checkURI("github:foo/bar", repositories)) + require.NoError(t, checkURI("github:foo/bar2", repositories)) } diff --git a/pkg/cmd/kamelet_delete.go b/pkg/cmd/kamelet_delete.go index 0c0fd9d739..408ca3fdb4 100644 --- a/pkg/cmd/kamelet_delete.go +++ b/pkg/cmd/kamelet_delete.go @@ -37,7 +37,7 @@ func newKameletDeleteCmd(rootCmdOptions *RootCmdOptions) (*cobra.Command, *kamel cmd := cobra.Command{ Use: "delete [Kamelet1] [Kamelet2] ...", Short: "Delete Kamelets deployed on Kubernetes", - PreRunE: decode(&options), + PreRunE: decode(&options, options.Flags), RunE: func(cmd *cobra.Command, args []string) error { if err := options.validate(args); err != nil { return err diff --git a/pkg/cmd/kamelet_get.go b/pkg/cmd/kamelet_get.go index 707e300676..0f2e833514 100644 --- a/pkg/cmd/kamelet_get.go +++ b/pkg/cmd/kamelet_get.go @@ -39,7 +39,7 @@ func newKameletGetCmd(rootCmdOptions *RootCmdOptions) (*cobra.Command, *kameletG Use: "get", Short: "Get defined Kamelet", Long: `Get defined Kamelet.`, - PreRunE: decode(&options), + PreRunE: decode(&options, options.Flags), RunE: func(cmd *cobra.Command, args []string) error { if err := options.validate(); err != nil { return err diff --git a/pkg/cmd/kamelet_remove_repo.go b/pkg/cmd/kamelet_remove_repo.go index f3de5e0837..f521d27e36 100644 --- a/pkg/cmd/kamelet_remove_repo.go +++ b/pkg/cmd/kamelet_remove_repo.go @@ -36,7 +36,7 @@ func newKameletRemoveRepoCmd(rootCmdOptions *RootCmdOptions) (*cobra.Command, *k Use: "remove-repo github:owner/repo[/path_to_kamelets_folder][@version] ...", Short: "Remove a Kamelet repository", Long: `Remove a Kamelet repository.`, - PreRunE: decode(&options), + PreRunE: decode(&options, options.Flags), RunE: func(cmd *cobra.Command, args []string) error { if err := options.validate(args); err != nil { return err diff --git a/pkg/cmd/kamelet_remove_repo_test.go b/pkg/cmd/kamelet_remove_repo_test.go index 10d7ce71be..8b0d06acf7 100644 --- a/pkg/cmd/kamelet_remove_repo_test.go +++ b/pkg/cmd/kamelet_remove_repo_test.go @@ -22,6 +22,7 @@ import ( "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" "github.com/apache/camel-k/v2/pkg/util/test" @@ -35,7 +36,7 @@ func initializeKameletRemoveRepoCmdOptions(t *testing.T) (*kameletRemoveRepoComm options, rootCmd := kamelTestPreAddCommandInit() kameletRemoveRepoCommandOptions := addTestKameletRemoveRepoCmd(*options, rootCmd) - kamelTestPostAddCommandInit(t, rootCmd) + kamelTestPostAddCommandInit(t, rootCmd, options) return kameletRemoveRepoCommandOptions, rootCmd, *options } @@ -57,30 +58,30 @@ func addTestKameletRemoveRepoCmd(options RootCmdOptions, rootCmd *cobra.Command) func TestKameletRemoveRepoNoFlag(t *testing.T) { _, rootCmd, _ := initializeKameletRemoveRepoCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdKameletRemoveRepo, "foo") - assert.Nil(t, err) + require.NoError(t, err) } func TestKameletRemoveRepoNonExistingFlag(t *testing.T) { _, rootCmd, _ := initializeKameletRemoveRepoCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdKameletRemoveRepo, "--nonExistingFlag", "foo") - assert.NotNil(t, err) + require.Error(t, err) } func TestKameletRemoveRepoURINotFoundEmpty(t *testing.T) { repositories := []v1.KameletRepositorySpec{} _, err := getURIIndex("foo", repositories) - assert.NotNil(t, err) + require.Error(t, err) } func TestKameletRemoveRepoURINotFoundNotEmpty(t *testing.T) { repositories := []v1.KameletRepositorySpec{{URI: "github:foo/bar"}} _, err := getURIIndex("foo", repositories) - assert.NotNil(t, err) + require.Error(t, err) } func TestKameletRemoveRepoURIFound(t *testing.T) { repositories := []v1.KameletRepositorySpec{{URI: "github:foo/bar1"}, {URI: "github:foo/bar2"}, {URI: "github:foo/bar3"}} i, err := getURIIndex("github:foo/bar2", repositories) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, 1, i) } diff --git a/pkg/cmd/kit_create.go b/pkg/cmd/kit_create.go index 1d893022fd..f488c7ee46 100644 --- a/pkg/cmd/kit_create.go +++ b/pkg/cmd/kit_create.go @@ -43,7 +43,7 @@ func newKitCreateCmd(rootCmdOptions *RootCmdOptions) (*cobra.Command, *kitCreate Short: "Create an Integration Kit", Long: `Create an Integration Kit.`, Args: options.validateArgs, - PreRunE: decode(&options), + PreRunE: decode(&options, options.Flags), RunE: options.run, } diff --git a/pkg/cmd/kit_create_test.go b/pkg/cmd/kit_create_test.go index 06ffa52534..520dda50a0 100644 --- a/pkg/cmd/kit_create_test.go +++ b/pkg/cmd/kit_create_test.go @@ -23,6 +23,7 @@ import ( "github.com/apache/camel-k/v2/pkg/util/test" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) const subCmdKit = "create" @@ -33,7 +34,7 @@ func initializeKitCreateCmdOptions(t *testing.T) (*kitCreateCommandOptions, *cob options, rootCmd := kamelTestPreAddCommandInit() kitCreateCmdOptions := addTestKitCreateCmd(*options, rootCmd) - kamelTestPostAddCommandInit(t, rootCmd) + kamelTestPostAddCommandInit(t, rootCmd, options) return kitCreateCmdOptions, rootCmd, *options } @@ -55,7 +56,7 @@ func addTestKitCreateCmd(options RootCmdOptions, rootCmd *cobra.Command) *kitCre func TestKitCreateNonExistingFlag(t *testing.T) { _, rootCmd, _ := initializeKitCreateCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, subCmdKit, "--nonExistingFlag") - assert.NotNil(t, err) + require.Error(t, err) } func TestKitCreateConfigMapFlag(t *testing.T) { @@ -63,7 +64,7 @@ func TestKitCreateConfigMapFlag(t *testing.T) { _, err := test.ExecuteCommand(rootCmd, subCmdKit, "--configmap", "someString1", "--configmap", "someString2") - assert.Nil(t, err) + require.NoError(t, err) assert.Len(t, kitCreateCmdOptions.Configmaps, 2) assert.Equal(t, "someString1", kitCreateCmdOptions.Configmaps[0]) assert.Equal(t, "someString2", kitCreateCmdOptions.Configmaps[1]) @@ -74,7 +75,7 @@ func TestKitCreateDependencyFlag(t *testing.T) { _, err := test.ExecuteCommand(rootCmd, subCmdKit, "--dependency", "someString1", "--dependency", "someString2") - assert.Nil(t, err) + require.NoError(t, err) assert.Len(t, kitCreateCmdOptions.Dependencies, 2) assert.Equal(t, "someString1", kitCreateCmdOptions.Dependencies[0]) assert.Equal(t, "someString2", kitCreateCmdOptions.Dependencies[1]) @@ -83,7 +84,7 @@ func TestKitCreateDependencyFlag(t *testing.T) { func TestKitCreateImageFlag(t *testing.T) { kitCreateCmdOptions, rootCmd, _ := initializeKitCreateCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, subCmdKit, "--image", "someString") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "someString", kitCreateCmdOptions.Image) } @@ -92,7 +93,7 @@ func TestKitCreatePropertyFlag(t *testing.T) { _, err := test.ExecuteCommand(rootCmd, subCmdKit, "--property", "someString1", "--property", "someString2") - assert.Nil(t, err) + require.NoError(t, err) assert.Len(t, kitCreateCmdOptions.Properties, 2) assert.Equal(t, "someString1", kitCreateCmdOptions.Properties[0]) assert.Equal(t, "someString2", kitCreateCmdOptions.Properties[1]) @@ -103,7 +104,7 @@ func TestKitCreateRepositoryFlag(t *testing.T) { _, err := test.ExecuteCommand(rootCmd, subCmdKit, "--repository", "someString1", "--repository", "someString2") - assert.Nil(t, err) + require.NoError(t, err) assert.Len(t, kitCreateCmdOptions.Repositories, 2) assert.Equal(t, "someString1", kitCreateCmdOptions.Repositories[0]) assert.Equal(t, "someString2", kitCreateCmdOptions.Repositories[1]) @@ -114,7 +115,7 @@ func TestKitCreateSecretFlag(t *testing.T) { _, err := test.ExecuteCommand(rootCmd, subCmdKit, "--secret", "someString1", "--secret", "someString2") - assert.Nil(t, err) + require.NoError(t, err) assert.Len(t, kitCreateCmdOptions.Secrets, 2) assert.Equal(t, "someString1", kitCreateCmdOptions.Secrets[0]) assert.Equal(t, "someString2", kitCreateCmdOptions.Secrets[1]) @@ -125,7 +126,7 @@ func TestKitCreateTraitFlag(t *testing.T) { _, err := test.ExecuteCommand(rootCmd, subCmdKit, "--trait", "someString1", "--trait", "someString2") - assert.Nil(t, err) + require.NoError(t, err) assert.Len(t, kitCreateCmdOptions.Traits, 2) assert.Equal(t, "someString1", kitCreateCmdOptions.Traits[0]) assert.Equal(t, "someString2", kitCreateCmdOptions.Traits[1]) diff --git a/pkg/cmd/kit_delete.go b/pkg/cmd/kit_delete.go index 31f02609ab..df9aea8342 100644 --- a/pkg/cmd/kit_delete.go +++ b/pkg/cmd/kit_delete.go @@ -38,7 +38,7 @@ func newKitDeleteCmd(rootCmdOptions *RootCmdOptions) (*cobra.Command, *kitDelete cmd := cobra.Command{ Use: "delete [integration kit1] [integration kit2] ...", Short: "Delete integration kits deployed on Kubernetes", - PreRunE: decode(&options), + PreRunE: decode(&options, options.Flags), RunE: func(cmd *cobra.Command, args []string) error { if err := options.validate(args); err != nil { return err diff --git a/pkg/cmd/kit_get.go b/pkg/cmd/kit_get.go index da8e350071..20b5e5c0de 100644 --- a/pkg/cmd/kit_get.go +++ b/pkg/cmd/kit_get.go @@ -37,7 +37,7 @@ func newKitGetCmd(rootCmdOptions *RootCmdOptions) (*cobra.Command, *kitGetComman Use: "get", Short: "Get defined Integration Kit", Long: `Get defined Integration Kit.`, - PreRunE: decode(&options), + PreRunE: decode(&options, options.Flags), RunE: func(cmd *cobra.Command, args []string) error { if err := options.validate(cmd, args); err != nil { return err diff --git a/pkg/cmd/log.go b/pkg/cmd/log.go index c01e14bb44..d6367ca5f1 100644 --- a/pkg/cmd/log.go +++ b/pkg/cmd/log.go @@ -42,7 +42,7 @@ func newCmdLog(rootCmdOptions *RootCmdOptions) (*cobra.Command, *logCmdOptions) Long: `Print the logs of an integration.`, Aliases: []string{"logs"}, Args: options.validate, - PreRunE: decode(&options), + PreRunE: decode(&options, options.Flags), RunE: options.run, } diff --git a/pkg/cmd/log_test.go b/pkg/cmd/log_test.go index 28ba243bda..2046f640ad 100644 --- a/pkg/cmd/log_test.go +++ b/pkg/cmd/log_test.go @@ -28,7 +28,7 @@ func TestLogsAlias(t *testing.T) { logCommand, _ := newCmdLog(options) rootCommand.AddCommand(logCommand) - kamelTestPostAddCommandInit(t, rootCommand) + kamelTestPostAddCommandInit(t, rootCommand, options) _, err := test.ExecuteCommand(rootCommand, "logs") diff --git a/pkg/cmd/modeline_test.go b/pkg/cmd/modeline_test.go index fa3bd91dda..66e1e2753a 100644 --- a/pkg/cmd/modeline_test.go +++ b/pkg/cmd/modeline_test.go @@ -27,6 +27,7 @@ import ( "github.com/apache/camel-k/v2/pkg/util" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestModelineRunSimple(t *testing.T) { @@ -36,17 +37,17 @@ func TestModelineRunSimple(t *testing.T) { ` fileName := filepath.Join(dir, "simple.groovy") err := os.WriteFile(fileName, []byte(file), 0o400) - assert.NoError(t, err) + require.NoError(t, err) cmd, flags, err := NewKamelWithModelineCommand(context.TODO(), []string{"kamel", "run", fileName}) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, cmd) assert.Equal(t, []string{"run", fileName, "--dependency=mvn:org.my:lib:1.0"}, flags) return nil }) - assert.NoError(t, err) + require.NoError(t, err) } func TestModelineRunHelp(t *testing.T) { @@ -55,14 +56,14 @@ func TestModelineRunHelp(t *testing.T) { fileName := filepath.Join(dir, "simple.groovy") cmd, flags, err := NewKamelWithModelineCommand(context.TODO(), []string{"kamel", "run", fileName, "--help"}) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, cmd) assert.Equal(t, []string{"run", fileName, "--help"}, flags) return nil }) - assert.NoError(t, err) + require.NoError(t, err) } func TestModelineRunChain(t *testing.T) { @@ -72,17 +73,17 @@ func TestModelineRunChain(t *testing.T) { ` fileName := filepath.Join(dir, "simple.groovy") err := os.WriteFile(fileName, []byte(file), 0o400) - assert.NoError(t, err) + require.NoError(t, err) cmd, flags, err := NewKamelWithModelineCommand(context.TODO(), []string{"kamel", "run", "-d", "mvn:org.my:lib2:1.0", fileName}) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, cmd) assert.Equal(t, []string{"run", "-d", "mvn:org.my:lib2:1.0", fileName, "--dependency=mvn:org.my:lib:2.0"}, flags) return nil }) - assert.NoError(t, err) + require.NoError(t, err) } func TestModelineRunMultipleFiles(t *testing.T) { @@ -92,55 +93,55 @@ func TestModelineRunMultipleFiles(t *testing.T) { ` fileName := filepath.Join(dir, "simple.groovy") err := os.WriteFile(fileName, []byte(file), 0o400) - assert.NoError(t, err) + require.NoError(t, err) file2 := ` // camel-k: dependency=mvn:org.my:lib2:3.0 ` fileName2 := filepath.Join(dir, "ext.groovy") err = os.WriteFile(fileName2, []byte(file2), 0o400) - assert.NoError(t, err) + require.NoError(t, err) cmd, flags, err := NewKamelWithModelineCommand(context.TODO(), []string{"kamel", "run", fileName, fileName2}) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, cmd) assert.Equal(t, []string{"run", fileName, fileName2, "--dependency=mvn:org.my:lib1:3.0", "--dependency=mvn:org.my:lib2:3.0"}, flags) return nil }) - assert.NoError(t, err) + require.NoError(t, err) } func TestModelineRunProperty(t *testing.T) { err := util.WithTempDir("camel-k-test-", func(dir string) error { subDir := filepath.Join(dir, "sub") err := os.Mkdir(subDir, 0o700) - assert.NoError(t, err) + require.NoError(t, err) file := ` // camel-k: property=my-prop=my-val ` fileName := filepath.Join(subDir, "simple.groovy") err = os.WriteFile(fileName, []byte(file), 0o400) - assert.NoError(t, err) + require.NoError(t, err) cmd, flags, err := NewKamelWithModelineCommand(context.TODO(), []string{"kamel", "run", fileName}) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, cmd) assert.Equal(t, []string{"run", fileName, "--property=my-prop=my-val"}, flags) return nil }) - assert.NoError(t, err) + require.NoError(t, err) } func TestModelineRunDuplicatedProperties(t *testing.T) { err := util.WithTempDir("camel-k-test-", func(dir string) error { subDir := filepath.Join(dir, "sub") err := os.Mkdir(subDir, 0o700) - assert.NoError(t, err) + require.NoError(t, err) file := ` // camel-k: property=prop1=false @@ -149,24 +150,24 @@ func TestModelineRunDuplicatedProperties(t *testing.T) { ` fileName := filepath.Join(subDir, "simple.groovy") err = os.WriteFile(fileName, []byte(file), 0o400) - assert.NoError(t, err) + require.NoError(t, err) cmd, flags, err := NewKamelWithModelineCommand(context.TODO(), []string{"kamel", "run", fileName, "-p", "prop1=true", "--property", "prop2=true"}) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, cmd) assert.Equal(t, []string{"run", fileName, "-p", "prop1=true", "--property", "prop2=true", "--property=foo=bar"}, flags) return nil }) - assert.NoError(t, err) + require.NoError(t, err) } func TestModelineRunDuplicatedBuildProperties(t *testing.T) { err := util.WithTempDir("camel-k-test-", func(dir string) error { subDir := filepath.Join(dir, "sub") err := os.Mkdir(subDir, 0o700) - assert.NoError(t, err) + require.NoError(t, err) file := ` // camel-k: build-property=prop1=false @@ -175,13 +176,13 @@ func TestModelineRunDuplicatedBuildProperties(t *testing.T) { ` fileName := filepath.Join(subDir, "simple.groovy") err = os.WriteFile(fileName, []byte(file), 0o400) - assert.NoError(t, err) + require.NoError(t, err) cmd, flags, err := NewKamelWithModelineCommand(context.TODO(), []string{ "kamel", "run", fileName, "--build-property", "prop1=true", "--build-property", "prop2=true", }) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, cmd) assert.Equal(t, []string{ "run", fileName, "--build-property", "prop1=true", "--build-property", "prop2=true", @@ -191,100 +192,100 @@ func TestModelineRunDuplicatedBuildProperties(t *testing.T) { return nil }) - assert.NoError(t, err) + require.NoError(t, err) } func TestModelineRunPropertyFiles(t *testing.T) { err := util.WithTempDir("camel-k-test-", func(dir string) error { subDir := filepath.Join(dir, "sub") err := os.Mkdir(subDir, 0o700) - assert.NoError(t, err) + require.NoError(t, err) file := ` // camel-k: property=file:application.properties ` fileName := filepath.Join(subDir, "simple.groovy") err = os.WriteFile(fileName, []byte(file), 0o400) - assert.NoError(t, err) + require.NoError(t, err) propFile := ` a=b ` propFileName := filepath.Join(subDir, "application.properties") err = os.WriteFile(propFileName, []byte(propFile), 0o400) - assert.NoError(t, err) + require.NoError(t, err) cmd, flags, err := NewKamelWithModelineCommand(context.TODO(), []string{"kamel", "run", fileName}) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, cmd) assert.Equal(t, []string{"run", fileName, fmt.Sprintf("--property=file:%s", propFileName)}, flags) return nil }) - assert.NoError(t, err) + require.NoError(t, err) } func TestModelineRunBuildProperty(t *testing.T) { err := util.WithTempDir("camel-k-test-", func(dir string) error { subDir := filepath.Join(dir, "sub") err := os.Mkdir(subDir, 0o700) - assert.NoError(t, err) + require.NoError(t, err) file := ` // camel-k: build-property=my-build-prop=my-val ` fileName := filepath.Join(subDir, "simple.groovy") err = os.WriteFile(fileName, []byte(file), 0o400) - assert.NoError(t, err) + require.NoError(t, err) cmd, flags, err := NewKamelWithModelineCommand(context.TODO(), []string{"kamel", "run", fileName}) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, cmd) assert.Equal(t, []string{"run", fileName, "--build-property=my-build-prop=my-val"}, flags) return nil }) - assert.NoError(t, err) + require.NoError(t, err) } func TestModelineRunBuildPropertyFiles(t *testing.T) { err := util.WithTempDir("camel-k-test-", func(dir string) error { subDir := filepath.Join(dir, "sub") err := os.Mkdir(subDir, 0o700) - assert.NoError(t, err) + require.NoError(t, err) file := ` // camel-k: build-property=file:application.properties ` fileName := filepath.Join(subDir, "simple.groovy") err = os.WriteFile(fileName, []byte(file), 0o400) - assert.NoError(t, err) + require.NoError(t, err) propFile := ` a=b ` propFileName := filepath.Join(subDir, "application.properties") err = os.WriteFile(propFileName, []byte(propFile), 0o400) - assert.NoError(t, err) + require.NoError(t, err) cmd, flags, err := NewKamelWithModelineCommand(context.TODO(), []string{"kamel", "run", fileName}) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, cmd) assert.Equal(t, []string{"run", fileName, fmt.Sprintf("--build-property=file:%s", propFileName)}, flags) return nil }) - assert.NoError(t, err) + require.NoError(t, err) } func TestModelineRunDuplicateTraits(t *testing.T) { err := util.WithTempDir("camel-k-test-", func(dir string) error { subDir := filepath.Join(dir, "sub") err := os.Mkdir(subDir, 0o700) - assert.NoError(t, err) + require.NoError(t, err) file := ` // camel-k: trait=trait1=false @@ -293,113 +294,113 @@ func TestModelineRunDuplicateTraits(t *testing.T) { ` fileName := filepath.Join(subDir, "simple.groovy") err = os.WriteFile(fileName, []byte(file), 0o400) - assert.NoError(t, err) + require.NoError(t, err) cmd, flags, err := NewKamelWithModelineCommand(context.TODO(), []string{"kamel", "run", fileName, "-t", "trait1=true", "--trait", "trait2=true"}) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, cmd) assert.Equal(t, []string{"run", fileName, "-t", "trait1=true", "--trait", "trait2=true", "--trait=foo=bar"}, flags) return nil }) - assert.NoError(t, err) + require.NoError(t, err) } func TestModelineRunConfigConfigmap(t *testing.T) { err := util.WithTempDir("camel-k-test-", func(dir string) error { subDir := filepath.Join(dir, "sub") err := os.Mkdir(subDir, 0o700) - assert.NoError(t, err) + require.NoError(t, err) file := ` // camel-k: config=configmap:my-cm ` fileName := filepath.Join(subDir, "simple.groovy") err = os.WriteFile(fileName, []byte(file), 0o400) - assert.NoError(t, err) + require.NoError(t, err) cmd, flags, err := NewKamelWithModelineCommand(context.TODO(), []string{"kamel", "run", fileName}) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, cmd) assert.Equal(t, []string{"run", fileName, "--config=configmap:my-cm"}, flags) return nil }) - assert.NoError(t, err) + require.NoError(t, err) } func TestModelineRunConfigSecret(t *testing.T) { err := util.WithTempDir("camel-k-test-", func(dir string) error { subDir := filepath.Join(dir, "sub") err := os.Mkdir(subDir, 0o700) - assert.NoError(t, err) + require.NoError(t, err) file := ` // camel-k: config=secret:my-secret ` fileName := filepath.Join(subDir, "simple.groovy") err = os.WriteFile(fileName, []byte(file), 0o400) - assert.NoError(t, err) + require.NoError(t, err) cmd, flags, err := NewKamelWithModelineCommand(context.TODO(), []string{"kamel", "run", fileName}) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, cmd) assert.Equal(t, []string{"run", fileName, "--config=secret:my-secret"}, flags) return nil }) - assert.NoError(t, err) + require.NoError(t, err) } func TestModelineRunResourceConfigmap(t *testing.T) { err := util.WithTempDir("camel-k-test-", func(dir string) error { subDir := filepath.Join(dir, "sub") err := os.Mkdir(subDir, 0o700) - assert.NoError(t, err) + require.NoError(t, err) file := ` // camel-k: resource=configmap:my-cm ` fileName := filepath.Join(subDir, "simple.groovy") err = os.WriteFile(fileName, []byte(file), 0o400) - assert.NoError(t, err) + require.NoError(t, err) cmd, flags, err := NewKamelWithModelineCommand(context.TODO(), []string{"kamel", "run", fileName}) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, cmd) assert.Equal(t, []string{"run", fileName, "--resource=configmap:my-cm"}, flags) return nil }) - assert.NoError(t, err) + require.NoError(t, err) } func TestModelineRunResourceSecret(t *testing.T) { err := util.WithTempDir("camel-k-test-", func(dir string) error { subDir := filepath.Join(dir, "sub") err := os.Mkdir(subDir, 0o700) - assert.NoError(t, err) + require.NoError(t, err) file := ` // camel-k: resource=secret:my-secret ` fileName := filepath.Join(subDir, "simple.groovy") err = os.WriteFile(fileName, []byte(file), 0o400) - assert.NoError(t, err) + require.NoError(t, err) cmd, flags, err := NewKamelWithModelineCommand(context.TODO(), []string{"kamel", "run", fileName}) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, cmd) assert.Equal(t, []string{"run", fileName, "--resource=secret:my-secret"}, flags) return nil }) - assert.NoError(t, err) + require.NoError(t, err) } func TestModelineQuotedPodTemplate(t *testing.T) { @@ -410,15 +411,15 @@ func TestModelineQuotedPodTemplate(t *testing.T) { ` fileName := filepath.Join(dir, "simple.groovy") err := os.WriteFile(fileName, []byte(file), 0o400) - assert.NoError(t, err) + require.NoError(t, err) cmd, flags, err := NewKamelWithModelineCommand(context.TODO(), []string{"kamel", "run", fileName}) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, cmd) assert.Equal(t, []string{"run", fileName, "--pod-template={ \"containers\": [], \"securityContext\": { \"supplementalGroups\": [ 553 ] }, \"volumes\": [] } }"}, flags) return nil }) - assert.NoError(t, err) + require.NoError(t, err) } diff --git a/pkg/cmd/operator.go b/pkg/cmd/operator.go index cec5934201..f46a6dac16 100644 --- a/pkg/cmd/operator.go +++ b/pkg/cmd/operator.go @@ -18,16 +18,15 @@ limitations under the License. package cmd import ( + "github.com/apache/camel-k/v2/pkg/cmd/operator" "github.com/apache/camel-k/v2/pkg/platform" "github.com/apache/camel-k/v2/pkg/util/defaults" "github.com/spf13/cobra" - - "github.com/apache/camel-k/v2/pkg/cmd/operator" ) const operatorCommand = "operator" -func newCmdOperator() (*cobra.Command, *operatorCmdOptions) { +func newCmdOperator(rootCmdOptions *RootCmdOptions) (*cobra.Command, *operatorCmdOptions) { options := operatorCmdOptions{} cmd := cobra.Command{ @@ -35,7 +34,7 @@ func newCmdOperator() (*cobra.Command, *operatorCmdOptions) { Short: "Run the Camel K operator", Long: `Run the Camel K operator`, Hidden: true, - PreRunE: decode(&options), + PreRunE: decode(&options, rootCmdOptions.Flags), Run: options.run, } diff --git a/pkg/cmd/operator_test.go b/pkg/cmd/operator_test.go index d783ffbeb9..6ffd29f50c 100644 --- a/pkg/cmd/operator_test.go +++ b/pkg/cmd/operator_test.go @@ -24,6 +24,7 @@ import ( "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) const cmdOperator = "operator" @@ -34,7 +35,7 @@ func initializeOperatorCmdOptions(t *testing.T) (*operatorCmdOptions, *cobra.Com options, rootCmd := kamelTestPreAddCommandInit() operatorCmdOptions := addTestOperatorCmd(*options, rootCmd) - kamelTestPostAddCommandInit(t, rootCmd) + kamelTestPostAddCommandInit(t, rootCmd, options) return operatorCmdOptions, rootCmd, *options } @@ -42,7 +43,7 @@ func initializeOperatorCmdOptions(t *testing.T) (*operatorCmdOptions, *cobra.Com // nolint: unparam func addTestOperatorCmd(options RootCmdOptions, rootCmd *cobra.Command) *operatorCmdOptions { // add a testing version of operator Command - operatorCmd, operatorOptions := newCmdOperator() + operatorCmd, operatorOptions := newCmdOperator(&options) operatorCmd.RunE = func(c *cobra.Command, args []string) error { return nil } @@ -57,7 +58,7 @@ func addTestOperatorCmd(options RootCmdOptions, rootCmd *cobra.Command) *operato func TestOperatorNoFlag(t *testing.T) { operatorCmdOptions, rootCmd, _ := initializeOperatorCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdOperator) - assert.Nil(t, err) + require.NoError(t, err) // Check default expected values assert.Equal(t, int32(8081), operatorCmdOptions.HealthPort) assert.Equal(t, int32(8080), operatorCmdOptions.MonitoringPort) @@ -66,19 +67,19 @@ func TestOperatorNoFlag(t *testing.T) { func TestOperatorNonExistingFlag(t *testing.T) { _, rootCmd, _ := initializeOperatorCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdOperator, "--nonExistingFlag") - assert.NotNil(t, err) + require.Error(t, err) } func TestOperatorHealthPortFlag(t *testing.T) { operatorCmdOptions, rootCmd, _ := initializeOperatorCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdOperator, "--health-port", "7171") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, int32(7171), operatorCmdOptions.HealthPort) } func TestOperatorMonitoringPortFlag(t *testing.T) { operatorCmdOptions, rootCmd, _ := initializeOperatorCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdOperator, "--monitoring-port", "7172") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, int32(7172), operatorCmdOptions.MonitoringPort) } diff --git a/pkg/cmd/promote.go b/pkg/cmd/promote.go index 562b4dac56..9b73e71ee9 100644 --- a/pkg/cmd/promote.go +++ b/pkg/cmd/promote.go @@ -53,7 +53,7 @@ func newCmdPromote(rootCmdOptions *RootCmdOptions) (*cobra.Command, *promoteCmdO Use: "promote my-it [--to ] [-x ]", Short: "Promote an Integration/Pipe from an environment to another", Long: "Promote an Integration/Pipe from an environment to another, for example from a Development environment to a Production environment", - PreRunE: decode(&options), + PreRunE: decode(&options, options.Flags), RunE: options.run, } diff --git a/pkg/cmd/promote_test.go b/pkg/cmd/promote_test.go index 50616d5811..91ebce901f 100644 --- a/pkg/cmd/promote_test.go +++ b/pkg/cmd/promote_test.go @@ -27,6 +27,7 @@ import ( "github.com/apache/camel-k/v2/pkg/util/test" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "k8s.io/apimachinery/pkg/runtime" ) @@ -36,11 +37,11 @@ const cmdPromote = "promote" func initializePromoteCmdOptions(t *testing.T, initObjs ...runtime.Object) (*promoteCmdOptions, *cobra.Command, RootCmdOptions) { t.Helper() fakeClient, err := test.NewFakeClient(initObjs...) - assert.Nil(t, err) + require.NoError(t, err) options, rootCmd := kamelTestPreAddCommandInitWithClient(fakeClient) options.Namespace = "default" promoteCmdOptions := addTestPromoteCmd(*options, rootCmd) - kamelTestPostAddCommandInit(t, rootCmd) + kamelTestPostAddCommandInit(t, rootCmd, options) return promoteCmdOptions, rootCmd, *options } @@ -67,7 +68,7 @@ func TestIntegrationNotCompatible(t *testing.T) { _, promoteCmd, _ := initializePromoteCmdOptions(t, &srcPlatform, &dstPlatform, &defaultIntegration, &srcCatalog, &dstCatalog) _, err := test.ExecuteCommand(promoteCmd, cmdPromote, "my-it-test", "--to", "prod-namespace", "-n", "default") - assert.NotNil(t, err) + require.Error(t, err) assert.Equal(t, fmt.Sprintf("could not verify operators compatibility: source (%s) and destination (0.0.1) Camel K operator versions are not compatible", defaults.Version), err.Error(), @@ -90,7 +91,7 @@ func TestIntegrationDryRun(t *testing.T) { promoteCmdOptions, promoteCmd, _ := initializePromoteCmdOptions(t, &srcPlatform, &dstPlatform, &defaultIntegration, &srcCatalog, &dstCatalog) output, err := test.ExecuteCommand(promoteCmd, cmdPromote, "my-it-test", "--to", "prod-namespace", "-o", "yaml", "-n", "default") assert.Equal(t, "yaml", promoteCmdOptions.OutputFormat) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, `apiVersion: camel.apache.org/v1 kind: Integration metadata: @@ -103,8 +104,7 @@ spec: image: my-special-image jvm: enabled: true -status: - traits: {} +status: {} `, output) } @@ -132,7 +132,7 @@ func TestPipeDryRun(t *testing.T) { promoteCmdOptions, promoteCmd, _ := initializePromoteCmdOptions(t, &srcPlatform, &dstPlatform, &defaultKB, &defaultIntegration, &srcCatalog, &dstCatalog) output, err := test.ExecuteCommand(promoteCmd, cmdPromote, "my-kb-test", "--to", "prod-namespace", "-o", "yaml", "-n", "default") assert.Equal(t, "yaml", promoteCmdOptions.OutputFormat) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, `apiVersion: camel.apache.org/v1 kind: Pipe metadata: @@ -187,7 +187,7 @@ func TestIntegrationWithMetadataDryRun(t *testing.T) { promoteCmdOptions, promoteCmd, _ := initializePromoteCmdOptions(t, &srcPlatform, &dstPlatform, &defaultIntegration, &srcCatalog, &dstCatalog) output, err := test.ExecuteCommand(promoteCmd, cmdPromote, "my-it-test", "--to", "prod-namespace", "-o", "yaml", "-n", "default") assert.Equal(t, "yaml", promoteCmdOptions.OutputFormat) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, `apiVersion: camel.apache.org/v1 kind: Integration metadata: @@ -204,8 +204,7 @@ spec: image: my-special-image jvm: enabled: true -status: - traits: {} +status: {} `, output) } @@ -233,7 +232,7 @@ func TestPipeWithMetadataDryRun(t *testing.T) { promoteCmdOptions, promoteCmd, _ := initializePromoteCmdOptions(t, &srcPlatform, &dstPlatform, &defaultKB, &defaultIntegration, &srcCatalog, &dstCatalog) output, err := test.ExecuteCommand(promoteCmd, cmdPromote, "my-kb-test", "--to", "prod-namespace", "-o", "yaml", "-n", "default") assert.Equal(t, "yaml", promoteCmdOptions.OutputFormat) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, `apiVersion: camel.apache.org/v1 kind: Pipe metadata: @@ -272,7 +271,7 @@ func TestItImageOnly(t *testing.T) { _, promoteCmd, _ := initializePromoteCmdOptions(t, &srcPlatform, &dstPlatform, &defaultIntegration, &srcCatalog, &dstCatalog) output, err := test.ExecuteCommand(promoteCmd, cmdPromote, "my-it-test", "--to", "prod-namespace", "-i", "-n", "default") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "my-special-image\n", output) } @@ -292,7 +291,7 @@ func TestPipeImageOnly(t *testing.T) { _, promoteCmd, _ := initializePromoteCmdOptions(t, &srcPlatform, &dstPlatform, &defaultKB, &defaultIntegration, &srcCatalog, &dstCatalog) output, err := test.ExecuteCommand(promoteCmd, cmdPromote, "my-kb-test", "--to", "prod-namespace", "-i", "-n", "default") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "my-special-image\n", output) } @@ -313,7 +312,7 @@ func TestIntegrationToOperatorId(t *testing.T) { promoteCmdOptions, promoteCmd, _ := initializePromoteCmdOptions(t, &srcPlatform, &dstPlatform, &defaultIntegration, &srcCatalog, &dstCatalog) output, err := test.ExecuteCommand(promoteCmd, cmdPromote, "my-it-test", "-x", "my-prod-operator", "-o", "yaml", "--to", "prod") assert.Equal(t, "yaml", promoteCmdOptions.OutputFormat) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, `apiVersion: camel.apache.org/v1 kind: Integration metadata: @@ -328,8 +327,7 @@ spec: image: my-special-image jvm: enabled: true -status: - traits: {} +status: {} `, output) // Verify also when the operator Id is set in the integration defaultIntegration.Annotations = map[string]string{ @@ -338,7 +336,7 @@ status: promoteCmdOptions, promoteCmd, _ = initializePromoteCmdOptions(t, &srcPlatform, &dstPlatform, &defaultIntegration, &srcCatalog, &dstCatalog) output, err = test.ExecuteCommand(promoteCmd, cmdPromote, "my-it-test", "-x", "my-prod-operator", "-o", "yaml", "--to", "prod") assert.Equal(t, "yaml", promoteCmdOptions.OutputFormat) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, `apiVersion: camel.apache.org/v1 kind: Integration metadata: @@ -353,7 +351,6 @@ spec: image: my-special-image jvm: enabled: true -status: - traits: {} +status: {} `, output) } diff --git a/pkg/cmd/rebuild.go b/pkg/cmd/rebuild.go index d249982b12..147ee98c8f 100644 --- a/pkg/cmd/rebuild.go +++ b/pkg/cmd/rebuild.go @@ -37,7 +37,7 @@ func newCmdRebuild(rootCmdOptions *RootCmdOptions) (*cobra.Command, *rebuildCmdO Use: "rebuild [integration1] [integration2] ...", Short: "Clear the state of integrations to rebuild them.", Long: `Clear the state of one or more integrations causing a rebuild. Rebuild always targets Integration CR, the operator is in charge to apply any change to the related bindings resources (if any).`, - PreRunE: decode(&options), + PreRunE: decode(&options, options.Flags), RunE: func(cmd *cobra.Command, args []string) error { if err := options.validate(args); err != nil { return err diff --git a/pkg/cmd/rebuild_test.go b/pkg/cmd/rebuild_test.go index 021c1cf6ba..5d91422990 100644 --- a/pkg/cmd/rebuild_test.go +++ b/pkg/cmd/rebuild_test.go @@ -23,6 +23,7 @@ import ( "github.com/apache/camel-k/v2/pkg/util/test" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) const cmdRebuild = "rebuild" @@ -33,7 +34,7 @@ func initializeRebuildCmdOptions(t *testing.T) (*rebuildCmdOptions, *cobra.Comma options, rootCmd := kamelTestPreAddCommandInit() rebuildCmdOptions := addTestRebuildCmd(*options, rootCmd) - kamelTestPostAddCommandInit(t, rootCmd) + kamelTestPostAddCommandInit(t, rootCmd, options) return rebuildCmdOptions, rootCmd, *options } @@ -55,12 +56,12 @@ func addTestRebuildCmd(options RootCmdOptions, rootCmd *cobra.Command) *rebuildC func TestRebuildNonExistingFlag(t *testing.T) { _, rootCmd, _ := initializeRebuildCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdRebuild, "--nonExistingFlag") - assert.NotNil(t, err) + require.Error(t, err) } func TestRebuildAllFlag(t *testing.T) { rebuildCmdOptions, rootCmd, _ := initializeRebuildCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdRebuild, "--all") - assert.Nil(t, err) - assert.Equal(t, true, rebuildCmdOptions.RebuildAll) + require.NoError(t, err) + assert.True(t, rebuildCmdOptions.RebuildAll) } diff --git a/pkg/cmd/reset.go b/pkg/cmd/reset.go index 1e6ece75d2..ec9416ff26 100644 --- a/pkg/cmd/reset.go +++ b/pkg/cmd/reset.go @@ -38,7 +38,7 @@ func newCmdReset(rootCmdOptions *RootCmdOptions) (*cobra.Command, *resetCmdOptio Use: "reset", Short: "Reset the Camel K installation", Long: `Reset the Camel K installation by deleting everything except current integration profile.`, - PreRunE: decode(&options), + PreRunE: decode(&options, options.Flags), Run: options.reset, } diff --git a/pkg/cmd/root.go b/pkg/cmd/root.go index a43e5a3491..e7b9b83131 100644 --- a/pkg/cmd/root.go +++ b/pkg/cmd/root.go @@ -46,6 +46,7 @@ type RootCmdOptions struct { Context context.Context `mapstructure:"-"` ContextCancel context.CancelFunc `mapstructure:"-"` _client client.Client `mapstructure:"-"` + Flags *viper.Viper `mapstructure:"-"` KubeConfig string `mapstructure:"kube-config"` Namespace string `mapstructure:"namespace"` Verbose bool `mapstructure:"verbose" yaml:",omitempty"` @@ -58,6 +59,7 @@ func NewKamelCommand(ctx context.Context) (*cobra.Command, error) { RootContext: ctx, Context: childCtx, ContextCancel: childCancel, + Flags: viper.New(), } cmd := kamelPreAddCommandInit(&options) @@ -67,7 +69,7 @@ func NewKamelCommand(ctx context.Context) (*cobra.Command, error) { return cmd, err } - err := kamelPostAddCommandInit(cmd) + err := kamelPostAddCommandInit(cmd, options.Flags) return cmd, err } @@ -92,8 +94,8 @@ func kamelPreAddCommandInit(options *RootCmdOptions) *cobra.Command { return &cmd } -func kamelPostAddCommandInit(cmd *cobra.Command) error { - if err := bindPFlagsHierarchy(cmd); err != nil { +func kamelPostAddCommandInit(cmd *cobra.Command, v *viper.Viper) error { + if err := bindPFlagsHierarchy(cmd, v); err != nil { return err } @@ -102,26 +104,26 @@ func kamelPostAddCommandInit(cmd *cobra.Command) error { configName = DefaultConfigName } - viper.SetConfigName(configName) + v.SetConfigName(configName) configPath := os.Getenv("KAMEL_CONFIG_PATH") if configPath != "" { // if a specific config path is set, don't add // default locations - viper.AddConfigPath(configPath) + v.AddConfigPath(configPath) } else { - viper.AddConfigPath(".") - viper.AddConfigPath(".kamel") - viper.AddConfigPath("$HOME/.kamel") + v.AddConfigPath(".") + v.AddConfigPath(".kamel") + v.AddConfigPath("$HOME/.kamel") } - viper.AutomaticEnv() - viper.SetEnvKeyReplacer(strings.NewReplacer( + v.AutomaticEnv() + v.SetEnvKeyReplacer(strings.NewReplacer( ".", "_", "-", "_", )) - if err := viper.ReadInConfig(); err != nil { + if err := v.ReadInConfig(); err != nil { if !errors.As(err, &viper.ConfigFileNotFoundError{}) { return err } @@ -143,7 +145,7 @@ func addKamelSubcommands(cmd *cobra.Command, options *RootCmdOptions) { cmd.AddCommand(cmdOnly(newCmdReset(options))) cmd.AddCommand(newCmdDescribe(options)) cmd.AddCommand(cmdOnly(newCmdRebuild(options))) - cmd.AddCommand(cmdOnly(newCmdOperator())) + cmd.AddCommand(cmdOnly(newCmdOperator(options))) cmd.AddCommand(cmdOnly(newCmdBuilder(options))) cmd.AddCommand(cmdOnly(newCmdDebug(options))) cmd.AddCommand(cmdOnly(newCmdDump(options))) @@ -179,7 +181,7 @@ func (command *RootCmdOptions) preRun(cmd *cobra.Command, _ []string) error { return fmt.Errorf("cannot get command client: %w", err) } if command.Namespace == "" { - current := viper.GetString("kamel.config.default-namespace") + current := command.Flags.GetString("kamel.config.default-namespace") if current == "" { defaultNS, err := c.GetCurrentNamespace(command.KubeConfig) if err != nil { diff --git a/pkg/cmd/root_test.go b/pkg/cmd/root_test.go index 6c9afd3ce0..40cbead6ac 100644 --- a/pkg/cmd/root_test.go +++ b/pkg/cmd/root_test.go @@ -29,10 +29,10 @@ import ( "github.com/spf13/viper" ) -func kamelTestPostAddCommandInit(t *testing.T, rootCmd *cobra.Command) { +func kamelTestPostAddCommandInit(t *testing.T, rootCmd *cobra.Command, options *RootCmdOptions) { t.Helper() - err := kamelPostAddCommandInit(rootCmd) + err := kamelPostAddCommandInit(rootCmd, options.Flags) if err != nil { t.Fatalf("Unexpected error: %v", err) } @@ -41,6 +41,7 @@ func kamelTestPostAddCommandInit(t *testing.T, rootCmd *cobra.Command) { func kamelTestPreAddCommandInitWithClient(client client.Client) (*RootCmdOptions, *cobra.Command) { options := RootCmdOptions{ Context: context.Background(), + Flags: viper.New(), _client: client, } rootCmd := kamelPreAddCommandInit(&options) @@ -54,13 +55,13 @@ func kamelTestPreAddCommandInit() (*RootCmdOptions, *cobra.Command) { } func TestLoadFromEnvVar(t *testing.T) { - defer teardown(t) // shows how to include a "," character inside an env value see VAR1 value if err := os.Setenv("KAMEL_RUN_ENVS", "\"VAR1=value,\"\"othervalue\"\"\",VAR2=value2"); err != nil { t.Fatalf("Unexpected error: %v", err) } runCmdOptions, rootCmd, _ := initializeRunCmdOptions(t) + defer teardown(t, runCmdOptions.Flags) _, err := test.ExecuteCommand(rootCmd, "run", "route.java") if err != nil { @@ -75,12 +76,12 @@ func TestLoadFromEnvVar(t *testing.T) { } func TestLoadFromFile(t *testing.T) { + runCmdOptions, rootCmd, _ := initializeRunCmdOptions(t) + // shows how to include a "," character inside a property value see VAR1 value propertiesFile := []byte(`kamel.run.envs: "VAR1=value,""othervalue""",VAR2=value2`) - viper.SetConfigType("properties") - readViperConfigFromBytes(t, propertiesFile) - - runCmdOptions, rootCmd, _ := initializeRunCmdOptions(t) + runCmdOptions.Flags.SetConfigType("properties") + readViperConfigFromBytes(t, runCmdOptions.Flags, propertiesFile) _, err := test.ExecuteCommand(rootCmd, "run", "route.java") if err != nil { @@ -95,16 +96,16 @@ func TestLoadFromFile(t *testing.T) { } func TestPrecedenceEnvVarOverFile(t *testing.T) { - defer teardown(t) if err := os.Setenv("KAMEL_RUN_ENVS", "VAR1=envVar"); err != nil { t.Fatalf("Unexpected error: %v", err) } + runCmdOptions, rootCmd, _ := initializeRunCmdOptions(t) + defer teardown(t, runCmdOptions.Flags) + propertiesFile := []byte(`kamel.run.envs: VAR2=file`) viper.SetConfigType("properties") - readViperConfigFromBytes(t, propertiesFile) - - runCmdOptions, rootCmd, _ := initializeRunCmdOptions(t) + readViperConfigFromBytes(t, runCmdOptions.Flags, propertiesFile) _, err := test.ExecuteCommand(rootCmd, "run", "route.java") if err != nil { @@ -119,16 +120,16 @@ func TestPrecedenceEnvVarOverFile(t *testing.T) { } func TestPrecedenceCommandLineOverEverythingElse(t *testing.T) { - defer teardown(t) if err := os.Setenv("KAMEL_RUN_ENVS", "VAR1=envVar"); err != nil { t.Fatalf("Unexpected error: %v", err) } + runCmdOptions, rootCmd, _ := initializeRunCmdOptions(t) + defer teardown(t, runCmdOptions.Flags) + propertiesFile := []byte(`kamel.run.envs: VAR2=file`) viper.SetConfigType("properties") - readViperConfigFromBytes(t, propertiesFile) - - runCmdOptions, rootCmd, _ := initializeRunCmdOptions(t) + readViperConfigFromBytes(t, runCmdOptions.Flags, propertiesFile) _, err := test.ExecuteCommand(rootCmd, "run", "route.java", "--env", "VAR3=commandLine") if err != nil { @@ -142,20 +143,20 @@ func TestPrecedenceCommandLineOverEverythingElse(t *testing.T) { } } -func readViperConfigFromBytes(t *testing.T, propertiesFile []byte) { +func readViperConfigFromBytes(t *testing.T, v *viper.Viper, propertiesFile []byte) { t.Helper() - unexpectedErr := viper.ReadConfig(bytes.NewReader(propertiesFile)) + unexpectedErr := v.ReadConfig(bytes.NewReader(propertiesFile)) if unexpectedErr != nil { t.Fatalf("Unexpected error: %v", unexpectedErr) } } // We must ALWAYS clean the environment variables and viper library properties to avoid mess up with the rest of the tests. -func teardown(t *testing.T) { +func teardown(t *testing.T, v *viper.Viper) { t.Helper() if err := os.Setenv("KAMEL_RUN_ENVS", ""); err != nil { t.Fatalf("Unexpected error: %v", err) } - readViperConfigFromBytes(t, make([]byte, 0)) + readViperConfigFromBytes(t, v, make([]byte, 0)) } diff --git a/pkg/cmd/run.go b/pkg/cmd/run.go index 0a4a05b891..548f642a04 100644 --- a/pkg/cmd/run.go +++ b/pkg/cmd/run.go @@ -76,8 +76,6 @@ import ( "github.com/apache/camel-k/v2/pkg/util/watch" ) -const usageDependency = `A dependency that should be included, e.g., "-d camel:mail" for a Camel component, "-d mvn:org.my:app:1.0" for a Maven dependency, "-d http(s)://my-repo/my-dependency.jar|targetPath=®istry=&skipChecksums=&skipPOM=&classpath=" for custom dependencies located on an http server or "file://localPath[?targetPath=®istry=&skipChecksums=&skipPOM=&classpath=]" for local files` - func newCmdRun(rootCmdOptions *RootCmdOptions) (*cobra.Command, *runCmdOptions) { options := runCmdOptions{ RootCmdOptions: rootCmdOptions, @@ -98,7 +96,7 @@ func newCmdRun(rootCmdOptions *RootCmdOptions) (*cobra.Command, *runCmdOptions) cmd.Flags().String("name", "", "The integration name") cmd.Flags().String("image", "", "An image built externally (ie, via CICD). Enabling it will skip the Integration build phase.") cmd.Flags().StringArrayP("connect", "c", nil, "A Service that the integration should bind to, specified as [[apigroup/]version:]kind:[namespace/]name") - cmd.Flags().StringArrayP("dependency", "d", nil, usageDependency) + cmd.Flags().StringArrayP("dependency", "d", nil, `A dependency that should be included, e.g., "-d camel:mail" for a Camel component, "-d mvn:org.my:app:1.0" for a Maven dependency`) cmd.Flags().BoolP("wait", "w", false, "Wait for the integration to be running") cmd.Flags().StringP("kit", "k", "", "The kit used to run the integration") cmd.Flags().StringArrayP("property", "p", nil, "Add a runtime property or properties file from a path, a config map or a secret (syntax: [my-key=my-value|file:/path/to/my-conf.properties|[configmap|secret]:name])") @@ -189,7 +187,8 @@ func (o *runCmdOptions) decode(cmd *cobra.Command, args []string) error { // load from kamel.run (1) pathToRoot := pathToRoot(cmd) - if err := decodeKey(o, pathToRoot); err != nil { + + if err := decodeKey(o, pathToRoot, o.Flags.AllSettings()); err != nil { return err } @@ -214,7 +213,7 @@ func (o *runCmdOptions) decode(cmd *cobra.Command, args []string) error { if name != "" { // load from kamel.run.integration.$name (2) pathToRoot += ".integration." + name - if err := decodeKey(o, pathToRoot); err != nil { + if err := decodeKey(o, pathToRoot, o.Flags.AllSettings()); err != nil { return err } diff --git a/pkg/cmd/run_support_test.go b/pkg/cmd/run_support_test.go index 45e4249984..5ef9830686 100644 --- a/pkg/cmd/run_support_test.go +++ b/pkg/cmd/run_support_test.go @@ -25,6 +25,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestFilterFileLocation(t *testing.T) { @@ -47,36 +48,36 @@ func TestFilterFileLocation(t *testing.T) { func TestDownloadDependencyWithBadURL(t *testing.T) { u, _ := url.Parse("http://foo") _, err := downloadDependency(context.Background(), *u) - assert.NotNil(t, err) + require.Error(t, err) } func TestDownloadDependencyWithFileNameInURL(t *testing.T) { u, _ := url.Parse("https://repo1.maven.org/maven2/org/apache/camel/camel-core/3.18.2/camel-core-3.18.2.jar") path, err := downloadDependency(context.Background(), *u) t.Cleanup(func() { os.Remove(path) }) - assert.Nil(t, err) + require.NoError(t, err) assert.True(t, strings.HasSuffix(path, "camel-core-3.18.2.jar"), "The name of the jar file is expected") _, err = os.Stat(path) - assert.Nil(t, err) + require.NoError(t, err) } func TestDownloadDependencyWithFileNameInQuery(t *testing.T) { u, _ := url.Parse("https://search.maven.org/remotecontent?filepath=org/apache/camel/quarkus/camel-quarkus-file/2.12.0/camel-quarkus-file-2.12.0.jar") path, err := downloadDependency(context.Background(), *u) t.Cleanup(func() { os.Remove(path) }) - assert.Nil(t, err) + require.NoError(t, err) assert.True(t, strings.HasSuffix(path, "camel-quarkus-file-2.12.0.jar"), "The name of the jar file is expected") _, err = os.Stat(path) - assert.Nil(t, err) + require.NoError(t, err) } func TestDownloadDependencyWithoutFileName(t *testing.T) { u, _ := url.Parse("https://search.maven.org") path, err := downloadDependency(context.Background(), *u) t.Cleanup(func() { os.Remove(path) }) - assert.Nil(t, err) + require.NoError(t, err) _, err = os.Stat(path) - assert.Nil(t, err) + require.NoError(t, err) } func TestExtractTraitNames(t *testing.T) { diff --git a/pkg/cmd/run_test.go b/pkg/cmd/run_test.go index d6bddb689a..625a850d4c 100644 --- a/pkg/cmd/run_test.go +++ b/pkg/cmd/run_test.go @@ -60,7 +60,7 @@ func initializeRunCmdOptions(t *testing.T) (*runCmdOptions, *cobra.Command, Root options, rootCmd := kamelTestPreAddCommandInit() runCmdOptions := addTestRunCmd(*options, rootCmd) - kamelTestPostAddCommandInit(t, rootCmd) + kamelTestPostAddCommandInit(t, rootCmd, options) return runCmdOptions, rootCmd, *options } @@ -75,7 +75,7 @@ func initializeRunCmdOptionsWithOutput(t *testing.T) (*runCmdOptions, *cobra.Com options, rootCmd := kamelTestPreAddCommandInitWithClient(fakeClient) runCmdOptions := addTestRunCmdWithOutput(*options, rootCmd) - kamelTestPostAddCommandInit(t, rootCmd) + kamelTestPostAddCommandInit(t, rootCmd, options) return runCmdOptions, rootCmd, *options } @@ -105,28 +105,28 @@ func addTestRunCmdWithOutput(options RootCmdOptions, rootCmd *cobra.Command) *ru func TestRunNoFlag(t *testing.T) { runCmdOptions, rootCmd, _ := initializeRunCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdRun, integrationSource) - assert.Nil(t, err) + require.NoError(t, err) // Check default expected values - assert.Equal(t, false, runCmdOptions.Wait) - assert.Equal(t, false, runCmdOptions.Logs) - assert.Equal(t, false, runCmdOptions.Sync) - assert.Equal(t, false, runCmdOptions.Dev) - assert.Equal(t, true, runCmdOptions.UseFlows) - assert.Equal(t, false, runCmdOptions.Compression) - assert.Equal(t, false, runCmdOptions.Save) + assert.False(t, runCmdOptions.Wait) + assert.False(t, runCmdOptions.Logs) + assert.False(t, runCmdOptions.Sync) + assert.False(t, runCmdOptions.Dev) + assert.True(t, runCmdOptions.UseFlows) + assert.False(t, runCmdOptions.Compression) + assert.False(t, runCmdOptions.Save) } func TestRunNonExistingFlag(t *testing.T) { _, rootCmd, _ := initializeRunCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdRun, "--nonExistingFlag", integrationSource) - assert.NotNil(t, err) + require.Error(t, err) } func TestRunCompressionFlag(t *testing.T) { runCmdOptions, rootCmd, _ := initializeRunCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdRun, "--compression", integrationSource) - assert.Nil(t, err) - assert.Equal(t, true, runCmdOptions.Compression) + require.NoError(t, err) + assert.True(t, runCmdOptions.Compression) } func TestRunDependencyFlag(t *testing.T) { @@ -136,7 +136,7 @@ func TestRunDependencyFlag(t *testing.T) { "--dependency", "dependency2", "--dependency", "dependency3", integrationSource) - assert.Nil(t, err) + require.NoError(t, err) assert.Len(t, runCmdOptions.Dependencies, 3) assert.Equal(t, "dependency1", runCmdOptions.Dependencies[0]) assert.Equal(t, "dependency2", runCmdOptions.Dependencies[1]) @@ -146,16 +146,16 @@ func TestRunDependencyFlag(t *testing.T) { func TestRunDevFlag(t *testing.T) { runCmdOptions, rootCmd, _ := initializeRunCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdRun, "--dev", integrationSource) - assert.Nil(t, err) - assert.Equal(t, true, runCmdOptions.Dev) + require.NoError(t, err) + assert.True(t, runCmdOptions.Dev) } func TestRunDevModeOutputFlag(t *testing.T) { runCmdOptions, rootCmd, _ := initializeRunCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdRun, "--dev", "-o", "yaml", integrationSource) - assert.Equal(t, true, runCmdOptions.Dev) + assert.True(t, runCmdOptions.Dev) assert.Equal(t, "yaml", runCmdOptions.OutputFormat) - assert.NotNil(t, err) + require.Error(t, err) assert.Equal(t, "cannot use --dev with -o/--output option", err.Error()) } @@ -166,7 +166,7 @@ func TestRunEnvFlag(t *testing.T) { "--env", "env1", "--env", "env2", integrationSource) - assert.Nil(t, err) + require.NoError(t, err) assert.Len(t, runCmdOptions.EnvVars, 2) assert.Equal(t, "env1", runCmdOptions.EnvVars[0]) assert.Equal(t, "env2", runCmdOptions.EnvVars[1]) @@ -175,7 +175,7 @@ func TestRunEnvFlag(t *testing.T) { func TestRunKitFlag(t *testing.T) { runCmdOptions, rootCmd, _ := initializeRunCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdRun, "--kit", "myKit", integrationSource) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "myKit", runCmdOptions.IntegrationKit) } @@ -186,7 +186,7 @@ func TestRunLabelFlag(t *testing.T) { "--label", "label2=l2", "--label", "label3=l3", integrationSource) - assert.Nil(t, err) + require.NoError(t, err) assert.Len(t, runCmdOptions.Labels, 3) assert.Equal(t, "label1=l1", runCmdOptions.Labels[0]) assert.Equal(t, "label2=l2", runCmdOptions.Labels[1]) @@ -196,14 +196,14 @@ func TestRunLabelFlag(t *testing.T) { func TestRunLabelWrongFormatFlag(t *testing.T) { _, rootCmd, _ := initializeRunCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdRun, "--label", "label1", integrationSource) - assert.NotNil(t, err) + require.Error(t, err) } func TestRunLogsFlag(t *testing.T) { runCmdOptions, rootCmd, _ := initializeRunCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdRun, "--logs", integrationSource) - assert.Nil(t, err) - assert.Equal(t, true, runCmdOptions.Logs) + require.NoError(t, err) + assert.True(t, runCmdOptions.Logs) } func TestRunMavenRepositoryFlag(t *testing.T) { @@ -213,7 +213,7 @@ func TestRunMavenRepositoryFlag(t *testing.T) { "--maven-repository", "repo2", "--maven-repository", "repo3", integrationSource) - assert.Nil(t, err) + require.NoError(t, err) assert.Len(t, runCmdOptions.Repositories, 3) assert.Equal(t, "repo1", runCmdOptions.Repositories[0]) assert.Equal(t, "repo2", runCmdOptions.Repositories[1]) @@ -223,7 +223,7 @@ func TestRunMavenRepositoryFlag(t *testing.T) { func TestRunNameFlag(t *testing.T) { runCmdOptions, rootCmd, _ := initializeRunCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdRun, "--name", "myIntegration", integrationSource) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "myIntegration", runCmdOptions.IntegrationName) } @@ -232,7 +232,7 @@ func TestRunOpenApiFlag(t *testing.T) { _, err := test.ExecuteCommand(rootCmd, cmdRun, "--open-api", "configmap:oapi2", integrationSource) - assert.Nil(t, err) + require.NoError(t, err) assert.Len(t, runCmdOptions.OpenAPIs, 1) assert.Equal(t, "configmap:oapi2", runCmdOptions.OpenAPIs[0]) } @@ -243,20 +243,20 @@ func TestRunOpenApiInvalidFlag(t *testing.T) { "--open-api", "secret:oapi1", "--open-api", "oapi2", integrationSource) - assert.NotNil(t, err) + require.Error(t, err) } func TestRunOutputFlag(t *testing.T) { runCmdOptions, rootCmd, _ := initializeRunCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdRun, "-o", "yaml", integrationSource) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "yaml", runCmdOptions.OutputFormat) } func TestRunProfileFlag(t *testing.T) { runCmdOptions, rootCmd, _ := initializeRunCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdRun, "--profile", "myProfile", integrationSource) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "myProfile", runCmdOptions.Profile) } @@ -267,7 +267,7 @@ func TestRunPropertyFlag(t *testing.T) { "--property", "property2", "--property", "property3", integrationSource) - assert.Nil(t, err) + require.NoError(t, err) assert.Len(t, runCmdOptions.Properties, 3) assert.Equal(t, "property1", runCmdOptions.Properties[0]) assert.Equal(t, "property2", runCmdOptions.Properties[1]) @@ -290,7 +290,7 @@ func TestExtractProperties_SingleKeyValue(t *testing.T) { runCmdOptions, _, _ := initializeRunCmdOptionsWithOutput(t) for _, val := range correctValues { prop, err := runCmdOptions.extractProperties(nil, val) - assert.Nil(t, err) + require.NoError(t, err) value, ok := prop.Get("key") assert.True(t, ok) assert.Equal(t, "val", value) @@ -304,15 +304,15 @@ func TestExtractProperties_FromFile(t *testing.T) { t.Error(err) } - assert.Nil(t, tmpFile1.Close()) - assert.Nil(t, os.WriteFile(tmpFile1.Name(), []byte(` + require.NoError(t, tmpFile1.Close()) + require.NoError(t, os.WriteFile(tmpFile1.Name(), []byte(` key=value #key2=value2 my.key=value `), 0o400)) runCmdOptions, _, _ := initializeRunCmdOptionsWithOutput(t) props, err := runCmdOptions.extractProperties(nil, "file:"+tmpFile1.Name()) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, 2, props.Len()) for _, prop := range props.Keys() { value, ok := props.Get(prop) @@ -328,8 +328,8 @@ func TestExtractPropertiesFromFileAndSingleValue(t *testing.T) { t.Error(err) } - assert.Nil(t, tmpFile1.Close()) - assert.Nil(t, os.WriteFile(tmpFile1.Name(), []byte(` + require.NoError(t, tmpFile1.Close()) + require.NoError(t, os.WriteFile(tmpFile1.Name(), []byte(` key=value #key2=value2 my.key=value @@ -338,7 +338,7 @@ func TestExtractPropertiesFromFileAndSingleValue(t *testing.T) { properties := []string{"key=override", "file:" + tmpFile1.Name(), "my.key = override"} runCmdOptions, _, _ := initializeRunCmdOptionsWithOutput(t) props, err := runCmdOptions.mergePropertiesWithPrecedence(nil, properties) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, 2, props.Len()) val, ok := props.Get("key") assert.True(t, ok) @@ -355,12 +355,12 @@ func TestAddPropertyFile(t *testing.T) { t.Error(err) } - assert.Nil(t, tmpFile.Close()) - assert.Nil(t, os.WriteFile(tmpFile.Name(), []byte(TestPropertyFileContent), 0o400)) + require.NoError(t, tmpFile.Close()) + require.NoError(t, os.WriteFile(tmpFile.Name(), []byte(TestPropertyFileContent), 0o400)) runCmdOptions, _, _ := initializeRunCmdOptionsWithOutput(t) properties, err := runCmdOptions.convertToTraitParameter(nil, "file:"+tmpFile.Name(), "trait.properties") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, 3, len(properties)) assert.Equal(t, `trait.properties=a = b`, properties[0]) assert.Equal(t, `trait.properties=f = g:h`, properties[1]) @@ -370,7 +370,7 @@ func TestAddPropertyFile(t *testing.T) { func TestRunProperty(t *testing.T) { runCmdOptions, _, _ := initializeRunCmdOptionsWithOutput(t) properties, err := runCmdOptions.convertToTraitParameter(nil, `key=value\nnewline`, "trait.properties") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, 1, len(properties)) assert.Equal(t, `trait.properties=key = value\nnewline`, properties[0]) } @@ -381,7 +381,7 @@ func TestRunResourceFlag(t *testing.T) { "--resource", "res1", "--resource", "res2", integrationSource) - assert.Nil(t, err) + require.NoError(t, err) assert.Len(t, runCmdOptions.Resources, 2) assert.Equal(t, "res1", runCmdOptions.Resources[0]) assert.Equal(t, "res2", runCmdOptions.Resources[1]) @@ -390,14 +390,14 @@ func TestRunResourceFlag(t *testing.T) { func TestRunSaveFlag(t *testing.T) { runCmdOptions, rootCmd, _ := initializeRunCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdRun, "--save", integrationSource) - assert.Nil(t, err) - assert.Equal(t, true, runCmdOptions.Save) + require.NoError(t, err) + assert.True(t, runCmdOptions.Save) } func TestRunSourceFlag(t *testing.T) { runCmdOptions, rootCmd, _ := initializeRunCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdRun, "--source", "source1", integrationSource) - assert.Nil(t, err) + require.NoError(t, err) assert.Len(t, runCmdOptions.Sources, 1) assert.Equal(t, "source1", runCmdOptions.Sources[0]) } @@ -405,8 +405,8 @@ func TestRunSourceFlag(t *testing.T) { func TestRunSyncFlag(t *testing.T) { runCmdOptions, rootCmd, _ := initializeRunCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdRun, "--sync", integrationSource) - assert.Nil(t, err) - assert.Equal(t, true, runCmdOptions.Sync) + require.NoError(t, err) + assert.True(t, runCmdOptions.Sync) } func TestRunExistingTraitFlag(t *testing.T) { @@ -415,7 +415,7 @@ func TestRunExistingTraitFlag(t *testing.T) { "--trait", "jvm.enabled", "--trait", "logging.enabled", integrationSource) - assert.Nil(t, err) + require.NoError(t, err) assert.Len(t, runCmdOptions.Traits, 2) assert.Equal(t, "jvm.enabled", runCmdOptions.Traits[0]) assert.Equal(t, "logging.enabled", runCmdOptions.Traits[1]) @@ -426,7 +426,7 @@ func TestRunMissingTraitFlag(t *testing.T) { _, err := test.ExecuteCommand(rootCmd, cmdRun, "--trait", "bogus.missing", integrationSource) - assert.NotNil(t, err) + require.Error(t, err) assert.Equal(t, "trait bogus does not exist in catalog", err.Error()) assert.Len(t, runCmdOptions.Traits, 1) assert.Equal(t, "bogus.missing", runCmdOptions.Traits[0]) @@ -452,9 +452,9 @@ func TestConfigureTraits(t *testing.T) { traits := v1.Traits{} err = configureTraits(runCmdOptions.Traits, &traits, catalog) - assert.Nil(t, err) + require.NoError(t, err) traitMap, err := trait.ToTraitMap(traits) - assert.Nil(t, err) + require.NoError(t, err) assert.Len(t, traitMap, 4) assertTraitConfiguration(t, traits.Affinity, &traitv1.AffinityTrait{PodAffinity: pointer.Bool(false)}) assertTraitConfiguration(t, traits.Environment, &traitv1.EnvironmentTrait{ContainerMeta: pointer.Bool(false)}) @@ -472,8 +472,8 @@ func assertTraitConfiguration(t *testing.T, trait interface{}, expected interfac func TestRunUseFlowsFlag(t *testing.T) { runCmdOptions, rootCmd, _ := initializeRunCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdRun, "--use-flows=false", integrationSource) - assert.Nil(t, err) - assert.Equal(t, false, runCmdOptions.UseFlows) + require.NoError(t, err) + assert.False(t, runCmdOptions.UseFlows) } func TestRunVolumeFlag(t *testing.T) { @@ -482,7 +482,7 @@ func TestRunVolumeFlag(t *testing.T) { "-v", "pvcname:/container1/path", "-v", "pvcname:/container2/path", integrationSource) - assert.Nil(t, err) + require.NoError(t, err) assert.Len(t, runCmdOptions.Volumes, 2) assert.Equal(t, "pvcname:/container1/path", runCmdOptions.Volumes[0]) assert.Equal(t, "pvcname:/container2/path", runCmdOptions.Volumes[1]) @@ -494,7 +494,7 @@ func TestRunVolumeFlagWrongPVCFormat(t *testing.T) { "-v", "pvcname", "-v", "pvcname/container2/path", integrationSource) - assert.NotNil(t, err) + require.Error(t, err) } func TestRunBuildPropertyFlag(t *testing.T) { @@ -503,7 +503,7 @@ func TestRunBuildPropertyFlag(t *testing.T) { "--build-property", "build-prop1=val1", "--build-property", "build-prop2=val2", integrationSource) - assert.Nil(t, err) + require.NoError(t, err) assert.Len(t, runCmdOptions.BuildProperties, 2) assert.Equal(t, "build-prop1=val1", runCmdOptions.BuildProperties[0]) assert.Equal(t, "build-prop2=val2", runCmdOptions.BuildProperties[1]) @@ -514,11 +514,11 @@ func TestRunValidateArgs(t *testing.T) { args := []string{"run_test.go"} err := runCmdOptions.validateArgs(rootCmd, args) - assert.Nil(t, err) + require.NoError(t, err) args = []string{"missing_file"} err = runCmdOptions.validateArgs(rootCmd, args) - assert.NotNil(t, err) + require.Error(t, err) assert.Equal(t, "one of the provided sources is not reachable: missing file or unsupported scheme in missing_file", err.Error()) } @@ -540,7 +540,7 @@ volumes: integrationSpec := v1.IntegrationSpec{} err := resolvePodTemplate(context.TODO(), rootCmd, templateText, &integrationSpec) - assert.Nil(t, err) + require.NoError(t, err) assert.NotNil(t, integrationSpec.PodTemplate) assert.Equal(t, 1, len(integrationSpec.PodTemplate.Spec.Containers)) // assert.Equal(t, 1,len(integrationSpec.PodTemplate.Spec.Containers[0].VolumeMounts)) @@ -553,7 +553,7 @@ func TestResolveJsonPodTemplate(t *testing.T) { err := resolvePodTemplate(context.TODO(), rootCmd, minifiedYamlTemplate, &integrationSpec) - assert.Nil(t, err) + require.NoError(t, err) assert.NotNil(t, integrationSpec.PodTemplate) assert.Equal(t, 2, len(integrationSpec.PodTemplate.Spec.Containers)) } @@ -562,8 +562,8 @@ func TestFilterBuildPropertyFiles(t *testing.T) { inputValues := []string{"file:/tmp/test", "key=val"} outputValues := filterBuildPropertyFiles(inputValues) - assert.Equal(t, len(outputValues), 1) - assert.Equal(t, outputValues[0], "/tmp/test") + assert.Len(t, outputValues, 1) + assert.Equal(t, "/tmp/test", outputValues[0]) } const TestSrcContent = ` @@ -586,14 +586,14 @@ func TestOutputYaml(t *testing.T) { } assert.Nil(t, tmpFile.Close()) - assert.Nil(t, os.WriteFile(tmpFile.Name(), []byte(TestSrcContent), 0o400)) + require.NoError(t, os.WriteFile(tmpFile.Name(), []byte(TestSrcContent), 0o400)) fileName := filepath.Base(tmpFile.Name()) runCmdOptions, runCmd, _ := initializeRunCmdOptionsWithOutput(t) output, err := test.ExecuteCommand(runCmd, cmdRun, tmpFile.Name(), "-o", "yaml") assert.Equal(t, "yaml", runCmdOptions.OutputFormat) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, fmt.Sprintf(`apiVersion: camel.apache.org/v1 kind: Integration metadata: @@ -608,8 +608,7 @@ spec: {\n\t from(\"timer:tick\")\n .log(\"Hello Camel K!\");\n }\n}\n" name: %s traits: {} -status: - traits: {} +status: {} `, fileName, fileName), output) } @@ -621,14 +620,14 @@ func TestTrait(t *testing.T) { } assert.Nil(t, tmpFile.Close()) - assert.Nil(t, os.WriteFile(tmpFile.Name(), []byte(TestSrcContent), 0o400)) + require.NoError(t, os.WriteFile(tmpFile.Name(), []byte(TestSrcContent), 0o400)) fileName := filepath.Base(tmpFile.Name()) runCmdOptions, runCmd, _ := initializeRunCmdOptionsWithOutput(t) output, err := test.ExecuteCommand(runCmd, cmdRun, tmpFile.Name(), "-o", "yaml", "-t", "mount.configs=configmap:my-cm", "--connect", "my-service-binding") assert.Equal(t, "yaml", runCmdOptions.OutputFormat) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, fmt.Sprintf(`apiVersion: camel.apache.org/v1 kind: Integration metadata: @@ -649,8 +648,7 @@ spec: service-binding: services: - my-service-binding -status: - traits: {} +status: {} `, fileName, fileName), output) } @@ -662,13 +660,13 @@ func TestMissingTrait(t *testing.T) { } assert.Nil(t, tmpFile.Close()) - assert.Nil(t, os.WriteFile(tmpFile.Name(), []byte(TestSrcContent), 0o400)) + require.NoError(t, os.WriteFile(tmpFile.Name(), []byte(TestSrcContent), 0o400)) runCmdOptions, runCmd, _ := initializeRunCmdOptionsWithOutput(t) output, err := test.ExecuteCommand(runCmd, cmdRun, tmpFile.Name(), "-o", "yaml", "-t", "bogus.fail=i-must-fail") assert.Equal(t, "yaml", runCmdOptions.OutputFormat) assert.Equal(t, "Error: trait bogus does not exist in catalog\n", output) - assert.NotNil(t, err) + require.Error(t, err) } func TestResolveYamlPodTemplateWithSupplementalGroups(t *testing.T) { @@ -680,7 +678,7 @@ securityContext: ` integrationSpec := v1.IntegrationSpec{} err := resolvePodTemplate(context.TODO(), rootCmd, templateText, &integrationSpec) - assert.Nil(t, err) + require.NoError(t, err) assert.NotNil(t, integrationSpec.PodTemplate) assert.NotNil(t, integrationSpec.PodTemplate.Spec) assert.NotNil(t, integrationSpec.PodTemplate.Spec.SecurityContext) @@ -695,7 +693,7 @@ func TestResolveJsonPodTemplateWithSupplementalGroups(t *testing.T) { integrationSpec := v1.IntegrationSpec{} err := resolvePodTemplate(context.TODO(), rootCmd, minifiedYamlTemplate, &integrationSpec) - assert.Nil(t, err) + require.NoError(t, err) assert.NotNil(t, integrationSpec.PodTemplate) assert.NotNil(t, integrationSpec.PodTemplate.Spec) assert.NotNil(t, integrationSpec.PodTemplate.Spec.SecurityContext) @@ -712,12 +710,12 @@ func TestIntegrationServiceAccountName(t *testing.T) { } assert.Nil(t, tmpFile.Close()) - assert.Nil(t, os.WriteFile(tmpFile.Name(), []byte(TestSrcContent), 0o400)) + require.NoError(t, os.WriteFile(tmpFile.Name(), []byte(TestSrcContent), 0o400)) _, runCmd, _ := initializeRunCmdOptionsWithOutput(t) output, err := test.ExecuteCommand(runCmd, cmdRun, tmpFile.Name(), "-o", "yaml", "--service-account", "my-service-account") - assert.Nil(t, err) + require.NoError(t, err) assert.Contains(t, output, "serviceAccountName: my-service-account") } @@ -729,7 +727,7 @@ func TestFileProperties(t *testing.T) { } assert.Nil(t, tmpFile1.Close()) - assert.Nil(t, os.WriteFile(tmpFile1.Name(), []byte(` + require.NoError(t, os.WriteFile(tmpFile1.Name(), []byte(` key=${value} #key2=value2 my.key=value @@ -741,13 +739,13 @@ func TestFileProperties(t *testing.T) { } assert.Nil(t, tmpFile.Close()) - assert.Nil(t, os.WriteFile(tmpFile.Name(), []byte(TestSrcContent), 0o400)) + require.NoError(t, os.WriteFile(tmpFile.Name(), []byte(TestSrcContent), 0o400)) _, runCmd, _ := initializeRunCmdOptionsWithOutput(t) output, err := test.ExecuteCommand(runCmd, cmdRun, tmpFile.Name(), "-p", "file:"+tmpFile1.Name(), "-o", "yaml", ) - assert.Nil(t, err) + require.NoError(t, err) assert.NotContains(t, output, "#key2") assert.Contains(t, output, "my.key = value") assert.Contains(t, output, "key = ${value}") @@ -761,7 +759,7 @@ func TestPropertyShouldNotExpand(t *testing.T) { } assert.Nil(t, tmpFile1.Close()) - assert.Nil(t, os.WriteFile(tmpFile1.Name(), []byte(` + require.NoError(t, os.WriteFile(tmpFile1.Name(), []byte(` key=${value} `), 0o400)) @@ -771,7 +769,7 @@ func TestPropertyShouldNotExpand(t *testing.T) { } assert.Nil(t, tmpFile.Close()) - assert.Nil(t, os.WriteFile(tmpFile.Name(), []byte(TestSrcContent), 0o400)) + require.NoError(t, os.WriteFile(tmpFile.Name(), []byte(TestSrcContent), 0o400)) _, runCmd, _ := initializeRunCmdOptionsWithOutput(t) output, err := test.ExecuteCommand(runCmd, cmdRun, tmpFile.Name(), "-o", "yaml", @@ -779,7 +777,7 @@ func TestPropertyShouldNotExpand(t *testing.T) { "--build-property", "buildProp=${value}", "-p", "file:"+tmpFile1.Name(), ) - assert.Nil(t, err) + require.NoError(t, err) assert.Contains(t, output, "runtimeProp = ${value}") assert.Contains(t, output, "buildProp = ${value}") assert.Contains(t, output, "key = ${value}") @@ -794,23 +792,23 @@ func TestRunOutput(t *testing.T) { defer tmpFile1.Close() assert.Nil(t, tmpFile1.Sync()) - assert.Nil(t, os.WriteFile(tmpFile1.Name(), []byte(yamlIntegration), 0o400)) + require.NoError(t, os.WriteFile(tmpFile1.Name(), []byte(yamlIntegration), 0o400)) _, rootCmd, _ := initializeRunCmdOptionsWithOutput(t) output, err := test.ExecuteCommand(rootCmd, cmdRun, tmpFile1.Name()) _, fileName := filepath.Split(tmpFile1.Name()) integrationName := strings.TrimSuffix(fileName, filepath.Ext(fileName)) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, fmt.Sprintf("Integration \"%s\" created\n", integrationName), output) output, err = test.ExecuteCommand(rootCmd, cmdRun, tmpFile1.Name()) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, fmt.Sprintf("Integration \"%s\" unchanged\n", integrationName), output) - assert.Nil(t, os.WriteFile(tmpFile1.Name(), []byte(strings.Replace(yamlIntegration, "Hello", "Hi", 1)), 0o400)) + require.NoError(t, os.WriteFile(tmpFile1.Name(), []byte(strings.Replace(yamlIntegration, "Hello", "Hi", 1)), 0o400)) assert.Nil(t, tmpFile1.Sync()) output, err = test.ExecuteCommand(rootCmd, cmdRun, tmpFile1.Name()) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, fmt.Sprintf("Integration \"%s\" updated\n", integrationName), output) } @@ -828,7 +826,7 @@ func TestRunGlob(t *testing.T) { } defer tmpFile1.Close() assert.Nil(t, tmpFile1.Sync()) - assert.Nil(t, os.WriteFile(tmpFile1.Name(), []byte(yamlIntegration), 0o400)) + require.NoError(t, os.WriteFile(tmpFile1.Name(), []byte(yamlIntegration), 0o400)) tmpFile2, err := os.CreateTemp(dir, pattern) if err != nil { @@ -836,7 +834,7 @@ func TestRunGlob(t *testing.T) { } defer tmpFile2.Close() assert.Nil(t, tmpFile2.Sync()) - assert.Nil(t, os.WriteFile(tmpFile2.Name(), []byte(yamlIntegration), 0o400)) + require.NoError(t, os.WriteFile(tmpFile2.Name(), []byte(yamlIntegration), 0o400)) integrationName := "myname" @@ -845,7 +843,7 @@ func TestRunGlob(t *testing.T) { file := fmt.Sprintf("%s%c%s*", dir, os.PathSeparator, "camel-k-*") // = dir/camel-k-* output, err := test.ExecuteCommand(rootCmd, cmdRun, "--name", integrationName, file) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, fmt.Sprintf("Integration \"%s\" created\n", integrationName), output) } @@ -863,7 +861,7 @@ func TestRunGlobAllFiles(t *testing.T) { } defer tmpFile1.Close() assert.Nil(t, tmpFile1.Sync()) - assert.Nil(t, os.WriteFile(tmpFile1.Name(), []byte(yamlIntegration), 0o400)) + require.NoError(t, os.WriteFile(tmpFile1.Name(), []byte(yamlIntegration), 0o400)) tmpFile2, err := os.CreateTemp(dir, pattern) if err != nil { @@ -871,7 +869,7 @@ func TestRunGlobAllFiles(t *testing.T) { } defer tmpFile2.Close() assert.Nil(t, tmpFile2.Sync()) - assert.Nil(t, os.WriteFile(tmpFile2.Name(), []byte(yamlIntegration), 0o400)) + require.NoError(t, os.WriteFile(tmpFile2.Name(), []byte(yamlIntegration), 0o400)) integrationName := "myname" @@ -880,7 +878,7 @@ func TestRunGlobAllFiles(t *testing.T) { file := fmt.Sprintf("%s%c*", dir, os.PathSeparator) // = dir/* output, err := test.ExecuteCommand(rootCmd, cmdRun, "--name", integrationName, file) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, fmt.Sprintf("Integration \"%s\" created\n", integrationName), output) } @@ -898,7 +896,7 @@ func TestRunGlobChange(t *testing.T) { } defer tmpFile1.Close() assert.Nil(t, tmpFile1.Sync()) - assert.Nil(t, os.WriteFile(tmpFile1.Name(), []byte(yamlIntegration), 0o400)) + require.NoError(t, os.WriteFile(tmpFile1.Name(), []byte(yamlIntegration), 0o400)) integrationName := "myname" @@ -907,11 +905,11 @@ func TestRunGlobChange(t *testing.T) { file := fmt.Sprintf("%s%c%s", dir, os.PathSeparator, "camel-k-*") output, err := test.ExecuteCommand(rootCmd, cmdRun, "--name", integrationName, file) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, fmt.Sprintf("Integration \"%s\" created\n", integrationName), output) output, err = test.ExecuteCommand(rootCmd, cmdRun, "--name", integrationName, file) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, fmt.Sprintf("Integration \"%s\" unchanged\n", integrationName), output) tmpFile2, err := os.CreateTemp(dir, pattern) @@ -920,10 +918,10 @@ func TestRunGlobChange(t *testing.T) { } defer tmpFile2.Close() assert.Nil(t, tmpFile2.Sync()) - assert.Nil(t, os.WriteFile(tmpFile2.Name(), []byte(yamlIntegration), 0o400)) + require.NoError(t, os.WriteFile(tmpFile2.Name(), []byte(yamlIntegration), 0o400)) output, err = test.ExecuteCommand(rootCmd, cmdRun, "--name", integrationName, file) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, fmt.Sprintf("Integration \"%s\" updated\n", integrationName), output) } @@ -943,7 +941,7 @@ func TestSourceLessIntegration(t *testing.T) { output, err := test.ExecuteCommand(runCmd, cmdRun, "--image", "docker.io/my-org/my-app:1.0.0", "-o", "yaml", "-t", "mount.configs=configmap:my-cm") assert.Equal(t, "yaml", runCmdOptions.OutputFormat) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, `apiVersion: camel.apache.org/v1 kind: Integration metadata: @@ -958,7 +956,6 @@ spec: mount: configs: - configmap:my-cm -status: - traits: {} +status: {} `, output) } diff --git a/pkg/cmd/source/content_test.go b/pkg/cmd/source/content_test.go index c76b591391..051245cff2 100644 --- a/pkg/cmd/source/content_test.go +++ b/pkg/cmd/source/content_test.go @@ -27,11 +27,12 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestRawContentFileMissing(t *testing.T) { _, _, err := LoadRawContent(context.Background(), "dsadas") - assert.NotNil(t, err) + require.Error(t, err) } func TestRawBinaryContentType(t *testing.T) { @@ -40,11 +41,11 @@ func TestRawBinaryContentType(t *testing.T) { if tmpFile, err = os.CreateTemp("", "camel-k-*.json"); err != nil { t.Error(err) } - assert.Nil(t, tmpFile.Close()) - assert.Nil(t, os.WriteFile(tmpFile.Name(), []byte{1, 2, 3, 4, 5, 6}, 0o400)) + require.NoError(t, tmpFile.Close()) + require.NoError(t, os.WriteFile(tmpFile.Name(), []byte{1, 2, 3, 4, 5, 6}, 0o400)) data, contentType, err := LoadRawContent(context.Background(), tmpFile.Name()) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, []byte{1, 2, 3, 4, 5, 6}, data) assert.True(t, IsBinary(contentType)) } @@ -55,11 +56,11 @@ func TestRawApplicationContentType(t *testing.T) { if tmpFile, err = os.CreateTemp("", "camel-k-*.json"); err != nil { t.Error(err) } - assert.Nil(t, tmpFile.Close()) - assert.Nil(t, os.WriteFile(tmpFile.Name(), []byte(`{"hello":"world"}`), 0o400)) + require.NoError(t, tmpFile.Close()) + require.NoError(t, os.WriteFile(tmpFile.Name(), []byte(`{"hello":"world"}`), 0o400)) data, contentType, err := LoadRawContent(context.Background(), tmpFile.Name()) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, `{"hello":"world"}`, string(data)) assert.False(t, IsBinary(contentType)) } @@ -70,11 +71,11 @@ func TestTextContentType(t *testing.T) { if tmpFile, err = os.CreateTemp("", "camel-k-*.json"); err != nil { t.Error(err) } - assert.Nil(t, tmpFile.Close()) - assert.Nil(t, os.WriteFile(tmpFile.Name(), []byte(`{"hello":"world"}`), 0o400)) + require.NoError(t, tmpFile.Close()) + require.NoError(t, os.WriteFile(tmpFile.Name(), []byte(`{"hello":"world"}`), 0o400)) data, contentType, compressed, err := LoadTextContent(context.Background(), tmpFile.Name(), false) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, `{"hello":"world"}`, data) assert.False(t, IsBinary(contentType)) assert.False(t, compressed) @@ -87,10 +88,10 @@ func TestTextCompressed(t *testing.T) { t.Error(err) } assert.Nil(t, tmpFile.Close()) - assert.Nil(t, os.WriteFile(tmpFile.Name(), []byte(`{"hello":"world"}`), 0o400)) + require.NoError(t, os.WriteFile(tmpFile.Name(), []byte(`{"hello":"world"}`), 0o400)) data, contentType, compressed, err := LoadTextContent(context.Background(), tmpFile.Name(), true) - assert.Nil(t, err) + require.NoError(t, err) assert.NotEqual(t, `{"hello":"world"}`, data) assert.False(t, IsBinary(contentType)) assert.True(t, compressed) @@ -110,10 +111,10 @@ func TestContentHttp(t *testing.T) { defer svr.Close() u, err := url.Parse(svr.URL) - assert.Nil(t, err) + require.NoError(t, err) data, err := loadContentHTTP(context.Background(), u) - assert.Nil(t, err) + require.NoError(t, err) assert.NotEmpty(t, data) assert.Equal(t, expected, string(data)) } diff --git a/pkg/cmd/source/util_test.go b/pkg/cmd/source/util_test.go index d04e8fd252..fe01243968 100644 --- a/pkg/cmd/source/util_test.go +++ b/pkg/cmd/source/util_test.go @@ -27,6 +27,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestCorrectFileValuesButNotFound(t *testing.T) { @@ -34,9 +35,9 @@ func TestCorrectFileValuesButNotFound(t *testing.T) { value2, err2 := IsLocalAndFileExists("path/to/file") // they are all not found, but it must not panic - assert.Nil(t, err1) + require.NoError(t, err1) assert.False(t, value1) - assert.Nil(t, err2) + require.NoError(t, err2) assert.False(t, value2) } @@ -51,19 +52,19 @@ func TestPermissionDenied(t *testing.T) { } dir, err := os.MkdirTemp("/tmp", "camel-k-") - assert.Nil(t, err) + require.NoError(t, err) filename := filepath.Join(dir, "file.txt") f, err := os.Create(filename) - assert.Nil(t, err) + require.NoError(t, err) defer f.Close() err = os.Chmod(dir, 0000) - assert.Nil(t, err) + require.NoError(t, err) value, err := IsLocalAndFileExists(filename) // must not panic because a permission error - assert.NotNil(t, err) + require.Error(t, err) assert.False(t, value) } @@ -73,19 +74,19 @@ func TestSupportedScheme(t *testing.T) { httpValue, err3 := IsLocalAndFileExists("http://some/http/resource") httpsValue, err4 := IsLocalAndFileExists("https://some/https/resource") - assert.Nil(t, err1) + require.NoError(t, err1) assert.False(t, gistValue) - assert.Nil(t, err2) + require.NoError(t, err2) assert.False(t, githubValue) - assert.Nil(t, err3) + require.NoError(t, err3) assert.False(t, httpValue) - assert.Nil(t, err4) + require.NoError(t, err4) assert.False(t, httpsValue) } func TestUnSupportedScheme(t *testing.T) { value, err := IsLocalAndFileExists("bad_scheme:some/bad/resource") // must not report an error - assert.Nil(t, err) + require.NoError(t, err) assert.False(t, value) } diff --git a/pkg/cmd/uninstall.go b/pkg/cmd/uninstall.go index eb0e5b7794..b433dcf4cb 100644 --- a/pkg/cmd/uninstall.go +++ b/pkg/cmd/uninstall.go @@ -24,8 +24,6 @@ import ( "time" "github.com/spf13/cobra" - "github.com/spf13/viper" - k8serrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" @@ -107,13 +105,14 @@ var defaultListOptions = metav1.ListOptions{ func (o *uninstallCmdOptions) decode(cmd *cobra.Command, _ []string) error { path := pathToRoot(cmd) - if err := decodeKey(o, path); err != nil { + + if err := decodeKey(o, path, o.Flags.AllSettings()); err != nil { return err } - o.OlmOptions.OperatorName = viper.GetString(path + ".olm-operator-name") - o.OlmOptions.Package = viper.GetString(path + ".olm-package") - o.OlmOptions.GlobalNamespace = viper.GetString(path + ".olm-global-namespace") + o.OlmOptions.OperatorName = o.Flags.GetString(path + ".olm-operator-name") + o.OlmOptions.Package = o.Flags.GetString(path + ".olm-package") + o.OlmOptions.GlobalNamespace = o.Flags.GetString(path + ".olm-global-namespace") return nil } @@ -146,7 +145,7 @@ func (o *uninstallCmdOptions) uninstall(cmd *cobra.Command, _ []string) error { uninstallViaOLM := false if o.OlmEnabled { var err error - if uninstallViaOLM, err = olm.IsAPIAvailable(o.Context, c, o.Namespace); err != nil { + if uninstallViaOLM, err = olm.IsAPIAvailable(c); err != nil { return fmt.Errorf("error while checking OLM availability. Run with '--olm=false' to skip this check: %w", err) } diff --git a/pkg/cmd/uninstall_test.go b/pkg/cmd/uninstall_test.go index e10f9f3882..6c20d90b27 100644 --- a/pkg/cmd/uninstall_test.go +++ b/pkg/cmd/uninstall_test.go @@ -21,6 +21,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/apache/camel-k/v2/pkg/util/test" "github.com/spf13/cobra" @@ -42,10 +43,10 @@ func TestUninstallOlmFlags(t *testing.T) { uninstallCmdOptions := addTestUninstallCmd(options, cmd) - kamelTestPostAddCommandInit(t, cmd) + kamelTestPostAddCommandInit(t, cmd, options) _, err := test.ExecuteCommand(cmd, "uninstall", "--olm=false", "--olm-operator-name", "my-operator") - assert.Nil(t, err) + require.NoError(t, err) assert.False(t, uninstallCmdOptions.OlmEnabled) assert.Equal(t, "my-operator", uninstallCmdOptions.OlmOptions.OperatorName) } @@ -55,10 +56,10 @@ func TestUninstallSkipFlags(t *testing.T) { uninstallCmdOptions := addTestUninstallCmd(options, cmd) - kamelTestPostAddCommandInit(t, cmd) + kamelTestPostAddCommandInit(t, cmd, options) _, err := test.ExecuteCommand(cmd, "uninstall", "--skip-crd", "--skip-cluster-roles", "--skip-integration-platform", "--skip-integration-profile") - assert.Nil(t, err) + require.NoError(t, err) assert.True(t, uninstallCmdOptions.SkipCrd) assert.True(t, uninstallCmdOptions.SkipClusterRoles) assert.True(t, uninstallCmdOptions.SkipIntegrationPlatform) @@ -70,10 +71,10 @@ func TestUninstallAllFlag(t *testing.T) { uninstallCmdOptions := addTestUninstallCmd(options, cmd) - kamelTestPostAddCommandInit(t, cmd) + kamelTestPostAddCommandInit(t, cmd, options) _, err := test.ExecuteCommand(cmd, "uninstall", "--all") - assert.Nil(t, err) + require.NoError(t, err) assert.True(t, uninstallCmdOptions.SkipCrd) assert.True(t, uninstallCmdOptions.SkipClusterRoles) assert.False(t, uninstallCmdOptions.SkipIntegrationPlatform) diff --git a/pkg/cmd/util.go b/pkg/cmd/util.go index 966eb80a9c..1ecdcf35e0 100644 --- a/pkg/cmd/util.go +++ b/pkg/cmd/util.go @@ -59,13 +59,13 @@ func DeleteIntegration(ctx context.Context, c client.Client, name string, namesp return c.Delete(ctx, &integration) } -func bindPFlagsHierarchy(cmd *cobra.Command) error { +func bindPFlagsHierarchy(cmd *cobra.Command, v *viper.Viper) error { for _, c := range cmd.Commands() { - if err := bindPFlags(c); err != nil { + if err := bindPFlags(c, v); err != nil { return err } - if err := bindPFlagsHierarchy(c); err != nil { + if err := bindPFlagsHierarchy(c, v); err != nil { return err } } @@ -73,7 +73,7 @@ func bindPFlagsHierarchy(cmd *cobra.Command) error { return nil } -func bindPFlags(cmd *cobra.Command) error { +func bindPFlags(cmd *cobra.Command, v *viper.Viper) error { prefix := pathToRoot(cmd) pl := p.NewClient() @@ -82,16 +82,16 @@ func bindPFlags(cmd *cobra.Command) error { name = strings.ReplaceAll(name, "_", "-") name = strings.ReplaceAll(name, ".", "-") - if err := viper.BindPFlag(prefix+"."+name, flag); err != nil { + if err := v.BindPFlag(prefix+"."+name, flag); err != nil { log.Printf("error binding flag %s with prefix %s to viper: %v", flag.Name, prefix, err) } - // this is a little bit of an hack to register plural version of properties + // this is a little bit of a hack to register plural version of properties // based on the naming conventions used by the flag type because it is not - // possible to know what is the type of a flag + // possible to know what is the type of the flag flagType := strings.ToUpper(flag.Value.Type()) if strings.Contains(flagType, "SLICE") || strings.Contains(flagType, "ARRAY") { - if err := viper.BindPFlag(prefix+"."+pl.Plural(name), flag); err != nil { + if err := v.BindPFlag(prefix+"."+pl.Plural(name), flag); err != nil { log.Printf("error binding plural flag %s with prefix %s to viper: %v", flag.Name, prefix, err) } } @@ -113,9 +113,8 @@ func pathToRoot(cmd *cobra.Command) string { return path } -func decodeKey(target interface{}, key string) error { +func decodeKey(target interface{}, key string, settings map[string]any) error { nodes := strings.Split(key, ".") - settings := viper.AllSettings() for _, node := range nodes { v := settings[node] @@ -154,10 +153,10 @@ func decodeKey(target interface{}, key string) error { return nil } -func decode(target interface{}) func(*cobra.Command, []string) error { +func decode(target interface{}, v *viper.Viper) func(*cobra.Command, []string) error { return func(cmd *cobra.Command, args []string) error { path := pathToRoot(cmd) - if err := decodeKey(target, path); err != nil { + if err := decodeKey(target, path, v.AllSettings()); err != nil { return err } diff --git a/pkg/cmd/util_config.go b/pkg/cmd/util_config.go index df7b7dcc8c..6212426f35 100644 --- a/pkg/cmd/util_config.go +++ b/pkg/cmd/util_config.go @@ -57,7 +57,7 @@ func LoadConfiguration() (*Config, error) { return loadConfiguration(viper.ConfigFileUsed()) } -// LoadConfiguration loads a kamel configuration file from a specific location. +// LoadConfigurationFrom loads a kamel configuration file from a specific location. func LoadConfigurationFrom(location string) (*Config, error) { return loadConfiguration(location) } diff --git a/pkg/cmd/version.go b/pkg/cmd/version.go index 1f635209d7..e9bc20b902 100644 --- a/pkg/cmd/version.go +++ b/pkg/cmd/version.go @@ -50,7 +50,7 @@ func newCmdVersion(rootCmdOptions *RootCmdOptions) (*cobra.Command, *versionCmdO Use: "version", Short: "Display client version", Long: `Display Camel K client version.`, - PersistentPreRunE: decode(&options), + PersistentPreRunE: decode(&options, options.Flags), PreRunE: options.preRunE, RunE: options.run, Annotations: make(map[string]string), diff --git a/pkg/cmd/version_test.go b/pkg/cmd/version_test.go index e911e12d37..dfd33a54b8 100644 --- a/pkg/cmd/version_test.go +++ b/pkg/cmd/version_test.go @@ -29,6 +29,7 @@ import ( "github.com/apache/camel-k/v2/pkg/util/test" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) const cmdVersion = "version" @@ -38,10 +39,10 @@ func initializeVersionCmdOptions(t *testing.T, initObjs ...runtime.Object) (*ver t.Helper() fakeClient, err := test.NewFakeClient(initObjs...) - assert.Nil(t, err) + require.NoError(t, err) options, rootCmd := kamelTestPreAddCommandInitWithClient(fakeClient) versionCmdOptions := addTestVersionCmd(*options, rootCmd) - kamelTestPostAddCommandInit(t, rootCmd) + kamelTestPostAddCommandInit(t, rootCmd, options) return versionCmdOptions, rootCmd, *options } @@ -57,28 +58,28 @@ func addTestVersionCmd(options RootCmdOptions, rootCmd *cobra.Command) *versionC func TestVersionNonExistingFlag(t *testing.T) { _, rootCmd, _ := initializeVersionCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdVersion, "--nonExistingFlag") - assert.NotNil(t, err) + require.Error(t, err) } func TestVersionClient(t *testing.T) { _, rootCmd, _ := initializeVersionCmdOptions(t) output, err := test.ExecuteCommand(rootCmd, cmdVersion) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, fmt.Sprintf("Camel K Client %s\n", defaults.Version), output) } func TestVersionOperatorFlag(t *testing.T) { versionCmdOptions, rootCmd, _ := initializeVersionCmdOptions(t) _, err := test.ExecuteCommand(rootCmd, cmdVersion, "--operator") - assert.Nil(t, err) - assert.Equal(t, true, versionCmdOptions.Operator) + require.NoError(t, err) + assert.True(t, versionCmdOptions.Operator) } func TestVersionClientVerbose(t *testing.T) { versionCmdOptions, rootCmd, _ := initializeVersionCmdOptions(t) output, err := test.ExecuteCommand(rootCmd, cmdVersion, "-v") - assert.Nil(t, err) - assert.Equal(t, true, versionCmdOptions.Verbose) + require.NoError(t, err) + assert.True(t, versionCmdOptions.Verbose) assert.Equal(t, fmt.Sprintf("Camel K Client %s\nGit Commit: %s\n", defaults.Version, defaults.GitCommit), output) } @@ -98,8 +99,8 @@ func TestOperatorVersionVerbose(t *testing.T) { versionCmdOptions, rootCmd, _ := initializeVersionCmdOptions(t, &platform, &catalog) output, err := test.ExecuteCommand(rootCmd, cmdVersion, "-v", "--operator") - assert.Nil(t, err) - assert.Equal(t, true, versionCmdOptions.Verbose) + require.NoError(t, err) + assert.True(t, versionCmdOptions.Verbose) assert.Contains(t, output, fmt.Sprintf("Camel K Operator %s\n", defaults.Version)) assert.Contains(t, output, fmt.Sprintf("Camel version: %s\n", catalog.Spec.GetCamelVersion())) assert.Contains(t, output, fmt.Sprintf("Camel Quarkus version: %s\n", catalog.Spec.GetCamelQuarkusVersion())) @@ -108,17 +109,17 @@ func TestOperatorVersionVerbose(t *testing.T) { func TestCompatibleVersions(t *testing.T) { _, rootCmd, _ := initializeVersionCmdOptions(t) - assert.Equal(t, true, compatibleVersions("1.3.0", "1.3.0", rootCmd)) - assert.Equal(t, true, compatibleVersions("1.3.0", "1.3.1", rootCmd)) - assert.Equal(t, true, compatibleVersions("1.3.0", "1.3.0-SNAPSHOT", rootCmd)) - assert.Equal(t, false, compatibleVersions("1.3.0", "1.2.0", rootCmd)) - assert.Equal(t, false, compatibleVersions("1.3.0", "2.3.0", rootCmd)) - assert.Equal(t, false, compatibleVersions("1.3.0", "dsadsa", rootCmd)) - assert.Equal(t, false, compatibleVersions("dsadsa", "1.3.4", rootCmd)) + assert.True(t, compatibleVersions("1.3.0", "1.3.0", rootCmd)) + assert.True(t, compatibleVersions("1.3.0", "1.3.1", rootCmd)) + assert.True(t, compatibleVersions("1.3.0", "1.3.0-SNAPSHOT", rootCmd)) + assert.False(t, compatibleVersions("1.3.0", "1.2.0", rootCmd)) + assert.False(t, compatibleVersions("1.3.0", "2.3.0", rootCmd)) + assert.False(t, compatibleVersions("1.3.0", "dsadsa", rootCmd)) + assert.False(t, compatibleVersions("dsadsa", "1.3.4", rootCmd)) } func TestCompatibleVersionsNonSemver(t *testing.T) { _, rootCmd, _ := initializeVersionCmdOptions(t) - assert.Equal(t, true, compatibleVersions("1.3.0.special-version", "1.3.0.special-version", rootCmd)) - assert.Equal(t, false, compatibleVersions("1.3.1.special-version", "1.3.0.special-version", rootCmd)) + assert.True(t, compatibleVersions("1.3.0.special-version", "1.3.0.special-version", rootCmd)) + assert.False(t, compatibleVersions("1.3.1.special-version", "1.3.0.special-version", rootCmd)) } diff --git a/pkg/controller/build/build_monitor_test.go b/pkg/controller/build/build_monitor_test.go index a5be2b6582..9b75eed48e 100644 --- a/pkg/controller/build/build_monitor_test.go +++ b/pkg/controller/build/build_monitor_test.go @@ -26,6 +26,7 @@ import ( "github.com/apache/camel-k/v2/pkg/util/test" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -155,7 +156,7 @@ func TestMonitorSequentialBuilds(t *testing.T) { c, err := test.NewFakeClient(initObjs...) - assert.Nil(t, err) + require.NoError(t, err) bm := Monitor{ maxRunningBuilds: 3, @@ -170,7 +171,7 @@ func TestMonitorSequentialBuilds(t *testing.T) { allowed, condition, err := bm.canSchedule(context.TODO(), c, tc.build) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, tc.allowed, allowed) assert.Equal(t, tc.condition.Type, condition.Type) assert.Equal(t, tc.condition.Status, condition.Status) @@ -183,7 +184,7 @@ func TestMonitorSequentialBuilds(t *testing.T) { func TestAllowBuildRequeue(t *testing.T) { c, err := test.NewFakeClient() - assert.Nil(t, err) + require.NoError(t, err) bm := Monitor{ maxRunningBuilds: 3, @@ -200,7 +201,7 @@ func TestAllowBuildRequeue(t *testing.T) { build := newBuild("ns", "my-build") allowed, condition, err := bm.canSchedule(context.TODO(), c, build) - assert.Nil(t, err) + require.NoError(t, err) assert.False(t, allowed) assert.Equal(t, corev1.ConditionFalse, condition.Status) @@ -208,7 +209,7 @@ func TestAllowBuildRequeue(t *testing.T) { allowed, condition, err = bm.canSchedule(context.TODO(), c, build) - assert.Nil(t, err) + require.NoError(t, err) assert.True(t, allowed) assert.Equal(t, corev1.ConditionTrue, condition.Status) } @@ -367,7 +368,7 @@ func TestMonitorFIFOBuilds(t *testing.T) { c, err := test.NewFakeClient(initObjs...) - assert.Nil(t, err) + require.NoError(t, err) bm := Monitor{ maxRunningBuilds: 3, @@ -382,7 +383,7 @@ func TestMonitorFIFOBuilds(t *testing.T) { allowed, condition, err := bm.canSchedule(context.TODO(), c, tc.build) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, tc.allowed, allowed) assert.Equal(t, tc.condition.Type, condition.Type) assert.Equal(t, tc.condition.Status, condition.Status) @@ -607,7 +608,7 @@ func TestMonitorDependencyMatchingBuilds(t *testing.T) { c, err := test.NewFakeClient(initObjs...) - assert.Nil(t, err) + require.NoError(t, err) bm := Monitor{ maxRunningBuilds: 3, @@ -622,7 +623,7 @@ func TestMonitorDependencyMatchingBuilds(t *testing.T) { allowed, condition, err := bm.canSchedule(context.TODO(), c, tc.build) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, tc.allowed, allowed) assert.Equal(t, tc.condition.Type, condition.Type) assert.Equal(t, tc.condition.Status, condition.Status) diff --git a/pkg/controller/build/build_pod_test.go b/pkg/controller/build/build_pod_test.go index 3dc5c87da2..d2bc045876 100644 --- a/pkg/controller/build/build_pod_test.go +++ b/pkg/controller/build/build_pod_test.go @@ -24,6 +24,7 @@ import ( v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" "github.com/apache/camel-k/v2/pkg/util/test" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -31,7 +32,7 @@ func TestNewBuildPodConfiguration(t *testing.T) { ctx := context.TODO() c, err := test.NewFakeClient() - assert.Nil(t, err) + require.NoError(t, err) build := v1.Build{ ObjectMeta: metav1.ObjectMeta{ diff --git a/pkg/controller/build/monitor_pod.go b/pkg/controller/build/monitor_pod.go index 506fe105bd..e58a85038a 100644 --- a/pkg/controller/build/monitor_pod.go +++ b/pkg/controller/build/monitor_pod.go @@ -308,7 +308,7 @@ func (action *monitorPodAction) setConditionsFromTerminationMessages(ctx context var err error terminationMessage := t.Message // Dynamic condition type (it depends on each container name) - containerConditionType := v1.BuildConditionType(fmt.Sprintf("Container %s succeeded", container.Name)) + containerConditionType := v1.BuildConditionType(fmt.Sprintf("Container%sSucceeded", container.Name)) containerSucceeded := corev1.ConditionTrue if t.ExitCode != 0 { containerSucceeded = corev1.ConditionFalse diff --git a/pkg/controller/integration/build_kit.go b/pkg/controller/integration/build_kit.go index 6d47c00088..0605e01138 100644 --- a/pkg/controller/integration/build_kit.go +++ b/pkg/controller/integration/build_kit.go @@ -46,13 +46,13 @@ func (action *buildKitAction) CanHandle(integration *v1.Integration) bool { func (action *buildKitAction) Handle(ctx context.Context, integration *v1.Integration) (*v1.Integration, error) { // TODO: we may need to add a timeout strategy, i.e give up after some time in case of an unrecoverable error. - secrets, configmaps := getIntegrationSecretsAndConfigmaps(ctx, action.client, integration) + secrets, configmaps := getIntegrationSecretAndConfigmapResourceVersions(ctx, action.client, integration) hash, err := digest.ComputeForIntegration(integration, configmaps, secrets) if err != nil { return nil, err } if hash != integration.Status.Digest { - action.L.Info("Integration needs a rebuild") + action.L.Info("Integration %s digest has changed: resetting its status. Will check if it needs to be rebuilt and restarted.", integration.Name) integration.Initialize() integration.Status.Digest = hash return integration, nil diff --git a/pkg/controller/integration/health_test.go b/pkg/controller/integration/health_test.go index 35b4c81818..946ae88693 100644 --- a/pkg/controller/integration/health_test.go +++ b/pkg/controller/integration/health_test.go @@ -25,6 +25,7 @@ import ( camelv1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestNewHealthCheck(t *testing.T) { @@ -63,7 +64,7 @@ func TestNewHealthCheck(t *testing.T) { } `) health, err := NewHealthCheck(body) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, camelv1.HealthCheckStatusDown, health.Status) assert.Len(t, health.Checks, 3) assert.Equal(t, "camel-routes", health.Checks[0].Name) @@ -94,7 +95,7 @@ func raw2map(t *testing.T, in camelv1.RawMessage) map[string]interface{} { answer := make(map[string]interface{}) err := json.Unmarshal(in, &answer) - assert.Nil(t, err) + require.NoError(t, err) return answer } diff --git a/pkg/controller/integration/initialize_test.go b/pkg/controller/integration/initialize_test.go index 2beaaa798b..f9d323f332 100644 --- a/pkg/controller/integration/initialize_test.go +++ b/pkg/controller/integration/initialize_test.go @@ -30,6 +30,7 @@ import ( "github.com/apache/camel-k/v2/pkg/util/test" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestCamelImportDeployment(t *testing.T) { @@ -52,7 +53,7 @@ func TestCamelImportDeployment(t *testing.T) { }, } c, err := test.NewFakeClient(importedIt) - assert.Nil(t, err) + require.NoError(t, err) a := initializeAction{} a.InjectLogger(log.Log) @@ -60,7 +61,7 @@ func TestCamelImportDeployment(t *testing.T) { assert.Equal(t, "initialize", a.Name()) assert.True(t, a.CanHandle(importedIt)) handledIt, err := a.Handle(context.TODO(), importedIt) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, v1.IntegrationPhaseRunning, handledIt.Status.Phase) // Ready condition assert.Equal(t, corev1.ConditionTrue, handledIt.Status.GetCondition(v1.IntegrationConditionReady).Status) @@ -92,7 +93,7 @@ func TestCamelImportCronJob(t *testing.T) { }, } c, err := test.NewFakeClient(importedIt) - assert.Nil(t, err) + require.NoError(t, err) a := initializeAction{} a.InjectLogger(log.Log) @@ -100,7 +101,7 @@ func TestCamelImportCronJob(t *testing.T) { assert.Equal(t, "initialize", a.Name()) assert.True(t, a.CanHandle(importedIt)) handledIt, err := a.Handle(context.TODO(), importedIt) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, v1.IntegrationPhaseRunning, handledIt.Status.Phase) // Ready condition assert.Equal(t, corev1.ConditionTrue, handledIt.Status.GetCondition(v1.IntegrationConditionReady).Status) @@ -132,7 +133,7 @@ func TestCamelImportKnativeService(t *testing.T) { }, } c, err := test.NewFakeClient(importedIt) - assert.Nil(t, err) + require.NoError(t, err) a := initializeAction{} a.InjectLogger(log.Log) @@ -140,7 +141,7 @@ func TestCamelImportKnativeService(t *testing.T) { assert.Equal(t, "initialize", a.Name()) assert.True(t, a.CanHandle(importedIt)) handledIt, err := a.Handle(context.TODO(), importedIt) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, v1.IntegrationPhaseRunning, handledIt.Status.Phase) // Ready condition assert.Equal(t, corev1.ConditionTrue, handledIt.Status.GetCondition(v1.IntegrationConditionReady).Status) @@ -172,7 +173,7 @@ func TestCamelImportUnsupportedKind(t *testing.T) { }, } c, err := test.NewFakeClient(importedIt) - assert.Nil(t, err) + require.NoError(t, err) a := initializeAction{} a.InjectLogger(log.Log) @@ -180,7 +181,7 @@ func TestCamelImportUnsupportedKind(t *testing.T) { assert.Equal(t, "initialize", a.Name()) assert.True(t, a.CanHandle(importedIt)) handledIt, err := a.Handle(context.TODO(), importedIt) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, v1.IntegrationPhaseError, handledIt.Status.Phase) // Ready condition assert.Equal(t, corev1.ConditionFalse, handledIt.Status.GetCondition(v1.IntegrationConditionReady).Status) diff --git a/pkg/controller/integration/integration_controller.go b/pkg/controller/integration/integration_controller.go index 18ebcb24a8..a731792464 100644 --- a/pkg/controller/integration/integration_controller.go +++ b/pkg/controller/integration/integration_controller.go @@ -20,6 +20,7 @@ package integration import ( "context" "fmt" + "reflect" "time" @@ -95,6 +96,7 @@ func integrationUpdateFunc(old *v1.Integration, it *v1.Integration) bool { timeToFirstReadiness.Observe(duration.Seconds()) } + updateIntegrationPhase(it.Name, string(it.Status.Phase)) // If traits have changed, the reconciliation loop must kick in as // traits may have impact sameTraits, err := trait.IntegrationsHaveSameTraits(old, it) @@ -595,7 +597,7 @@ func (r *reconcileIntegration) Reconcile(ctx context.Context, request reconcile. } func (r *reconcileIntegration) update(ctx context.Context, base *v1.Integration, target *v1.Integration, log *log.Logger) error { - secrets, configmaps := getIntegrationSecretsAndConfigmaps(ctx, r.client, target) + secrets, configmaps := getIntegrationSecretAndConfigmapResourceVersions(ctx, r.client, target) d, err := digest.ComputeForIntegration(target, configmaps, secrets) if err != nil { return err diff --git a/pkg/controller/integration/kits.go b/pkg/controller/integration/kits.go index fd1a106ddf..22adf0f039 100644 --- a/pkg/controller/integration/kits.go +++ b/pkg/controller/integration/kits.go @@ -19,8 +19,6 @@ package integration import ( "context" - "fmt" - "reflect" k8serrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/labels" @@ -127,12 +125,12 @@ func integrationMatches(ctx context.Context, c client.Client, integration *v1.In if err != nil { return false, err } - ikc, err := trait.NewStatusTraitsOptionsForIntegrationKit(kit) + ikc, err := trait.NewSpecTraitsOptionsForIntegrationKit(kit) if err != nil { return false, err } - if match, err := hasMatchingTraits(itc, ikc); !match || err != nil { + if match, err := trait.HasMatchingTraits(itc, ikc); !match || err != nil { ilog.Debug("Integration and integration-kit traits do not match", "integration", integration.Name, "integration-kit", kit.Name, "namespace", integration.Namespace) return false, err } @@ -190,12 +188,12 @@ func kitMatches(kit *v1.IntegrationKit, target *v1.IntegrationKit) (bool, error) if err != nil { return false, err } - c2, err := trait.NewStatusTraitsOptionsForIntegrationKit(target) + c2, err := trait.NewSpecTraitsOptionsForIntegrationKit(target) if err != nil { return false, err } - if match, err := hasMatchingTraits(c1, c2); !match || err != nil { + if match, err := trait.HasMatchingTraits(c1, c2); !match || err != nil { return false, err } if !util.StringSliceContains(kit.Spec.Dependencies, target.Spec.Dependencies) { @@ -205,67 +203,6 @@ func kitMatches(kit *v1.IntegrationKit, target *v1.IntegrationKit) (bool, error) return true, nil } -func hasMatchingTraits(traitMap trait.Options, kitTraitMap trait.Options) (bool, error) { - catalog := trait.NewCatalog(nil) - - for _, t := range catalog.AllTraits() { - if t == nil { - continue - } - - id := string(t.ID()) - it, ok1 := traitMap.Get(id) - kt, ok2 := kitTraitMap.Get(id) - - if !ok1 && !ok2 { - continue - } - - if t.InfluencesKit() && t.InfluencesBuild(it, kt) { - if ct, ok := t.(trait.ComparableTrait); ok { - // if it's match trait use its matches method to determine the match - if match, err := matchesComparableTrait(ct, it, kt); !match || err != nil { - return false, err - } - } else { - if !matchesTrait(it, kt) { - return false, nil - } - } - } - } - - return true, nil -} - -func matchesComparableTrait(ct trait.ComparableTrait, it map[string]interface{}, kt map[string]interface{}) (bool, error) { - t1 := reflect.New(reflect.TypeOf(ct).Elem()).Interface() - if err := trait.ToTrait(it, &t1); err != nil { - return false, err - } - - t2 := reflect.New(reflect.TypeOf(ct).Elem()).Interface() - if err := trait.ToTrait(kt, &t2); err != nil { - return false, err - } - - ct2, ok := t2.(trait.ComparableTrait) - if !ok { - return false, fmt.Errorf("type assertion failed: %v", t2) - } - tt1, ok := t1.(trait.Trait) - if !ok { - return false, fmt.Errorf("type assertion failed: %v", t1) - } - - return ct2.Matches(tt1), nil -} - -func matchesTrait(it map[string]interface{}, kt map[string]interface{}) bool { - // perform exact match on the two trait maps - return reflect.DeepEqual(it, kt) -} - func hasMatchingSourcesForNative(it *v1.Integration, kit *v1.IntegrationKit) bool { if len(it.UserDefinedSources()) != len(kit.Spec.Sources) { return false diff --git a/pkg/controller/integration/kits_test.go b/pkg/controller/integration/kits_test.go index 4e5d70907d..1f946aa350 100644 --- a/pkg/controller/integration/kits_test.go +++ b/pkg/controller/integration/kits_test.go @@ -27,10 +27,10 @@ import ( traitv1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1/trait" "github.com/apache/camel-k/v2/pkg/trait" - "github.com/apache/camel-k/v2/pkg/util/log" "github.com/apache/camel-k/v2/pkg/util/test" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestLookupKitForIntegration_DiscardKitsInError(t *testing.T) { @@ -91,11 +91,7 @@ func TestLookupKitForIntegration_DiscardKitsInError(t *testing.T) { }, ) - assert.Nil(t, err) - - a := buildKitAction{} - a.InjectLogger(log.Log) - a.InjectClient(c) + require.NoError(t, err) kits, err := lookupKitsForIntegration(context.TODO(), c, &v1.Integration{ TypeMeta: metav1.TypeMeta{ @@ -114,7 +110,7 @@ func TestLookupKitForIntegration_DiscardKitsInError(t *testing.T) { }, }) - assert.Nil(t, err) + require.NoError(t, err) assert.NotNil(t, kits) assert.Len(t, kits, 1) assert.Equal(t, "my-kit-2", kits[0].Name) @@ -182,11 +178,6 @@ func TestLookupKitForIntegration_DiscardKitsWithIncompatibleTraits(t *testing.T) }, Status: v1.IntegrationKitStatus{ Phase: v1.IntegrationKitPhaseReady, - Traits: v1.IntegrationKitTraits{ - Builder: &traitv1.BuilderTrait{ - PlatformBaseTrait: traitv1.PlatformBaseTrait{}, - }, - }, }, }, // Should NOT be discarded because it contains a subset of the required traits and @@ -219,23 +210,11 @@ func TestLookupKitForIntegration_DiscardKitsWithIncompatibleTraits(t *testing.T) }, Status: v1.IntegrationKitStatus{ Phase: v1.IntegrationKitPhaseReady, - Traits: v1.IntegrationKitTraits{ - Builder: &traitv1.BuilderTrait{ - PlatformBaseTrait: traitv1.PlatformBaseTrait{}, - Properties: []string{ - "build-key1=build-value1", - }, - }, - }, }, }, ) - assert.Nil(t, err) - - a := buildKitAction{} - a.InjectLogger(log.Log) - a.InjectClient(c) + require.NoError(t, err) kits, err := lookupKitsForIntegration(context.TODO(), c, &v1.Integration{ TypeMeta: metav1.TypeMeta{ @@ -261,18 +240,10 @@ func TestLookupKitForIntegration_DiscardKitsWithIncompatibleTraits(t *testing.T) "camel-core", "camel-irc", }, - Traits: v1.Traits{ - Builder: &traitv1.BuilderTrait{ - PlatformBaseTrait: traitv1.PlatformBaseTrait{}, - Properties: []string{ - "build-key1=build-value1", - }, - }, - }, }, }) - assert.Nil(t, err) + require.NoError(t, err) assert.NotNil(t, kits) assert.Len(t, kits, 1) assert.Equal(t, "my-kit-3", kits[0].Name) @@ -295,13 +266,6 @@ func TestHasMatchingTraits_KitNoTraitShouldNotBePicked(t *testing.T) { }, }, }, - Status: v1.IntegrationStatus{ - Traits: v1.Traits{ - Builder: &traitv1.BuilderTrait{ - PlatformBaseTrait: traitv1.PlatformBaseTrait{}, - }, - }, - }, } kit := &v1.IntegrationKit{ @@ -315,11 +279,8 @@ func TestHasMatchingTraits_KitNoTraitShouldNotBePicked(t *testing.T) { }, } - a := buildKitAction{} - a.InjectLogger(log.Log) - ok, err := integrationAndKitHaveSameTraits(integration, kit) - assert.Nil(t, err) + require.NoError(t, err) assert.False(t, ok) } @@ -343,16 +304,6 @@ func TestHasMatchingTraits_KitSameTraitShouldBePicked(t *testing.T) { }, }, }, - Status: v1.IntegrationStatus{ - Traits: v1.Traits{ - Builder: &traitv1.BuilderTrait{ - PlatformBaseTrait: traitv1.PlatformBaseTrait{}, - Properties: []string{ - "build-key1=build-value1", - }, - }, - }, - }, } kit := &v1.IntegrationKit{ @@ -374,23 +325,10 @@ func TestHasMatchingTraits_KitSameTraitShouldBePicked(t *testing.T) { }, }, }, - Status: v1.IntegrationKitStatus{ - Traits: v1.IntegrationKitTraits{ - Builder: &traitv1.BuilderTrait{ - PlatformBaseTrait: traitv1.PlatformBaseTrait{}, - Properties: []string{ - "build-key1=build-value1", - }, - }, - }, - }, } - a := buildKitAction{} - a.InjectLogger(log.Log) - ok, err := integrationAndKitHaveSameTraits(integration, kit) - assert.Nil(t, err) + require.NoError(t, err) assert.True(t, ok) } diff --git a/pkg/controller/integration/metrics.go b/pkg/controller/integration/metrics.go index 46eb3f2cee..f235a0bc2d 100644 --- a/pkg/controller/integration/metrics.go +++ b/pkg/controller/integration/metrics.go @@ -18,6 +18,7 @@ limitations under the License. package integration import ( + "strings" "time" "sigs.k8s.io/controller-runtime/pkg/metrics" @@ -25,21 +26,45 @@ import ( "github.com/prometheus/client_golang/prometheus" ) -var timeToFirstReadiness = prometheus.NewHistogram( - prometheus.HistogramOpts{ - Name: "camel_k_integration_first_readiness_seconds", - Help: "Camel K integration time to first readiness", - Buckets: []float64{ - 5 * time.Second.Seconds(), - 10 * time.Second.Seconds(), - 30 * time.Second.Seconds(), - 1 * time.Minute.Seconds(), - 2 * time.Minute.Seconds(), +var ( + timeToFirstReadiness = prometheus.NewHistogram( + prometheus.HistogramOpts{ + Name: "camel_k_integration_first_readiness_seconds", + Help: "Camel K integration time to first readiness", + Buckets: []float64{ + 5 * time.Second.Seconds(), + 10 * time.Second.Seconds(), + 30 * time.Second.Seconds(), + 1 * time.Minute.Seconds(), + 2 * time.Minute.Seconds(), + }, }, - }, + ) + + integration = prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "camel_k_integration_phase_total", + Help: "Number of integration processed", + }, []string{ + "phase", + "id", + }, + ) ) func init() { // Register custom metrics with the global prometheus registry - metrics.Registry.MustRegister(timeToFirstReadiness) + metrics.Registry.MustRegister(timeToFirstReadiness, integration) +} + +func updateIntegrationPhase(iID string, p string) { + phase := strings.ReplaceAll(strings.ToLower(p), " ", "_") + + if phase != "" && iID != "" { + labels := prometheus.Labels{ + "id": iID, + "phase": phase, + } + integration.With(labels).Inc() + } } diff --git a/pkg/controller/integration/metrics_test.go b/pkg/controller/integration/metrics_test.go new file mode 100644 index 0000000000..5fce7b832c --- /dev/null +++ b/pkg/controller/integration/metrics_test.go @@ -0,0 +1,82 @@ +package integration + +import ( + "github.com/prometheus/client_golang/prometheus" + dto "github.com/prometheus/client_model/go" + "github.com/stretchr/testify/assert" + "testing" +) + +// getMetricValue returns the sum of the Counter metrics associated with the Collector +// e.g. the metric for a non-vector, or the sum of the metrics for vector labels. +// If the metric is a Histogram then number of samples is used. +func getMetricValue(col prometheus.Collector) float64 { + var total float64 + collect(col, func(m *dto.Metric) { + if h := m.GetHistogram(); h != nil { + total += float64(h.GetSampleCount()) + } else { + total += m.GetCounter().GetValue() + } + }) + return total +} + +// collect calls the function for each metric associated with the Collector +func collect(col prometheus.Collector, do func(*dto.Metric)) { + c := make(chan prometheus.Metric) + go func(c chan prometheus.Metric) { + col.Collect(c) + close(c) + }(c) + for x := range c { // eg range across distinct label vector values + m := dto.Metric{} + _ = x.Write(&m) + do(&m) + } +} + +func Test_updateIntegrationPhase(t *testing.T) { + type args struct { + iId string + p string + expected float64 + } + tests := []struct { + name string + args args + }{ + { + name: "test should fail with empty id", args: args{ + iId: "", + p: "running", + expected: 0, + }, + }, + { + name: "test should fail with empty phase", args: args{ + iId: "int-1", + p: "", + expected: 0, + }, + }, + { + name: "test should pass and increase the counter", args: args{ + iId: "int-1", + p: "running", + expected: 1, + }, + }, + } + for _, tt := range tests { + // integration.Reset() + t.Run(tt.name, func(t *testing.T) { + updateIntegrationPhase(tt.args.iId, tt.args.p) + labels := map[string]string{"phase": tt.args.p, "id": tt.args.iId} + if i, err := integration.GetMetricWith(labels); err == nil { + val := getMetricValue(i) + assert.Equal(t, val, tt.args.expected) + } + }) + } +} diff --git a/pkg/controller/integration/monitor.go b/pkg/controller/integration/monitor.go index 276216920e..2c526be948 100644 --- a/pkg/controller/integration/monitor.go +++ b/pkg/controller/integration/monitor.go @@ -30,6 +30,7 @@ import ( k8serrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/selection" + "k8s.io/utils/pointer" ctrl "sigs.k8s.io/controller-runtime/pkg/client" @@ -41,6 +42,7 @@ import ( "github.com/apache/camel-k/v2/pkg/util/digest" "github.com/apache/camel-k/v2/pkg/util/kubernetes" utilResource "github.com/apache/camel-k/v2/pkg/util/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) // NewMonitorAction is an action used to monitor manager Integrations. @@ -228,19 +230,17 @@ func isInIntegrationKitFailed(status v1.IntegrationStatus) bool { } func (action *monitorAction) checkDigestAndRebuild(ctx context.Context, integration *v1.Integration, kit *v1.IntegrationKit) (*v1.Integration, error) { - secrets, configmaps := getIntegrationSecretsAndConfigmaps(ctx, action.client, integration) + secrets, configmaps := getIntegrationSecretAndConfigmapResourceVersions(ctx, action.client, integration) hash, err := digest.ComputeForIntegration(integration, configmaps, secrets) if err != nil { return nil, err } if hash != integration.Status.Digest { - action.L.Info("Monitor: Integration needs a rebuild") - + action.L.Infof("Integration %s digest has changed: resetting its status. Will check if it needs to be rebuilt and restarted.", integration.Name) if isIntegrationKitResetRequired(integration, kit) { integration.SetIntegrationKit(nil) } - integration.Initialize() integration.Status.Digest = hash @@ -279,29 +279,40 @@ func isIntegrationKitResetRequired(integration *v1.Integration, kit *v1.Integrat return false } -func getIntegrationSecretsAndConfigmaps(ctx context.Context, client client.Client, integration *v1.Integration) ([]*corev1.Secret, []*corev1.ConfigMap) { - configmaps := make([]*corev1.ConfigMap, 0) - secrets := make([]*corev1.Secret, 0) - if integration.Spec.Traits.Mount != nil { - for _, c := range integration.Spec.Traits.Mount.Configs { +// getIntegrationSecretAndConfigmapResourceVersions returns the list of resource versions only useful to watch for changes. +func getIntegrationSecretAndConfigmapResourceVersions(ctx context.Context, client client.Client, integration *v1.Integration) ([]string, []string) { + configmaps := make([]string, 0) + secrets := make([]string, 0) + if integration.Spec.Traits.Mount != nil && pointer.BoolDeref(integration.Spec.Traits.Mount.HotReload, false) { + mergedResources := make([]string, 0) + mergedResources = append(mergedResources, integration.Spec.Traits.Mount.Configs...) + mergedResources = append(mergedResources, integration.Spec.Traits.Mount.Resources...) + for _, c := range mergedResources { if conf, parseErr := utilResource.ParseConfig(c); parseErr == nil { if conf.StorageType() == utilResource.StorageTypeConfigmap { - configmap := kubernetes.LookupConfigmap(ctx, client, integration.Namespace, conf.Name()) - configmaps = append(configmaps, configmap) - } else if conf.StorageType() == utilResource.StorageTypeSecret { - secret := kubernetes.LookupSecret(ctx, client, integration.Namespace, conf.Name()) - secrets = append(secrets, secret) - } - } - } - for _, r := range integration.Spec.Traits.Mount.Resources { - if conf, parseErr := utilResource.ParseConfig(r); parseErr == nil { - if conf.StorageType() == utilResource.StorageTypeConfigmap { - configmap := kubernetes.LookupConfigmap(ctx, client, integration.Namespace, conf.Name()) - configmaps = append(configmaps, configmap) + cm := corev1.ConfigMap{ + TypeMeta: metav1.TypeMeta{ + Kind: "ConfigMap", + APIVersion: corev1.SchemeGroupVersion.String(), + }, + ObjectMeta: metav1.ObjectMeta{ + Namespace: integration.Namespace, + Name: conf.Name(), + }, + } + configmaps = append(configmaps, kubernetes.LookupResourceVersion(ctx, client, &cm)) } else if conf.StorageType() == utilResource.StorageTypeSecret { - secret := kubernetes.LookupSecret(ctx, client, integration.Namespace, conf.Name()) - secrets = append(secrets, secret) + sec := corev1.Secret{ + TypeMeta: metav1.TypeMeta{ + Kind: "Secret", + APIVersion: corev1.SchemeGroupVersion.String(), + }, + ObjectMeta: metav1.ObjectMeta{ + Namespace: integration.Namespace, + Name: conf.Name(), + }, + } + secrets = append(secrets, kubernetes.LookupResourceVersion(ctx, client, &sec)) } } } diff --git a/pkg/controller/integration/monitor_synthetic_test.go b/pkg/controller/integration/monitor_synthetic_test.go index b1cf8a66c2..d9893c378c 100644 --- a/pkg/controller/integration/monitor_synthetic_test.go +++ b/pkg/controller/integration/monitor_synthetic_test.go @@ -34,6 +34,7 @@ import ( "github.com/apache/camel-k/v2/pkg/util/test" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "knative.dev/pkg/apis" duckv1 "knative.dev/pkg/apis/duck/v1" ) @@ -58,7 +59,7 @@ func TestMonitorSyntheticIntegrationImportingKindUnavailable(t *testing.T) { }, } c, err := test.NewFakeClient(importedIt) - assert.Nil(t, err) + require.NoError(t, err) a := monitorSyntheticAction{} a.InjectLogger(log.Log) @@ -66,7 +67,7 @@ func TestMonitorSyntheticIntegrationImportingKindUnavailable(t *testing.T) { assert.Equal(t, "monitor-synthetic", a.Name()) assert.True(t, a.CanHandle(importedIt)) handledIt, err := a.Handle(context.TODO(), importedIt) - assert.NotNil(t, err) + require.Error(t, err) assert.Equal(t, v1.IntegrationPhaseError, handledIt.Status.Phase) assert.Equal(t, corev1.ConditionFalse, handledIt.Status.GetCondition(v1.IntegrationConditionReady).Status) assert.Equal(t, v1.IntegrationConditionImportingKindAvailableReason, handledIt.Status.GetCondition(v1.IntegrationConditionReady).Reason) @@ -116,7 +117,7 @@ func TestMonitorSyntheticIntegrationCannotMonitorPods(t *testing.T) { }, } c, err := test.NewFakeClient(importedIt, deploy) - assert.Nil(t, err) + require.NoError(t, err) a := monitorSyntheticAction{} a.InjectLogger(log.Log) @@ -124,7 +125,7 @@ func TestMonitorSyntheticIntegrationCannotMonitorPods(t *testing.T) { assert.Equal(t, "monitor-synthetic", a.Name()) assert.True(t, a.CanHandle(importedIt)) handledIt, err := a.Handle(context.TODO(), importedIt) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, corev1.ConditionFalse, handledIt.Status.GetCondition(v1.IntegrationConditionReady).Status) // Check monitoring pods condition assert.Equal(t, v1.IntegrationConditionMonitoringPodsAvailableReason, handledIt.Status.GetCondition(v1.IntegrationConditionReady).Reason) @@ -228,7 +229,7 @@ func TestMonitorSyntheticIntegrationDeployment(t *testing.T) { }, } c, err := test.NewFakeClient(importedIt, deploy, pod) - assert.Nil(t, err) + require.NoError(t, err) a := monitorSyntheticAction{} a.InjectLogger(log.Log) @@ -236,7 +237,7 @@ func TestMonitorSyntheticIntegrationDeployment(t *testing.T) { assert.Equal(t, "monitor-synthetic", a.Name()) assert.True(t, a.CanHandle(importedIt)) handledIt, err := a.Handle(context.TODO(), importedIt) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, v1.IntegrationPhaseRunning, handledIt.Status.Phase) assert.Equal(t, int32(1), *handledIt.Status.Replicas) // Ready condition @@ -247,10 +248,10 @@ func TestMonitorSyntheticIntegrationDeployment(t *testing.T) { // Remove label from deployment deploy.Labels = nil c, err = test.NewFakeClient(importedIt, deploy) - assert.Nil(t, err) + require.NoError(t, err) a.InjectClient(c) handledIt, err = a.Handle(context.TODO(), importedIt) - assert.Nil(t, err) + require.NoError(t, err) assert.Nil(t, handledIt) } @@ -348,7 +349,7 @@ func TestMonitorSyntheticIntegrationCronJob(t *testing.T) { }, } c, err := test.NewFakeClient(importedIt, cron, pod) - assert.Nil(t, err) + require.NoError(t, err) a := monitorSyntheticAction{} a.InjectLogger(log.Log) @@ -356,7 +357,7 @@ func TestMonitorSyntheticIntegrationCronJob(t *testing.T) { assert.Equal(t, "monitor-synthetic", a.Name()) assert.True(t, a.CanHandle(importedIt)) handledIt, err := a.Handle(context.TODO(), importedIt) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, v1.IntegrationPhaseRunning, handledIt.Status.Phase) assert.Equal(t, int32(1), *handledIt.Status.Replicas) // Ready condition @@ -469,7 +470,7 @@ func TestMonitorSyntheticIntegrationKnativeService(t *testing.T) { }, } c, err := test.NewFakeClient(importedIt, ksvc, pod) - assert.Nil(t, err) + require.NoError(t, err) a := monitorSyntheticAction{} a.InjectLogger(log.Log) @@ -477,7 +478,7 @@ func TestMonitorSyntheticIntegrationKnativeService(t *testing.T) { assert.Equal(t, "monitor-synthetic", a.Name()) assert.True(t, a.CanHandle(importedIt)) handledIt, err := a.Handle(context.TODO(), importedIt) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, v1.IntegrationPhaseRunning, handledIt.Status.Phase) assert.Equal(t, int32(1), *handledIt.Status.Replicas) // Ready condition diff --git a/pkg/controller/integration/monitor_test.go b/pkg/controller/integration/monitor_test.go new file mode 100644 index 0000000000..fcd3423d8e --- /dev/null +++ b/pkg/controller/integration/monitor_test.go @@ -0,0 +1,85 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package integration + +import ( + "context" + "testing" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/utils/pointer" + + v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" + "github.com/apache/camel-k/v2/pkg/apis/camel/v1/trait" + + "github.com/apache/camel-k/v2/pkg/util/kubernetes" + "github.com/apache/camel-k/v2/pkg/util/test" + + "github.com/stretchr/testify/assert" +) + +func TestGetIntegrationSecretAndConfigmapResourceVersions(t *testing.T) { + cm := kubernetes.NewConfigMap("default", "cm-test", "test.txt", "test.txt", "xyz", nil) + sec := &corev1.Secret{ + TypeMeta: metav1.TypeMeta{ + Kind: "Secret", + APIVersion: "v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "sec-test", + Namespace: "default", + }, + Immutable: pointer.Bool(true), + } + sec.Data = map[string][]byte{ + "test.txt": []byte("hello"), + } + it := &v1.Integration{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-it", + Namespace: "default", + }, + TypeMeta: metav1.TypeMeta{ + APIVersion: v1.SchemeGroupVersion.String(), + Kind: v1.IntegrationKind, + }, + Spec: v1.IntegrationSpec{ + Traits: v1.Traits{ + Mount: &trait.MountTrait{ + Configs: []string{"configmap:cm-test"}, + Resources: []string{"secret:sec-test"}, + }, + }, + }, + } + c, err := test.NewFakeClient(cm, sec) + assert.Nil(t, err) + // Default hot reload (false) + configmaps, secrets := getIntegrationSecretAndConfigmapResourceVersions(context.TODO(), c, it) + assert.Len(t, configmaps, 0) + assert.Len(t, secrets, 0) + // Enabled hot reload (true) + it.Spec.Traits.Mount.HotReload = pointer.Bool(true) + configmaps, secrets = getIntegrationSecretAndConfigmapResourceVersions(context.TODO(), c, it) + assert.Len(t, configmaps, 1) + assert.Len(t, secrets, 1) + // We cannot guess resource version value. It should be enough to have any non empty value though. + assert.NotEqual(t, "", configmaps[0]) + assert.NotEqual(t, "", secrets[0]) +} diff --git a/pkg/controller/integrationplatform/catalog_test.go b/pkg/controller/integrationplatform/catalog_test.go index a6a8f0b8ed..9451f7a4e3 100644 --- a/pkg/controller/integrationplatform/catalog_test.go +++ b/pkg/controller/integrationplatform/catalog_test.go @@ -34,6 +34,7 @@ import ( "github.com/apache/camel-k/v2/pkg/util/test" "github.com/rs/xid" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime" @@ -54,7 +55,7 @@ func TestCanHandlePhaseCreateCatalog(t *testing.T) { ip.Status.Phase = v1.IntegrationPlatformPhaseCreateCatalog c, err := test.NewFakeClient(&ip) - assert.Nil(t, err) + require.NoError(t, err) action := NewCreateCatalogAction() action.InjectLogger(log.Log) @@ -83,11 +84,11 @@ func TestCreateCatalog(t *testing.T) { ip.Status.Phase = v1.IntegrationPlatformPhaseCreateCatalog ip.Spec.Build.RuntimeVersion = defaults.DefaultRuntimeVersion if strings.Contains(ip.Spec.Build.RuntimeVersion, "SNAPSHOT") { - maven.DefaultMavenRepositories = "https://repo.maven.apache.org/maven2@id=central,https://repository.apache.org/content/repositories/snapshots-group@snapshots@id=apache-snapshots" + maven.DefaultMavenRepositories += ",https://repository.apache.org/content/repositories/snapshots-group@snapshots@id=apache-snapshots" } c, err := test.NewFakeClient(&ip) - assert.Nil(t, err) + require.NoError(t, err) // use local Maven executable in tests t.Setenv("MAVEN_WRAPPER", "false") @@ -106,14 +107,14 @@ func TestCreateCatalog(t *testing.T) { }) err = platform.ConfigureDefaults(context.TODO(), c, &ip, false) - assert.Nil(t, err) + require.NoError(t, err) action := NewCreateCatalogAction() action.InjectLogger(log.Log) action.InjectClient(c) answer, err := action.Handle(context.TODO(), &ip) - assert.Nil(t, err) + require.NoError(t, err) assert.NotNil(t, answer) assert.Equal(t, v1.IntegrationPlatformPhaseReady, answer.Status.Phase, "Error", answer.Status.Conditions[0].Message) @@ -122,11 +123,11 @@ func TestCreateCatalog(t *testing.T) { list := v1.NewCamelCatalogList() err = c.List(context.TODO(), &list, k8sclient.InNamespace(ip.Namespace)) - assert.Nil(t, err) + require.NoError(t, err) assert.NotEmpty(t, list.Items) items, err := resources.WithPrefix("/camel-catelog-") - assert.Nil(t, err) + require.NoError(t, err) for _, k := range items { found := false @@ -159,17 +160,17 @@ func TestCatalogAlreadyPresent(t *testing.T) { catalog.Spec.Runtime.Provider = v1.RuntimeProviderQuarkus c, err := test.NewFakeClient(&ip, &catalog) - assert.Nil(t, err) + require.NoError(t, err) err = platform.ConfigureDefaults(context.TODO(), c, &ip, false) - assert.Nil(t, err) + require.NoError(t, err) action := NewMonitorAction() action.InjectLogger(log.Log) action.InjectClient(c) answer, err := action.Handle(context.TODO(), &ip) - assert.Nil(t, err) + require.NoError(t, err) assert.NotNil(t, answer) assert.Equal(t, v1.IntegrationPlatformPhaseReady, answer.Status.Phase) @@ -190,7 +191,7 @@ func TestCreateCatalogError(t *testing.T) { ip.Spec.Build.RuntimeVersion = "0.0.0" c, err := test.NewFakeClient(&ip) - assert.Nil(t, err) + require.NoError(t, err) // use local Maven executable in tests t.Setenv("MAVEN_WRAPPER", "false") @@ -209,14 +210,14 @@ func TestCreateCatalogError(t *testing.T) { }) err = platform.ConfigureDefaults(context.TODO(), c, &ip, false) - assert.Nil(t, err) + require.NoError(t, err) action := NewCreateCatalogAction() action.InjectLogger(log.Log) action.InjectClient(c) answer, err := action.Handle(context.TODO(), &ip) - assert.Nil(t, err) + require.NoError(t, err) assert.NotNil(t, answer) assert.Equal(t, v1.IntegrationPlatformPhaseError, answer.Status.Phase) diff --git a/pkg/controller/integrationplatform/create_test.go b/pkg/controller/integrationplatform/create_test.go index c5009d08c3..55230f0243 100644 --- a/pkg/controller/integrationplatform/create_test.go +++ b/pkg/controller/integrationplatform/create_test.go @@ -29,6 +29,7 @@ import ( "github.com/apache/camel-k/v2/pkg/util/test" "github.com/rs/xid" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" k8sclient "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -40,27 +41,27 @@ func TestCreate(t *testing.T) { ip.Spec.Profile = v1.TraitProfileOpenShift c, err := test.NewFakeClient(&ip) - assert.Nil(t, err) + require.NoError(t, err) err = platform.ConfigureDefaults(context.TODO(), c, &ip, false) - assert.Nil(t, err) + require.NoError(t, err) h := NewCreateAction() h.InjectLogger(log.Log) h.InjectClient(c) answer, err := h.Handle(context.TODO(), &ip) - assert.Nil(t, err) + require.NoError(t, err) assert.NotNil(t, answer) list := v1.NewCamelCatalogList() err = c.List(context.TODO(), &list, k8sclient.InNamespace(ip.Namespace)) - assert.Nil(t, err) + require.NoError(t, err) assert.NotEmpty(t, list.Items) items, err := resources.WithPrefix("/resources/camel-catalog-") - assert.Nil(t, err) + require.NoError(t, err) foundOverall := 0 for _, k := range items { diff --git a/pkg/controller/integrationplatform/initialize_test.go b/pkg/controller/integrationplatform/initialize_test.go index 158815b039..b7b3960536 100644 --- a/pkg/controller/integrationplatform/initialize_test.go +++ b/pkg/controller/integrationplatform/initialize_test.go @@ -25,6 +25,7 @@ import ( "github.com/rs/xid" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" "github.com/apache/camel-k/v2/pkg/platform" @@ -41,16 +42,16 @@ func TestTimeouts_Default(t *testing.T) { ip.Spec.Profile = v1.TraitProfileOpenShift c, err := test.NewFakeClient(&ip) - assert.Nil(t, err) + require.NoError(t, err) - assert.Nil(t, platform.ConfigureDefaults(context.TODO(), c, &ip, false)) + require.NoError(t, platform.ConfigureDefaults(context.TODO(), c, &ip, false)) h := NewInitializeAction() h.InjectLogger(log.Log) h.InjectClient(c) answer, err := h.Handle(context.TODO(), &ip) - assert.Nil(t, err) + require.NoError(t, err) assert.NotNil(t, answer) assert.Equal(t, 5*time.Minute, answer.Status.Build.GetTimeout().Duration) @@ -64,23 +65,23 @@ func TestTimeouts_MavenComputedFromBuild(t *testing.T) { ip.Spec.Profile = v1.TraitProfileOpenShift timeout, err := time.ParseDuration("1m1ms") - assert.Nil(t, err) + require.NoError(t, err) ip.Spec.Build.Timeout = &metav1.Duration{ Duration: timeout, } c, err := test.NewFakeClient(&ip) - assert.Nil(t, err) + require.NoError(t, err) - assert.Nil(t, platform.ConfigureDefaults(context.TODO(), c, &ip, false)) + require.NoError(t, platform.ConfigureDefaults(context.TODO(), c, &ip, false)) h := NewInitializeAction() h.InjectLogger(log.Log) h.InjectClient(c) answer, err := h.Handle(context.TODO(), &ip) - assert.Nil(t, err) + require.NoError(t, err) assert.NotNil(t, answer) assert.Equal(t, 1*time.Minute, answer.Status.Build.GetTimeout().Duration) @@ -94,23 +95,23 @@ func TestTimeouts_Truncated(t *testing.T) { ip.Spec.Profile = v1.TraitProfileOpenShift bt, err := time.ParseDuration("5m1ms") - assert.Nil(t, err) + require.NoError(t, err) ip.Spec.Build.Timeout = &metav1.Duration{ Duration: bt, } c, err := test.NewFakeClient(&ip) - assert.Nil(t, err) + require.NoError(t, err) - assert.Nil(t, platform.ConfigureDefaults(context.TODO(), c, &ip, false)) + require.NoError(t, platform.ConfigureDefaults(context.TODO(), c, &ip, false)) h := NewInitializeAction() h.InjectLogger(log.Log) h.InjectClient(c) answer, err := h.Handle(context.TODO(), &ip) - assert.Nil(t, err) + require.NoError(t, err) assert.NotNil(t, answer) assert.Equal(t, 5*time.Minute, answer.Status.Build.GetTimeout().Duration) diff --git a/pkg/controller/integrationplatform/monitor_test.go b/pkg/controller/integrationplatform/monitor_test.go index ee22a94968..875c237f8c 100644 --- a/pkg/controller/integrationplatform/monitor_test.go +++ b/pkg/controller/integrationplatform/monitor_test.go @@ -29,6 +29,7 @@ import ( "github.com/apache/camel-k/v2/pkg/util/test" "github.com/rs/xid" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" ) @@ -46,7 +47,7 @@ func TestCanHandlePhaseReadyOrError(t *testing.T) { ip.Status.Phase = v1.IntegrationPlatformPhaseReady c, err := test.NewFakeClient(&ip) - assert.Nil(t, err) + require.NoError(t, err) action := NewMonitorAction() action.InjectLogger(log.Log) @@ -77,17 +78,17 @@ func TestMonitor(t *testing.T) { catalog.Spec.Runtime.Provider = v1.RuntimeProviderQuarkus c, err := test.NewFakeClient(&ip, &catalog) - assert.Nil(t, err) + require.NoError(t, err) err = platform.ConfigureDefaults(context.TODO(), c, &ip, false) - assert.Nil(t, err) + require.NoError(t, err) action := NewMonitorAction() action.InjectLogger(log.Log) action.InjectClient(c) answer, err := action.Handle(context.TODO(), &ip) - assert.Nil(t, err) + require.NoError(t, err) assert.NotNil(t, answer) assert.Equal(t, v1.IntegrationPlatformPhaseReady, answer.Status.Phase) @@ -106,17 +107,17 @@ func TestMonitorTransitionToCreateCatalog(t *testing.T) { ip.Spec.Build.RuntimeVersion = defaults.DefaultRuntimeVersion c, err := test.NewFakeClient(&ip) - assert.Nil(t, err) + require.NoError(t, err) err = platform.ConfigureDefaults(context.TODO(), c, &ip, false) - assert.Nil(t, err) + require.NoError(t, err) action := NewMonitorAction() action.InjectLogger(log.Log) action.InjectClient(c) answer, err := action.Handle(context.TODO(), &ip) - assert.Nil(t, err) + require.NoError(t, err) assert.NotNil(t, answer) assert.Equal(t, v1.IntegrationPlatformPhaseCreateCatalog, answer.Status.Phase) @@ -139,17 +140,17 @@ func TestMonitorRetainErrorState(t *testing.T) { ip.Status.Phase = v1.IntegrationPlatformPhaseError c, err := test.NewFakeClient(&ip) - assert.Nil(t, err) + require.NoError(t, err) err = platform.ConfigureDefaults(context.TODO(), c, &ip, false) - assert.Nil(t, err) + require.NoError(t, err) action := NewMonitorAction() action.InjectLogger(log.Log) action.InjectClient(c) answer, err := action.Handle(context.TODO(), &ip) - assert.Nil(t, err) + require.NoError(t, err) assert.NotNil(t, answer) assert.Equal(t, v1.IntegrationPlatformPhaseError, answer.Status.Phase) @@ -171,17 +172,17 @@ func TestMonitorMissingRegistryError(t *testing.T) { catalog.Spec.Runtime.Provider = v1.RuntimeProviderQuarkus c, err := test.NewFakeClient(&ip, &catalog) - assert.Nil(t, err) + require.NoError(t, err) err = platform.ConfigureDefaults(context.TODO(), c, &ip, false) - assert.Nil(t, err) + require.NoError(t, err) action := NewMonitorAction() action.InjectLogger(log.Log) action.InjectClient(c) answer, err := action.Handle(context.TODO(), &ip) - assert.Nil(t, err) + require.NoError(t, err) assert.NotNil(t, answer) assert.Equal(t, v1.IntegrationPlatformPhaseError, answer.Status.Phase) diff --git a/pkg/controller/kameletbinding/error_handler.go b/pkg/controller/kameletbinding/error_handler.go index 603b8af7aa..ad8aced4dd 100644 --- a/pkg/controller/kameletbinding/error_handler.go +++ b/pkg/controller/kameletbinding/error_handler.go @@ -105,7 +105,7 @@ func setErrorHandlerConfiguration(errorHandlerBinding *bindings.Binding, errorHa errorHandlerBinding.ApplicationProperties[key] = fmt.Sprintf("%v", value) } if errorHandler.Type() == v1alpha1.ErrorHandlerTypeSink && errorHandlerBinding.URI != "" { - errorHandlerBinding.ApplicationProperties[fmt.Sprintf("%s.deadLetterUri", v1alpha1.ErrorHandlerAppPropertiesPrefix)] = fmt.Sprintf("%v", errorHandlerBinding.URI) + errorHandlerBinding.ApplicationProperties[fmt.Sprintf("%s.deadLetterUri", v1alpha1.ErrorHandlerAppPropertiesPrefix)] = errorHandlerBinding.URI } return nil } diff --git a/pkg/controller/kameletbinding/error_handler_test.go b/pkg/controller/kameletbinding/error_handler_test.go index 6abbf21870..1d991c5acb 100644 --- a/pkg/controller/kameletbinding/error_handler_test.go +++ b/pkg/controller/kameletbinding/error_handler_test.go @@ -23,16 +23,17 @@ import ( "github.com/apache/camel-k/v2/pkg/apis/camel/v1alpha1" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestParseErrorHandlerNoneDoesSucceed(t *testing.T) { noErrorHandler, err := parseErrorHandler( []byte(`{"none": null}`), ) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, v1alpha1.ErrorHandlerTypeNone, noErrorHandler.Type()) parameters, err := noErrorHandler.Configuration() - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "#class:org.apache.camel.builder.NoErrorHandlerBuilder", parameters[v1alpha1.ErrorHandlerAppPropertiesPrefix]) assert.Equal(t, v1alpha1.ErrorHandlerRefDefaultName, parameters[v1alpha1.ErrorHandlerRefName]) } @@ -41,10 +42,10 @@ func TestParseErrorHandlerLogDoesSucceed(t *testing.T) { logErrorHandler, err := parseErrorHandler( []byte(`{"log": null}`), ) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, v1alpha1.ErrorHandlerTypeLog, logErrorHandler.Type()) parameters, err := logErrorHandler.Configuration() - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "#class:org.apache.camel.builder.DefaultErrorHandlerBuilder", parameters[v1alpha1.ErrorHandlerAppPropertiesPrefix]) assert.Equal(t, v1alpha1.ErrorHandlerRefDefaultName, parameters[v1alpha1.ErrorHandlerRefName]) } @@ -53,10 +54,10 @@ func TestParseErrorHandlerLogWithParametersDoesSucceed(t *testing.T) { logErrorHandler, err := parseErrorHandler( []byte(`{"log": {"parameters": {"param1": "value1", "param2": "value2"}}}`), ) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, v1alpha1.ErrorHandlerTypeLog, logErrorHandler.Type()) parameters, err := logErrorHandler.Configuration() - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "#class:org.apache.camel.builder.DefaultErrorHandlerBuilder", parameters[v1alpha1.ErrorHandlerAppPropertiesPrefix]) assert.Equal(t, "value1", parameters["camel.beans.defaultErrorHandler.param1"]) assert.Equal(t, "value2", parameters["camel.beans.defaultErrorHandler.param2"]) @@ -68,12 +69,12 @@ func TestParseErrorHandlerSinkDoesSucceed(t *testing.T) { sinkErrorHandler, err := parseErrorHandler( []byte(`{"sink": {"endpoint": {"uri": "someUri"}}}`), ) - assert.Nil(t, err) + require.NoError(t, err) assert.NotNil(t, sinkErrorHandler) assert.Equal(t, v1alpha1.ErrorHandlerTypeSink, sinkErrorHandler.Type()) assert.Equal(t, "someUri", *sinkErrorHandler.Endpoint().URI) parameters, err := sinkErrorHandler.Configuration() - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "#class:org.apache.camel.builder.DeadLetterChannelBuilder", parameters[v1alpha1.ErrorHandlerAppPropertiesPrefix]) assert.Equal(t, v1alpha1.ErrorHandlerRefDefaultName, parameters[v1alpha1.ErrorHandlerRefName]) } @@ -90,12 +91,12 @@ func TestParseErrorHandlerSinkWithParametersDoesSucceed(t *testing.T) { } }`), ) - assert.Nil(t, err) + require.NoError(t, err) assert.NotNil(t, sinkErrorHandler) assert.Equal(t, v1alpha1.ErrorHandlerTypeSink, sinkErrorHandler.Type()) assert.Equal(t, "someUri", *sinkErrorHandler.Endpoint().URI) parameters, err := sinkErrorHandler.Configuration() - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "#class:org.apache.camel.builder.DeadLetterChannelBuilder", parameters[v1alpha1.ErrorHandlerAppPropertiesPrefix]) assert.Equal(t, v1alpha1.ErrorHandlerRefDefaultName, parameters[v1alpha1.ErrorHandlerRefName]) assert.Equal(t, "value1", parameters["camel.beans.defaultErrorHandler.param1"]) diff --git a/pkg/controller/pipe/error_handler.go b/pkg/controller/pipe/error_handler.go index fd00c85bc4..13e89ea508 100644 --- a/pkg/controller/pipe/error_handler.go +++ b/pkg/controller/pipe/error_handler.go @@ -105,7 +105,7 @@ func setErrorHandlerConfiguration(errorHandlerBinding *bindings.Binding, errorHa errorHandlerBinding.ApplicationProperties[key] = fmt.Sprintf("%v", value) } if errorHandler.Type() == v1.ErrorHandlerTypeSink && errorHandlerBinding.URI != "" { - errorHandlerBinding.ApplicationProperties[fmt.Sprintf("%s.deadLetterUri", v1.ErrorHandlerAppPropertiesPrefix)] = fmt.Sprintf("%v", errorHandlerBinding.URI) + errorHandlerBinding.ApplicationProperties[fmt.Sprintf("%s.deadLetterUri", v1.ErrorHandlerAppPropertiesPrefix)] = errorHandlerBinding.URI } return nil } diff --git a/pkg/controller/pipe/error_handler_test.go b/pkg/controller/pipe/error_handler_test.go index 53877e638f..4cd751f8d2 100644 --- a/pkg/controller/pipe/error_handler_test.go +++ b/pkg/controller/pipe/error_handler_test.go @@ -22,16 +22,17 @@ import ( v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestParseErrorHandlerNoneDoesSucceed(t *testing.T) { noErrorHandler, err := parseErrorHandler( []byte(`{"none": null}`), ) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, v1.ErrorHandlerTypeNone, noErrorHandler.Type()) parameters, err := noErrorHandler.Configuration() - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "#class:org.apache.camel.builder.NoErrorHandlerBuilder", parameters[v1.ErrorHandlerAppPropertiesPrefix]) assert.Equal(t, v1.ErrorHandlerRefDefaultName, parameters[v1.ErrorHandlerRefName]) } @@ -40,10 +41,10 @@ func TestParseErrorHandlerLogDoesSucceed(t *testing.T) { logErrorHandler, err := parseErrorHandler( []byte(`{"log": null}`), ) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, v1.ErrorHandlerTypeLog, logErrorHandler.Type()) parameters, err := logErrorHandler.Configuration() - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "#class:org.apache.camel.builder.DefaultErrorHandlerBuilder", parameters[v1.ErrorHandlerAppPropertiesPrefix]) assert.Equal(t, v1.ErrorHandlerRefDefaultName, parameters[v1.ErrorHandlerRefName]) } @@ -52,10 +53,10 @@ func TestParseErrorHandlerLogWithParametersDoesSucceed(t *testing.T) { logErrorHandler, err := parseErrorHandler( []byte(`{"log": {"parameters": {"param1": "value1", "param2": "value2"}}}`), ) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, v1.ErrorHandlerTypeLog, logErrorHandler.Type()) parameters, err := logErrorHandler.Configuration() - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "#class:org.apache.camel.builder.DefaultErrorHandlerBuilder", parameters[v1.ErrorHandlerAppPropertiesPrefix]) assert.Equal(t, "value1", parameters["camel.beans.defaultErrorHandler.param1"]) assert.Equal(t, "value2", parameters["camel.beans.defaultErrorHandler.param2"]) @@ -66,12 +67,12 @@ func TestParseErrorHandlerSinkDoesSucceed(t *testing.T) { sinkErrorHandler, err := parseErrorHandler( []byte(`{"sink": {"endpoint": {"uri": "someUri"}}}`), ) - assert.Nil(t, err) + require.NoError(t, err) assert.NotNil(t, sinkErrorHandler) assert.Equal(t, v1.ErrorHandlerTypeSink, sinkErrorHandler.Type()) assert.Equal(t, "someUri", *sinkErrorHandler.Endpoint().URI) parameters, err := sinkErrorHandler.Configuration() - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "#class:org.apache.camel.builder.DeadLetterChannelBuilder", parameters[v1.ErrorHandlerAppPropertiesPrefix]) assert.Equal(t, v1.ErrorHandlerRefDefaultName, parameters[v1.ErrorHandlerRefName]) } @@ -88,12 +89,12 @@ func TestParseErrorHandlerSinkWithParametersDoesSucceed(t *testing.T) { } }`), ) - assert.Nil(t, err) + require.NoError(t, err) assert.NotNil(t, sinkErrorHandler) assert.Equal(t, v1.ErrorHandlerTypeSink, sinkErrorHandler.Type()) assert.Equal(t, "someUri", *sinkErrorHandler.Endpoint().URI) parameters, err := sinkErrorHandler.Configuration() - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "#class:org.apache.camel.builder.DeadLetterChannelBuilder", parameters[v1.ErrorHandlerAppPropertiesPrefix]) assert.Equal(t, v1.ErrorHandlerRefDefaultName, parameters[v1.ErrorHandlerRefName]) assert.Equal(t, "value1", parameters["camel.beans.defaultErrorHandler.param1"]) @@ -104,6 +105,6 @@ func TestParseErrorHandlerSinkFail(t *testing.T) { _, err := parseErrorHandler( []byte(`{"sink": {"ref": {"uri": "someUri"}}}`), ) - assert.NotNil(t, err) + require.Error(t, err) assert.Equal(t, "missing endpoint in Error Handler Sink", err.Error()) } diff --git a/pkg/controller/pipe/integration.go b/pkg/controller/pipe/integration.go index d78928f65d..80b06d662a 100644 --- a/pkg/controller/pipe/integration.go +++ b/pkg/controller/pipe/integration.go @@ -224,10 +224,7 @@ func configureBinding(integration *v1.Integration, bindings ...*bindings.Binding return err } - integration.Spec.Configuration = append(integration.Spec.Configuration, v1.ConfigurationSpec{ - Type: "property", - Value: entry, - }) + integration.Spec.AddConfigurationProperty(entry) } } diff --git a/pkg/controller/pipe/integration_test.go b/pkg/controller/pipe/integration_test.go index f3488038a9..30af047067 100644 --- a/pkg/controller/pipe/integration_test.go +++ b/pkg/controller/pipe/integration_test.go @@ -25,16 +25,17 @@ import ( "github.com/apache/camel-k/v2/pkg/util/dsl" "github.com/apache/camel-k/v2/pkg/util/test" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" ) func TestCreateIntegrationForPipe(t *testing.T) { client, err := test.NewFakeClient() - assert.NoError(t, err) + require.NoError(t, err) pipe := nominalPipe("my-pipe") it, err := CreateIntegrationFor(context.TODO(), client, &pipe) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "my-pipe", it.Name) assert.Equal(t, "default", it.Namespace) assert.Equal(t, map[string]string{ @@ -49,13 +50,63 @@ func TestCreateIntegrationForPipe(t *testing.T) { assert.Equal(t, "Pipe", it.OwnerReferences[0].Kind) assert.Equal(t, "my-pipe", it.OwnerReferences[0].Name) dsl, err := dsl.ToYamlDSL(it.Spec.Flows) - assert.Nil(t, err) + require.NoError(t, err) + assert.Equal(t, expectedNominalRoute(), string(dsl)) +} + +func TestCreateIntegrationForPipeWithSinkErrorHandler(t *testing.T) { + client, err := test.NewFakeClient() + require.NoError(t, err) + + pipe := nominalPipe("my-error-handler-pipe") + pipe.Spec.ErrorHandler = &v1.ErrorHandlerSpec{ + RawMessage: []byte(`{"sink": {"endpoint": {"uri": "someUri"}}}`), + } + + it, err := CreateIntegrationFor(context.TODO(), client, &pipe) + require.NoError(t, err) + assert.Equal(t, "my-error-handler-pipe", it.Name) + assert.Equal(t, "default", it.Namespace) + assert.Equal(t, "camel.apache.org/v1", it.OwnerReferences[0].APIVersion) + assert.Equal(t, "Pipe", it.OwnerReferences[0].Kind) + assert.Equal(t, "my-error-handler-pipe", it.OwnerReferences[0].Name) + assert.Len(t, it.Spec.Configuration, 3) + assert.Equal(t, "#class:org.apache.camel.builder.DeadLetterChannelBuilder", it.Spec.GetConfigurationProperty("camel.beans.defaultErrorHandler")) + assert.Equal(t, "someUri", it.Spec.GetConfigurationProperty("camel.beans.defaultErrorHandler.deadLetterUri")) + assert.Equal(t, "defaultErrorHandler", it.Spec.GetConfigurationProperty(v1.ErrorHandlerRefName)) + dsl, err := dsl.ToYamlDSL(it.Spec.Flows) + require.NoError(t, err) + assert.Equal(t, expectedNominalRoute(), string(dsl)) +} + +func TestCreateIntegrationForPipeWithLogErrorHandler(t *testing.T) { + client, err := test.NewFakeClient() + require.NoError(t, err) + + pipe := nominalPipe("my-error-handler-pipe") + pipe.Spec.ErrorHandler = &v1.ErrorHandlerSpec{ + RawMessage: []byte(`{"log": {"parameters": {"showHeaders": "true"}}}`), + } + + it, err := CreateIntegrationFor(context.TODO(), client, &pipe) + require.NoError(t, err) + assert.Equal(t, "my-error-handler-pipe", it.Name) + assert.Equal(t, "default", it.Namespace) + assert.Equal(t, "camel.apache.org/v1", it.OwnerReferences[0].APIVersion) + assert.Equal(t, "Pipe", it.OwnerReferences[0].Kind) + assert.Equal(t, "my-error-handler-pipe", it.OwnerReferences[0].Name) + assert.Len(t, it.Spec.Configuration, 3) + assert.Equal(t, "#class:org.apache.camel.builder.DefaultErrorHandlerBuilder", it.Spec.GetConfigurationProperty("camel.beans.defaultErrorHandler")) + assert.Equal(t, "true", it.Spec.GetConfigurationProperty("camel.beans.defaultErrorHandler.showHeaders")) + assert.Equal(t, "defaultErrorHandler", it.Spec.GetConfigurationProperty(v1.ErrorHandlerRefName)) + dsl, err := dsl.ToYamlDSL(it.Spec.Flows) + require.NoError(t, err) assert.Equal(t, expectedNominalRoute(), string(dsl)) } func TestCreateIntegrationForPipeDataType(t *testing.T) { client, err := test.NewFakeClient() - assert.NoError(t, err) + require.NoError(t, err) pipe := nominalPipe("my-pipe-data-type") pipe.Spec.Sink.DataTypes = map[v1.TypeSlot]v1.DataTypeReference{ @@ -64,15 +115,15 @@ func TestCreateIntegrationForPipeDataType(t *testing.T) { }, } it, err := CreateIntegrationFor(context.TODO(), client, &pipe) - assert.Nil(t, err) + require.NoError(t, err) dsl, err := dsl.ToYamlDSL(it.Spec.Flows) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, expectedNominalRouteWithDataType("data-type-action"), string(dsl)) } func TestCreateIntegrationForPipeDataTypeOverridden(t *testing.T) { client, err := test.NewFakeClient() - assert.NoError(t, err) + require.NoError(t, err) pipe := nominalPipe("my-pipe-data-type") pipe.Spec.Sink.DataTypes = map[v1.TypeSlot]v1.DataTypeReference{ @@ -83,9 +134,9 @@ func TestCreateIntegrationForPipeDataTypeOverridden(t *testing.T) { newDataTypeKameletAction := "data-type-action-v4-2" pipe.Annotations[v1.KameletDataTypeLabel] = newDataTypeKameletAction it, err := CreateIntegrationFor(context.TODO(), client, &pipe) - assert.Nil(t, err) + require.NoError(t, err) dsl, err := dsl.ToYamlDSL(it.Spec.Flows) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, expectedNominalRouteWithDataType(newDataTypeKameletAction), string(dsl)) } diff --git a/pkg/controller/synthetic/synthetic_test.go b/pkg/controller/synthetic/synthetic_test.go index fcc15077af..ad436fa37a 100644 --- a/pkg/controller/synthetic/synthetic_test.go +++ b/pkg/controller/synthetic/synthetic_test.go @@ -30,6 +30,7 @@ import ( "github.com/apache/camel-k/v2/pkg/apis/camel/v1/trait" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestNonManagedUnsupported(t *testing.T) { @@ -65,7 +66,7 @@ func TestNonManagedUnsupported(t *testing.T) { } nilAdapter, err := nonManagedCamelApplicationFactory(pod) - assert.NotNil(t, err) + require.Error(t, err) assert.Equal(t, "unsupported my-pod object kind", err.Error()) assert.Nil(t, nilAdapter) } @@ -128,7 +129,7 @@ func TestNonManagedDeployment(t *testing.T) { expectedIt.SetOwnerReferences(references) deploymentAdapter, err := nonManagedCamelApplicationFactory(deploy) - assert.Nil(t, err) + require.NoError(t, err) assert.NotNil(t, deploymentAdapter) assert.Equal(t, expectedIt, *deploymentAdapter.Integration()) } @@ -187,7 +188,7 @@ func TestNonManagedCronJob(t *testing.T) { } expectedIt.SetOwnerReferences(references) cronJobAdapter, err := nonManagedCamelApplicationFactory(cron) - assert.Nil(t, err) + require.NoError(t, err) assert.NotNil(t, cronJobAdapter) assert.Equal(t, expectedIt, *cronJobAdapter.Integration()) } @@ -247,7 +248,7 @@ func TestNonManagedKnativeService(t *testing.T) { expectedIt.SetOwnerReferences(references) knativeServiceAdapter, err := nonManagedCamelApplicationFactory(ksvc) - assert.Nil(t, err) + require.NoError(t, err) assert.NotNil(t, knativeServiceAdapter) assert.Equal(t, expectedIt, *knativeServiceAdapter.Integration()) } diff --git a/pkg/install/kamelets_test.go b/pkg/install/kamelets_test.go index 292dbacf31..67d0cb5779 100644 --- a/pkg/install/kamelets_test.go +++ b/pkg/install/kamelets_test.go @@ -22,18 +22,19 @@ import ( v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestLoadKamelet(t *testing.T) { kamelet, err := loadKamelet("testdata/timer-source.kamelet.yaml", "some-namespace") assert.NotNil(t, kamelet) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "timer-source", kamelet.GetName()) assert.Equal(t, "some-namespace", kamelet.GetNamespace()) - assert.Equal(t, 3, len(kamelet.GetLabels())) + assert.Len(t, kamelet.GetLabels(), 3) assert.Equal(t, "true", kamelet.GetLabels()[v1.KameletBundledLabel]) assert.Equal(t, "true", kamelet.GetLabels()[v1.KameletReadOnlyLabel]) - assert.Equal(t, 2, len(kamelet.GetAnnotations())) + assert.Len(t, kamelet.GetAnnotations(), 2) assert.NotNil(t, kamelet.GetAnnotations()[kamelVersionAnnotation]) } diff --git a/pkg/kamelet/repository/composite_repository_test.go b/pkg/kamelet/repository/composite_repository_test.go index b385b34810..bc9a4554e4 100644 --- a/pkg/kamelet/repository/composite_repository_test.go +++ b/pkg/kamelet/repository/composite_repository_test.go @@ -24,6 +24,7 @@ import ( v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" "github.com/apache/camel-k/v2/pkg/client/camel/clientset/versioned/fake" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -47,12 +48,12 @@ func TestKubernetesRepositoryMultiNS(t *testing.T) { newKubernetesKameletRepository(fakeClient, "test2"), ) list, err := repo.List(ctx) - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, list, 2) k1, err := repo.Get(ctx, "kamelet1") - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, "kamelet1", k1.Name) k2, err := repo.Get(ctx, "kamelet2") - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, "kamelet2", k2.Name) } diff --git a/pkg/kamelet/repository/empty_repository_test.go b/pkg/kamelet/repository/empty_repository_test.go index 79c96c3361..b7398c3009 100644 --- a/pkg/kamelet/repository/empty_repository_test.go +++ b/pkg/kamelet/repository/empty_repository_test.go @@ -22,15 +22,16 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestEmptyRepository(t *testing.T) { ctx := context.Background() repo := newEmptyKameletRepository() list, err := repo.List(ctx) - assert.NoError(t, err) - assert.Len(t, list, 0) + require.NoError(t, err) + assert.Empty(t, list) k, err := repo.Get(ctx, "non-existing") - assert.NoError(t, err) + require.NoError(t, err) assert.Nil(t, k) } diff --git a/pkg/kamelet/repository/github_repository_test.go b/pkg/kamelet/repository/github_repository_test.go index 9bb53713a6..60471aa6c4 100644 --- a/pkg/kamelet/repository/github_repository_test.go +++ b/pkg/kamelet/repository/github_repository_test.go @@ -34,8 +34,8 @@ func TestGithubRepository(t *testing.T) { ctx := context.Background() repo := newGithubKameletRepository(ctx, "apache", "camel-kamelets", "kamelets", "") list, err := repo.List(ctx) - assert.NoError(t, err) - require.True(t, len(list) > 0) + require.NoError(t, err) + require.Greater(t, len(list), 0) // Repeat multiple times to be sure cache is working and we don't hit rate limits maxDistinct := 5 for i := 0; i < 200; i++ { @@ -45,7 +45,7 @@ func TestGithubRepository(t *testing.T) { } kameletName := list[i%maxPos] kamelet, err := repo.Get(ctx, kameletName) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, kameletName, kamelet.Name) } diff --git a/pkg/kamelet/repository/kubernetes_repository_test.go b/pkg/kamelet/repository/kubernetes_repository_test.go index ec306d1d8f..3a6da5072d 100644 --- a/pkg/kamelet/repository/kubernetes_repository_test.go +++ b/pkg/kamelet/repository/kubernetes_repository_test.go @@ -24,6 +24,7 @@ import ( v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" "github.com/apache/camel-k/v2/pkg/client/camel/clientset/versioned/fake" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -32,8 +33,8 @@ func TestKubernetesEmptyRepository(t *testing.T) { fakeClient := fake.NewSimpleClientset() repo := newKubernetesKameletRepository(fakeClient, "test") list, err := repo.List(ctx) - assert.NoError(t, err) - assert.Len(t, list, 0) + require.NoError(t, err) + assert.Empty(t, list) } func TestKubernetesRepository(t *testing.T) { @@ -53,12 +54,12 @@ func TestKubernetesRepository(t *testing.T) { }) repo := newKubernetesKameletRepository(fakeClient, "test") list, err := repo.List(ctx) - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, list, 2) k1, err := repo.Get(ctx, "kamelet1") - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, "kamelet1", k1.Name) k2, err := repo.Get(ctx, "kamelet2") - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, "kamelet2", k2.Name) } diff --git a/pkg/kamelet/repository/repository_test.go b/pkg/kamelet/repository/repository_test.go index 6bb40c3839..daa2103b3d 100644 --- a/pkg/kamelet/repository/repository_test.go +++ b/pkg/kamelet/repository/repository_test.go @@ -102,9 +102,9 @@ func TestURIParse(t *testing.T) { t.Run(fmt.Sprintf("%d-%s", i, test.uri), func(t *testing.T) { catalog, err := newFromURI(context.Background(), test.uri) if test.error { - assert.Error(t, err) + require.Error(t, err) } else { - assert.NoError(t, err) + require.NoError(t, err) switch r := test.repository.(type) { case *githubKameletRepository: gc, ok := catalog.(*githubKameletRepository) @@ -149,7 +149,7 @@ func TestNewRepositoryWithCamelKamelets(t *testing.T) { require.NoError(t, err) list, err := repo.List(ctx) require.NoError(t, err) - assert.True(t, len(list) > 2) + assert.Greater(t, len(list), 2) k1, err := repo.Get(ctx, "kamelet1") require.NoError(t, err) assert.Equal(t, "kamelet1", k1.Name) diff --git a/pkg/metadata/metadata_capabilities_test.go b/pkg/metadata/metadata_capabilities_test.go index a0b7708104..6917e6ddb0 100644 --- a/pkg/metadata/metadata_capabilities_test.go +++ b/pkg/metadata/metadata_capabilities_test.go @@ -21,6 +21,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" "github.com/apache/camel-k/v2/pkg/util/camel" @@ -36,10 +37,10 @@ func TestPlatformHttpCapabilities(t *testing.T) { } catalog, err := camel.DefaultCatalog() - assert.NoError(t, err) + require.NoError(t, err) meta, err := Extract(catalog, code) - assert.NoError(t, err) + require.NoError(t, err) assert.ElementsMatch( t, diff --git a/pkg/metadata/metadata_dependencies_test.go b/pkg/metadata/metadata_dependencies_test.go index d28fde73a9..f4dd111f8a 100644 --- a/pkg/metadata/metadata_dependencies_test.go +++ b/pkg/metadata/metadata_dependencies_test.go @@ -178,7 +178,7 @@ func TestDependencyInexistent(t *testing.T) { require.NoError(t, err) _, err = Extract(catalog, code) - assert.Error(t, err) + require.Error(t, err) } func TestDependenciesQuarkus(t *testing.T) { diff --git a/pkg/platform/defaults_test.go b/pkg/platform/defaults_test.go index ac9ecd7de5..36d366dd38 100644 --- a/pkg/platform/defaults_test.go +++ b/pkg/platform/defaults_test.go @@ -22,6 +22,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -40,10 +41,10 @@ func TestIntegrationPlatformDefaults(t *testing.T) { } c, err := test.NewFakeClient(&ip) - assert.Nil(t, err) + require.NoError(t, err) err = ConfigureDefaults(context.TODO(), c, &ip, false) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, v1.IntegrationPlatformClusterKubernetes, ip.Status.Cluster) assert.Equal(t, v1.TraitProfile(""), ip.Status.Profile) @@ -51,8 +52,8 @@ func TestIntegrationPlatformDefaults(t *testing.T) { assert.Equal(t, v1.BuildOrderStrategySequential, ip.Status.Build.BuildConfiguration.OrderStrategy) assert.Equal(t, defaults.BaseImage(), ip.Status.Build.BaseImage) assert.Equal(t, defaults.LocalRepository, ip.Status.Build.Maven.LocalRepository) - assert.True(t, ip.Status.Build.MaxRunningBuilds == 3) // default for build strategy routine - assert.Equal(t, 3, len(ip.Status.Build.Maven.CLIOptions)) + assert.Equal(t, int32(3), ip.Status.Build.MaxRunningBuilds) // default for build strategy routine + assert.Len(t, ip.Status.Build.Maven.CLIOptions, 3) assert.NotNil(t, ip.Status.Traits) } @@ -90,10 +91,10 @@ func TestApplyGlobalPlatformSpec(t *testing.T) { } c, err := test.NewFakeClient(&global) - assert.Nil(t, err) + require.NoError(t, err) err = ConfigureDefaults(context.TODO(), c, &global, false) - assert.Nil(t, err) + require.NoError(t, err) ip := v1.IntegrationPlatform{ ObjectMeta: metav1.ObjectMeta{ @@ -110,7 +111,7 @@ func TestApplyGlobalPlatformSpec(t *testing.T) { assert.Equal(t, v1.TraitProfileOpenShift, ip.Status.Profile) assert.Equal(t, v1.BuildStrategyRoutine, ip.Status.Build.BuildConfiguration.Strategy) assert.Equal(t, v1.BuildOrderStrategyFIFO, ip.Status.Build.BuildConfiguration.OrderStrategy) - assert.True(t, ip.Status.Build.MaxRunningBuilds == 3) // default for build strategy routine + assert.Equal(t, int32(3), ip.Status.Build.MaxRunningBuilds) // default for build strategy routine assert.Equal(t, len(global.Status.Build.Maven.CLIOptions), len(ip.Status.Build.Maven.CLIOptions)) assert.Equal(t, global.Status.Build.Maven.CLIOptions, ip.Status.Build.Maven.CLIOptions) assert.NotNil(t, ip.Status.Traits) @@ -119,7 +120,7 @@ func TestApplyGlobalPlatformSpec(t *testing.T) { assert.NotNil(t, ip.Status.Traits.Container) assert.Equal(t, corev1.PullAlways, ip.Status.Traits.Container.ImagePullPolicy) assert.Equal(t, "0.1", ip.Status.Traits.Container.LimitCPU) - assert.Equal(t, 2, len(ip.Status.Build.Maven.Properties)) + assert.Len(t, ip.Status.Build.Maven.Properties, 2) assert.Equal(t, "global_value1", ip.Status.Build.Maven.Properties["global_prop1"]) assert.Equal(t, "global_value2", ip.Status.Build.Maven.Properties["global_prop2"]) } @@ -137,10 +138,10 @@ func TestPlatformS2IhUpdateOverrideLocalPlatformSpec(t *testing.T) { } c, err := test.NewFakeClient(&global) - assert.Nil(t, err) + require.NoError(t, err) err = ConfigureDefaults(context.TODO(), c, &global, false) - assert.Nil(t, err) + require.NoError(t, err) ip := v1.IntegrationPlatform{ ObjectMeta: metav1.ObjectMeta{ @@ -177,10 +178,10 @@ func TestPlatformS2IUpdateDefaultLocalPlatformSpec(t *testing.T) { } c, err := test.NewFakeClient(&global) - assert.Nil(t, err) + require.NoError(t, err) err = ConfigureDefaults(context.TODO(), c, &global, false) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "overridden", global.Status.Build.BaseImage) ip := v1.IntegrationPlatform{ @@ -236,10 +237,10 @@ func TestRetainLocalPlatformSpec(t *testing.T) { } c, err := test.NewFakeClient(&global) - assert.Nil(t, err) + require.NoError(t, err) err = ConfigureDefaults(context.TODO(), c, &global, false) - assert.Nil(t, err) + require.NoError(t, err) ip := v1.IntegrationPlatform{ ObjectMeta: metav1.ObjectMeta{ @@ -278,7 +279,7 @@ func TestRetainLocalPlatformSpec(t *testing.T) { assert.Equal(t, v1.TraitProfileKnative, ip.Status.Profile) assert.Equal(t, v1.BuildStrategyPod, ip.Status.Build.BuildConfiguration.Strategy) assert.Equal(t, v1.BuildOrderStrategyFIFO, ip.Status.Build.BuildConfiguration.OrderStrategy) - assert.True(t, ip.Status.Build.MaxRunningBuilds == 1) + assert.Equal(t, int32(1), ip.Status.Build.MaxRunningBuilds) assert.Equal(t, len(global.Status.Build.Maven.CLIOptions), len(ip.Status.Build.Maven.CLIOptions)) assert.Equal(t, global.Status.Build.Maven.CLIOptions, ip.Status.Build.Maven.CLIOptions) assert.NotNil(t, ip.Status.Traits) @@ -287,7 +288,7 @@ func TestRetainLocalPlatformSpec(t *testing.T) { assert.NotNil(t, ip.Status.Traits.Container) assert.Equal(t, corev1.PullAlways, ip.Status.Traits.Container.ImagePullPolicy) assert.Equal(t, "0.1", ip.Status.Traits.Container.LimitCPU) - assert.Equal(t, 3, len(ip.Status.Build.Maven.Properties)) + assert.Len(t, ip.Status.Build.Maven.Properties, 3) assert.Equal(t, "global_value1", ip.Status.Build.Maven.Properties["global_prop1"]) assert.Equal(t, "local_value2", ip.Status.Build.Maven.Properties["global_prop2"]) assert.Equal(t, "local_value1", ip.Status.Build.Maven.Properties["local_prop1"]) diff --git a/pkg/platform/platform.go b/pkg/platform/platform.go index 9963f855e2..e4f655bd0c 100644 --- a/pkg/platform/platform.go +++ b/pkg/platform/platform.go @@ -135,7 +135,7 @@ func findAny(ctx context.Context, c k8sclient.Reader, namespace string) (*v1.Int // findLocal returns the currently installed platform or any platform existing in local namespace. func findLocal(ctx context.Context, c k8sclient.Reader, namespace string) (*v1.IntegrationPlatform, error) { - log.Debug("Finding available platforms") + log.Debugf("Finding available platforms in namespace %s", namespace) operatorNamespace := GetOperatorNamespace() if namespace == operatorNamespace { @@ -168,7 +168,7 @@ func findLocal(ctx context.Context, c k8sclient.Reader, namespace string) (*v1.I return fallback, nil } - log.Debugf("Unable to find integration platform") + log.Debugf("Unable to find integration platform in namespace %s", namespace) return nil, k8serrors.NewNotFound(v1.Resource("IntegrationPlatform"), DefaultPlatformName) } diff --git a/pkg/platform/profile_test.go b/pkg/platform/profile_test.go index 6d14e8e336..15a90fec0c 100644 --- a/pkg/platform/profile_test.go +++ b/pkg/platform/profile_test.go @@ -22,6 +22,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -41,7 +42,7 @@ func TestFindIntegrationProfile(t *testing.T) { profile.ResyncStatusFullConfig() c, err := test.NewFakeClient(&profile) - assert.Nil(t, err) + require.NoError(t, err) integration := v1.Integration{ ObjectMeta: metav1.ObjectMeta{ @@ -57,7 +58,7 @@ func TestFindIntegrationProfile(t *testing.T) { } found, err := findIntegrationProfile(context.TODO(), c, &integration) - assert.Nil(t, err) + require.NoError(t, err) assert.NotNil(t, found) } @@ -72,7 +73,7 @@ func TestFindIntegrationProfileWithNamespace(t *testing.T) { profile.ResyncStatusFullConfig() c, err := test.NewFakeClient(&profile) - assert.Nil(t, err) + require.NoError(t, err) integration := v1.Integration{ ObjectMeta: metav1.ObjectMeta{ @@ -89,7 +90,7 @@ func TestFindIntegrationProfileWithNamespace(t *testing.T) { } found, err := findIntegrationProfile(context.TODO(), c, &integration) - assert.Nil(t, err) + require.NoError(t, err) assert.NotNil(t, found) } @@ -104,7 +105,7 @@ func TestFindIntegrationProfileInOperatorNamespace(t *testing.T) { profile.ResyncStatusFullConfig() c, err := test.NewFakeClient(&profile) - assert.Nil(t, err) + require.NoError(t, err) t.Setenv(operatorNamespaceEnvVariable, "operator-namespace") @@ -122,7 +123,7 @@ func TestFindIntegrationProfileInOperatorNamespace(t *testing.T) { } found, err := findIntegrationProfile(context.TODO(), c, &integration) - assert.Nil(t, err) + require.NoError(t, err) assert.NotNil(t, found) } @@ -163,7 +164,7 @@ func TestApplyIntegrationProfile(t *testing.T) { profile.ResyncStatusFullConfig() c, err := test.NewFakeClient(&profile) - assert.Nil(t, err) + require.NoError(t, err) ip := v1.IntegrationPlatform{ ObjectMeta: metav1.ObjectMeta{ @@ -185,7 +186,7 @@ func TestApplyIntegrationProfile(t *testing.T) { ip.ResyncStatusFullConfig() err = ConfigureDefaults(context.TODO(), c, &ip, true) - assert.Nil(t, err) + require.NoError(t, err) integration := v1.Integration{ ObjectMeta: metav1.ObjectMeta{ @@ -201,7 +202,7 @@ func TestApplyIntegrationProfile(t *testing.T) { } _, err = ApplyIntegrationProfile(context.TODO(), c, &ip, &integration) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, v1.IntegrationPlatformClusterOpenShift, ip.Status.Cluster) assert.Equal(t, v1.TraitProfileOpenShift, ip.Status.Profile) @@ -251,7 +252,7 @@ func TestApplyIntegrationProfileAndRetainPlatformSpec(t *testing.T) { profile.ResyncStatusFullConfig() c, err := test.NewFakeClient(&profile) - assert.Nil(t, err) + require.NoError(t, err) ip := v1.IntegrationPlatform{ ObjectMeta: metav1.ObjectMeta{ @@ -285,7 +286,7 @@ func TestApplyIntegrationProfileAndRetainPlatformSpec(t *testing.T) { ip.ResyncStatusFullConfig() err = ConfigureDefaults(context.TODO(), c, &ip, true) - assert.Nil(t, err) + require.NoError(t, err) integration := v1.Integration{ ObjectMeta: metav1.ObjectMeta{ @@ -301,7 +302,7 @@ func TestApplyIntegrationProfileAndRetainPlatformSpec(t *testing.T) { } _, err = ApplyIntegrationProfile(context.TODO(), c, &ip, &integration) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, v1.IntegrationPlatformClusterKubernetes, ip.Status.Cluster) assert.Equal(t, v1.TraitProfileKnative, ip.Status.Profile) diff --git a/pkg/resources/config/crd/bases/camel.apache.org_builds.yaml b/pkg/resources/config/crd/bases/camel.apache.org_builds.yaml index ae2925cd2d..31635f79dd 100644 --- a/pkg/resources/config/crd/bases/camel.apache.org_builds.yaml +++ b/pkg/resources/config/crd/bases/camel.apache.org_builds.yaml @@ -117,6 +117,12 @@ spec: - fifo - sequential type: string + platforms: + description: The list of platforms used in order to build a container + image. + items: + type: string + type: array requestCPU: description: The minimum amount of CPU required. Only used for `pod` strategy @@ -196,6 +202,12 @@ spec: - fifo - sequential type: string + platforms: + description: The list of platforms used in order to + build a container image. + items: + type: string + type: array requestCPU: description: The minimum amount of CPU required. Only used for `pod` strategy @@ -300,6 +312,12 @@ spec: - fifo - sequential type: string + platforms: + description: The list of platforms used in order to + build a container image. + items: + type: string + type: array requestCPU: description: The minimum amount of CPU required. Only used for `pod` strategy @@ -638,10 +656,27 @@ spec: capabilities: additionalProperties: description: Capability is a particular feature which - requires a well known set of dependencies which - are specified in the runtime catalog. + requires a well known set of dependencies and other + properties which are specified in the runtime catalog. properties: + buildTimeProperties: + description: Set of required Camel build time + properties + items: + description: CamelProperty represents a Camel + property that may end up in an application.properties + file. + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array dependencies: + description: List of required Maven dependencies items: description: MavenArtifact defines a GAV (Group:Artifact:Type:Version:Classifier) Maven artifact. @@ -666,8 +701,26 @@ spec: - groupId type: object type: array - required: - - dependencies + metadata: + additionalProperties: + type: string + description: Set of generic metadata + type: object + runtimeProperties: + description: Set of required Camel runtime properties + items: + description: CamelProperty represents a Camel + property that may end up in an application.properties + file. + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array type: object description: features offered by this runtime type: object @@ -835,6 +888,12 @@ spec: - fifo - sequential type: string + platforms: + description: The list of platforms used in order to + build a container image. + items: + type: string + type: array requestCPU: description: The minimum amount of CPU required. Only used for `pod` strategy @@ -910,6 +969,12 @@ spec: - fifo - sequential type: string + platforms: + description: The list of platforms used in order to + build a container image. + items: + type: string + type: array requestCPU: description: The minimum amount of CPU required. Only used for `pod` strategy @@ -1013,6 +1078,12 @@ spec: - fifo - sequential type: string + platforms: + description: The list of platforms used in order to + build a container image. + items: + type: string + type: array requestCPU: description: The minimum amount of CPU required. Only used for `pod` strategy @@ -1115,6 +1186,12 @@ spec: - fifo - sequential type: string + platforms: + description: The list of platforms used in order to + build a container image. + items: + type: string + type: array requestCPU: description: The minimum amount of CPU required. Only used for `pod` strategy @@ -1453,10 +1530,27 @@ spec: capabilities: additionalProperties: description: Capability is a particular feature which - requires a well known set of dependencies which - are specified in the runtime catalog. + requires a well known set of dependencies and other + properties which are specified in the runtime catalog. properties: + buildTimeProperties: + description: Set of required Camel build time + properties + items: + description: CamelProperty represents a Camel + property that may end up in an application.properties + file. + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array dependencies: + description: List of required Maven dependencies items: description: MavenArtifact defines a GAV (Group:Artifact:Type:Version:Classifier) Maven artifact. @@ -1481,8 +1575,26 @@ spec: - groupId type: object type: array - required: - - dependencies + metadata: + additionalProperties: + type: string + description: Set of generic metadata + type: object + runtimeProperties: + description: Set of required Camel runtime properties + items: + description: CamelProperty represents a Camel + property that may end up in an application.properties + file. + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array type: object description: features offered by this runtime type: object @@ -1641,6 +1753,12 @@ spec: - fifo - sequential type: string + platforms: + description: The list of platforms used in order to + build a container image. + items: + type: string + type: array requestCPU: description: The minimum amount of CPU required. Only used for `pod` strategy @@ -1712,6 +1830,12 @@ spec: - fifo - sequential type: string + platforms: + description: The list of platforms used in order to + build a container image. + items: + type: string + type: array requestCPU: description: The minimum amount of CPU required. Only used for `pod` strategy diff --git a/pkg/resources/config/crd/bases/camel.apache.org_camelcatalogs.yaml b/pkg/resources/config/crd/bases/camel.apache.org_camelcatalogs.yaml index 4f75f02b6a..e76c6bb594 100644 --- a/pkg/resources/config/crd/bases/camel.apache.org_camelcatalogs.yaml +++ b/pkg/resources/config/crd/bases/camel.apache.org_camelcatalogs.yaml @@ -372,10 +372,25 @@ spec: capabilities: additionalProperties: description: Capability is a particular feature which requires - a well known set of dependencies which are specified in the - runtime catalog. + a well known set of dependencies and other properties which + are specified in the runtime catalog. properties: + buildTimeProperties: + description: Set of required Camel build time properties + items: + description: CamelProperty represents a Camel property + that may end up in an application.properties file. + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array dependencies: + description: List of required Maven dependencies items: description: MavenArtifact defines a GAV (Group:Artifact:Type:Version:Classifier) Maven artifact. @@ -400,8 +415,25 @@ spec: - groupId type: object type: array - required: - - dependencies + metadata: + additionalProperties: + type: string + description: Set of generic metadata + type: object + runtimeProperties: + description: Set of required Camel runtime properties + items: + description: CamelProperty represents a Camel property + that may end up in an application.properties file. + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array type: object description: features offered by this runtime type: object diff --git a/pkg/resources/config/crd/bases/camel.apache.org_integrationkits.yaml b/pkg/resources/config/crd/bases/camel.apache.org_integrationkits.yaml index 8a16efffcb..1d5bfb5378 100644 --- a/pkg/resources/config/crd/bases/camel.apache.org_integrationkits.yaml +++ b/pkg/resources/config/crd/bases/camel.apache.org_integrationkits.yaml @@ -88,6 +88,11 @@ spec: spec: description: the desired configuration properties: + capabilities: + description: features offered by the IntegrationKit + items: + type: string + type: array configuration: description: 'Deprecated: Use camel trait (camel.properties) to manage properties Use mount trait (mount.configs) to manage configs Use @@ -258,6 +263,12 @@ spec: - fifo - sequential type: string + platforms: + description: The list of manifest platforms to use to build + a container image (default `linux/amd64`). + items: + type: string + type: array properties: description: A list of properties to be provided to the build task @@ -402,8 +413,9 @@ spec: type: array type: object registry: - description: The Registry trait sets up Maven to use the Image - registry as a Maven repository. + description: 'The Registry trait sets up Maven to use the Image + registry as a Maven repository. Deprecated: use jvm trait or + read documentation.' properties: configuration: description: 'Legacy trait configuration parameters. Deprecated: @@ -539,236 +551,6 @@ spec: runtimeVersion: description: the runtime version for which this kit was configured type: string - traits: - description: generated traits executed by the kit - properties: - addons: - additionalProperties: - description: AddonTrait represents the configuration of an addon - trait. - type: object - x-kubernetes-preserve-unknown-fields: true - description: The collection of addon trait configurations - type: object - builder: - description: The builder trait is internally used to determine - the best strategy to build and configure IntegrationKits. - properties: - annotations: - additionalProperties: - type: string - description: When using `pod` strategy, annotation to use - for the builder pod. - type: object - baseImage: - description: Specify a base image - type: string - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: 'Deprecated: no longer in use.' - type: boolean - incrementalImageBuild: - description: Use the incremental image build option, to reuse - existing containers (default `true`) - type: boolean - limitCPU: - description: 'When using `pod` strategy, the maximum amount - of CPU required by the pod builder. Deprecated: use TasksRequestCPU - instead with task name `builder`.' - type: string - limitMemory: - description: 'When using `pod` strategy, the maximum amount - of memory required by the pod builder. Deprecated: use TasksRequestCPU - instead with task name `builder`.' - type: string - mavenProfiles: - description: 'A list of references pointing to configmaps/secrets - that contains a maven profile. The content of the maven - profile is expected to be a text containing a valid maven - profile starting with `` and ending with `` - that will be integrated as an inline profile in the POM. - Syntax: [configmap|secret]:name[/key], where name represents - the resource name, key optionally represents the resource - key to be filtered (default key value = profile.xml).' - items: - type: string - type: array - nodeSelector: - additionalProperties: - type: string - description: Defines a set of nodes the builder pod is eligible - to be scheduled on, based on labels on the node. - type: object - orderStrategy: - description: The build order strategy to use, either `dependencies`, - `fifo` or `sequential` (default `sequential`) - enum: - - dependencies - - fifo - - sequential - type: string - properties: - description: A list of properties to be provided to the build - task - items: - type: string - type: array - requestCPU: - description: 'When using `pod` strategy, the minimum amount - of CPU required by the pod builder. Deprecated: use TasksRequestCPU - instead with task name `builder`.' - type: string - requestMemory: - description: 'When using `pod` strategy, the minimum amount - of memory required by the pod builder. Deprecated: use TasksRequestCPU - instead with task name `builder`.' - type: string - strategy: - description: The strategy to use, either `pod` or `routine` - (default `routine`) - enum: - - pod - - routine - type: string - tasks: - description: A list of tasks to be executed (available only - when using `pod` strategy) with format `;;`. - items: - type: string - type: array - tasksFilter: - description: A list of tasks sorted by the order of execution - in a csv format, ie, `,,...`. Mind - that you must include also the operator tasks (`builder`, - `quarkus-native`, `package`, `jib`, `spectrum`, `s2i`) if - you need to execute them. Useful only with `pod` strategy. - type: string - tasksLimitCPU: - description: A list of limit cpu configuration for the specific - task with format `:`. - items: - type: string - type: array - tasksLimitMemory: - description: A list of limit memory configuration for the - specific task with format `:`. - items: - type: string - type: array - tasksRequestCPU: - description: A list of request cpu configuration for the specific - task with format `:`. - items: - type: string - type: array - tasksRequestMemory: - description: A list of request memory configuration for the - specific task with format `:`. - items: - type: string - type: array - verbose: - description: Enable verbose logging on build components that - support it (e.g. Kaniko build pod). Deprecated no longer - in use - type: boolean - type: object - camel: - description: The Camel trait sets up Camel configuration. - properties: - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: 'Deprecated: no longer in use.' - type: boolean - properties: - description: A list of properties to be provided to the Integration - runtime - items: - type: string - type: array - runtimeVersion: - description: The camel-k-runtime version to use for the integration. - It overrides the default version set in the Integration - Platform. - type: string - type: object - quarkus: - description: 'The Quarkus trait configures the Quarkus runtime. - It''s enabled by default. NOTE: Compiling to a native executable, - requires at least 4GiB of memory, so the Pod running the native - build must have enough memory available.' - properties: - buildMode: - description: 'The Quarkus mode to run: either `jvm` or `native` - (default `jvm`). In case both `jvm` and `native` are specified, - two `IntegrationKit` resources are created, with the `native` - kit having precedence over the `jvm` one once ready.' - items: - description: QuarkusMode is the type of Quarkus build packaging. - enum: - - jvm - - native - type: string - type: array - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: 'Deprecated: no longer in use.' - type: boolean - nativeBaseImage: - description: The base image to use when running a native build - (default `quay.io/quarkus/quarkus-micro-image:2.0`) - type: string - nativeBuilderImage: - description: The image containing the tooling required for - a native build (by default it will use the one provided - in the runtime catalog) - type: string - packageTypes: - description: 'The Quarkus package types, `fast-jar` or `native` - (default `fast-jar`). In case both `fast-jar` and `native` - are specified, two `IntegrationKit` resources are created, - with the native kit having precedence over the `fast-jar` - one once ready. The order influences the resolution of the - current kit for the integration. The kit corresponding to - the first package type will be assigned to the integration - in case no existing kit that matches the integration exists. - Deprecated: use `build-mode` instead.' - items: - description: 'QuarkusPackageType is the type of Quarkus - build packaging. Deprecated: use `QuarkusMode` instead.' - enum: - - fast-jar - - native - type: string - type: array - type: object - registry: - description: The Registry trait sets up Maven to use the Image - registry as a Maven repository. - properties: - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: Can be used to enable or disable a trait. All - traits share this common property. - type: boolean - type: object - type: object version: description: the Camel K operator version for which this kit was configured type: string diff --git a/pkg/resources/config/crd/bases/camel.apache.org_integrationplatforms.yaml b/pkg/resources/config/crd/bases/camel.apache.org_integrationplatforms.yaml index a76be34402..2ab9010acf 100644 --- a/pkg/resources/config/crd/bases/camel.apache.org_integrationplatforms.yaml +++ b/pkg/resources/config/crd/bases/camel.apache.org_integrationplatforms.yaml @@ -136,6 +136,12 @@ spec: - fifo - sequential type: string + platforms: + description: The list of platforms used in order to build + a container image. + items: + type: string + type: array requestCPU: description: The minimum amount of CPU required. Only used for `pod` strategy @@ -573,6 +579,12 @@ spec: - fifo - sequential type: string + platforms: + description: The list of manifest platforms to use to build + a container image (default `linux/amd64`). + items: + type: string + type: array properties: description: A list of properties to be provided to the build task @@ -852,20 +864,26 @@ spec: format: int32 type: integer rollingUpdateMaxSurge: + anyOf: + - type: integer + - type: string description: 'The maximum number of pods that can be scheduled above the desired number of pods. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). This can not be 0 if MaxUnavailable is 0. Absolute number is calculated from percentage by rounding up. Defaults to `25%`.' - type: integer + x-kubernetes-int-or-string: true rollingUpdateMaxUnavailable: + anyOf: + - type: integer + - type: string description: 'The maximum number of pods that can be unavailable during the update. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). Absolute number is calculated from percentage by rounding down. This can not be 0 if MaxSurge is 0. Defaults to `25%`.' - type: integer + x-kubernetes-int-or-string: true strategy: description: The deployment strategy to use to replace existing pods with new ones. @@ -1483,7 +1501,8 @@ spec: description: Enable "hot reload" when a secret/configmap mounted is edited (default `false`). The configmap/secret must be marked with `camel.apache.org/integration` label to be taken - in account. + in account. The resource will be watched for any kind change, + also for changes in metadata. type: boolean resources: description: 'A list of resources (text or binary content) @@ -1497,6 +1516,14 @@ spec: items: type: string type: array + scanKameletsImplicitLabelSecrets: + description: 'Deprecated: include your properties in an explicit + property file backed by a secret. Let the operator to scan + for secret labeled with `camel.apache.org/kamelet` and `camel.apache.org/kamelet.configuration`. + These secrets are mounted to the application and treated + as plain properties file with their key/value list (ie .spec.data["camel.my-property"] + = my-value) (default `true`).' + type: boolean volumes: description: 'A list of Persistent Volume Claims to be mounted. Syntax: [pvcname:/container/path]' @@ -1717,7 +1744,8 @@ spec: type: array type: object registry: - description: The configuration of Registry trait + description: 'The configuration of Registry trait Deprecated: + use jvm trait or read documentation.' properties: configuration: description: 'Legacy trait configuration parameters. Deprecated: @@ -1969,6 +1997,12 @@ spec: - fifo - sequential type: string + platforms: + description: The list of platforms used in order to build + a container image. + items: + type: string + type: array requestCPU: description: The minimum amount of CPU required. Only used for `pod` strategy @@ -2454,6 +2488,12 @@ spec: - fifo - sequential type: string + platforms: + description: The list of manifest platforms to use to build + a container image (default `linux/amd64`). + items: + type: string + type: array properties: description: A list of properties to be provided to the build task @@ -2733,20 +2773,26 @@ spec: format: int32 type: integer rollingUpdateMaxSurge: + anyOf: + - type: integer + - type: string description: 'The maximum number of pods that can be scheduled above the desired number of pods. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). This can not be 0 if MaxUnavailable is 0. Absolute number is calculated from percentage by rounding up. Defaults to `25%`.' - type: integer + x-kubernetes-int-or-string: true rollingUpdateMaxUnavailable: + anyOf: + - type: integer + - type: string description: 'The maximum number of pods that can be unavailable during the update. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). Absolute number is calculated from percentage by rounding down. This can not be 0 if MaxSurge is 0. Defaults to `25%`.' - type: integer + x-kubernetes-int-or-string: true strategy: description: The deployment strategy to use to replace existing pods with new ones. @@ -3364,7 +3410,8 @@ spec: description: Enable "hot reload" when a secret/configmap mounted is edited (default `false`). The configmap/secret must be marked with `camel.apache.org/integration` label to be taken - in account. + in account. The resource will be watched for any kind change, + also for changes in metadata. type: boolean resources: description: 'A list of resources (text or binary content) @@ -3378,6 +3425,14 @@ spec: items: type: string type: array + scanKameletsImplicitLabelSecrets: + description: 'Deprecated: include your properties in an explicit + property file backed by a secret. Let the operator to scan + for secret labeled with `camel.apache.org/kamelet` and `camel.apache.org/kamelet.configuration`. + These secrets are mounted to the application and treated + as plain properties file with their key/value list (ie .spec.data["camel.my-property"] + = my-value) (default `true`).' + type: boolean volumes: description: 'A list of Persistent Volume Claims to be mounted. Syntax: [pvcname:/container/path]' @@ -3598,7 +3653,8 @@ spec: type: array type: object registry: - description: The configuration of Registry trait + description: 'The configuration of Registry trait Deprecated: + use jvm trait or read documentation.' properties: configuration: description: 'Legacy trait configuration parameters. Deprecated: diff --git a/pkg/resources/config/crd/bases/camel.apache.org_integrationprofiles.yaml b/pkg/resources/config/crd/bases/camel.apache.org_integrationprofiles.yaml index 3e997b3cea..21e0c93340 100644 --- a/pkg/resources/config/crd/bases/camel.apache.org_integrationprofiles.yaml +++ b/pkg/resources/config/crd/bases/camel.apache.org_integrationprofiles.yaml @@ -455,6 +455,12 @@ spec: - fifo - sequential type: string + platforms: + description: The list of manifest platforms to use to build + a container image (default `linux/amd64`). + items: + type: string + type: array properties: description: A list of properties to be provided to the build task @@ -734,20 +740,26 @@ spec: format: int32 type: integer rollingUpdateMaxSurge: + anyOf: + - type: integer + - type: string description: 'The maximum number of pods that can be scheduled above the desired number of pods. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). This can not be 0 if MaxUnavailable is 0. Absolute number is calculated from percentage by rounding up. Defaults to `25%`.' - type: integer + x-kubernetes-int-or-string: true rollingUpdateMaxUnavailable: + anyOf: + - type: integer + - type: string description: 'The maximum number of pods that can be unavailable during the update. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). Absolute number is calculated from percentage by rounding down. This can not be 0 if MaxSurge is 0. Defaults to `25%`.' - type: integer + x-kubernetes-int-or-string: true strategy: description: The deployment strategy to use to replace existing pods with new ones. @@ -1358,7 +1370,8 @@ spec: description: Enable "hot reload" when a secret/configmap mounted is edited (default `false`). The configmap/secret must be marked with `camel.apache.org/integration` label to be taken - in account. + in account. The resource will be watched for any kind change, + also for changes in metadata. type: boolean resources: description: 'A list of resources (text or binary content) @@ -1372,6 +1385,14 @@ spec: items: type: string type: array + scanKameletsImplicitLabelSecrets: + description: 'Deprecated: include your properties in an explicit + property file backed by a secret. Let the operator to scan + for secret labeled with `camel.apache.org/kamelet` and `camel.apache.org/kamelet.configuration`. + These secrets are mounted to the application and treated + as plain properties file with their key/value list (ie .spec.data["camel.my-property"] + = my-value) (default `true`).' + type: boolean volumes: description: 'A list of Persistent Volume Claims to be mounted. Syntax: [pvcname:/container/path]' @@ -1592,7 +1613,8 @@ spec: type: array type: object registry: - description: The configuration of Registry trait + description: 'The configuration of Registry trait Deprecated: + use jvm trait or read documentation.' properties: configuration: description: 'Legacy trait configuration parameters. Deprecated: @@ -2218,6 +2240,12 @@ spec: - fifo - sequential type: string + platforms: + description: The list of manifest platforms to use to build + a container image (default `linux/amd64`). + items: + type: string + type: array properties: description: A list of properties to be provided to the build task @@ -2497,20 +2525,26 @@ spec: format: int32 type: integer rollingUpdateMaxSurge: + anyOf: + - type: integer + - type: string description: 'The maximum number of pods that can be scheduled above the desired number of pods. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). This can not be 0 if MaxUnavailable is 0. Absolute number is calculated from percentage by rounding up. Defaults to `25%`.' - type: integer + x-kubernetes-int-or-string: true rollingUpdateMaxUnavailable: + anyOf: + - type: integer + - type: string description: 'The maximum number of pods that can be unavailable during the update. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). Absolute number is calculated from percentage by rounding down. This can not be 0 if MaxSurge is 0. Defaults to `25%`.' - type: integer + x-kubernetes-int-or-string: true strategy: description: The deployment strategy to use to replace existing pods with new ones. @@ -3121,7 +3155,8 @@ spec: description: Enable "hot reload" when a secret/configmap mounted is edited (default `false`). The configmap/secret must be marked with `camel.apache.org/integration` label to be taken - in account. + in account. The resource will be watched for any kind change, + also for changes in metadata. type: boolean resources: description: 'A list of resources (text or binary content) @@ -3135,6 +3170,14 @@ spec: items: type: string type: array + scanKameletsImplicitLabelSecrets: + description: 'Deprecated: include your properties in an explicit + property file backed by a secret. Let the operator to scan + for secret labeled with `camel.apache.org/kamelet` and `camel.apache.org/kamelet.configuration`. + These secrets are mounted to the application and treated + as plain properties file with their key/value list (ie .spec.data["camel.my-property"] + = my-value) (default `true`).' + type: boolean volumes: description: 'A list of Persistent Volume Claims to be mounted. Syntax: [pvcname:/container/path]' @@ -3355,7 +3398,8 @@ spec: type: array type: object registry: - description: The configuration of Registry trait + description: 'The configuration of Registry trait Deprecated: + use jvm trait or read documentation.' properties: configuration: description: 'Legacy trait configuration parameters. Deprecated: diff --git a/pkg/resources/config/crd/bases/camel.apache.org_integrations.yaml b/pkg/resources/config/crd/bases/camel.apache.org_integrations.yaml index 3c343c6bbb..db212a24e7 100644 --- a/pkg/resources/config/crd/bases/camel.apache.org_integrations.yaml +++ b/pkg/resources/config/crd/bases/camel.apache.org_integrations.yaml @@ -6474,6 +6474,12 @@ spec: - fifo - sequential type: string + platforms: + description: The list of manifest platforms to use to build + a container image (default `linux/amd64`). + items: + type: string + type: array properties: description: A list of properties to be provided to the build task @@ -6753,20 +6759,26 @@ spec: format: int32 type: integer rollingUpdateMaxSurge: + anyOf: + - type: integer + - type: string description: 'The maximum number of pods that can be scheduled above the desired number of pods. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). This can not be 0 if MaxUnavailable is 0. Absolute number is calculated from percentage by rounding up. Defaults to `25%`.' - type: integer + x-kubernetes-int-or-string: true rollingUpdateMaxUnavailable: + anyOf: + - type: integer + - type: string description: 'The maximum number of pods that can be unavailable during the update. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). Absolute number is calculated from percentage by rounding down. This can not be 0 if MaxSurge is 0. Defaults to `25%`.' - type: integer + x-kubernetes-int-or-string: true strategy: description: The deployment strategy to use to replace existing pods with new ones. @@ -7384,7 +7396,8 @@ spec: description: Enable "hot reload" when a secret/configmap mounted is edited (default `false`). The configmap/secret must be marked with `camel.apache.org/integration` label to be taken - in account. + in account. The resource will be watched for any kind change, + also for changes in metadata. type: boolean resources: description: 'A list of resources (text or binary content) @@ -7398,6 +7411,14 @@ spec: items: type: string type: array + scanKameletsImplicitLabelSecrets: + description: 'Deprecated: include your properties in an explicit + property file backed by a secret. Let the operator to scan + for secret labeled with `camel.apache.org/kamelet` and `camel.apache.org/kamelet.configuration`. + These secrets are mounted to the application and treated + as plain properties file with their key/value list (ie .spec.data["camel.my-property"] + = my-value) (default `true`).' + type: boolean volumes: description: 'A list of Persistent Volume Claims to be mounted. Syntax: [pvcname:/container/path]' @@ -7618,7 +7639,8 @@ spec: type: array type: object registry: - description: The configuration of Registry trait + description: 'The configuration of Registry trait Deprecated: + use jvm trait or read documentation.' properties: configuration: description: 'Legacy trait configuration parameters. Deprecated: @@ -8079,1462 +8101,6 @@ spec: selector: description: label selector type: string - traits: - description: the traits generated and executed for this Integration - properties: - 3scale: - description: 'Deprecated: for backward compatibility.' - properties: - configuration: - description: TraitConfiguration parameters configuration - type: object - x-kubernetes-preserve-unknown-fields: true - required: - - configuration - type: object - addons: - additionalProperties: - description: AddonTrait represents the configuration of an addon - trait. - type: object - x-kubernetes-preserve-unknown-fields: true - description: The extension point with addon traits - type: object - affinity: - description: The configuration of Affinity trait - properties: - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: Can be used to enable or disable a trait. All - traits share this common property. - type: boolean - nodeAffinityLabels: - description: Defines a set of nodes the integration pod(s) - are eligible to be scheduled on, based on labels on the - node. - items: - type: string - type: array - podAffinity: - description: Always co-locates multiple replicas of the integration - in the same node (default `false`). - type: boolean - podAffinityLabels: - description: Defines a set of pods (namely those matching - the label selector, relative to the given namespace) that - the integration pod(s) should be co-located with. - items: - type: string - type: array - podAntiAffinity: - description: Never co-locates multiple replicas of the integration - in the same node (default `false`). - type: boolean - podAntiAffinityLabels: - description: Defines a set of pods (namely those matching - the label selector, relative to the given namespace) that - the integration pod(s) should not be co-located with. - items: - type: string - type: array - type: object - builder: - description: The configuration of Builder trait - properties: - annotations: - additionalProperties: - type: string - description: When using `pod` strategy, annotation to use - for the builder pod. - type: object - baseImage: - description: Specify a base image - type: string - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: 'Deprecated: no longer in use.' - type: boolean - incrementalImageBuild: - description: Use the incremental image build option, to reuse - existing containers (default `true`) - type: boolean - limitCPU: - description: 'When using `pod` strategy, the maximum amount - of CPU required by the pod builder. Deprecated: use TasksRequestCPU - instead with task name `builder`.' - type: string - limitMemory: - description: 'When using `pod` strategy, the maximum amount - of memory required by the pod builder. Deprecated: use TasksRequestCPU - instead with task name `builder`.' - type: string - mavenProfiles: - description: 'A list of references pointing to configmaps/secrets - that contains a maven profile. The content of the maven - profile is expected to be a text containing a valid maven - profile starting with `` and ending with `` - that will be integrated as an inline profile in the POM. - Syntax: [configmap|secret]:name[/key], where name represents - the resource name, key optionally represents the resource - key to be filtered (default key value = profile.xml).' - items: - type: string - type: array - nodeSelector: - additionalProperties: - type: string - description: Defines a set of nodes the builder pod is eligible - to be scheduled on, based on labels on the node. - type: object - orderStrategy: - description: The build order strategy to use, either `dependencies`, - `fifo` or `sequential` (default `sequential`) - enum: - - dependencies - - fifo - - sequential - type: string - properties: - description: A list of properties to be provided to the build - task - items: - type: string - type: array - requestCPU: - description: 'When using `pod` strategy, the minimum amount - of CPU required by the pod builder. Deprecated: use TasksRequestCPU - instead with task name `builder`.' - type: string - requestMemory: - description: 'When using `pod` strategy, the minimum amount - of memory required by the pod builder. Deprecated: use TasksRequestCPU - instead with task name `builder`.' - type: string - strategy: - description: The strategy to use, either `pod` or `routine` - (default `routine`) - enum: - - pod - - routine - type: string - tasks: - description: A list of tasks to be executed (available only - when using `pod` strategy) with format `;;`. - items: - type: string - type: array - tasksFilter: - description: A list of tasks sorted by the order of execution - in a csv format, ie, `,,...`. Mind - that you must include also the operator tasks (`builder`, - `quarkus-native`, `package`, `jib`, `spectrum`, `s2i`) if - you need to execute them. Useful only with `pod` strategy. - type: string - tasksLimitCPU: - description: A list of limit cpu configuration for the specific - task with format `:`. - items: - type: string - type: array - tasksLimitMemory: - description: A list of limit memory configuration for the - specific task with format `:`. - items: - type: string - type: array - tasksRequestCPU: - description: A list of request cpu configuration for the specific - task with format `:`. - items: - type: string - type: array - tasksRequestMemory: - description: A list of request memory configuration for the - specific task with format `:`. - items: - type: string - type: array - verbose: - description: Enable verbose logging on build components that - support it (e.g. Kaniko build pod). Deprecated no longer - in use - type: boolean - type: object - camel: - description: The configuration of Camel trait - properties: - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: 'Deprecated: no longer in use.' - type: boolean - properties: - description: A list of properties to be provided to the Integration - runtime - items: - type: string - type: array - runtimeVersion: - description: The camel-k-runtime version to use for the integration. - It overrides the default version set in the Integration - Platform. - type: string - type: object - container: - description: The configuration of Container trait - properties: - auto: - description: To automatically enable the trait - type: boolean - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: 'Deprecated: no longer in use.' - type: boolean - expose: - description: Can be used to enable/disable exposure via kubernetes - Service. - type: boolean - image: - description: The main container image - type: string - imagePullPolicy: - description: 'The pull policy: Always|Never|IfNotPresent' - enum: - - Always - - Never - - IfNotPresent - type: string - limitCPU: - description: The maximum amount of CPU required. - type: string - limitMemory: - description: The maximum amount of memory required. - type: string - name: - description: The main container name. It's named `integration` - by default. - type: string - port: - description: To configure a different port exposed by the - container (default `8080`). - type: integer - portName: - description: To configure a different port name for the port - exposed by the container. It defaults to `http` only when - the `expose` parameter is true. - type: string - requestCPU: - description: The minimum amount of CPU required. - type: string - requestMemory: - description: The minimum amount of memory required. - type: string - servicePort: - description: To configure under which service port the container - port is to be exposed (default `80`). - type: integer - servicePortName: - description: To configure under which service port name the - container port is to be exposed (default `http`). - type: string - type: object - cron: - description: The configuration of Cron trait - properties: - activeDeadlineSeconds: - description: Specifies the duration in seconds, relative to - the start time, that the job may be continuously active - before it is considered to be failed. It defaults to 60s. - format: int64 - type: integer - auto: - description: "Automatically deploy the integration as CronJob - when all routes are either starting from a periodic consumer - (only `cron`, `timer` and `quartz` are supported) or a passive - consumer (e.g. `direct` is a passive consumer). \n It's - required that all periodic consumers have the same period, - and it can be expressed as cron schedule (e.g. `1m` can - be expressed as `0/1 * * * *`, while `35m` or `50s` cannot)." - type: boolean - backoffLimit: - description: Specifies the number of retries before marking - the job failed. It defaults to 2. - format: int32 - type: integer - components: - description: "A comma separated list of the Camel components - that need to be customized in order for them to work when - the schedule is triggered externally by Kubernetes. A specific - customizer is activated for each specified component. E.g. - for the `timer` component, the `cron-timer` customizer is - activated (it's present in the `org.apache.camel.k:camel-k-cron` - library). \n Supported components are currently: `cron`, - `timer` and `quartz`." - type: string - concurrencyPolicy: - description: 'Specifies how to treat concurrent executions - of a Job. Valid values are: - "Allow": allows CronJobs to - run concurrently; - "Forbid" (default): forbids concurrent - runs, skipping next run if previous run hasn''t finished - yet; - "Replace": cancels currently running job and replaces - it with a new one' - enum: - - Allow - - Forbid - - Replace - type: string - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: Can be used to enable or disable a trait. All - traits share this common property. - type: boolean - fallback: - description: Use the default Camel implementation of the `cron` - endpoint (`quartz`) instead of trying to materialize the - integration as Kubernetes CronJob. - type: boolean - schedule: - description: The CronJob schedule for the whole integration. - If multiple routes are declared, they must have the same - schedule for this mechanism to work correctly. - type: string - startingDeadlineSeconds: - description: Optional deadline in seconds for starting the - job if it misses scheduled time for any reason. Missed - jobs executions will be counted as failed ones. - format: int64 - type: integer - type: object - dependencies: - description: The configuration of Dependencies trait - properties: - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: 'Deprecated: no longer in use.' - type: boolean - type: object - deployer: - description: The configuration of Deployer trait - properties: - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: 'Deprecated: no longer in use.' - type: boolean - kind: - description: Allows to explicitly select the desired deployment - kind between `deployment`, `cron-job` or `knative-service` - when creating the resources for running the integration. - enum: - - deployment - - cron-job - - knative-service - type: string - useSSA: - description: Use server-side apply to update the owned resources - (default `true`). Note that it automatically falls back - to client-side patching, if SSA is not available, e.g., - on old Kubernetes clusters. - type: boolean - type: object - deployment: - description: The configuration of Deployment trait - properties: - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: 'Deprecated: no longer in use.' - type: boolean - progressDeadlineSeconds: - description: The maximum time in seconds for the deployment - to make progress before it is considered to be failed. It - defaults to `60s`. - format: int32 - type: integer - rollingUpdateMaxSurge: - description: 'The maximum number of pods that can be scheduled - above the desired number of pods. Value can be an absolute - number (ex: 5) or a percentage of desired pods (ex: 10%). - This can not be 0 if MaxUnavailable is 0. Absolute number - is calculated from percentage by rounding up. Defaults to - `25%`.' - type: integer - rollingUpdateMaxUnavailable: - description: 'The maximum number of pods that can be unavailable - during the update. Value can be an absolute number (ex: - 5) or a percentage of desired pods (ex: 10%). Absolute number - is calculated from percentage by rounding down. This can - not be 0 if MaxSurge is 0. Defaults to `25%`.' - type: integer - strategy: - description: The deployment strategy to use to replace existing - pods with new ones. - enum: - - Recreate - - RollingUpdate - type: string - type: object - environment: - description: The configuration of Environment trait - properties: - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - containerMeta: - description: Enables injection of `NAMESPACE` and `POD_NAME` - environment variables (default `true`) - type: boolean - enabled: - description: 'Deprecated: no longer in use.' - type: boolean - httpProxy: - description: Propagates the `HTTP_PROXY`, `HTTPS_PROXY` and - `NO_PROXY` environment variables (default `true`) - type: boolean - vars: - description: A list of environment variables to be added to - the integration container. The syntax is KEY=VALUE, e.g., - `MY_VAR="my value"`. These take precedence over the previously - defined environment variables. - items: - type: string - type: array - type: object - error-handler: - description: The configuration of Error Handler trait - properties: - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: 'Deprecated: no longer in use.' - type: boolean - ref: - description: The error handler ref name provided or found - in application properties - type: string - type: object - gc: - description: The configuration of GC trait - properties: - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - discoveryCache: - description: 'Discovery client cache to be used, either `disabled`, - `disk` or `memory` (default `memory`). Deprecated: to be - removed from trait configuration.' - enum: - - disabled - - disk - - memory - type: string - enabled: - description: Can be used to enable or disable a trait. All - traits share this common property. - type: boolean - type: object - health: - description: The configuration of Health trait - properties: - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: Can be used to enable or disable a trait. All - traits share this common property. - type: boolean - livenessFailureThreshold: - description: Minimum consecutive failures for the liveness - probe to be considered failed after having succeeded. - format: int32 - type: integer - livenessInitialDelay: - description: Number of seconds after the container has started - before the liveness probe is initiated. - format: int32 - type: integer - livenessPeriod: - description: How often to perform the liveness probe. - format: int32 - type: integer - livenessProbeEnabled: - description: Configures the liveness probe for the integration - container (default `false`). - type: boolean - livenessScheme: - description: Scheme to use when connecting to the liveness - probe (default `HTTP`). - type: string - livenessSuccessThreshold: - description: Minimum consecutive successes for the liveness - probe to be considered successful after having failed. - format: int32 - type: integer - livenessTimeout: - description: Number of seconds after which the liveness probe - times out. - format: int32 - type: integer - readinessFailureThreshold: - description: Minimum consecutive failures for the readiness - probe to be considered failed after having succeeded. - format: int32 - type: integer - readinessInitialDelay: - description: Number of seconds after the container has started - before the readiness probe is initiated. - format: int32 - type: integer - readinessPeriod: - description: How often to perform the readiness probe. - format: int32 - type: integer - readinessProbeEnabled: - description: Configures the readiness probe for the integration - container (default `true`). - type: boolean - readinessScheme: - description: Scheme to use when connecting to the readiness - probe (default `HTTP`). - type: string - readinessSuccessThreshold: - description: Minimum consecutive successes for the readiness - probe to be considered successful after having failed. - format: int32 - type: integer - readinessTimeout: - description: Number of seconds after which the readiness probe - times out. - format: int32 - type: integer - startupFailureThreshold: - description: Minimum consecutive failures for the startup - probe to be considered failed after having succeeded. - format: int32 - type: integer - startupInitialDelay: - description: Number of seconds after the container has started - before the startup probe is initiated. - format: int32 - type: integer - startupPeriod: - description: How often to perform the startup probe. - format: int32 - type: integer - startupProbeEnabled: - description: Configures the startup probe for the integration - container (default `false`). - type: boolean - startupScheme: - description: Scheme to use when connecting to the startup - probe (default `HTTP`). - type: string - startupSuccessThreshold: - description: Minimum consecutive successes for the startup - probe to be considered successful after having failed. - format: int32 - type: integer - startupTimeout: - description: Number of seconds after which the startup probe - times out. - format: int32 - type: integer - type: object - ingress: - description: The configuration of Ingress trait - properties: - annotations: - additionalProperties: - type: string - description: 'The annotations added to the ingress. This can - be used to set controller specific annotations, e.g., when - using the NGINX Ingress controller: See https://github.com/kubernetes/ingress-nginx/blob/main/docs/user-guide/nginx-configuration/annotations.md' - type: object - auto: - description: To automatically add an ingress whenever the - integration uses an HTTP endpoint consumer. - type: boolean - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: Can be used to enable or disable a trait. All - traits share this common property. - type: boolean - host: - description: To configure the host exposed by the ingress. - type: string - path: - description: To configure the path exposed by the ingress - (default `/`). - type: string - pathType: - description: To configure the path type exposed by the ingress. - One of `Exact`, `Prefix`, `ImplementationSpecific` (default - to `Prefix`). - enum: - - Exact - - Prefix - - ImplementationSpecific - type: string - type: object - istio: - description: The configuration of Istio trait - properties: - allow: - description: Configures a (comma-separated) list of CIDR subnets - that should not be intercepted by the Istio proxy (`10.0.0.0/8,172.16.0.0/12,192.168.0.0/16` - by default). - type: string - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: Can be used to enable or disable a trait. All - traits share this common property. - type: boolean - inject: - description: Forces the value for labels `sidecar.istio.io/inject`. - By default the label is set to `true` on deployment and - not set on Knative Service. - type: boolean - type: object - jolokia: - description: The configuration of Jolokia trait - properties: - CACert: - description: The PEM encoded CA certification file path, used - to verify client certificates, applicable when `protocol` - is `https` and `use-ssl-client-authentication` is `true` - (default `/var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt` - for OpenShift). - type: string - clientPrincipal: - description: The principal(s) which must be given in a client - certificate to allow access to the Jolokia endpoint, applicable - when `protocol` is `https` and `use-ssl-client-authentication` - is `true` (default `clientPrincipal=cn=system:master-proxy`, - `cn=hawtio-online.hawtio.svc` and `cn=fuse-console.fuse.svc` - for OpenShift). - items: - type: string - type: array - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - discoveryEnabled: - description: Listen for multicast requests (default `false`) - type: boolean - enabled: - description: Can be used to enable or disable a trait. All - traits share this common property. - type: boolean - extendedClientCheck: - description: Mandate the client certificate contains a client - flag in the extended key usage section, applicable when - `protocol` is `https` and `use-ssl-client-authentication` - is `true` (default `true` for OpenShift). - type: boolean - host: - description: The Host address to which the Jolokia agent should - bind to. If `"\*"` or `"0.0.0.0"` is given, the servers - binds to every network interface (default `"*"`). - type: string - options: - description: A list of additional Jolokia options as defined - in https://jolokia.org/reference/html/agents.html#agent-jvm-config[JVM - agent configuration options] - items: - type: string - type: array - password: - description: The password used for authentication, applicable - when the `user` option is set. - type: string - port: - description: The Jolokia endpoint port (default `8778`). - type: integer - protocol: - description: The protocol to use, either `http` or `https` - (default `https` for OpenShift) - type: string - useSSLClientAuthentication: - description: Whether client certificates should be used for - authentication (default `true` for OpenShift). - type: boolean - user: - description: The user to be used for authentication - type: string - type: object - jvm: - description: The configuration of JVM trait - properties: - classpath: - description: Additional JVM classpath (use `Linux` classpath - separator) - type: string - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - debug: - description: Activates remote debugging, so that a debugger - can be attached to the JVM, e.g., using port-forwarding - type: boolean - debugAddress: - description: Transport address at which to listen for the - newly launched JVM (default `*:5005`) - type: string - debugSuspend: - description: Suspends the target JVM immediately before the - main class is loaded - type: boolean - enabled: - description: Can be used to enable or disable a trait. All - traits share this common property. - type: boolean - options: - description: A list of JVM options - items: - type: string - type: array - printCommand: - description: Prints the command used the start the JVM in - the container logs (default `true`) - type: boolean - type: object - kamelets: - description: The configuration of Kamelets trait - properties: - auto: - description: Automatically inject all referenced Kamelets - and their default configuration (enabled by default) - type: boolean - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: Can be used to enable or disable a trait. All - traits share this common property. - type: boolean - list: - description: Comma separated list of Kamelet names to load - into the current integration - type: string - mountPoint: - description: The directory where the application mounts and - reads Kamelet spec (default `/etc/camel/kamelets`) - type: string - type: object - keda: - description: 'Deprecated: for backward compatibility.' - properties: - configuration: - description: TraitConfiguration parameters configuration - type: object - x-kubernetes-preserve-unknown-fields: true - required: - - configuration - type: object - knative: - description: The configuration of Knative trait - properties: - auto: - description: Enable automatic discovery of all trait properties. - type: boolean - channelSinks: - description: List of channels used as destination of integration - routes. Can contain simple channel names or full Camel URIs. - items: - type: string - type: array - channelSources: - description: List of channels used as source of integration - routes. Can contain simple channel names or full Camel URIs. - items: - type: string - type: array - config: - description: Can be used to inject a Knative complete configuration - in JSON format. - type: string - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: Can be used to enable or disable a trait. All - traits share this common property. - type: boolean - endpointSinks: - description: List of endpoints used as destination of integration - routes. Can contain simple endpoint names or full Camel - URIs. - items: - type: string - type: array - endpointSources: - description: List of channels used as source of integration - routes. - items: - type: string - type: array - eventSinks: - description: List of event types that the integration will - produce. Can contain simple event types or full Camel URIs - (to use a specific broker). - items: - type: string - type: array - eventSources: - description: List of event types that the integration will - be subscribed to. Can contain simple event types or full - Camel URIs (to use a specific broker different from "default"). - items: - type: string - type: array - filterSourceChannels: - description: Enables filtering on events based on the header - "ce-knativehistory". Since this header has been removed - in newer versions of Knative, filtering is disabled by default. - type: boolean - namespaceLabel: - description: 'Enables the camel-k-operator to set the "bindings.knative.dev/include=true" - label to the namespace As Knative requires this label to - perform injection of K_SINK URL into the service. If this - is false, the integration pod may start and fail, read the - SinkBinding Knative documentation. (default: true)' - type: boolean - sinkBinding: - description: Allows binding the integration to a sink via - a Knative SinkBinding resource. This can be used when the - integration targets a single sink. It's enabled by default - when the integration targets a single sink (except when - the integration is owned by a Knative source). - type: boolean - type: object - knative-service: - description: The configuration of Knative Service trait - properties: - annotations: - additionalProperties: - type: string - description: 'The annotations added to route. This can be - used to set knative service specific annotations CLI usage - example: -t "knative-service.annotations.''haproxy.router.openshift.io/balance''=true"' - type: object - auto: - description: "Automatically deploy the integration as Knative - service when all conditions hold: \n * Integration is using - the Knative profile * All routes are either starting from - an HTTP based consumer or a passive consumer (e.g. `direct` - is a passive consumer)" - type: boolean - autoscalingMetric: - description: "Configures the Knative autoscaling metric property - (e.g. to set `concurrency` based or `cpu` based autoscaling). - \n Refer to the Knative documentation for more information." - type: string - autoscalingTarget: - description: "Sets the allowed concurrency level or CPU percentage - (depending on the autoscaling metric) for each Pod. \n Refer - to the Knative documentation for more information." - type: integer - class: - description: "Configures the Knative autoscaling class property - (e.g. to set `hpa.autoscaling.knative.dev` or `kpa.autoscaling.knative.dev` - autoscaling). \n Refer to the Knative documentation for - more information." - enum: - - kpa.autoscaling.knative.dev - - hpa.autoscaling.knative.dev - type: string - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: Can be used to enable or disable a trait. All - traits share this common property. - type: boolean - maxScale: - description: "An upper bound for the number of Pods that can - be running in parallel for the integration. Knative has - its own cap value that depends on the installation. \n Refer - to the Knative documentation for more information." - type: integer - minScale: - description: "The minimum number of Pods that should be running - at any time for the integration. It's **zero** by default, - meaning that the integration is scaled down to zero when - not used for a configured amount of time. \n Refer to the - Knative documentation for more information." - type: integer - rolloutDuration: - description: Enables to gradually shift traffic to the latest - Revision and sets the rollout duration. It's disabled by - default and must be expressed as a Golang `time.Duration` - string representation, rounded to a second precision. - type: string - visibility: - description: "Setting `cluster-local`, Knative service becomes - a private service. Specifically, this option applies the - `networking.knative.dev/visibility` label to Knative service. - \n Refer to the Knative documentation for more information." - enum: - - cluster-local - type: string - type: object - logging: - description: The configuration of Logging trait - properties: - color: - description: Colorize the log output - type: boolean - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: Can be used to enable or disable a trait. All - traits share this common property. - type: boolean - format: - description: Logs message format - type: string - json: - description: Output the logs in JSON - type: boolean - jsonPrettyPrint: - description: Enable "pretty printing" of the JSON logs - type: boolean - level: - description: Adjust the logging level (defaults to `INFO`) - enum: - - FATAL - - WARN - - INFO - - DEBUG - - TRACE - type: string - type: object - master: - description: 'Deprecated: for backward compatibility.' - properties: - configuration: - description: TraitConfiguration parameters configuration - type: object - x-kubernetes-preserve-unknown-fields: true - required: - - configuration - type: object - mount: - description: The configuration of Mount trait - properties: - configs: - description: 'A list of configuration pointing to configmap/secret. - The configuration are expected to be UTF-8 resources as - they are processed by runtime Camel Context and tried to - be parsed as property files. They are also made available - on the classpath in order to ease their usage directly from - the Route. Syntax: [configmap|secret]:name[/key], where - name represents the resource name and key optionally represents - the resource key to be filtered' - items: - type: string - type: array - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: 'Deprecated: no longer in use.' - type: boolean - hotReload: - description: Enable "hot reload" when a secret/configmap mounted - is edited (default `false`). The configmap/secret must be - marked with `camel.apache.org/integration` label to be taken - in account. - type: boolean - resources: - description: 'A list of resources (text or binary content) - pointing to configmap/secret. The resources are expected - to be any resource type (text or binary content). The destination - path can be either a default location or any path specified - by the user. Syntax: [configmap|secret]:name[/key][@path], - where name represents the resource name, key optionally - represents the resource key to be filtered and path represents - the destination path' - items: - type: string - type: array - volumes: - description: 'A list of Persistent Volume Claims to be mounted. - Syntax: [pvcname:/container/path]' - items: - type: string - type: array - type: object - openapi: - description: The configuration of OpenAPI trait - properties: - configmaps: - description: The configmaps holding the spec of the OpenAPI - items: - type: string - type: array - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: 'Deprecated: no longer in use.' - type: boolean - type: object - owner: - description: The configuration of Owner trait - properties: - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: Can be used to enable or disable a trait. All - traits share this common property. - type: boolean - targetAnnotations: - description: The set of annotations to be transferred - items: - type: string - type: array - targetLabels: - description: The set of labels to be transferred - items: - type: string - type: array - type: object - pdb: - description: The configuration of PDB trait - properties: - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: Can be used to enable or disable a trait. All - traits share this common property. - type: boolean - maxUnavailable: - description: The number of pods for the Integration that can - be unavailable after an eviction. It can be either an absolute - number or a percentage (default `1` if `min-available` is - also not set). Only one of `max-unavailable` and `min-available` - can be specified. - type: string - minAvailable: - description: The number of pods for the Integration that must - still be available after an eviction. It can be either an - absolute number or a percentage. Only one of `min-available` - and `max-unavailable` can be specified. - type: string - type: object - platform: - description: The configuration of Platform trait - properties: - auto: - description: 'To automatically detect from the environment - if a default platform can be created (it will be created - on OpenShift or when a registry address is set). Deprecated: - Platform is auto generated by the operator install procedure - - maintained for backward compatibility' - type: boolean - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - createDefault: - description: 'To create a default (empty) platform when the - platform is missing. Deprecated: Platform is auto generated - by the operator install procedure - maintained for backward - compatibility' - type: boolean - enabled: - description: 'Deprecated: no longer in use.' - type: boolean - global: - description: 'Indicates if the platform should be created - globally in the case of global operator (default true). - Deprecated: Platform is auto generated by the operator install - procedure - maintained for backward compatibility' - type: boolean - type: object - pod: - description: The configuration of Pod trait - properties: - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: Can be used to enable or disable a trait. All - traits share this common property. - type: boolean - type: object - prometheus: - description: The configuration of Prometheus trait - properties: - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: Can be used to enable or disable a trait. All - traits share this common property. - type: boolean - podMonitor: - description: Whether a `PodMonitor` resource is created (default - `true`). - type: boolean - podMonitorLabels: - description: The `PodMonitor` resource labels, applicable - when `pod-monitor` is `true`. - items: - type: string - type: array - type: object - pull-secret: - description: The configuration of Pull Secret trait - properties: - auto: - description: Automatically configures the platform registry - secret on the pod if it is of type `kubernetes.io/dockerconfigjson`. - type: boolean - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: Can be used to enable or disable a trait. All - traits share this common property. - type: boolean - imagePullerDelegation: - description: When using a global operator with a shared platform, - this enables delegation of the `system:image-puller` cluster - role on the operator namespace to the integration service - account. - type: boolean - secretName: - description: The pull secret name to set on the Pod. If left - empty this is automatically taken from the `IntegrationPlatform` - registry configuration. - type: string - type: object - quarkus: - description: The configuration of Quarkus trait - properties: - buildMode: - description: 'The Quarkus mode to run: either `jvm` or `native` - (default `jvm`). In case both `jvm` and `native` are specified, - two `IntegrationKit` resources are created, with the `native` - kit having precedence over the `jvm` one once ready.' - items: - description: QuarkusMode is the type of Quarkus build packaging. - enum: - - jvm - - native - type: string - type: array - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: 'Deprecated: no longer in use.' - type: boolean - nativeBaseImage: - description: The base image to use when running a native build - (default `quay.io/quarkus/quarkus-micro-image:2.0`) - type: string - nativeBuilderImage: - description: The image containing the tooling required for - a native build (by default it will use the one provided - in the runtime catalog) - type: string - packageTypes: - description: 'The Quarkus package types, `fast-jar` or `native` - (default `fast-jar`). In case both `fast-jar` and `native` - are specified, two `IntegrationKit` resources are created, - with the native kit having precedence over the `fast-jar` - one once ready. The order influences the resolution of the - current kit for the integration. The kit corresponding to - the first package type will be assigned to the integration - in case no existing kit that matches the integration exists. - Deprecated: use `build-mode` instead.' - items: - description: 'QuarkusPackageType is the type of Quarkus - build packaging. Deprecated: use `QuarkusMode` instead.' - enum: - - fast-jar - - native - type: string - type: array - type: object - registry: - description: The configuration of Registry trait - properties: - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: Can be used to enable or disable a trait. All - traits share this common property. - type: boolean - type: object - route: - description: The configuration of Route trait - properties: - annotations: - additionalProperties: - type: string - description: 'The annotations added to route. This can be - used to set route specific annotations For annotations options - see https://docs.openshift.com/container-platform/3.11/architecture/networking/routes.html#route-specific-annotations - CLI usage example: -t "route.annotations.''haproxy.router.openshift.io/balance''=true"' - type: object - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: Can be used to enable or disable a trait. All - traits share this common property. - type: boolean - host: - description: To configure the host exposed by the route. - type: string - tlsCACertificate: - description: "The TLS CA certificate contents. \n Refer to - the OpenShift route documentation for additional information." - type: string - tlsCACertificateSecret: - description: "The secret name and key reference to the TLS - CA certificate. The format is \"secret-name[/key-name]\", - the value represents the secret name, if there is only one - key in the secret it will be read, otherwise you can set - a key name separated with a \"/\". \n Refer to the OpenShift - route documentation for additional information." - type: string - tlsCertificate: - description: "The TLS certificate contents. \n Refer to the - OpenShift route documentation for additional information." - type: string - tlsCertificateSecret: - description: "The secret name and key reference to the TLS - certificate. The format is \"secret-name[/key-name]\", the - value represents the secret name, if there is only one key - in the secret it will be read, otherwise you can set a key - name separated with a \"/\". \n Refer to the OpenShift route - documentation for additional information." - type: string - tlsDestinationCACertificate: - description: "The destination CA certificate provides the - contents of the ca certificate of the final destination. - \ When using reencrypt termination this file should be provided - in order to have routers use it for health checks on the - secure connection. If this field is not specified, the router - may provide its own destination CA and perform hostname - validation using the short service name (service.namespace.svc), - which allows infrastructure generated certificates to automatically - verify. \n Refer to the OpenShift route documentation for - additional information." - type: string - tlsDestinationCACertificateSecret: - description: "The secret name and key reference to the destination - CA certificate. The format is \"secret-name[/key-name]\", - the value represents the secret name, if there is only one - key in the secret it will be read, otherwise you can set - a key name separated with a \"/\". \n Refer to the OpenShift - route documentation for additional information." - type: string - tlsInsecureEdgeTerminationPolicy: - description: "To configure how to deal with insecure traffic, - e.g. `Allow`, `Disable` or `Redirect` traffic. \n Refer - to the OpenShift route documentation for additional information." - enum: - - None - - Allow - - Redirect - type: string - tlsKey: - description: "The TLS certificate key contents. \n Refer to - the OpenShift route documentation for additional information." - type: string - tlsKeySecret: - description: "The secret name and key reference to the TLS - certificate key. The format is \"secret-name[/key-name]\", - the value represents the secret name, if there is only one - key in the secret it will be read, otherwise you can set - a key name separated with a \"/\". \n Refer to the OpenShift - route documentation for additional information." - type: string - tlsTermination: - description: "The TLS termination type, like `edge`, `passthrough` - or `reencrypt`. \n Refer to the OpenShift route documentation - for additional information." - enum: - - edge - - reencrypt - - passthrough - type: string - type: object - service: - description: The configuration of Service trait - properties: - auto: - description: To automatically detect from the code if a Service - needs to be created. - type: boolean - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: Can be used to enable or disable a trait. All - traits share this common property. - type: boolean - nodePort: - description: 'Enable Service to be exposed as NodePort (default - `false`). Deprecated: Use service type instead.' - type: boolean - type: - description: The type of service to be used, either 'ClusterIP', - 'NodePort' or 'LoadBalancer'. - enum: - - ClusterIP - - NodePort - - LoadBalancer - type: string - type: object - service-binding: - description: The configuration of Service Binding trait - properties: - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: Can be used to enable or disable a trait. All - traits share this common property. - type: boolean - services: - description: List of Services in the form [[apigroup/]version:]kind:[namespace/]name - items: - type: string - type: array - type: object - strimzi: - description: 'Deprecated: for backward compatibility.' - properties: - configuration: - description: TraitConfiguration parameters configuration - type: object - x-kubernetes-preserve-unknown-fields: true - required: - - configuration - type: object - toleration: - description: The configuration of Toleration trait - properties: - configuration: - description: 'Legacy trait configuration parameters. Deprecated: - for backward compatibility.' - type: object - x-kubernetes-preserve-unknown-fields: true - enabled: - description: Can be used to enable or disable a trait. All - traits share this common property. - type: boolean - taints: - description: The list of taints to tolerate, in the form `Key[=Value]:Effect[:Seconds]` - items: - type: string - type: array - type: object - tracing: - description: 'Deprecated: for backward compatibility.' - properties: - configuration: - description: TraitConfiguration parameters configuration - type: object - x-kubernetes-preserve-unknown-fields: true - required: - - configuration - type: object - type: object version: description: the operator version type: string diff --git a/pkg/resources/config/crd/bases/camel.apache.org_kameletbindings.yaml b/pkg/resources/config/crd/bases/camel.apache.org_kameletbindings.yaml index ea5c186bbf..137de07cee 100644 --- a/pkg/resources/config/crd/bases/camel.apache.org_kameletbindings.yaml +++ b/pkg/resources/config/crd/bases/camel.apache.org_kameletbindings.yaml @@ -6758,6 +6758,12 @@ spec: - fifo - sequential type: string + platforms: + description: The list of manifest platforms to use to + build a container image (default `linux/amd64`). + items: + type: string + type: array properties: description: A list of properties to be provided to the build task @@ -7040,20 +7046,26 @@ spec: format: int32 type: integer rollingUpdateMaxSurge: + anyOf: + - type: integer + - type: string description: 'The maximum number of pods that can be scheduled above the desired number of pods. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). This can not be 0 if MaxUnavailable is 0. Absolute number is calculated from percentage by rounding up. Defaults to `25%`.' - type: integer + x-kubernetes-int-or-string: true rollingUpdateMaxUnavailable: + anyOf: + - type: integer + - type: string description: 'The maximum number of pods that can be unavailable during the update. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). Absolute number is calculated from percentage by rounding down. This can not be 0 if MaxSurge is 0. Defaults to `25%`.' - type: integer + x-kubernetes-int-or-string: true strategy: description: The deployment strategy to use to replace existing pods with new ones. @@ -7681,7 +7693,8 @@ spec: description: Enable "hot reload" when a secret/configmap mounted is edited (default `false`). The configmap/secret must be marked with `camel.apache.org/integration` label - to be taken in account. + to be taken in account. The resource will be watched + for any kind change, also for changes in metadata. type: boolean resources: description: 'A list of resources (text or binary content) @@ -7695,6 +7708,16 @@ spec: items: type: string type: array + scanKameletsImplicitLabelSecrets: + description: 'Deprecated: include your properties in an + explicit property file backed by a secret. Let the operator + to scan for secret labeled with `camel.apache.org/kamelet` + and `camel.apache.org/kamelet.configuration`. These + secrets are mounted to the application and treated as + plain properties file with their key/value list (ie + .spec.data["camel.my-property"] = my-value) (default + `true`).' + type: boolean volumes: description: 'A list of Persistent Volume Claims to be mounted. Syntax: [pvcname:/container/path]' @@ -7918,7 +7941,8 @@ spec: type: array type: object registry: - description: The configuration of Registry trait + description: 'The configuration of Registry trait Deprecated: + use jvm trait or read documentation.' properties: configuration: description: 'Legacy trait configuration parameters. Deprecated: diff --git a/pkg/resources/config/crd/bases/camel.apache.org_pipes.yaml b/pkg/resources/config/crd/bases/camel.apache.org_pipes.yaml index 98d3d9ac8b..a5fa027a72 100644 --- a/pkg/resources/config/crd/bases/camel.apache.org_pipes.yaml +++ b/pkg/resources/config/crd/bases/camel.apache.org_pipes.yaml @@ -6756,6 +6756,12 @@ spec: - fifo - sequential type: string + platforms: + description: The list of manifest platforms to use to + build a container image (default `linux/amd64`). + items: + type: string + type: array properties: description: A list of properties to be provided to the build task @@ -7038,20 +7044,26 @@ spec: format: int32 type: integer rollingUpdateMaxSurge: + anyOf: + - type: integer + - type: string description: 'The maximum number of pods that can be scheduled above the desired number of pods. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). This can not be 0 if MaxUnavailable is 0. Absolute number is calculated from percentage by rounding up. Defaults to `25%`.' - type: integer + x-kubernetes-int-or-string: true rollingUpdateMaxUnavailable: + anyOf: + - type: integer + - type: string description: 'The maximum number of pods that can be unavailable during the update. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). Absolute number is calculated from percentage by rounding down. This can not be 0 if MaxSurge is 0. Defaults to `25%`.' - type: integer + x-kubernetes-int-or-string: true strategy: description: The deployment strategy to use to replace existing pods with new ones. @@ -7679,7 +7691,8 @@ spec: description: Enable "hot reload" when a secret/configmap mounted is edited (default `false`). The configmap/secret must be marked with `camel.apache.org/integration` label - to be taken in account. + to be taken in account. The resource will be watched + for any kind change, also for changes in metadata. type: boolean resources: description: 'A list of resources (text or binary content) @@ -7693,6 +7706,16 @@ spec: items: type: string type: array + scanKameletsImplicitLabelSecrets: + description: 'Deprecated: include your properties in an + explicit property file backed by a secret. Let the operator + to scan for secret labeled with `camel.apache.org/kamelet` + and `camel.apache.org/kamelet.configuration`. These + secrets are mounted to the application and treated as + plain properties file with their key/value list (ie + .spec.data["camel.my-property"] = my-value) (default + `true`).' + type: boolean volumes: description: 'A list of Persistent Volume Claims to be mounted. Syntax: [pvcname:/container/path]' @@ -7916,7 +7939,8 @@ spec: type: array type: object registry: - description: The configuration of Registry trait + description: 'The configuration of Registry trait Deprecated: + use jvm trait or read documentation.' properties: configuration: description: 'Legacy trait configuration parameters. Deprecated: diff --git a/pkg/resources/config/samples/bases/camel_v1alpha1_kamelet.yaml b/pkg/resources/config/samples/bases/camel_v1alpha1_kamelet.yaml new file mode 100644 index 0000000000..b44a4ea45f --- /dev/null +++ b/pkg/resources/config/samples/bases/camel_v1alpha1_kamelet.yaml @@ -0,0 +1,46 @@ +# --------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# --------------------------------------------------------------------------- + +apiVersion: camel.apache.org/v1alpha1 +kind: Kamelet +metadata: + name: example-source +spec: + definition: + description: Produces periodic events with a custom payload + properties: + message: + description: The message to generate + title: Message + type: string + period: + default: 1000 + description: The time interval between two events + title: Period + type: integer + required: + - message + title: Example Timer + template: + from: + uri: timer:tick + parameters: + period: "#property:period" + steps: + - setBody: + constant: "#property:message" + - to: kamelet:sink diff --git a/pkg/resources/config/samples/kustomization.yaml b/pkg/resources/config/samples/kustomization.yaml index e973532e24..cda69fdad6 100644 --- a/pkg/resources/config/samples/kustomization.yaml +++ b/pkg/resources/config/samples/kustomization.yaml @@ -29,6 +29,7 @@ resources: - bases/camel_v1_build.yaml - bases/camel_v1_kamelet.yaml - bases/camel_v1_pipe.yaml +- bases/camel_v1alpha1_kamelet.yaml - bases/camel_v1alpha1_kameletbinding.yaml patchesStrategicMerge: diff --git a/pkg/resources/resources_test.go b/pkg/resources/resources_test.go index d6f73d1dac..7f6cfdd7bc 100644 --- a/pkg/resources/resources_test.go +++ b/pkg/resources/resources_test.go @@ -25,6 +25,7 @@ import ( "k8s.io/apimachinery/pkg/util/yaml" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func NoErrorAndNotEmptyBytes(t *testing.T, path string, callable func(path string) ([]byte, error)) { @@ -32,7 +33,7 @@ func NoErrorAndNotEmptyBytes(t *testing.T, path string, callable func(path strin object, err := callable(path) - assert.Nil(t, err) + require.NoError(t, err) assert.NotEmpty(t, object) } func NoErrorAndNotEmptyString(t *testing.T, path string, callable func(path string) (string, error)) { @@ -40,7 +41,7 @@ func NoErrorAndNotEmptyString(t *testing.T, path string, callable func(path stri object, err := callable(path) - assert.Nil(t, err) + require.NoError(t, err) assert.NotEmpty(t, object) } @@ -49,7 +50,7 @@ func NoErrorAndContains(t *testing.T, path string, contains string, callable fun elements, err := callable(path) - assert.Nil(t, err) + require.NoError(t, err) assert.Contains(t, elements, contains) } func NoErrorAndNotContains(t *testing.T, path string, contains string, callable func(path string) ([]string, error)) { @@ -57,7 +58,7 @@ func NoErrorAndNotContains(t *testing.T, path string, contains string, callable elements, err := callable(path) - assert.Nil(t, err) + require.NoError(t, err) assert.NotContains(t, elements, contains) } func NoErrorAndEmpty(t *testing.T, path string, callable func(path string) ([]string, error)) { @@ -65,7 +66,7 @@ func NoErrorAndEmpty(t *testing.T, path string, callable func(path string) ([]st elements, err := callable(path) - assert.Nil(t, err) + require.NoError(t, err) assert.Empty(t, elements) } @@ -73,14 +74,14 @@ func ErrorBytes(t *testing.T, path string, callable func(path string) ([]byte, e t.Helper() _, err := callable(path) - assert.NotNil(t, err) + require.Error(t, err) } func ErrorString(t *testing.T, path string, callable func(path string) (string, error)) { t.Helper() _, err := callable(path) - assert.NotNil(t, err) + require.Error(t, err) } func TestGetResource(t *testing.T) { @@ -106,7 +107,7 @@ func TestResources(t *testing.T) { NoErrorAndEmpty(t, "config/dirnotexist", Resources) _, err := Resources("/") - assert.Nil(t, err) + require.NoError(t, err) } func TestResourcesWithPrefix(t *testing.T) { @@ -137,14 +138,14 @@ func TestTemplateResource(t *testing.T) { } data, err := TemplateResource(fmt.Sprintf("/resources/addons/master/%s", fname), templateData) - assert.NoError(t, err) + require.NoError(t, err) jsonSrc, err := yaml.ToJSON([]byte(data)) - assert.NoError(t, err) + require.NoError(t, err) uns := unstructured.Unstructured{} err = uns.UnmarshalJSON(jsonSrc) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, uns.GetName(), name) assert.Equal(t, uns.GetNamespace(), ns) diff --git a/pkg/trait/affinity_test.go b/pkg/trait/affinity_test.go index 35a27e9bcb..06885e7159 100644 --- a/pkg/trait/affinity_test.go +++ b/pkg/trait/affinity_test.go @@ -21,6 +21,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -36,7 +37,7 @@ func TestConfigureAffinityTraitDoesSucceed(t *testing.T) { assert.True(t, configured) assert.Nil(t, condition) - assert.Nil(t, err) + require.NoError(t, err) } func TestConfigureAffinityTraitWithConflictingAffinitiesFails(t *testing.T) { @@ -48,7 +49,7 @@ func TestConfigureAffinityTraitWithConflictingAffinitiesFails(t *testing.T) { assert.False(t, configured) assert.Nil(t, condition) - assert.NotNil(t, err) + require.Error(t, err) } func TestConfigureDisabledAffinityTraitFails(t *testing.T) { @@ -58,7 +59,7 @@ func TestConfigureDisabledAffinityTraitFails(t *testing.T) { configured, condition, err := affinityTrait.Configure(environment) assert.False(t, configured) - assert.Nil(t, err) + require.NoError(t, err) assert.Nil(t, condition) } @@ -68,7 +69,7 @@ func TestApplyAffinityMissingDeployment(t *testing.T) { environment := createNominalMissingDeploymentTraitTest() err := tolerationTrait.Apply(environment) - assert.NotNil(t, err) + require.Error(t, err) } func TestApplyEmptyAffinityLabelsDoesSucceed(t *testing.T) { @@ -89,7 +90,7 @@ func testApplyEmptyAffinityLabelsDoesSucceed(t *testing.T, trait *affinityTrait, err := trait.Apply(environment) - assert.Nil(t, err) + require.NoError(t, err) assert.Nil(t, affinity) } @@ -112,7 +113,7 @@ func testApplyNodeAffinityLabelsDoesSucceed(t *testing.T, trait *affinityTrait, err := trait.Apply(environment) - assert.Nil(t, err) + require.NoError(t, err) assert.NotNil(t, podSpec.Affinity.NodeAffinity) nodeAffinity := podSpec.Affinity.NodeAffinity assert.NotNil(t, nodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[0].MatchExpressions[0]) @@ -142,7 +143,7 @@ func testApplyPodAntiAffinityLabelsDoesSucceed(t *testing.T, trait *affinityTrai err := trait.Apply(environment) - assert.Nil(t, err) + require.NoError(t, err) assert.NotNil(t, podSpec.Affinity.PodAntiAffinity) podAntiAffinity := podSpec.Affinity.PodAntiAffinity assert.NotNil(t, podAntiAffinity.RequiredDuringSchedulingIgnoredDuringExecution[0].LabelSelector.MatchExpressions[0]) @@ -177,7 +178,7 @@ func testApplyPodAffinityLabelsDoesSucceed(t *testing.T, trait *affinityTrait, e err := trait.Apply(environment) - assert.Nil(t, err) + require.NoError(t, err) assert.NotNil(t, podSpec.Affinity.PodAffinity) podAffinity := podSpec.Affinity.PodAffinity assert.NotNil(t, podAffinity.RequiredDuringSchedulingIgnoredDuringExecution[0].LabelSelector.MatchExpressions[0]) diff --git a/pkg/trait/builder.go b/pkg/trait/builder.go index 6b93751262..48ad9dab08 100644 --- a/pkg/trait/builder.go +++ b/pkg/trait/builder.go @@ -20,6 +20,7 @@ package trait import ( "fmt" "regexp" + "slices" "sort" "strconv" "strings" @@ -56,9 +57,33 @@ func (t *builderTrait) InfluencesKit() bool { return true } -// InfluencesBuild overrides base class method. -func (t *builderTrait) InfluencesBuild(this, prev map[string]interface{}) bool { - return true +func (t *builderTrait) Matches(trait Trait) bool { + otherTrait, ok := trait.(*builderTrait) + if !ok { + return false + } + if t.BaseImage != otherTrait.BaseImage || len(t.Properties) != len(otherTrait.Properties) || len(t.Tasks) != len(otherTrait.Tasks) { + return false + } + // More sofisticated check if len is the same. Sort and compare via slices equal func. + // Although the Matches func is used as a support for comparison, it makes sense + // to copy the properties and avoid possible inconsistencies caused by the sorting operation. + srtThisProps := make([]string, len(t.Properties)) + srtOtheProps := make([]string, len(otherTrait.Properties)) + copy(srtThisProps, t.Properties) + copy(srtOtheProps, otherTrait.Properties) + slices.Sort(srtThisProps) + slices.Sort(srtOtheProps) + if !slices.Equal(srtThisProps, srtOtheProps) { + return false + } + srtThisTasks := make([]string, len(t.Tasks)) + srtOtheTasks := make([]string, len(otherTrait.Tasks)) + copy(srtThisTasks, t.Tasks) + copy(srtOtheTasks, otherTrait.Tasks) + slices.Sort(srtThisTasks) + slices.Sort(srtOtheTasks) + return slices.Equal(srtThisTasks, srtOtheTasks) } func (t *builderTrait) Configure(e *Environment) (bool, *TraitCondition, error) { @@ -140,7 +165,7 @@ func (t *builderTrait) adaptDeprecatedFields() *TraitCondition { m := "The limit-memory parameter is deprecated and may be removed in future releases. Make sure to use tasks-limit-memory parameter instead." t.L.Info(m) if condition == nil { - condition = NewIntegrationCondition(v1.IntegrationConditionTraitInfo, corev1.ConditionTrue, traitConfigurationReason, "") + condition = NewIntegrationCondition("Builder", v1.IntegrationConditionTraitInfo, corev1.ConditionTrue, traitConfigurationReason, "") } condition = newOrAppend(condition, m) t.TasksLimitMemory = append(t.TasksLimitMemory, fmt.Sprintf("builder:%s", t.LimitMemory)) @@ -151,7 +176,7 @@ func (t *builderTrait) adaptDeprecatedFields() *TraitCondition { func newOrAppend(condition *TraitCondition, message string) *TraitCondition { if condition == nil { - condition = NewIntegrationCondition(v1.IntegrationConditionTraitInfo, corev1.ConditionTrue, traitConfigurationReason, message) + condition = NewIntegrationCondition("Builder", v1.IntegrationConditionTraitInfo, corev1.ConditionTrue, traitConfigurationReason, message) } else { condition.message += "; " + message } @@ -241,7 +266,7 @@ func (t *builderTrait) Apply(e *Environment) error { }}) case v1.IntegrationPlatformBuildPublishStrategyJib: - pipelineTasks = append(pipelineTasks, v1.Task{Jib: &v1.JibTask{ + jibTask := v1.Task{Jib: &v1.JibTask{ BaseTask: v1.BaseTask{ Name: "jib", Configuration: *taskConfOrDefault(tasksConf, "jib"), @@ -251,7 +276,11 @@ func (t *builderTrait) Apply(e *Environment) error { Image: imageName, Registry: e.Platform.Status.Build.Registry, }, - }}) + }} + if t.ImagePlatforms != nil { + jibTask.Jib.Configuration.ImagePlatforms = t.ImagePlatforms + } + pipelineTasks = append(pipelineTasks, jibTask) case v1.IntegrationPlatformBuildPublishStrategyS2I: pipelineTasks = append(pipelineTasks, v1.Task{S2i: &v1.S2iTask{ diff --git a/pkg/trait/builder_test.go b/pkg/trait/builder_test.go index de1af59d6e..dd831b6409 100644 --- a/pkg/trait/builder_test.go +++ b/pkg/trait/builder_test.go @@ -22,11 +22,13 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" + traitv1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1/trait" "github.com/apache/camel-k/v2/pkg/util/camel" "github.com/apache/camel-k/v2/pkg/util/defaults" "github.com/apache/camel-k/v2/pkg/util/kubernetes" @@ -45,8 +47,8 @@ func TestBuilderTraitNotAppliedBecauseOfNilKit(t *testing.T) { t.Run(string(e.Platform.Status.Cluster), func(t *testing.T) { conditions, err := NewBuilderTestCatalog().apply(e) - assert.Nil(t, err) - assert.Empty(t, conditions) + require.NoError(t, err) + assert.NotEmpty(t, conditions) assert.NotEmpty(t, e.ExecutedTraits) assert.Nil(t, e.GetTrait("builder")) assert.Empty(t, e.Pipeline) @@ -66,8 +68,8 @@ func TestBuilderTraitNotAppliedBecauseOfNilPhase(t *testing.T) { t.Run(string(e.Platform.Status.Cluster), func(t *testing.T) { conditions, err := NewBuilderTestCatalog().apply(e) - assert.Nil(t, err) - assert.Empty(t, conditions) + require.NoError(t, err) + assert.NotEmpty(t, conditions) assert.NotEmpty(t, e.ExecutedTraits) assert.Nil(t, e.GetTrait("builder")) assert.Empty(t, e.Pipeline) @@ -79,8 +81,8 @@ func TestS2IBuilderTrait(t *testing.T) { env := createBuilderTestEnv(v1.IntegrationPlatformClusterOpenShift, v1.IntegrationPlatformBuildPublishStrategyS2I, v1.BuildStrategyRoutine) conditions, err := NewBuilderTestCatalog().apply(env) - assert.Nil(t, err) - assert.Empty(t, conditions) + require.NoError(t, err) + assert.NotEmpty(t, conditions) assert.NotEmpty(t, env.ExecutedTraits) assert.NotNil(t, env.GetTrait("builder")) assert.NotEmpty(t, env.Pipeline) @@ -159,7 +161,7 @@ func TestMavenPropertyBuilderTrait(t *testing.T) { err := builderTrait.Apply(env) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "build-time-value1", env.Pipeline[0].Builder.Maven.Properties["build-time-prop1"]) } @@ -175,7 +177,7 @@ func TestCustomTaskBuilderTrait(t *testing.T) { err := builderTrait.Apply(env) - assert.Nil(t, err) + require.NoError(t, err) builderTask := findCustomTaskByName(env.Pipeline, "builder") customTask := findCustomTaskByName(env.Pipeline, "test") packageTask := findCustomTaskByName(env.Pipeline, "package") @@ -185,7 +187,7 @@ func TestCustomTaskBuilderTrait(t *testing.T) { assert.NotNil(t, customTask) assert.NotNil(t, packageTask) assert.NotNil(t, publisherTask) - assert.Equal(t, 4, len(env.Pipeline)) + assert.Len(t, env.Pipeline, 4) assert.Equal(t, "test", customTask.Custom.Name) assert.Equal(t, "alpine", customTask.Custom.ContainerImage) assert.Equal(t, "ls", customTask.Custom.ContainerCommands[0]) @@ -199,11 +201,11 @@ func TestCustomTaskBuilderTraitValidStrategyOverride(t *testing.T) { err := builderTrait.Apply(env) - assert.Nil(t, err) + require.NoError(t, err) customTask := findCustomTaskByName(env.Pipeline, "test") - assert.Equal(t, 4, len(env.Pipeline)) + assert.Len(t, env.Pipeline, 4) assert.Equal(t, "test", customTask.Custom.Name) assert.Equal(t, "alpine", customTask.Custom.ContainerImage) assert.Equal(t, "ls", customTask.Custom.ContainerCommands[0]) @@ -217,9 +219,9 @@ func TestCustomTaskBuilderTraitInvalidStrategy(t *testing.T) { err := builderTrait.Apply(env) // The error will be reported to IntegrationKits - assert.Nil(t, err) - assert.Equal(t, env.IntegrationKit.Status.Phase, v1.IntegrationKitPhaseError) - assert.Equal(t, env.IntegrationKit.Status.Conditions[0].Status, corev1.ConditionFalse) + require.NoError(t, err) + assert.Equal(t, v1.IntegrationKitPhaseError, env.IntegrationKit.Status.Phase) + assert.Equal(t, corev1.ConditionFalse, env.IntegrationKit.Status.Conditions[0].Status) assert.Equal(t, env.IntegrationKit.Status.Conditions[0].Type, v1.IntegrationKitConditionType("IntegrationKitTasksValid")) } @@ -232,9 +234,9 @@ func TestCustomTaskBuilderTraitInvalidStrategyOverride(t *testing.T) { err := builderTrait.Apply(env) // The error will be reported to IntegrationKits - assert.Nil(t, err) - assert.Equal(t, env.IntegrationKit.Status.Phase, v1.IntegrationKitPhaseError) - assert.Equal(t, env.IntegrationKit.Status.Conditions[0].Status, corev1.ConditionFalse) + require.NoError(t, err) + assert.Equal(t, v1.IntegrationKitPhaseError, env.IntegrationKit.Status.Phase) + assert.Equal(t, corev1.ConditionFalse, env.IntegrationKit.Status.Conditions[0].Status) assert.Equal(t, env.IntegrationKit.Status.Conditions[0].Type, v1.IntegrationKitConditionType("IntegrationKitTasksValid")) } @@ -245,7 +247,7 @@ func TestMavenProfilesBuilderTrait(t *testing.T) { err := builderTrait.Apply(env) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, v1.ValueSource{ ConfigMapKeyRef: &corev1.ConfigMapKeySelector{ @@ -273,9 +275,9 @@ func TestInvalidMavenProfilesBuilderTrait(t *testing.T) { err := builderTrait.Apply(env) // The error will be reported to IntegrationKits - assert.Nil(t, err) - assert.Equal(t, env.IntegrationKit.Status.Phase, v1.IntegrationKitPhaseError) - assert.Equal(t, env.IntegrationKit.Status.Conditions[0].Status, corev1.ConditionFalse) + require.NoError(t, err) + assert.Equal(t, v1.IntegrationKitPhaseError, env.IntegrationKit.Status.Phase) + assert.Equal(t, corev1.ConditionFalse, env.IntegrationKit.Status.Conditions[0].Status) assert.Contains(t, env.IntegrationKit.Status.Conditions[0].Message, "fakeprofile") } @@ -285,7 +287,7 @@ func TestMavenBuilderTraitJib(t *testing.T) { err := builderTrait.Apply(env) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, v1.ValueSource{ ConfigMapKeyRef: &corev1.ConfigMapKeySelector{ @@ -304,8 +306,8 @@ func TestBuilderCustomTasks(t *testing.T) { tasks, err := builderTrait.customTasks(nil, "my-kit-img") - assert.Nil(t, err) - assert.Equal(t, 2, len(tasks)) + require.NoError(t, err) + assert.Len(t, tasks, 2) assert.Equal(t, "test", tasks[0].Custom.Name) assert.Equal(t, "alpine", tasks[0].Custom.ContainerImage) assert.Equal(t, "ls", tasks[0].Custom.ContainerCommands[0]) @@ -322,7 +324,7 @@ func TestBuilderCustomTasksFailure(t *testing.T) { _, err := builderTrait.customTasks(nil, "my-kit-img") - assert.NotNil(t, err) + require.Error(t, err) assert.Equal(t, "provide a custom task with at least 3 arguments, ie \"my-task-name;my-image;echo 'hello'\", was test;alpine", err.Error()) } @@ -332,8 +334,8 @@ func TestBuilderCustomTasksBashScript(t *testing.T) { tasks, err := builderTrait.customTasks(nil, "my-kit-img") - assert.Nil(t, err) - assert.Equal(t, 1, len(tasks)) + require.NoError(t, err) + assert.Len(t, tasks, 1) assert.Equal(t, "test", tasks[0].Custom.Name) assert.Equal(t, "alpine", tasks[0].Custom.ContainerImage) assert.Equal(t, "/bin/bash", tasks[0].Custom.ContainerCommands[0]) @@ -347,8 +349,8 @@ func TestBuilderCustomTasksSecurityContextScript(t *testing.T) { tasks, err := builderTrait.customTasks(nil, "my-kit-img") - assert.Nil(t, err) - assert.Equal(t, 1, len(tasks)) + require.NoError(t, err) + assert.Len(t, tasks, 1) assert.Equal(t, "test", tasks[0].Custom.Name) assert.Equal(t, "alpine", tasks[0].Custom.ContainerImage) assert.Equal(t, "/bin/bash", tasks[0].Custom.ContainerCommands[0]) @@ -366,7 +368,7 @@ func TestBuilderCustomTasksConfiguration(t *testing.T) { tasksConf, err := builderTrait.parseTasksConf() - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, 4, len(tasksConf)) assert.Equal(t, "1000m", tasksConf["builder"].RequestCPU) assert.Equal(t, "500m", tasksConf["custom1"].LimitCPU) @@ -380,7 +382,7 @@ func TestBuilderCustomTasksConfigurationError(t *testing.T) { _, err := builderTrait.parseTasksConf() - assert.NotNil(t, err) + require.Error(t, err) assert.Equal(t, "could not parse syntax error, expected format :", err.Error()) } @@ -422,7 +424,7 @@ func TestBuilderDeprecatedParams(t *testing.T) { active, condition, err := builderTrait.Configure(env) - assert.Nil(t, err) + require.NoError(t, err) assert.True(t, active) assert.NotNil(t, condition) assert.Contains(t, condition.message, "The request-cpu parameter is deprecated and may be removed in future releases") @@ -451,10 +453,10 @@ func TestBuilderWithNoNodeSelector(t *testing.T) { builderTrait := createNominalBuilderTraitTest() active, condition, err := builderTrait.Configure(env) - assert.Nil(t, err) + require.NoError(t, err) err = builderTrait.Apply(env) - assert.Nil(t, err) + require.NoError(t, err) assert.True(t, active) assert.Nil(t, condition) @@ -471,10 +473,10 @@ func TestBuilderWithNodeSelector(t *testing.T) { } active, condition, err := builderTrait.Configure(env) - assert.Nil(t, err) + require.NoError(t, err) err = builderTrait.Apply(env) - assert.Nil(t, err) + require.NoError(t, err) assert.True(t, active) assert.Nil(t, condition) @@ -491,10 +493,10 @@ func TestBuilderWithAnnotations(t *testing.T) { } active, condition, err := builderTrait.Configure(env) - assert.Nil(t, err) + require.NoError(t, err) err = builderTrait.Apply(env) - assert.Nil(t, err) + require.NoError(t, err) assert.True(t, active) assert.Nil(t, condition) @@ -508,7 +510,7 @@ func TestBuilderNoTasksFilter(t *testing.T) { builderTrait := createNominalBuilderTraitTest() err := builderTrait.Apply(env) - assert.Nil(t, err) + require.NoError(t, err) pipelineTasks := tasksByName(env.Pipeline) assert.Equal(t, []string{"builder", "package", "jib"}, pipelineTasks) @@ -520,7 +522,7 @@ func TestBuilderTasksFilterNotExistingTasks(t *testing.T) { builderTrait.TasksFilter = "builder,missing-task" err := builderTrait.Apply(env) - assert.NotNil(t, err) + require.Error(t, err) assert.Equal(t, "no task exist for missing-task name", err.Error()) } @@ -530,7 +532,7 @@ func TestBuilderTasksFilterMissingPublishTasks(t *testing.T) { builderTrait.TasksFilter = "builder,package" err := builderTrait.Apply(env) - assert.NotNil(t, err) + require.Error(t, err) assert.Equal(t, "last pipeline task is not a publishing or a user task", err.Error()) } @@ -540,7 +542,7 @@ func TestBuilderTasksFilterOperatorTasks(t *testing.T) { builderTrait.TasksFilter = "builder,package,jib" err := builderTrait.Apply(env) - assert.Nil(t, err) + require.NoError(t, err) pipelineTasks := tasksByName(env.Pipeline) assert.Equal(t, []string{"builder", "package", "jib"}, pipelineTasks) } @@ -551,7 +553,7 @@ func TestBuilderTasksFilterAndReorderOperatorTasks(t *testing.T) { builderTrait.TasksFilter = "package,builder,jib" err := builderTrait.Apply(env) - assert.Nil(t, err) + require.NoError(t, err) pipelineTasks := tasksByName(env.Pipeline) assert.Equal(t, []string{"package", "builder", "jib"}, pipelineTasks) } @@ -564,7 +566,7 @@ func TestBuilderTasksFilterAndReorderCustomTasks(t *testing.T) { builderTrait.TasksFilter = "builder,my-custom-task,package,my-custom-publish" err := builderTrait.Apply(env) - assert.Nil(t, err) + require.NoError(t, err) pipelineTasks := tasksByName(env.Pipeline) assert.Equal(t, []string{"builder", "my-custom-task", "package", "my-custom-publish"}, pipelineTasks) } @@ -602,3 +604,63 @@ func tasksByName(tasks []v1.Task) []string { } return pipelineTasks } + +func TestBuilderMatches(t *testing.T) { + t1 := builderTrait{ + BasePlatformTrait: NewBasePlatformTrait("builder", 600), + BuilderTrait: traitv1.BuilderTrait{ + OrderStrategy: "dependencies", + }, + } + t2 := builderTrait{ + BasePlatformTrait: NewBasePlatformTrait("builder", 600), + BuilderTrait: traitv1.BuilderTrait{ + OrderStrategy: "dependencies", + }, + } + assert.True(t, t1.Matches(&t2)) + // This is a property that does not influence the build + t2.OrderStrategy = "fifo" + assert.True(t, t1.Matches(&t2)) + // Changing properties which influences build + t1.Properties = []string{"hello=world"} + assert.False(t, t1.Matches(&t2)) + t2.Properties = []string{"hello=world"} + assert.True(t, t1.Matches(&t2)) + t1.Properties = []string{"hello=world", "weare=theworld"} + assert.False(t, t1.Matches(&t2)) + // should detect swap + t2.Properties = []string{"weare=theworld", "hello=world"} + assert.True(t, t1.Matches(&t2)) +} + +func TestBuilderMatchesTasks(t *testing.T) { + t1 := builderTrait{ + BasePlatformTrait: NewBasePlatformTrait("builder", 600), + BuilderTrait: traitv1.BuilderTrait{}, + } + t2 := builderTrait{ + BasePlatformTrait: NewBasePlatformTrait("builder", 600), + BuilderTrait: traitv1.BuilderTrait{ + Tasks: []string{"task1;my-task;do-something"}, + }, + } + t3 := builderTrait{ + BasePlatformTrait: NewBasePlatformTrait("builder", 600), + BuilderTrait: traitv1.BuilderTrait{ + Tasks: []string{"task1;my-task;do-something-else"}, + }, + } + assert.False(t, t1.Matches(&t2)) + assert.False(t, t2.Matches(&t3)) +} + +func TestBuilderTraitPlatforms(t *testing.T) { + env := createBuilderTestEnv(v1.IntegrationPlatformClusterKubernetes, v1.IntegrationPlatformBuildPublishStrategyJib, v1.BuildStrategyRoutine) + builderTrait := createNominalBuilderTraitTest() + builderTrait.ImagePlatforms = []string{"linux/amd64", "linux/arm64"} + err := builderTrait.Apply(env) + require.NoError(t, err) + + assert.Equal(t, []string{"linux/amd64", "linux/arm64"}, env.Pipeline[2].Jib.Configuration.ImagePlatforms) +} diff --git a/pkg/trait/camel.go b/pkg/trait/camel.go index f56c2bd1f5..3d2a991d8d 100644 --- a/pkg/trait/camel.go +++ b/pkg/trait/camel.go @@ -53,9 +53,13 @@ func (t *camelTrait) InfluencesKit() bool { return true } -// InfluencesBuild only when the runtime has changed. -func (t *camelTrait) InfluencesBuild(this, prev map[string]interface{}) bool { - return this["runtimeVersion"] != prev["runtimeVersion"] +func (t *camelTrait) Matches(trait Trait) bool { + otherTrait, ok := trait.(*camelTrait) + if !ok { + return false + } + + return otherTrait.RuntimeVersion == t.RuntimeVersion } func (t *camelTrait) Configure(e *Environment) (bool, *TraitCondition, error) { diff --git a/pkg/trait/camel_test.go b/pkg/trait/camel_test.go index ea67913d37..a3fc3688d6 100644 --- a/pkg/trait/camel_test.go +++ b/pkg/trait/camel_test.go @@ -25,18 +25,20 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" + traitv1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1/trait" "github.com/apache/camel-k/v2/pkg/util/camel" "github.com/apache/camel-k/v2/pkg/util/kubernetes" "github.com/apache/camel-k/v2/pkg/util/test" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestConfigureEnabledCamelTraitSucceeds(t *testing.T) { trait, environment := createNominalCamelTest(false) configured, condition, err := trait.Configure(environment) - assert.Nil(t, err) + require.NoError(t, err) assert.Nil(t, condition) assert.True(t, configured) } @@ -45,12 +47,12 @@ func TestApplyCamelTraitSucceeds(t *testing.T) { trait, environment := createNominalCamelTest(false) configured, condition, err := trait.Configure(environment) - assert.Nil(t, err) + require.NoError(t, err) assert.Nil(t, condition) assert.True(t, configured) err = trait.Apply(environment) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "0.0.1", environment.RuntimeVersion) assert.Equal(t, "0.0.1", environment.Integration.Status.RuntimeVersion) assert.Equal(t, "0.0.1", environment.IntegrationKit.Status.RuntimeVersion) @@ -68,12 +70,12 @@ func TestApplyCamelTraitWithoutEnvironmentCatalogAndUnmatchableVersionFails(t *t environment.Integration.Status.RuntimeProvider = v1.RuntimeProviderQuarkus configured, condition, err := trait.Configure(environment) - assert.Nil(t, err) + require.NoError(t, err) assert.Nil(t, condition) assert.True(t, configured) err = trait.Apply(environment) - assert.NotNil(t, err) + require.Error(t, err) assert.Equal(t, "unable to find catalog matching version requirement: runtime=Unmatchable version, provider=quarkus", err.Error()) } @@ -171,12 +173,12 @@ func TestApplyCamelTraitWithProperties(t *testing.T) { trait.Properties = []string{"a=b", "c=d"} configured, condition, err := trait.Configure(environment) - assert.Nil(t, err) + require.NoError(t, err) assert.Nil(t, condition) assert.True(t, configured) err = trait.Apply(environment) - assert.Nil(t, err) + require.NoError(t, err) userPropertiesCm := environment.Resources.GetConfigMap(func(cm *corev1.ConfigMap) bool { return cm.Labels["camel.apache.org/properties.type"] == "user" @@ -191,12 +193,12 @@ func TestApplyCamelTraitWithSources(t *testing.T) { trait, environment := createNominalCamelTest(true) configured, condition, err := trait.Configure(environment) - assert.Nil(t, err) + require.NoError(t, err) assert.Nil(t, condition) assert.True(t, configured) err = trait.Apply(environment) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, 1, environment.Resources.Size()) sourceCm := environment.Resources.GetConfigMap(func(cm *corev1.ConfigMap) bool { @@ -207,3 +209,24 @@ func TestApplyCamelTraitWithSources(t *testing.T) { "content": "XML Source Code", }, sourceCm.Data) } + +func TestCamelMatches(t *testing.T) { + t1 := camelTrait{ + BasePlatformTrait: NewBasePlatformTrait("camel", 600), + CamelTrait: traitv1.CamelTrait{ + RuntimeVersion: "1.2.3", + }, + } + t2 := camelTrait{ + BasePlatformTrait: NewBasePlatformTrait("camel", 600), + CamelTrait: traitv1.CamelTrait{ + RuntimeVersion: "1.2.3", + }, + } + + assert.True(t, t1.Matches(&t2)) + t1.Properties = []string{"hello=world"} + assert.True(t, t1.Matches(&t2)) + t2.RuntimeVersion = "3.2.1" + assert.False(t, t1.Matches(&t2)) +} diff --git a/pkg/trait/container.go b/pkg/trait/container.go index e4384f25a3..b58842df13 100644 --- a/pkg/trait/container.go +++ b/pkg/trait/container.go @@ -88,6 +88,7 @@ func (t *containerTrait) Configure(e *Environment) (bool, *TraitCondition, error t.L.ForIntegration(e.Integration).Infof("Integration %s/%s contains knative endpoint that cannot run, as knative is not installed in the cluster.", e.Integration.Namespace, e.Integration.Name) err := errors.New("integration cannot run, as knative is not installed in the cluster") return false, NewIntegrationCondition( + "Container", v1.IntegrationConditionKnativeAvailable, corev1.ConditionFalse, v1.IntegrationConditionKnativeNotInstalledReason, diff --git a/pkg/trait/container_probes_test.go b/pkg/trait/container_probes_test.go index edc6b5bfbe..87a070f941 100644 --- a/pkg/trait/container_probes_test.go +++ b/pkg/trait/container_probes_test.go @@ -21,6 +21,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" "k8s.io/utils/pointer" @@ -36,7 +37,7 @@ func newTestProbesEnv(t *testing.T, integration *v1.Integration) Environment { t.Helper() catalog, err := camel.DefaultCatalog() - assert.Nil(t, err) + require.NoError(t, err) assert.NotNil(t, catalog) client, _ := test.NewFakeClient() @@ -79,8 +80,8 @@ func TestProbesDependencies(t *testing.T) { env.Integration.Status.Phase = v1.IntegrationPhaseInitialization conditions, err := env.Catalog.apply(&env) - assert.Nil(t, err) - assert.Empty(t, conditions) + require.NoError(t, err) + assert.NotEmpty(t, conditions) assert.Contains(t, env.Integration.Status.Dependencies, "mvn:org.apache.camel.quarkus:camel-quarkus-microprofile-health") } @@ -104,8 +105,8 @@ func TestProbesOnDeployment(t *testing.T) { env.Integration.Status.Phase = v1.IntegrationPhaseDeploying conditions, err := env.Catalog.apply(&env) - assert.Nil(t, err) - assert.Empty(t, conditions) + require.NoError(t, err) + assert.NotEmpty(t, conditions) container := env.GetIntegrationContainer() @@ -142,8 +143,8 @@ func TestProbesOnDeploymentWithCustomScheme(t *testing.T) { env.Integration.Status.Phase = v1.IntegrationPhaseDeploying conditions, err := env.Catalog.apply(&env) - assert.Nil(t, err) - assert.Empty(t, conditions) + require.NoError(t, err) + assert.NotEmpty(t, conditions) container := env.GetIntegrationContainer() @@ -184,21 +185,22 @@ func TestProbesOnKnativeService(t *testing.T) { env.Integration.Status.Phase = v1.IntegrationPhaseDeploying serviceOverrideCondition := NewIntegrationCondition( + "Service", v1.IntegrationConditionTraitInfo, corev1.ConditionTrue, - "serviceTraitConfiguration", + "TraitConfiguration", "explicitly disabled by the platform: knative-service trait has priority over this trait", ) ctrlStrategyCondition := NewIntegrationCondition( + "Deployment", v1.IntegrationConditionDeploymentAvailable, corev1.ConditionFalse, - "deploymentTraitConfiguration", + "DeploymentAvailable", "controller strategy: knative-service", ) conditions, err := env.Catalog.apply(&env) - assert.Nil(t, err) - assert.Len(t, conditions, 2) + require.NoError(t, err) assert.Contains(t, conditions, ctrlStrategyCondition) assert.Contains(t, conditions, serviceOverrideCondition) diff --git a/pkg/trait/container_test.go b/pkg/trait/container_test.go index 7c424eb2be..6d039cda89 100644 --- a/pkg/trait/container_test.go +++ b/pkg/trait/container_test.go @@ -23,6 +23,7 @@ import ( "github.com/google/uuid" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -40,7 +41,7 @@ import ( func TestContainerWithDefaults(t *testing.T) { catalog, err := camel.DefaultCatalog() - assert.Nil(t, err) + require.NoError(t, err) client, _ := test.NewFakeClient() traitCatalog := NewCatalog(nil) @@ -87,8 +88,8 @@ func TestContainerWithDefaults(t *testing.T) { conditions, err := traitCatalog.apply(&environment) - assert.Nil(t, err) - assert.Empty(t, conditions) + require.NoError(t, err) + assert.NotEmpty(t, conditions) assert.NotEmpty(t, environment.ExecutedTraits) assert.NotNil(t, environment.GetTrait("deployment")) assert.NotNil(t, environment.GetTrait("container")) @@ -102,7 +103,7 @@ func TestContainerWithDefaults(t *testing.T) { func TestContainerWithOpenshift(t *testing.T) { catalog, err := camel.DefaultCatalog() - assert.Nil(t, err) + require.NoError(t, err) // Integration is in another constrained namespace constrainedIntNamespace := &corev1.Namespace{ @@ -168,8 +169,8 @@ func TestContainerWithOpenshift(t *testing.T) { conditions, err := traitCatalog.apply(&environment) - assert.Nil(t, err) - assert.Empty(t, conditions) + require.NoError(t, err) + assert.NotEmpty(t, conditions) assert.NotEmpty(t, environment.ExecutedTraits) assert.NotNil(t, environment.GetTrait("deployment")) assert.NotNil(t, environment.GetTrait("container")) @@ -185,7 +186,7 @@ func TestContainerWithOpenshift(t *testing.T) { func TestContainerWithCustomName(t *testing.T) { catalog, err := camel.DefaultCatalog() - assert.Nil(t, err) + require.NoError(t, err) client, _ := test.NewFakeClient() traitCatalog := NewCatalog(nil) @@ -236,8 +237,8 @@ func TestContainerWithCustomName(t *testing.T) { conditions, err := traitCatalog.apply(&environment) - assert.Nil(t, err) - assert.Empty(t, conditions) + require.NoError(t, err) + assert.NotEmpty(t, conditions) assert.NotEmpty(t, environment.ExecutedTraits) assert.NotNil(t, environment.GetTrait("deployment")) assert.NotNil(t, environment.GetTrait("container")) @@ -253,7 +254,7 @@ func TestContainerWithCustomName(t *testing.T) { func TestContainerWithCustomImage(t *testing.T) { catalog, err := camel.DefaultCatalog() - assert.Nil(t, err) + require.NoError(t, err) client, _ := test.NewFakeClient() traitCatalog := NewCatalog(nil) @@ -302,11 +303,11 @@ func TestContainerWithCustomImage(t *testing.T) { conditions, err := traitCatalog.apply(&environment) - assert.Nil(t, err) - assert.Empty(t, conditions) + require.NoError(t, err) + assert.NotEmpty(t, conditions) for _, postAction := range environment.PostActions { - assert.Nil(t, postAction(&environment)) + require.NoError(t, postAction(&environment)) } assert.NotEmpty(t, environment.ExecutedTraits) @@ -321,7 +322,7 @@ func TestContainerWithCustomImage(t *testing.T) { } err = client.Get(context.TODO(), key, &ikt) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, environment.Integration.ObjectMeta.UID, ikt.ObjectMeta.OwnerReferences[0].UID) trait := environment.Integration.Spec.Traits.Container @@ -330,7 +331,7 @@ func TestContainerWithCustomImage(t *testing.T) { func TestContainerWithCustomImageAndIntegrationKit(t *testing.T) { catalog, err := camel.DefaultCatalog() - assert.Nil(t, err) + require.NoError(t, err) client, _ := test.NewFakeClient() traitCatalog := NewCatalog(nil) @@ -382,14 +383,14 @@ func TestContainerWithCustomImageAndIntegrationKit(t *testing.T) { environment.Platform.ResyncStatusFullConfig() conditions, err := traitCatalog.apply(&environment) - assert.NotNil(t, err) + require.Error(t, err) assert.Empty(t, conditions) assert.Contains(t, err.Error(), "unsupported configuration: a container image has been set in conjunction with an IntegrationKit") } func TestContainerWithImagePullPolicy(t *testing.T) { catalog, err := camel.DefaultCatalog() - assert.Nil(t, err) + require.NoError(t, err) client, _ := test.NewFakeClient() traitCatalog := NewCatalog(nil) @@ -426,8 +427,8 @@ func TestContainerWithImagePullPolicy(t *testing.T) { conditions, err := traitCatalog.apply(&environment) - assert.Nil(t, err) - assert.Empty(t, conditions) + require.NoError(t, err) + assert.NotEmpty(t, conditions) container := environment.GetIntegrationContainer() @@ -449,13 +450,14 @@ func TestRunKnativeEndpointWithKnativeNotInstalled(t *testing.T) { }, } expectedCondition := NewIntegrationCondition( + "Container", v1.IntegrationConditionKnativeAvailable, corev1.ConditionFalse, v1.IntegrationConditionKnativeNotInstalledReason, "integration cannot run, as knative is not installed in the cluster", ) configured, condition, err := trait.Configure(environment) - assert.NotNil(t, err) + require.Error(t, err) assert.Equal(t, expectedCondition, condition) assert.False(t, configured) } @@ -477,11 +479,11 @@ func TestRunNonKnativeEndpointWithKnativeNotInstalled(t *testing.T) { } configured, condition, err := trait.Configure(environment) - assert.Nil(t, err) + require.NoError(t, err) assert.Nil(t, condition) assert.True(t, configured) conditions := environment.Integration.Status.Conditions - assert.Len(t, conditions, 0) + assert.Empty(t, conditions) } func createEnvironment() *Environment { diff --git a/pkg/trait/cron.go b/pkg/trait/cron.go index 0a7a69cb0f..adf04f0c3a 100644 --- a/pkg/trait/cron.go +++ b/pkg/trait/cron.go @@ -78,7 +78,7 @@ func (t *cronTrait) Configure(e *Environment) (bool, *TraitCondition, error) { return false, nil, nil } if !pointer.BoolDeref(t.Enabled, true) { - return false, NewIntegrationConditionUserDisabled(), nil + return false, NewIntegrationConditionUserDisabled("Cron"), nil } if !e.IntegrationInPhase(v1.IntegrationPhaseInitialization) && !e.IntegrationInRunningPhases() { return false, nil, nil @@ -86,6 +86,7 @@ func (t *cronTrait) Configure(e *Environment) (bool, *TraitCondition, error) { if _, ok := e.CamelCatalog.Runtime.Capabilities[v1.CapabilityCron]; !ok { return false, NewIntegrationCondition( + "Cron", v1.IntegrationConditionCronJobAvailable, corev1.ConditionFalse, v1.IntegrationConditionCronJobNotAvailableReason, @@ -97,6 +98,7 @@ func (t *cronTrait) Configure(e *Environment) (bool, *TraitCondition, error) { globalCron, err := t.getGlobalCron(e) if err != nil { return false, NewIntegrationCondition( + "Cron", v1.IntegrationConditionCronJobAvailable, corev1.ConditionFalse, v1.IntegrationConditionCronJobNotAvailableReason, @@ -140,6 +142,7 @@ func (t *cronTrait) Configure(e *Environment) (bool, *TraitCondition, error) { var condition *TraitCondition if e.IntegrationInPhase(v1.IntegrationPhaseDeploying) { condition = NewIntegrationCondition( + "Cron", v1.IntegrationConditionCronJobAvailable, corev1.ConditionFalse, v1.IntegrationConditionCronJobNotAvailableReason, @@ -153,6 +156,7 @@ func (t *cronTrait) Configure(e *Environment) (bool, *TraitCondition, error) { strategy, err := e.DetermineControllerStrategy() if err != nil { return false, NewIntegrationCondition( + "Cron", v1.IntegrationConditionCronJobAvailable, corev1.ConditionFalse, v1.IntegrationConditionCronJobNotAvailableReason, diff --git a/pkg/trait/cron_test.go b/pkg/trait/cron_test.go index 5b6492848c..1f10844693 100644 --- a/pkg/trait/cron_test.go +++ b/pkg/trait/cron_test.go @@ -23,6 +23,7 @@ import ( passert "github.com/magiconair/properties/assert" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" batchv1 "k8s.io/api/batch/v1" corev1 "k8s.io/api/core/v1" @@ -224,7 +225,7 @@ func TestCronFromURI(t *testing.T) { func TestCronDeps(t *testing.T) { catalog, err := camel.DefaultCatalog() - assert.Nil(t, err) + require.NoError(t, err) client, _ := test.NewFakeClient() traitCatalog := NewCatalog(nil) @@ -281,13 +282,13 @@ func TestCronDeps(t *testing.T) { environment.Platform.ResyncStatusFullConfig() c, err := NewFakeClient("ns") - assert.Nil(t, err) + require.NoError(t, err) tc := NewCatalog(c) conditions, err := tc.apply(&environment) - assert.Nil(t, err) - assert.Empty(t, conditions) + require.NoError(t, err) + assert.NotEmpty(t, conditions) assert.NotEmpty(t, environment.ExecutedTraits) ct, _ := environment.GetTrait("cron").(*cronTrait) @@ -297,13 +298,93 @@ func TestCronDeps(t *testing.T) { assert.Contains(t, environment.Integration.Status.Dependencies, "mvn:org.apache.camel.k:camel-k-cron") } -func TestCronDepsFallback(t *testing.T) { +func TestCronMultipleScheduleFallback(t *testing.T) { catalog, err := camel.DefaultCatalog() assert.Nil(t, err) client, _ := test.NewFakeClient() traitCatalog := NewCatalog(nil) + environment := Environment{ + CamelCatalog: catalog, + Catalog: traitCatalog, + Client: client, + Integration: &v1.Integration{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test", + Namespace: "ns", + }, + Status: v1.IntegrationStatus{ + Phase: v1.IntegrationPhaseInitialization, + }, + Spec: v1.IntegrationSpec{ + Profile: v1.TraitProfileKnative, + Sources: []v1.SourceSpec{ + { + DataSpec: v1.DataSpec{ + Name: "routes.java", + Content: `from("cron:tab?schedule=0 0/2 * * ?").to("log:test")`, + }, + Language: v1.LanguageJavaSource, + }, + { + DataSpec: v1.DataSpec{ + Name: "routes2.java", + Content: `from("cron:tab?schedule=0 0/3 * * ?").to("log:test")`, + }, + Language: v1.LanguageJavaSource, + }, + }, + Traits: v1.Traits{}, + }, + }, + IntegrationKit: &v1.IntegrationKit{ + Status: v1.IntegrationKitStatus{ + Phase: v1.IntegrationKitPhaseReady, + }, + }, + Platform: &v1.IntegrationPlatform{ + Spec: v1.IntegrationPlatformSpec{ + Cluster: v1.IntegrationPlatformClusterOpenShift, + Build: v1.IntegrationPlatformBuildSpec{ + PublishStrategy: v1.IntegrationPlatformBuildPublishStrategyS2I, + Registry: v1.RegistrySpec{Address: "registry"}, + RuntimeVersion: catalog.Runtime.Version, + }, + Profile: v1.TraitProfileKnative, + }, + Status: v1.IntegrationPlatformStatus{ + Phase: v1.IntegrationPlatformPhaseReady, + }, + }, + EnvVars: make([]corev1.EnvVar, 0), + ExecutedTraits: make([]Trait, 0), + Resources: kubernetes.NewCollection(), + } + environment.Platform.ResyncStatusFullConfig() + + c, err := NewFakeClient("ns") + assert.Nil(t, err) + + tc := NewCatalog(c) + conditions, err := tc.apply(&environment) + + assert.Nil(t, err) + assert.NotEmpty(t, conditions) + assert.NotEmpty(t, environment.ExecutedTraits) + + ct, _ := environment.GetTrait("cron").(*cronTrait) + assert.NotNil(t, ct) + assert.NotNil(t, ct.Fallback, "Should apply Fallback since non equivalent scheduling for mutiple cron compatible component") +} + +func TestCronDepsFallback(t *testing.T) { + catalog, err := camel.DefaultCatalog() + require.NoError(t, err) + + client, _ := test.NewFakeClient() + traitCatalog := NewCatalog(nil) + environment := Environment{ CamelCatalog: catalog, Catalog: traitCatalog, @@ -360,14 +441,14 @@ func TestCronDepsFallback(t *testing.T) { environment.Platform.ResyncStatusFullConfig() c, err := NewFakeClient("ns") - assert.Nil(t, err) + require.NoError(t, err) tc := NewCatalog(c) conditions, err := tc.apply(&environment) - assert.Nil(t, err) - assert.Empty(t, conditions) + require.NoError(t, err) + assert.NotEmpty(t, conditions) assert.NotEmpty(t, environment.ExecutedTraits) ct, _ := environment.GetTrait("cron").(*cronTrait) @@ -380,7 +461,7 @@ func TestCronDepsFallback(t *testing.T) { func TestCronWithActiveDeadline(t *testing.T) { catalog, err := camel.DefaultCatalog() - assert.Nil(t, err) + require.NoError(t, err) client, _ := test.NewFakeClient() traitCatalog := NewCatalog(nil) @@ -436,19 +517,19 @@ func TestCronWithActiveDeadline(t *testing.T) { environment.Platform.ResyncStatusFullConfig() c, err := NewFakeClient("ns") - assert.Nil(t, err) + require.NoError(t, err) tc := NewCatalog(c) expectedCondition := NewIntegrationCondition( + "Deployment", v1.IntegrationConditionDeploymentAvailable, corev1.ConditionFalse, - "deploymentTraitConfiguration", + "DeploymentAvailable", "controller strategy: cron-job", ) conditions, err := tc.apply(&environment) - assert.Nil(t, err) - assert.Len(t, conditions, 1) + require.NoError(t, err) assert.Contains(t, conditions, expectedCondition) assert.NotEmpty(t, environment.ExecutedTraits) @@ -469,7 +550,7 @@ func TestCronWithActiveDeadline(t *testing.T) { func TestCronWithBackoffLimit(t *testing.T) { catalog, err := camel.DefaultCatalog() - assert.Nil(t, err) + require.NoError(t, err) client, _ := test.NewFakeClient() traitCatalog := NewCatalog(nil) @@ -525,19 +606,19 @@ func TestCronWithBackoffLimit(t *testing.T) { environment.Platform.ResyncStatusFullConfig() c, err := NewFakeClient("ns") - assert.Nil(t, err) + require.NoError(t, err) tc := NewCatalog(c) expectedCondition := NewIntegrationCondition( + "Deployment", v1.IntegrationConditionDeploymentAvailable, corev1.ConditionFalse, - "deploymentTraitConfiguration", + "DeploymentAvailable", "controller strategy: cron-job", ) conditions, err := tc.apply(&environment) - assert.Nil(t, err) - assert.Len(t, conditions, 1) + require.NoError(t, err) assert.Contains(t, conditions, expectedCondition) assert.NotEmpty(t, environment.ExecutedTraits) diff --git a/pkg/trait/dependencies_test.go b/pkg/trait/dependencies_test.go index 1f39204532..bda3b785d0 100644 --- a/pkg/trait/dependencies_test.go +++ b/pkg/trait/dependencies_test.go @@ -21,6 +21,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" "github.com/apache/camel-k/v2/pkg/util/camel" @@ -34,26 +35,26 @@ func TestDependenciesTraitApplicability(t *testing.T) { trait := newDependenciesTrait() enabled, condition, err := trait.Configure(e) - assert.Nil(t, err) + require.NoError(t, err) assert.Nil(t, condition) assert.False(t, enabled) e.Integration.Status.Phase = v1.IntegrationPhaseNone enabled, condition, err = trait.Configure(e) - assert.Nil(t, err) + require.NoError(t, err) assert.Nil(t, condition) assert.False(t, enabled) e.Integration.Status.Phase = v1.IntegrationPhaseInitialization enabled, condition, err = trait.Configure(e) - assert.Nil(t, err) + require.NoError(t, err) assert.Nil(t, condition) assert.True(t, enabled) } func TestIntegrationDefaultDeps(t *testing.T) { catalog, err := camel.DefaultCatalog() - assert.Nil(t, err) + require.NoError(t, err) e := &Environment{ Catalog: NewEnvironmentTestCatalog(), @@ -78,12 +79,12 @@ func TestIntegrationDefaultDeps(t *testing.T) { trait := newDependenciesTrait() enabled, condition, err := trait.Configure(e) - assert.Nil(t, err) + require.NoError(t, err) assert.Nil(t, condition) assert.True(t, enabled) err = trait.Apply(e) - assert.Nil(t, err) + require.NoError(t, err) assert.ElementsMatch( t, []string{ @@ -98,7 +99,7 @@ func TestIntegrationDefaultDeps(t *testing.T) { func TestIntegrationCustomDeps(t *testing.T) { catalog, err := camel.DefaultCatalog() - assert.Nil(t, err) + require.NoError(t, err) e := &Environment{ Catalog: NewEnvironmentTestCatalog(), @@ -127,12 +128,12 @@ func TestIntegrationCustomDeps(t *testing.T) { trait := newDependenciesTrait() enabled, condition, err := trait.Configure(e) - assert.Nil(t, err) + require.NoError(t, err) assert.Nil(t, condition) assert.True(t, enabled) err = trait.Apply(e) - assert.Nil(t, err) + require.NoError(t, err) assert.ElementsMatch(t, []string{ "camel:direct", @@ -148,7 +149,7 @@ func TestIntegrationCustomDeps(t *testing.T) { func TestIntegrationAutoGeneratedDeps(t *testing.T) { catalog, err := camel.DefaultCatalog() - assert.Nil(t, err) + require.NoError(t, err) e := &Environment{ Catalog: NewEnvironmentTestCatalog(), @@ -182,7 +183,7 @@ func TestIntegrationAutoGeneratedDeps(t *testing.T) { for _, trait := range []Trait{NewInitTrait(), newDependenciesTrait()} { enabled, condition, err := trait.Configure(e) - assert.Nil(t, err) + require.NoError(t, err) assert.Nil(t, condition) assert.True(t, enabled) assert.Nil(t, trait.Apply(e)) @@ -212,7 +213,7 @@ func TestIntegrationAutoGeneratedDeps(t *testing.T) { // account when dependencies are computed. func TestIntegrationCustomLoader(t *testing.T) { catalog, err := camel.DefaultCatalog() - assert.Nil(t, err) + require.NoError(t, err) e := &Environment{ Catalog: NewEnvironmentTestCatalog(), @@ -238,12 +239,12 @@ func TestIntegrationCustomLoader(t *testing.T) { trait := newDependenciesTrait() enabled, condition, err := trait.Configure(e) - assert.Nil(t, err) + require.NoError(t, err) assert.Nil(t, condition) assert.True(t, enabled) err = trait.Apply(e) - assert.Nil(t, err) + require.NoError(t, err) assert.ElementsMatch(t, []string{ "camel:direct", @@ -257,7 +258,7 @@ func TestIntegrationCustomLoader(t *testing.T) { func TestRestDeps(t *testing.T) { catalog, err := camel.DefaultCatalog() - assert.Nil(t, err) + require.NoError(t, err) e := &Environment{ Catalog: NewEnvironmentTestCatalog(), @@ -282,12 +283,12 @@ func TestRestDeps(t *testing.T) { trait := newDependenciesTrait() enabled, condition, err := trait.Configure(e) - assert.Nil(t, err) + require.NoError(t, err) assert.Nil(t, condition) assert.True(t, enabled) err = trait.Apply(e) - assert.Nil(t, err) + require.NoError(t, err) assert.Subset( t, e.Integration.Status.Dependencies, @@ -300,7 +301,7 @@ func TestRestDeps(t *testing.T) { func TestRestDepsQuarkus(t *testing.T) { catalog, err := camel.QuarkusCatalog() - assert.Nil(t, err) + require.NoError(t, err) e := &Environment{ Catalog: NewEnvironmentTestCatalog(), @@ -325,12 +326,12 @@ func TestRestDepsQuarkus(t *testing.T) { trait := newDependenciesTrait() enabled, condition, err := trait.Configure(e) - assert.Nil(t, err) + require.NoError(t, err) assert.Nil(t, condition) assert.True(t, enabled) err = trait.Apply(e) - assert.Nil(t, err) + require.NoError(t, err) assert.Subset( t, e.Integration.Status.Dependencies, diff --git a/pkg/trait/deployer_test.go b/pkg/trait/deployer_test.go index 5809e16ecc..076fa95172 100644 --- a/pkg/trait/deployer_test.go +++ b/pkg/trait/deployer_test.go @@ -22,6 +22,7 @@ import ( v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -31,7 +32,7 @@ func TestConfigureDeployerTraitDoesSucceed(t *testing.T) { configured, condition, err := deployerTrait.Configure(environment) assert.True(t, configured) - assert.Nil(t, err) + require.NoError(t, err) assert.Nil(t, condition) } @@ -41,7 +42,7 @@ func TestConfigureDeployerTraitInWrongPhaseDoesNotSucceed(t *testing.T) { configured, condition, err := deployerTrait.Configure(environment) assert.True(t, configured) - assert.Nil(t, err) + require.NoError(t, err) assert.Nil(t, condition) } @@ -50,7 +51,7 @@ func TestApplyDeployerTraitDoesSucceed(t *testing.T) { err := deployerTrait.Apply(environment) - assert.Nil(t, err) + require.NoError(t, err) assert.Len(t, environment.PostActions, 1) } @@ -60,7 +61,7 @@ func TestApplyDeployerTraitInInitializationPhaseDoesSucceed(t *testing.T) { err := deployerTrait.Apply(environment) - assert.Nil(t, err) + require.NoError(t, err) assert.Len(t, environment.PostActions, 1) } diff --git a/pkg/trait/deployment.go b/pkg/trait/deployment.go index c11fff7fb8..600a843f05 100644 --- a/pkg/trait/deployment.go +++ b/pkg/trait/deployment.go @@ -57,6 +57,7 @@ func (t *deploymentTrait) Configure(e *Environment) (bool, *TraitCondition, erro strategy, err := e.DetermineControllerStrategy() if err != nil { return false, NewIntegrationCondition( + "Deployment", v1.IntegrationConditionDeploymentAvailable, corev1.ConditionFalse, v1.IntegrationConditionDeploymentAvailableReason, @@ -66,6 +67,7 @@ func (t *deploymentTrait) Configure(e *Environment) (bool, *TraitCondition, erro if strategy != ControllerStrategyDeployment { return false, NewIntegrationCondition( + "Deployment", v1.IntegrationConditionDeploymentAvailable, corev1.ConditionFalse, v1.IntegrationConditionDeploymentAvailableReason, @@ -163,12 +165,12 @@ func (t *deploymentTrait) getDeploymentFor(e *Environment) *appsv1.Deployment { var maxUnavailable *intstr.IntOrString if t.RollingUpdateMaxSurge != nil { - v := intstr.FromInt(*t.RollingUpdateMaxSurge) - maxSurge = &v + v := t.RollingUpdateMaxSurge + maxSurge = v } if t.RollingUpdateMaxUnavailable != nil { - v := intstr.FromInt(*t.RollingUpdateMaxUnavailable) - maxUnavailable = &v + v := t.RollingUpdateMaxUnavailable + maxUnavailable = v } deployment.Spec.Strategy.RollingUpdate = &appsv1.RollingUpdateDeployment{ diff --git a/pkg/trait/deployment_test.go b/pkg/trait/deployment_test.go index 9539cddecd..28c2a598f2 100644 --- a/pkg/trait/deployment_test.go +++ b/pkg/trait/deployment_test.go @@ -21,10 +21,12 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" "github.com/apache/camel-k/v2/pkg/util/camel" @@ -44,7 +46,7 @@ func TestConfigureDeploymentTraitWhileIntegrationIsRunningDoesSucceed(t *testing configured, condition, err := deploymentTrait.Configure(environment) assert.True(t, configured) - assert.Nil(t, err) + require.NoError(t, err) assert.Nil(t, condition) } @@ -53,7 +55,7 @@ func TestConfigureDeploymentTraitDoesSucceed(t *testing.T) { configured, condition, err := deploymentTrait.Configure(environment) assert.True(t, configured) - assert.Nil(t, err) + require.NoError(t, err) assert.Nil(t, condition) } @@ -63,7 +65,7 @@ func TestConfigureDeploymentTraitWhileBuildingKitDoesNotSucceed(t *testing.T) { configured, condition, err := deploymentTrait.Configure(environment) assert.False(t, configured) - assert.Nil(t, err) + require.NoError(t, err) assert.Nil(t, condition) } @@ -74,7 +76,7 @@ func TestConfigureDeploymentTraitWhileWaitingPlatformDoesNotSucceed(t *testing.T configured, condition, err := deploymentTrait.Configure(environment) assert.False(t, configured) - assert.Nil(t, err) + require.NoError(t, err) assert.Nil(t, condition) } @@ -84,14 +86,14 @@ func TestApplyDeploymentTraitWhileResolvingKitDoesNotSucceed(t *testing.T) { configured, condition, err := deploymentTrait.Configure(environment) assert.False(t, configured) - assert.Nil(t, err) + require.NoError(t, err) assert.Nil(t, condition) } func TestApplyDeploymentTraitWhileDeployingIntegrationDoesSucceed(t *testing.T) { deploymentTrait, environment := createNominalDeploymentTest() err := deploymentTrait.Apply(environment) - assert.Nil(t, err) + require.NoError(t, err) deployment := environment.Resources.GetDeployment(func(deployment *appsv1.Deployment) bool { return true }) assert.NotNil(t, deployment) @@ -109,7 +111,7 @@ func TestApplyDeploymentTraitWhileRunningIntegrationDoesSucceed(t *testing.T) { err := deploymentTrait.Apply(environment) - assert.Nil(t, err) + require.NoError(t, err) deployment := environment.Resources.GetDeployment(func(deployment *appsv1.Deployment) bool { return true }) assert.NotNil(t, deployment) @@ -126,7 +128,7 @@ func TestApplyDeploymentTraitWithProgressDeadline(t *testing.T) { err := deploymentTrait.Apply(environment) - assert.Nil(t, err) + require.NoError(t, err) deployment := environment.Resources.GetDeployment(func(deployment *appsv1.Deployment) bool { return true }) assert.NotNil(t, deployment) @@ -136,7 +138,7 @@ func TestApplyDeploymentTraitWithProgressDeadline(t *testing.T) { func TestApplyDeploymentTraitWitRecresteStrategy(t *testing.T) { deploymentTrait, environment := createNominalDeploymentTest() - maxSurge := 10 + maxSurge := intstr.FromInt(10) deploymentTrait.Strategy = appsv1.RecreateDeploymentStrategyType deploymentTrait.RollingUpdateMaxSurge = &maxSurge @@ -145,7 +147,7 @@ func TestApplyDeploymentTraitWitRecresteStrategy(t *testing.T) { err := deploymentTrait.Apply(environment) - assert.Nil(t, err) + require.NoError(t, err) deployment := environment.Resources.GetDeployment(func(deployment *appsv1.Deployment) bool { return true }) assert.NotNil(t, deployment) @@ -164,7 +166,7 @@ func TestApplyDeploymentTraitWitRollingUpdateStrategy(t *testing.T) { err := deploymentTrait.Apply(environment) - assert.Nil(t, err) + require.NoError(t, err) deployment := environment.Resources.GetDeployment(func(deployment *appsv1.Deployment) bool { return true }) assert.NotNil(t, deployment) @@ -176,7 +178,7 @@ func TestApplyDeploymentTraitWitRollingUpdateStrategy(t *testing.T) { t.Run("with surge", func(t *testing.T) { deploymentTrait, environment := createNominalDeploymentTest() - maxSurge := 10 + maxSurge := intstr.FromInt(10) deploymentTrait.Strategy = appsv1.RollingUpdateDeploymentStrategyType deploymentTrait.RollingUpdateMaxSurge = &maxSurge @@ -185,7 +187,7 @@ func TestApplyDeploymentTraitWitRollingUpdateStrategy(t *testing.T) { err := deploymentTrait.Apply(environment) - assert.Nil(t, err) + require.NoError(t, err) deployment := environment.Resources.GetDeployment(func(deployment *appsv1.Deployment) bool { return true }) assert.NotNil(t, deployment) @@ -193,14 +195,39 @@ func TestApplyDeploymentTraitWitRollingUpdateStrategy(t *testing.T) { assert.Equal(t, appsv1.RollingUpdateDeploymentStrategyType, deployment.Spec.Strategy.Type) assert.NotNil(t, deployment.Spec.Strategy.RollingUpdate) assert.Nil(t, deployment.Spec.Strategy.RollingUpdate.MaxUnavailable) - assert.Equal(t, maxSurge, deployment.Spec.Strategy.RollingUpdate.MaxSurge.IntValue()) + assert.Equal(t, maxSurge, *deployment.Spec.Strategy.RollingUpdate.MaxSurge) }) t.Run("with surge and unavailable", func(t *testing.T) { deploymentTrait, environment := createNominalDeploymentTest() - maxSurge := 10 - maxUnavailable := 11 + maxSurge := intstr.FromInt(10) + maxUnavailable := intstr.FromInt(11) + + deploymentTrait.Strategy = appsv1.RollingUpdateDeploymentStrategyType + deploymentTrait.RollingUpdateMaxSurge = &maxSurge + deploymentTrait.RollingUpdateMaxUnavailable = &maxUnavailable + + environment.Integration.Status.Phase = v1.IntegrationPhaseRunning + + err := deploymentTrait.Apply(environment) + + require.NoError(t, err) + + deployment := environment.Resources.GetDeployment(func(deployment *appsv1.Deployment) bool { return true }) + assert.NotNil(t, deployment) + assert.Equal(t, "integration-name", deployment.Name) + assert.Equal(t, appsv1.RollingUpdateDeploymentStrategyType, deployment.Spec.Strategy.Type) + assert.NotNil(t, deployment.Spec.Strategy.RollingUpdate) + assert.Equal(t, maxUnavailable, *deployment.Spec.Strategy.RollingUpdate.MaxUnavailable) + assert.Equal(t, maxSurge, *deployment.Spec.Strategy.RollingUpdate.MaxSurge) + }) + + t.Run("with surge and unavailable in percentage values", func(t *testing.T) { + deploymentTrait, environment := createNominalDeploymentTest() + + maxSurge := intstr.FromString("10%") + maxUnavailable := intstr.FromString("11%") deploymentTrait.Strategy = appsv1.RollingUpdateDeploymentStrategyType deploymentTrait.RollingUpdateMaxSurge = &maxSurge @@ -217,9 +244,10 @@ func TestApplyDeploymentTraitWitRollingUpdateStrategy(t *testing.T) { assert.Equal(t, "integration-name", deployment.Name) assert.Equal(t, appsv1.RollingUpdateDeploymentStrategyType, deployment.Spec.Strategy.Type) assert.NotNil(t, deployment.Spec.Strategy.RollingUpdate) - assert.Equal(t, maxUnavailable, deployment.Spec.Strategy.RollingUpdate.MaxUnavailable.IntValue()) - assert.Equal(t, maxSurge, deployment.Spec.Strategy.RollingUpdate.MaxSurge.IntValue()) + assert.Equal(t, maxUnavailable, *deployment.Spec.Strategy.RollingUpdate.MaxUnavailable) + assert.Equal(t, maxSurge, *deployment.Spec.Strategy.RollingUpdate.MaxSurge) }) + } func createNominalDeploymentTest() (*deploymentTrait, *Environment) { diff --git a/pkg/trait/environment_test.go b/pkg/trait/environment_test.go index 63f72e38fc..f83043702f 100644 --- a/pkg/trait/environment_test.go +++ b/pkg/trait/environment_test.go @@ -21,6 +21,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" @@ -36,14 +37,14 @@ import ( func TestDefaultEnvironment(t *testing.T) { catalog, err := camel.DefaultCatalog() - assert.Nil(t, err) + require.NoError(t, err) env := mockEnvironment(catalog) env.Platform.ResyncStatusFullConfig() conditions, err := NewEnvironmentTestCatalog().apply(&env) - assert.Nil(t, err) - assert.Empty(t, conditions) + require.NoError(t, err) + assert.NotEmpty(t, conditions) ns := false name := false @@ -80,7 +81,7 @@ func TestDefaultEnvironment(t *testing.T) { func TestEnabledContainerMetaDataEnvVars(t *testing.T) { c, err := camel.DefaultCatalog() - assert.Nil(t, err) + require.NoError(t, err) env := mockEnvironment(c) env.Integration.Spec.Traits = v1.Traits{ @@ -91,8 +92,8 @@ func TestEnabledContainerMetaDataEnvVars(t *testing.T) { env.Platform.ResyncStatusFullConfig() conditions, err := NewEnvironmentTestCatalog().apply(&env) - assert.Nil(t, err) - assert.Empty(t, conditions) + require.NoError(t, err) + assert.NotEmpty(t, conditions) ns := false name := false @@ -119,7 +120,7 @@ func TestEnabledContainerMetaDataEnvVars(t *testing.T) { func TestDisabledContainerMetaDataEnvVars(t *testing.T) { c, err := camel.DefaultCatalog() - assert.Nil(t, err) + require.NoError(t, err) env := mockEnvironment(c) env.Integration.Spec.Traits = v1.Traits{ @@ -131,8 +132,8 @@ func TestDisabledContainerMetaDataEnvVars(t *testing.T) { env.Platform.ResyncStatusFullConfig() conditions, err := NewEnvironmentTestCatalog().apply(&env) - assert.Nil(t, err) - assert.Empty(t, conditions) + require.NoError(t, err) + assert.NotEmpty(t, conditions) ns := false name := false @@ -159,7 +160,7 @@ func TestDisabledContainerMetaDataEnvVars(t *testing.T) { func TestCustomEnvVars(t *testing.T) { c, err := camel.DefaultCatalog() - assert.Nil(t, err) + require.NoError(t, err) env := mockEnvironment(c) env.Integration.Spec.Traits = v1.Traits{ @@ -170,8 +171,8 @@ func TestCustomEnvVars(t *testing.T) { env.Platform.ResyncStatusFullConfig() conditions, err := NewEnvironmentTestCatalog().apply(&env) - assert.Nil(t, err) - assert.Empty(t, conditions) + require.NoError(t, err) + assert.NotEmpty(t, conditions) userK1 := false userK2 := false diff --git a/pkg/trait/error_handler.go b/pkg/trait/error_handler.go index 116dd3883b..c37388e69b 100644 --- a/pkg/trait/error_handler.go +++ b/pkg/trait/error_handler.go @@ -25,7 +25,6 @@ import ( v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" traitv1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1/trait" - "github.com/apache/camel-k/v2/pkg/util" ) @@ -67,7 +66,7 @@ func (t *errorHandlerTrait) Apply(e *Environment) error { t.addErrorHandlerDependencies(e, defaultErrorHandlerURI) } - return t.addErrorHandlerAsSource(e) + return t.addGlobalErrorHandlerAsSource(e) } return nil } @@ -84,10 +83,10 @@ func (t *errorHandlerTrait) addErrorHandlerDependencies(e *Environment, uri stri } } -func (t *errorHandlerTrait) addErrorHandlerAsSource(e *Environment) error { +func (t *errorHandlerTrait) addGlobalErrorHandlerAsSource(e *Environment) error { flowErrorHandler := map[string]interface{}{ - "error-handler": map[string]string{ - "ref-error-handler": t.ErrorHandlerRef, + "errorHandler": map[string]string{ + "refErrorHandler": t.ErrorHandlerRef, }, } encodedFlowErrorHandler, err := yaml.Marshal([]map[string]interface{}{flowErrorHandler}) diff --git a/pkg/trait/error_handler_test.go b/pkg/trait/error_handler_test.go index 6c93206825..d5579aa957 100644 --- a/pkg/trait/error_handler_test.go +++ b/pkg/trait/error_handler_test.go @@ -22,9 +22,9 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" - "github.com/apache/camel-k/v2/pkg/util/camel" ) @@ -33,23 +33,23 @@ func TestErrorHandlerConfigureFromIntegrationProperty(t *testing.T) { Catalog: NewEnvironmentTestCatalog(), Integration: &v1.Integration{}, } - e.Integration.Spec.AddConfiguration("property", fmt.Sprintf("%v = %s", v1.ErrorHandlerRefName, "defaultErrorHandler")) + e.Integration.Spec.AddConfigurationProperty(fmt.Sprintf("%v = %s", v1.ErrorHandlerRefName, "defaultErrorHandler")) trait := newErrorHandlerTrait() enabled, condition, err := trait.Configure(e) - assert.Nil(t, err) + require.NoError(t, err) assert.False(t, enabled) assert.Nil(t, condition) e.Integration.Status.Phase = v1.IntegrationPhaseNone enabled, condition, err = trait.Configure(e) - assert.Nil(t, err) + require.NoError(t, err) assert.False(t, enabled) assert.Nil(t, condition) e.Integration.Status.Phase = v1.IntegrationPhaseInitialization enabled, condition, err = trait.Configure(e) - assert.Nil(t, err) + require.NoError(t, err) assert.True(t, enabled) assert.Nil(t, condition) @@ -65,37 +65,41 @@ func TestErrorHandlerApplySource(t *testing.T) { trait := newErrorHandlerTrait() enabled, condition, err := trait.Configure(e) - assert.Nil(t, err) + require.NoError(t, err) assert.True(t, enabled) assert.Nil(t, condition) err = trait.Apply(e) - assert.Nil(t, err) - assert.Equal(t, `- error-handler: - ref-error-handler: defaultErrorHandler + require.NoError(t, err) + assert.Equal(t, `- errorHandler: + refErrorHandler: defaultErrorHandler `, e.Integration.Status.GeneratedSources[0].Content) } func TestErrorHandlerApplyDependency(t *testing.T) { c, err := camel.DefaultCatalog() - assert.Nil(t, err) + require.NoError(t, err) e := &Environment{ Catalog: NewEnvironmentTestCatalog(), CamelCatalog: c, Integration: &v1.Integration{}, } - e.Integration.Spec.AddConfiguration("property", "camel.beans.defaultErrorHandler = #class:org.apache.camel.builder.DeadLetterChannelBuilder") - e.Integration.Spec.AddConfiguration("property", "camel.beans.defaultErrorHandler.deadLetterUri = log:info") - e.Integration.Spec.AddConfiguration("property", fmt.Sprintf("%v = %s", v1.ErrorHandlerRefName, "defaultErrorHandler")) + e.Integration.Spec.AddConfigurationProperty("camel.beans.defaultErrorHandler = #class:org.apache.camel.builder.DeadLetterChannelBuilder") + e.Integration.Spec.AddConfigurationProperty("camel.beans.defaultErrorHandler.deadLetterUri = log:info") + e.Integration.Spec.AddConfigurationProperty(fmt.Sprintf("%v = %s", v1.ErrorHandlerRefName, "defaultErrorHandler")) e.Integration.Status.Phase = v1.IntegrationPhaseInitialization trait := newErrorHandlerTrait() enabled, condition, err := trait.Configure(e) - assert.Nil(t, err) + require.NoError(t, err) assert.True(t, enabled) assert.Nil(t, condition) err = trait.Apply(e) - assert.Nil(t, err) + require.NoError(t, err) + assert.Len(t, e.Integration.Spec.Configuration, 3) + assert.Equal(t, "#class:org.apache.camel.builder.DeadLetterChannelBuilder", e.Integration.Spec.GetConfigurationProperty("camel.beans.defaultErrorHandler")) + assert.Equal(t, "log:info", e.Integration.Spec.GetConfigurationProperty("camel.beans.defaultErrorHandler.deadLetterUri")) + assert.Equal(t, "defaultErrorHandler", e.Integration.Spec.GetConfigurationProperty(v1.ErrorHandlerRefName)) assert.Equal(t, "camel:log", e.Integration.Status.Dependencies[0]) } diff --git a/pkg/trait/gc.go b/pkg/trait/gc.go index ef309c9ebb..5598c1c709 100644 --- a/pkg/trait/gc.go +++ b/pkg/trait/gc.go @@ -66,7 +66,7 @@ func (t *gcTrait) Configure(e *Environment) (bool, *TraitCondition, error) { return false, nil, nil } if !pointer.BoolDeref(t.Enabled, true) { - return false, NewIntegrationConditionUserDisabled(), nil + return false, NewIntegrationConditionUserDisabled("GC"), nil } return e.IntegrationInPhase(v1.IntegrationPhaseInitialization) || e.IntegrationInRunningPhases(), nil, nil diff --git a/pkg/trait/gc_test.go b/pkg/trait/gc_test.go index 2987f02b35..406b00e458 100644 --- a/pkg/trait/gc_test.go +++ b/pkg/trait/gc_test.go @@ -22,6 +22,7 @@ import ( v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -33,7 +34,7 @@ func TestConfigureGCTraitDoesSucceed(t *testing.T) { configured, condition, err := gcTrait.Configure(environment) assert.True(t, configured) - assert.Nil(t, err) + require.NoError(t, err) assert.Nil(t, condition) } @@ -43,6 +44,7 @@ func TestConfigureDisabledGCTraitDoesNotSucceed(t *testing.T) { gcTrait.Enabled = pointer.Bool(false) expectedCondition := NewIntegrationCondition( + "GC", v1.IntegrationConditionTraitInfo, corev1.ConditionTrue, "TraitConfiguration", @@ -50,7 +52,7 @@ func TestConfigureDisabledGCTraitDoesNotSucceed(t *testing.T) { ) configured, condition, err := gcTrait.Configure(environment) assert.False(t, configured) - assert.Nil(t, err) + require.NoError(t, err) assert.NotNil(t, condition) assert.Equal(t, expectedCondition, condition) } @@ -60,7 +62,7 @@ func TestApplyGarbageCollectorTraitFirstGenerationDoesSucceed(t *testing.T) { err := gcTrait.Apply(environment) - assert.Nil(t, err) + require.NoError(t, err) assert.Len(t, environment.PostProcessors, 1) assert.Len(t, environment.PostActions, 0) } @@ -71,7 +73,7 @@ func TestApplyGarbageCollectorTraitNextGenerationDoesSucceed(t *testing.T) { err := gcTrait.Apply(environment) - assert.Nil(t, err) + require.NoError(t, err) assert.Len(t, environment.PostProcessors, 1) assert.Len(t, environment.PostActions, 1) } @@ -82,7 +84,7 @@ func TestApplyGCTraitDuringInitializationPhaseSkipPostActions(t *testing.T) { err := gcTrait.Apply(environment) - assert.Nil(t, err) + require.NoError(t, err) assert.Len(t, environment.PostProcessors, 1) assert.Len(t, environment.PostActions, 0) } diff --git a/pkg/trait/ingress.go b/pkg/trait/ingress.go index f240f10d98..a9742cfbc7 100644 --- a/pkg/trait/ingress.go +++ b/pkg/trait/ingress.go @@ -61,6 +61,7 @@ func (t *ingressTrait) Configure(e *Environment) (bool, *TraitCondition, error) } if !pointer.BoolDeref(t.Enabled, true) { return false, NewIntegrationCondition( + "Ingress", v1.IntegrationConditionExposureAvailable, corev1.ConditionFalse, v1.IntegrationConditionIngressNotAvailableReason, diff --git a/pkg/trait/ingress_test.go b/pkg/trait/ingress_test.go index b299f8f46d..29e9ddc94b 100644 --- a/pkg/trait/ingress_test.go +++ b/pkg/trait/ingress_test.go @@ -21,6 +21,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" networkingv1 "k8s.io/api/networking/v1" @@ -37,7 +38,7 @@ func TestConfigureIngressTraitDoesSucceed(t *testing.T) { configured, condition, err := ingressTrait.Configure(environment) assert.True(t, configured) - assert.Nil(t, err) + require.NoError(t, err) assert.Nil(t, condition) assert.Len(t, environment.Integration.Status.Conditions, 0) assert.Nil(t, condition) @@ -49,6 +50,7 @@ func TestConfigureDisabledIngressTraitDoesNotSucceed(t *testing.T) { ingressTrait.Enabled = pointer.Bool(false) expectedCondition := NewIntegrationCondition( + "Ingress", v1.IntegrationConditionExposureAvailable, corev1.ConditionFalse, v1.IntegrationConditionIngressNotAvailableReason, @@ -57,7 +59,7 @@ func TestConfigureDisabledIngressTraitDoesNotSucceed(t *testing.T) { configured, condition, err := ingressTrait.Configure(environment) assert.False(t, configured) - assert.Nil(t, err) + require.NoError(t, err) assert.NotNil(t, condition) assert.Equal(t, expectedCondition, condition) } @@ -69,7 +71,7 @@ func TestConfigureIngressTraitInWrongPhaseDoesNotSucceed(t *testing.T) { configured, condition, err := ingressTrait.Configure(environment) assert.True(t, configured) - assert.Nil(t, err) + require.NoError(t, err) assert.Nil(t, condition) assert.Len(t, environment.Integration.Status.Conditions, 0) } @@ -81,7 +83,7 @@ func TestConfigureAutoIngressTraitWithUserServiceDoesSucceed(t *testing.T) { configured, condition, err := ingressTrait.Configure(environment) assert.True(t, configured) - assert.Nil(t, err) + require.NoError(t, err) assert.Nil(t, condition) assert.Len(t, environment.Integration.Status.Conditions, 0) } @@ -92,7 +94,7 @@ func TestApplyIngressTraitWithoutUserServiceDoesNotSucceed(t *testing.T) { err := ingressTrait.Apply(environment) - assert.NotNil(t, err) + require.Error(t, err) assert.Equal(t, "cannot Apply ingress trait: no target service", err.Error()) assert.Len(t, environment.Resources.Items(), 0) } @@ -102,7 +104,7 @@ func TestApplyIngressTraitDoesSucceed(t *testing.T) { err := ingressTrait.Apply(environment) - assert.Nil(t, err) + require.NoError(t, err) assert.Len(t, environment.Integration.Status.Conditions, 1) assert.Len(t, environment.Resources.Items(), 2) diff --git a/pkg/trait/istio_test.go b/pkg/trait/istio_test.go index 6c7d5b69bd..1e758bb4da 100644 --- a/pkg/trait/istio_test.go +++ b/pkg/trait/istio_test.go @@ -21,6 +21,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" @@ -40,7 +41,7 @@ func NewIstioTestEnv(t *testing.T, d *appsv1.Deployment, s *serving.Service, ena t.Helper() client, _ := test.NewFakeClient() catalog, err := camel.DefaultCatalog() - assert.Nil(t, err) + require.NoError(t, err) env := Environment{ Catalog: NewEnvironmentTestCatalog(), @@ -100,8 +101,8 @@ func TestIstioInject(t *testing.T) { env := NewIstioTestEnv(t, &d, &s, true) conditions, err := env.Catalog.apply(&env) - assert.Nil(t, err) - assert.Empty(t, conditions) + require.NoError(t, err) + assert.NotEmpty(t, conditions) assert.Empty(t, s.Spec.ConfigurationSpec.Template.Annotations[istioSidecarInjectAnnotation]) assert.NotEmpty(t, d.Spec.Template.Annotations[istioSidecarInjectAnnotation]) } @@ -125,8 +126,8 @@ func TestIstioForcedInjectTrue(t *testing.T) { env.Integration.Spec.Traits.Istio.Inject = pointer.Bool(true) conditions, err := env.Catalog.apply(&env) - assert.Nil(t, err) - assert.Empty(t, conditions) + require.NoError(t, err) + assert.NotEmpty(t, conditions) assert.Equal(t, "true", s.Spec.ConfigurationSpec.Template.Annotations[istioSidecarInjectAnnotation]) assert.Equal(t, "true", d.Spec.Template.Annotations[istioSidecarInjectAnnotation]) } @@ -150,8 +151,8 @@ func TestIstioForcedInjectFalse(t *testing.T) { env.Integration.Spec.Traits.Istio.Inject = pointer.Bool(false) conditions, err := env.Catalog.apply(&env) - assert.Nil(t, err) - assert.Empty(t, conditions) + require.NoError(t, err) + assert.NotEmpty(t, conditions) assert.Equal(t, "false", s.Spec.ConfigurationSpec.Template.Annotations[istioSidecarInjectAnnotation]) assert.Equal(t, "false", d.Spec.Template.Annotations[istioSidecarInjectAnnotation]) } @@ -173,7 +174,7 @@ func TestIstioDisabled(t *testing.T) { env := NewIstioTestEnv(t, &d, &s, false) conditions, err := env.Catalog.apply(&env) - assert.Nil(t, err) - assert.Empty(t, conditions) + require.NoError(t, err) + assert.NotEmpty(t, conditions) assert.NotContains(t, env.ExecutedTraits, "istio") } diff --git a/pkg/trait/jolokia_test.go b/pkg/trait/jolokia_test.go index 5d258903ce..307ae10359 100644 --- a/pkg/trait/jolokia_test.go +++ b/pkg/trait/jolokia_test.go @@ -21,6 +21,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" @@ -36,7 +37,7 @@ func TestConfigureJolokiaTraitInRunningPhaseDoesSucceed(t *testing.T) { configured, condition, err := trait.Configure(environment) - assert.Nil(t, err) + require.NoError(t, err) assert.True(t, configured) assert.Nil(t, condition) } @@ -46,7 +47,7 @@ func TestApplyJolokiaTraitNominalShouldSucceed(t *testing.T) { err := trait.Apply(environment) - assert.Nil(t, err) + require.NoError(t, err) container := environment.Resources.GetContainerByName(defaultContainerName) assert.NotNil(t, container) @@ -73,7 +74,7 @@ func TestApplyJolokiaTraitForOpenShiftProfileShouldSucceed(t *testing.T) { err := trait.Apply(environment) - assert.Nil(t, err) + require.NoError(t, err) container := environment.Resources.GetContainerByName(defaultContainerName) assert.NotNil(t, container) @@ -103,7 +104,7 @@ func TestApplyJolokiaTraitWithoutContainerShouldReportJolokiaUnavailable(t *test err := trait.Apply(environment) - assert.Nil(t, err) + require.NoError(t, err) assert.Len(t, environment.Integration.Status.Conditions, 1) condition := environment.Integration.Status.Conditions[0] assert.Equal(t, v1.IntegrationConditionJolokiaAvailable, condition.Type) @@ -124,7 +125,7 @@ func TestApplyJolokiaTraitWithOptionShouldOverrideDefault(t *testing.T) { err := trait.Apply(environment) - assert.Nil(t, err) + require.NoError(t, err) container := environment.Resources.GetContainerByName(defaultContainerName) @@ -141,7 +142,7 @@ func TestApplyJolokiaTraitWithUnparseableOptionShouldReturnError(t *testing.T) { err := trait.Apply(environment) - assert.NotNil(t, err) + require.Error(t, err) } func TestSetDefaultJolokiaOptionShouldNotOverrideOptionsMap(t *testing.T) { @@ -203,7 +204,7 @@ func TestSetDefaultBoolJolokiaOptionShouldSucceed(t *testing.T) { trait.setDefaultJolokiaOption(options, &option, "key", true) - assert.Equal(t, true, *option) + assert.True(t, *option) } func TestSetDefaultBoolJolokiaOptionShouldNotOverrideExistingValue(t *testing.T) { @@ -213,7 +214,7 @@ func TestSetDefaultBoolJolokiaOptionShouldNotOverrideExistingValue(t *testing.T) trait.setDefaultJolokiaOption(options, &option, "key", true) - assert.Equal(t, false, *option) + assert.False(t, *option) } func TestAddStringOptionToJolokiaOptions(t *testing.T) { diff --git a/pkg/trait/jvm.go b/pkg/trait/jvm.go index ab11617ff8..c9e3b32645 100644 --- a/pkg/trait/jvm.go +++ b/pkg/trait/jvm.go @@ -57,7 +57,7 @@ func newJvmTrait() Trait { func (t *jvmTrait) Configure(e *Environment) (bool, *TraitCondition, error) { if !pointer.BoolDeref(t.Enabled, true) { - return false, NewIntegrationConditionUserDisabled(), nil + return false, NewIntegrationConditionUserDisabled("JVM"), nil } if !e.IntegrationKitInPhase(v1.IntegrationKitPhaseReady) || !e.IntegrationInRunningPhases() { return false, nil, nil @@ -66,15 +66,15 @@ func (t *jvmTrait) Configure(e *Environment) (bool, *TraitCondition, error) { // The JVM trait must be disabled in case the current IntegrationKit corresponds to a native build if qt := e.Catalog.GetTrait(quarkusTraitID); qt != nil { if quarkus, ok := qt.(*quarkusTrait); ok && quarkus.isNativeIntegration(e) { - return false, newIntegrationConditionPlatformDisabledWithMessage("quarkus native build"), nil + return false, newIntegrationConditionPlatformDisabledWithMessage("JVM", "quarkus native build"), nil } } if e.IntegrationKit != nil && e.IntegrationKit.IsExternal() { if pointer.BoolDeref(t.Enabled, false) { - return true, NewIntegrationConditionUserEnabledWithMessage("integration kit was not created via Camel K operator"), nil + return true, NewIntegrationConditionUserEnabledWithMessage("JVM", "integration kit was not created via Camel K operator"), nil } else { - return false, newIntegrationConditionPlatformDisabledWithMessage("integration kit was not created via Camel K operator"), nil + return false, newIntegrationConditionPlatformDisabledWithMessage("JVM", "integration kit was not created via Camel K operator"), nil } } diff --git a/pkg/trait/jvm_test.go b/pkg/trait/jvm_test.go index 991d121f82..b3f33f65d3 100644 --- a/pkg/trait/jvm_test.go +++ b/pkg/trait/jvm_test.go @@ -25,6 +25,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" @@ -50,7 +51,7 @@ func TestConfigureJvmTraitInRightPhasesDoesSucceed(t *testing.T) { trait, environment := createNominalJvmTest(v1.IntegrationKitTypePlatform) configured, condition, err := trait.Configure(environment) - assert.Nil(t, err) + require.NoError(t, err) assert.True(t, configured) assert.Nil(t, condition) } @@ -60,7 +61,7 @@ func TestConfigureJvmTraitInWrongIntegrationPhaseDoesNotSucceed(t *testing.T) { environment.Integration.Status.Phase = v1.IntegrationPhaseError configured, condition, err := trait.Configure(environment) - assert.Nil(t, err) + require.NoError(t, err) assert.True(t, configured) assert.Nil(t, condition) } @@ -70,7 +71,7 @@ func TestConfigureJvmTraitInWrongIntegrationKitPhaseDoesNotSucceed(t *testing.T) environment.IntegrationKit.Status.Phase = v1.IntegrationKitPhaseWaitingForPlatform configured, condition, err := trait.Configure(environment) - assert.Nil(t, err) + require.NoError(t, err) assert.False(t, configured) assert.Nil(t, condition) } @@ -80,13 +81,14 @@ func TestConfigureJvmTraitInWrongJvmDisabled(t *testing.T) { trait.Enabled = pointer.Bool(false) expectedCondition := NewIntegrationCondition( + "JVM", v1.IntegrationConditionTraitInfo, corev1.ConditionTrue, "TraitConfiguration", "explicitly disabled by the user", ) configured, condition, err := trait.Configure(environment) - assert.Nil(t, err) + require.NoError(t, err) assert.False(t, configured) assert.NotNil(t, condition) assert.Equal(t, expectedCondition, condition) @@ -96,13 +98,14 @@ func TestConfigureJvmTraitInWrongIntegrationKitPhaseExternal(t *testing.T) { trait, environment := createNominalJvmTest(v1.IntegrationKitTypeExternal) expectedCondition := NewIntegrationCondition( + "JVM", v1.IntegrationConditionTraitInfo, corev1.ConditionTrue, "TraitConfiguration", "explicitly disabled by the platform: integration kit was not created via Camel K operator", ) configured, condition, err := trait.Configure(environment) - assert.Nil(t, err) + require.NoError(t, err) assert.False(t, configured) assert.NotNil(t, condition) assert.Equal(t, expectedCondition, condition) @@ -113,13 +116,14 @@ func TestConfigureJvmTraitInRightIntegrationKitPhaseExternalAndJvmEnabled(t *tes trait.Enabled = pointer.Bool(true) expectedCondition := NewIntegrationCondition( + "JVM", v1.IntegrationConditionTraitInfo, corev1.ConditionTrue, "TraitConfiguration", "explicitly enabled by the user: integration kit was not created via Camel K operator", ) configured, condition, err := trait.Configure(environment) - assert.Nil(t, err) + require.NoError(t, err) assert.True(t, configured) assert.NotNil(t, condition) assert.Equal(t, expectedCondition, condition) @@ -151,7 +155,7 @@ func TestApplyJvmTraitWithDeploymentResource(t *testing.T) { err := trait.Apply(environment) - assert.Nil(t, err) + require.NoError(t, err) s := sets.NewSet() s.Add("./resources", crMountPath, rdMountPath, "/mount/path") @@ -185,7 +189,7 @@ func TestApplyJvmTraitWithKNativeResource(t *testing.T) { err := trait.Apply(environment) - assert.Nil(t, err) + require.NoError(t, err) st := sets.NewSet() st.Add("./resources", crMountPath, rdMountPath, "/mount/path") @@ -227,7 +231,7 @@ func TestApplyJvmTraitWithDebugEnabled(t *testing.T) { err := trait.Apply(environment) - assert.Nil(t, err) + require.NoError(t, err) assert.Contains(t, d.Spec.Template.Spec.Containers[0].Args, "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5005", @@ -254,7 +258,7 @@ func TestApplyJvmTraitWithExternalKitType(t *testing.T) { environment.Resources.Add(&d) err := trait.Apply(environment) - assert.Nil(t, err) + require.NoError(t, err) container := environment.GetIntegrationContainer() @@ -295,7 +299,7 @@ func TestApplyJvmTraitWithClasspath(t *testing.T) { environment.Resources.Add(&d) err := trait.Apply(environment) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, []string{ "-cp", fmt.Sprintf("./resources:%s:%s:/mount/path:%s:%s", crMountPath, rdMountPath, diff --git a/pkg/trait/kamelets.go b/pkg/trait/kamelets.go index d0df47924f..280501848b 100644 --- a/pkg/trait/kamelets.go +++ b/pkg/trait/kamelets.go @@ -41,6 +41,7 @@ import ( ) const ( + kameletsTraitID = "kamelets" contentKey = "content" KameletLocationProperty = "camel.component.kamelet.location" kameletLabel = "camel.apache.org/kamelet" @@ -76,7 +77,7 @@ func (t *kameletsTrait) Configure(e *Environment) (bool, *TraitCondition, error) return false, nil, nil } if !pointer.BoolDeref(t.Enabled, true) { - return false, NewIntegrationConditionUserDisabled(), nil + return false, NewIntegrationConditionUserDisabled("Kamelets"), nil } if !e.IntegrationInPhase(v1.IntegrationPhaseInitialization) && !e.IntegrationInRunningPhases() { return false, nil, nil @@ -107,10 +108,6 @@ func (t *kameletsTrait) Apply(e *Environment) error { return err } } - if e.IntegrationInPhase(v1.IntegrationPhaseInitialization) { - return t.addConfigurationSecrets(e) - } - return nil } @@ -261,7 +258,9 @@ func (t *kameletsTrait) addKameletAsSource(e *Environment, kamelet *v1.Kamelet) return nil } -func (t *kameletsTrait) addConfigurationSecrets(e *Environment) error { +// Deprecated: use explicit secret configuration instead. +func (t *kameletsTrait) listConfigurationSecrets(e *Environment) ([]string, error) { + listConfigurationSecrets := make([]string, 0) for _, k := range t.getConfigurationKeys() { options := metav1.ListOptions{ LabelSelector: fmt.Sprintf("%s=%s", kameletLabel, k.kamelet), @@ -271,21 +270,16 @@ func (t *kameletsTrait) addConfigurationSecrets(e *Environment) error { } secrets, err := t.Client.CoreV1().Secrets(e.Integration.Namespace).List(e.Ctx, options) if err != nil { - return err + return nil, err } - for _, item := range secrets.Items { if item.Labels != nil && item.Labels[kameletConfigurationLabel] != k.configurationID { continue } - - e.Integration.Status.AddConfigurationsIfMissing(v1.ConfigurationSpec{ - Type: "secret", - Value: item.Name, - }) + listConfigurationSecrets = append(listConfigurationSecrets, item.Name) } } - return nil + return listConfigurationSecrets, nil } func (t *kameletsTrait) getKameletKeys() []string { diff --git a/pkg/trait/kamelets_support_test.go b/pkg/trait/kamelets_support_test.go index 2d38941544..5435960756 100644 --- a/pkg/trait/kamelets_support_test.go +++ b/pkg/trait/kamelets_support_test.go @@ -23,13 +23,14 @@ import ( v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestKameletBundleSingle(t *testing.T) { kb := newKameletBundle() kb.add(kamelet("my-ns", "test")) cmBundle, err := kb.toConfigmaps("my-it", "my-ns") - assert.Nil(t, err) + require.NoError(t, err) assert.NotNil(t, cmBundle) assert.Len(t, cmBundle, 1) assert.Equal(t, "my-ns", cmBundle[0].Namespace) @@ -47,7 +48,7 @@ func TestKameletBundleMultiKameletsSingleConfigmap(t *testing.T) { kb.add(kamelet("default", "test5")) kb.add(kamelet("default", "test6")) cmBundle, err := kb.toConfigmaps("my-it", "default") - assert.Nil(t, err) + require.NoError(t, err) assert.NotNil(t, cmBundle) assert.Len(t, cmBundle, 1) assert.Equal(t, "default", cmBundle[0].Namespace) @@ -68,7 +69,7 @@ func TestKameletBundleMultiKameletsMultiConfigmap(t *testing.T) { kb.add(kamelet("default", fmt.Sprintf("test%d", i))) } cmBundle, err := kb.toConfigmaps("my-it", "default") - assert.Nil(t, err) + require.NoError(t, err) assert.NotNil(t, cmBundle) assert.Len(t, cmBundle, 2) assert.Equal(t, "default", cmBundle[0].Namespace) diff --git a/pkg/trait/kamelets_test.go b/pkg/trait/kamelets_test.go index e3cf4fd09a..79b4e89d4f 100644 --- a/pkg/trait/kamelets_test.go +++ b/pkg/trait/kamelets_test.go @@ -370,12 +370,10 @@ func TestKameletConfigLookup(t *testing.T) { assert.Equal(t, []string{"timer"}, trait.getKameletKeys()) assert.Equal(t, []configurationKey{newConfigurationKey("timer", "")}, trait.getConfigurationKeys()) - err = trait.Apply(environment) + list, err := trait.listConfigurationSecrets(environment) require.NoError(t, err) - assert.Len(t, environment.Integration.Status.Configuration, 2) - assert.Contains(t, environment.Integration.Status.Configuration, v1.ConfigurationSpec{Type: "secret", Value: "my-secret"}) - assert.NotContains(t, environment.Integration.Status.Configuration, v1.ConfigurationSpec{Type: "secret", Value: "my-secret2"}) - assert.Contains(t, environment.Integration.Status.Configuration, v1.ConfigurationSpec{Type: "secret", Value: "my-secret3"}) + assert.Contains(t, list, "my-secret", "my-secret3") + assert.NotContains(t, list, "my-secret2") } func TestKameletNamedConfigLookup(t *testing.T) { @@ -437,12 +435,10 @@ func TestKameletNamedConfigLookup(t *testing.T) { newConfigurationKey("timer", "id2"), }, trait.getConfigurationKeys()) - err = trait.Apply(environment) + list, err := trait.listConfigurationSecrets(environment) require.NoError(t, err) - assert.Len(t, environment.Integration.Status.Configuration, 2) - assert.Contains(t, environment.Integration.Status.Configuration, v1.ConfigurationSpec{Type: "secret", Value: "my-secret"}) - assert.Contains(t, environment.Integration.Status.Configuration, v1.ConfigurationSpec{Type: "secret", Value: "my-secret2"}) - assert.NotContains(t, environment.Integration.Status.Configuration, v1.ConfigurationSpec{Type: "secret", Value: "my-secret3"}) + assert.Contains(t, list, "my-secret", "my-secret2") + assert.NotContains(t, list, "my-secret3") } func TestKameletConditionFalse(t *testing.T) { @@ -474,7 +470,7 @@ func TestKameletConditionFalse(t *testing.T) { assert.Nil(t, condition) err = trait.Apply(environment) - assert.Error(t, err) + require.Error(t, err) assert.Len(t, environment.Integration.Status.Conditions, 1) cond := environment.Integration.Status.GetCondition(v1.IntegrationConditionKameletsAvailable) diff --git a/pkg/trait/knative.go b/pkg/trait/knative.go index 5de71160c8..312a1af4b5 100644 --- a/pkg/trait/knative.go +++ b/pkg/trait/knative.go @@ -71,7 +71,7 @@ func (t *knativeTrait) Configure(e *Environment) (bool, *TraitCondition, error) return false, nil, nil } if !pointer.BoolDeref(t.Enabled, true) { - return false, NewIntegrationConditionUserDisabled(), nil + return false, NewIntegrationConditionUserDisabled("Knative"), nil } if !e.IntegrationInPhase(v1.IntegrationPhaseInitialization) && !e.IntegrationInRunningPhases() { return false, nil, nil diff --git a/pkg/trait/knative_service.go b/pkg/trait/knative_service.go index 7d667881a9..e8baaf7d61 100644 --- a/pkg/trait/knative_service.go +++ b/pkg/trait/knative_service.go @@ -75,6 +75,7 @@ func (t *knativeServiceTrait) Configure(e *Environment) (bool, *TraitCondition, } if !pointer.BoolDeref(t.Enabled, true) { return false, NewIntegrationCondition( + "KnativeService", v1.IntegrationConditionKnativeServiceAvailable, corev1.ConditionFalse, v1.IntegrationConditionKnativeServiceNotAvailableReason, @@ -89,6 +90,7 @@ func (t *knativeServiceTrait) Configure(e *Environment) (bool, *TraitCondition, if e.Resources.GetDeploymentForIntegration(e.Integration) != nil { // A controller is already present for the integration return false, NewIntegrationCondition( + "KnativeService", v1.IntegrationConditionKnativeServiceAvailable, corev1.ConditionFalse, v1.IntegrationConditionKnativeServiceNotAvailableReason, @@ -99,6 +101,7 @@ func (t *knativeServiceTrait) Configure(e *Environment) (bool, *TraitCondition, strategy, err := e.DetermineControllerStrategy() if err != nil { return false, NewIntegrationCondition( + "KnativeService", v1.IntegrationConditionKnativeServiceAvailable, corev1.ConditionFalse, v1.IntegrationConditionKnativeServiceNotAvailableReason, @@ -107,6 +110,7 @@ func (t *knativeServiceTrait) Configure(e *Environment) (bool, *TraitCondition, } if strategy != ControllerStrategyKnativeService { return false, NewIntegrationCondition( + "KnativeService", v1.IntegrationConditionKnativeServiceAvailable, corev1.ConditionFalse, v1.IntegrationConditionKnativeServiceNotAvailableReason, diff --git a/pkg/trait/knative_service_test.go b/pkg/trait/knative_service_test.go index 559ecbe4cc..55cf37efe4 100644 --- a/pkg/trait/knative_service_test.go +++ b/pkg/trait/knative_service_test.go @@ -524,7 +524,7 @@ func TestServiceAnnotation(t *testing.T) { traitsCatalog := environment.Catalog _, err := traitsCatalog.apply(environment) - assert.Nil(t, err) + require.NoError(t, err) service := environment.Resources.GetKnativeService(func(s *serving.Service) bool { return s.Name == KnativeServiceTestName diff --git a/pkg/trait/knative_test.go b/pkg/trait/knative_test.go index 7684cb6186..adc47978ab 100644 --- a/pkg/trait/knative_test.go +++ b/pkg/trait/knative_test.go @@ -24,6 +24,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -47,7 +48,7 @@ import ( func TestKnativeEnvConfigurationFromTrait(t *testing.T) { catalog, err := camel.DefaultCatalog() - assert.Nil(t, err) + require.NoError(t, err) traitCatalog := NewCatalog(nil) @@ -103,24 +104,24 @@ func TestKnativeEnvConfigurationFromTrait(t *testing.T) { environment.Platform.ResyncStatusFullConfig() c, err := NewFakeClient("ns") - assert.Nil(t, err) + require.NoError(t, err) tc := NewCatalog(c) err = tc.Configure(&environment) - assert.Nil(t, err) + require.NoError(t, err) tr, _ := tc.GetTrait("knative").(*knativeTrait) ok, condition, err := tr.Configure(&environment) - assert.Nil(t, err) + require.NoError(t, err) assert.True(t, ok) assert.Nil(t, condition) err = tr.Apply(&environment) - assert.Nil(t, err) + require.NoError(t, err) ne, err := fromCamelProperties(environment.ApplicationProperties) - assert.Nil(t, err) + require.NoError(t, err) cSource1 := ne.FindService("channel-source-1", knativeapi.CamelEndpointKindSource, knativeapi.CamelServiceTypeChannel, "messaging.knative.dev/v1", "Channel") assert.NotNil(t, cSource1) @@ -150,7 +151,7 @@ func TestKnativeEnvConfigurationFromTrait(t *testing.T) { func TestKnativeEnvConfigurationFromSource(t *testing.T) { catalog, err := camel.DefaultCatalog() - assert.Nil(t, err) + require.NoError(t, err) traitCatalog := NewCatalog(nil) @@ -220,25 +221,25 @@ func TestKnativeEnvConfigurationFromSource(t *testing.T) { environment.Platform.ResyncStatusFullConfig() c, err := NewFakeClient("ns") - assert.Nil(t, err) + require.NoError(t, err) tc := NewCatalog(c) err = tc.Configure(&environment) - assert.Nil(t, err) + require.NoError(t, err) tr, _ := tc.GetTrait("knative").(*knativeTrait) ok, condition, err := tr.Configure(&environment) - assert.Nil(t, err) + require.NoError(t, err) assert.True(t, ok) assert.Nil(t, condition) err = tr.Apply(&environment) - assert.Nil(t, err) + require.NoError(t, err) ne, err := fromCamelProperties(environment.ApplicationProperties) - assert.Nil(t, err) + require.NoError(t, err) source := ne.FindService("s3fileMover1", knativeapi.CamelEndpointKindSource, knativeapi.CamelServiceTypeEndpoint, "serving.knative.dev/v1", "Service") assert.NotNil(t, source) @@ -285,15 +286,15 @@ func TestKnativePlatformHttpConfig(t *testing.T) { environment := NewFakeEnvironment(t, source) c, err := NewFakeClient("ns") - assert.Nil(t, err) + require.NoError(t, err) tc := NewCatalog(c) err = tc.Configure(&environment) - assert.Nil(t, err) + require.NoError(t, err) _, err = tc.apply(&environment) - assert.Nil(t, err) + require.NoError(t, err) assert.Contains(t, environment.Integration.Status.Capabilities, v1.CapabilityPlatformHTTP) }) } @@ -331,16 +332,16 @@ func TestKnativePlatformHttpDependencies(t *testing.T) { environment.Integration.Status.Phase = v1.IntegrationPhaseInitialization c, err := NewFakeClient("ns") - assert.Nil(t, err) + require.NoError(t, err) tc := NewCatalog(c) err = tc.Configure(&environment) - assert.Nil(t, err) + require.NoError(t, err) conditions, err := tc.apply(&environment) - assert.Nil(t, err) - assert.Empty(t, conditions) + require.NoError(t, err) + assert.NotEmpty(t, conditions) assert.Contains(t, environment.Integration.Status.Capabilities, v1.CapabilityPlatformHTTP) assert.Contains(t, environment.Integration.Status.Dependencies, "mvn:org.apache.camel.quarkus:camel-quarkus-platform-http") }) @@ -352,7 +353,7 @@ func NewFakeEnvironment(t *testing.T, source v1.SourceSpec) Environment { client, _ := NewFakeClient("ns") catalog, err := camel.DefaultCatalog() - assert.Nil(t, err) + require.NoError(t, err) traitCatalog := NewCatalog(nil) @@ -663,15 +664,15 @@ func TestKnativeSinkBinding(t *testing.T) { environment.Integration.Status.Phase = v1.IntegrationPhaseDeploying c, err := NewFakeClient("ns") - assert.Nil(t, err) + require.NoError(t, err) tc := NewCatalog(c) err = tc.Configure(&environment) - assert.Nil(t, err) + require.NoError(t, err) _, err = tc.apply(&environment) - assert.Nil(t, err) + require.NoError(t, err) baseProp := "camel.component.knative.environment.resources[0]" assert.Equal(t, "channel-sink-1", environment.ApplicationProperties[baseProp+".name"]) assert.Equal(t, "${K_SINK}", environment.ApplicationProperties[baseProp+".url"]) diff --git a/pkg/trait/logging.go b/pkg/trait/logging.go index 78636346ab..d23caefcb3 100644 --- a/pkg/trait/logging.go +++ b/pkg/trait/logging.go @@ -58,7 +58,7 @@ func (l loggingTrait) Configure(e *Environment) (bool, *TraitCondition, error) { } if !pointer.BoolDeref(l.Enabled, true) { - return false, NewIntegrationConditionUserDisabled(), nil + return false, NewIntegrationConditionUserDisabled("Logging"), nil } return e.IntegrationInRunningPhases(), nil, nil diff --git a/pkg/trait/logging_test.go b/pkg/trait/logging_test.go index 9e3abc59f4..29f6395dc1 100644 --- a/pkg/trait/logging_test.go +++ b/pkg/trait/logging_test.go @@ -22,6 +22,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -113,8 +114,8 @@ func TestEmptyLoggingTrait(t *testing.T) { env := createDefaultLoggingTestEnv(t) conditions, err := NewLoggingTestCatalog().apply(env) - assert.Nil(t, err) - assert.Empty(t, conditions) + require.NoError(t, err) + assert.NotEmpty(t, conditions) assert.NotEmpty(t, env.ExecutedTraits) quarkusConsoleColor := false @@ -166,8 +167,8 @@ func TestJsonLoggingTrait(t *testing.T) { env := createLoggingTestEnv(t, true, true, false, "TRACE", "%d{HH:mm:ss} %-5p (%t) %s%e%n", map[string]string{}) conditions, err := NewLoggingTestCatalog().apply(env) - assert.Nil(t, err) - assert.Empty(t, conditions) + require.NoError(t, err) + assert.NotEmpty(t, conditions) assert.NotEmpty(t, env.ExecutedTraits) quarkusConsoleColor := false diff --git a/pkg/trait/mount.go b/pkg/trait/mount.go index 5c00185f5a..76cd01d0ec 100644 --- a/pkg/trait/mount.go +++ b/pkg/trait/mount.go @@ -25,9 +25,11 @@ import ( appsv1 "k8s.io/api/apps/v1" batchv1 "k8s.io/api/batch/v1" corev1 "k8s.io/api/core/v1" + "k8s.io/utils/pointer" serving "knative.dev/serving/pkg/apis/serving/v1" + v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" traitv1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1/trait" "github.com/apache/camel-k/v2/pkg/util/kubernetes" utilResource "github.com/apache/camel-k/v2/pkg/util/resource" @@ -52,6 +54,9 @@ func (t *mountTrait) Configure(e *Environment) (bool, *TraitCondition, error) { // Look for secrets which may have been created by service binding trait t.addServiceBindingSecret(e) + // Look for implicit secrets which may be required by kamelets + condition := t.addImplicitKameletsSecrets(e) + // Validate resources and pvcs for _, c := range t.Configs { if !strings.HasPrefix(c, "configmap:") && !strings.HasPrefix(c, "secret:") { @@ -68,7 +73,7 @@ func (t *mountTrait) Configure(e *Environment) (bool, *TraitCondition, error) { return len(e.Integration.AllSources()) > 0 || len(t.Configs) > 0 || len(t.Resources) > 0 || - len(t.Volumes) > 0, nil, nil + len(t.Volumes) > 0, condition, nil } func (t *mountTrait) Apply(e *Environment) error { @@ -176,3 +181,49 @@ func (t *mountTrait) addServiceBindingSecret(e *Environment) { } }) } + +// Deprecated: to be removed in future releases. +// nolint: staticcheck +func (t *mountTrait) addImplicitKameletsSecrets(e *Environment) *TraitCondition { + featureUsed := false + if trait := e.Catalog.GetTrait(kameletsTraitID); trait != nil { + kamelets, ok := trait.(*kameletsTrait) + if !ok { + return NewIntegrationCondition( + "Mount", + v1.IntegrationConditionTraitInfo, + corev1.ConditionTrue, + traitConfigurationReason, + "Unexpected error happened while casting to kamelets trait", + ) + } + if !pointer.BoolDeref(t.ScanKameletsImplicitLabelSecrets, true) { + return nil + } + implicitKameletSecrets, err := kamelets.listConfigurationSecrets(e) + if err != nil { + return NewIntegrationCondition( + "Mount", + v1.IntegrationConditionTraitInfo, + corev1.ConditionTrue, + traitConfigurationReason, + err.Error(), + ) + } + for _, secret := range implicitKameletSecrets { + featureUsed = true + t.Configs = append(t.Configs, "secret:"+secret) + } + } + + if featureUsed { + return NewIntegrationCondition( + "Mount", + v1.IntegrationConditionTraitInfo, + corev1.ConditionTrue, + traitConfigurationReason, + "Implicit Kamelet labelling secrets are deprecated and may be removed in future releases. Make sure to use explicit mount.config secrets instead.", + ) + } + return nil +} diff --git a/pkg/trait/mount_test.go b/pkg/trait/mount_test.go index 6191b2ae69..f64186878e 100644 --- a/pkg/trait/mount_test.go +++ b/pkg/trait/mount_test.go @@ -46,7 +46,7 @@ func TestMountVolumesEmpty(t *testing.T) { conditions, err := traitCatalog.apply(environment) require.NoError(t, err) - assert.Empty(t, conditions) + assert.NotEmpty(t, conditions) assert.NotEmpty(t, environment.ExecutedTraits) assert.NotNil(t, environment.GetTrait("mount")) @@ -69,7 +69,7 @@ func TestMountVolumesIntegrationPhaseDeploying(t *testing.T) { conditions, err := traitCatalog.apply(environment) require.NoError(t, err) - assert.Empty(t, conditions) + assert.NotEmpty(t, conditions) assert.NotEmpty(t, environment.ExecutedTraits) assert.NotNil(t, environment.GetTrait("mount")) @@ -118,7 +118,7 @@ func TestMountVolumesIntegrationPhaseInitialization(t *testing.T) { conditions, err := traitCatalog.apply(environment) require.NoError(t, err) - assert.Empty(t, conditions) + assert.NotEmpty(t, conditions) assert.NotEmpty(t, environment.ExecutedTraits) assert.Nil(t, environment.GetTrait("mount")) diff --git a/pkg/trait/openapi_test.go b/pkg/trait/openapi_test.go index 05e710dc7f..8619d6d833 100644 --- a/pkg/trait/openapi_test.go +++ b/pkg/trait/openapi_test.go @@ -25,11 +25,12 @@ import ( v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestRestDslTraitApplicability(t *testing.T) { catalog, err := camel.DefaultCatalog() - assert.Nil(t, err) + require.NoError(t, err) e := &Environment{ CamelCatalog: catalog, @@ -37,7 +38,7 @@ func TestRestDslTraitApplicability(t *testing.T) { trait, _ := newOpenAPITrait().(*openAPITrait) enabled, condition, err := trait.Configure(e) - assert.Nil(t, err) + require.NoError(t, err) assert.False(t, enabled) assert.Nil(t, condition) @@ -47,20 +48,20 @@ func TestRestDslTraitApplicability(t *testing.T) { }, } enabled, condition, err = trait.Configure(e) - assert.Nil(t, err) + require.NoError(t, err) assert.False(t, enabled) assert.Nil(t, condition) trait.Configmaps = []string{"my-configmap"} enabled, condition, err = trait.Configure(e) - assert.Nil(t, err) + require.NoError(t, err) assert.False(t, enabled) assert.Nil(t, condition) e.Integration.Status.Phase = v1.IntegrationPhaseInitialization enabled, condition, err = trait.Configure(e) - assert.Nil(t, err) + require.NoError(t, err) assert.True(t, enabled) assert.Nil(t, condition) } diff --git a/pkg/trait/owner.go b/pkg/trait/owner.go index 20bab1952d..3b5c8f4286 100644 --- a/pkg/trait/owner.go +++ b/pkg/trait/owner.go @@ -44,7 +44,7 @@ func (t *ownerTrait) Configure(e *Environment) (bool, *TraitCondition, error) { return false, nil, nil } if !pointer.BoolDeref(t.Enabled, true) { - return false, NewIntegrationConditionUserDisabled(), nil + return false, NewIntegrationConditionUserDisabled("Owner"), nil } return e.IntegrationInPhase(v1.IntegrationPhaseInitialization) || e.IntegrationInRunningPhases(), nil, nil diff --git a/pkg/trait/pdb_test.go b/pkg/trait/pdb_test.go index 17518c4f95..5c72d5a7cd 100644 --- a/pkg/trait/pdb_test.go +++ b/pkg/trait/pdb_test.go @@ -21,6 +21,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" @@ -37,7 +38,7 @@ func TestConfigurePdbTraitDoesSucceed(t *testing.T) { configured, condition, err := pdbTrait.Configure(environment) assert.True(t, configured) - assert.Nil(t, err) + require.NoError(t, err) assert.Nil(t, condition) } @@ -47,7 +48,7 @@ func TestConfigurePdbTraitDoesNotSucceed(t *testing.T) { pdbTrait.MinAvailable = "1" pdbTrait.MaxUnavailable = "2" configured, condition, err := pdbTrait.Configure(environment) - assert.NotNil(t, err) + require.Error(t, err) assert.False(t, configured) assert.Nil(t, condition) } @@ -79,7 +80,7 @@ func pdbCreatedCheck(t *testing.T, pdbTrait *pdbTrait, environment *Environment) t.Helper() err := pdbTrait.Apply(environment) - assert.Nil(t, err) + require.NoError(t, err) pdb := findPdb(environment.Resources) assert.NotNil(t, pdb) diff --git a/pkg/trait/platform_test.go b/pkg/trait/platform_test.go index 7db06c3bd3..11211df065 100644 --- a/pkg/trait/platform_test.go +++ b/pkg/trait/platform_test.go @@ -26,6 +26,7 @@ import ( "github.com/apache/camel-k/v2/pkg/util/test" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/utils/pointer" @@ -63,15 +64,15 @@ func TestPlatformTraitChangeStatus(t *testing.T) { var err error trait.Client, err = test.NewFakeClient() - assert.Nil(t, err) + require.NoError(t, err) enabled, condition, err := trait.Configure(&e) - assert.Nil(t, err) + require.NoError(t, err) assert.True(t, enabled) assert.Nil(t, condition) err = trait.Apply(&e) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, v1.IntegrationPhaseWaitingForPlatform, e.Integration.Status.Phase) assert.Empty(t, e.Resources.Items()) @@ -98,15 +99,15 @@ func TestPlatformTraitCreatesDefaultPlatform(t *testing.T) { var err error trait.Client, err = test.NewFakeClient() - assert.Nil(t, err) + require.NoError(t, err) enabled, condition, err := trait.Configure(&e) - assert.Nil(t, err) + require.NoError(t, err) assert.True(t, enabled) assert.Nil(t, condition) err = trait.Apply(&e) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, v1.IntegrationPhaseWaitingForPlatform, e.Integration.Status.Phase) assert.Equal(t, 1, len(e.Resources.Items())) @@ -156,15 +157,15 @@ func TestPlatformTraitExisting(t *testing.T) { existingPlatform := v1.NewIntegrationPlatform("ns1", "existing") existingPlatform.Status.Phase = input.platformPhase trait.Client, err = test.NewFakeClient(&existingPlatform) - assert.Nil(t, err) + require.NoError(t, err) enabled, condition, err := trait.Configure(&e) - assert.Nil(t, err) + require.NoError(t, err) assert.True(t, enabled) assert.Nil(t, condition) err = trait.Apply(&e) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, input.expectedPhase, e.Integration.Status.Phase) assert.Empty(t, e.Resources.Items()) diff --git a/pkg/trait/pod.go b/pkg/trait/pod.go index 5233bd513a..12fc35df6f 100644 --- a/pkg/trait/pod.go +++ b/pkg/trait/pod.go @@ -49,7 +49,7 @@ func (t *podTrait) Configure(e *Environment) (bool, *TraitCondition, error) { return false, nil, nil } if !pointer.BoolDeref(t.Enabled, true) { - return false, NewIntegrationConditionUserDisabled(), nil + return false, NewIntegrationConditionUserDisabled("Pod"), nil } if e.Integration.Spec.PodTemplate == nil { return false, nil, nil diff --git a/pkg/trait/pod_test.go b/pkg/trait/pod_test.go index 5a994cb508..96875c763b 100755 --- a/pkg/trait/pod_test.go +++ b/pkg/trait/pod_test.go @@ -21,6 +21,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "k8s.io/apimachinery/pkg/util/yaml" @@ -40,13 +41,13 @@ func TestConfigurePodTraitDoesSucceed(t *testing.T) { assert.True(t, configured) assert.Nil(t, condition) - assert.Nil(t, err) + require.NoError(t, err) configured, condition, err = trait.Configure(environment) assert.True(t, configured) assert.Nil(t, condition) - assert.Nil(t, err) + require.NoError(t, err) } func TestSimpleChange(t *testing.T) { @@ -206,11 +207,11 @@ func testPodTemplateSpec(t *testing.T, template string) corev1.PodTemplateSpec { trait, environment, _ := createPodTest(template) _, condition, err := trait.Configure(environment) - assert.Nil(t, err) + require.NoError(t, err) assert.Nil(t, condition) err = trait.Apply(environment) - assert.Nil(t, err) + require.NoError(t, err) deployment := environment.Resources.GetDeployment(func(deployment *appsv1.Deployment) bool { return deployment.Name == "pod-template-test-integration" diff --git a/pkg/trait/prometheus_test.go b/pkg/trait/prometheus_test.go index 71c097f3f5..48c581d98a 100644 --- a/pkg/trait/prometheus_test.go +++ b/pkg/trait/prometheus_test.go @@ -21,6 +21,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" @@ -38,7 +39,7 @@ func TestConfigurePrometheusTraitInRightPhaseDoesSucceed(t *testing.T) { configured, condition, err := trait.Configure(environment) - assert.Nil(t, err) + require.NoError(t, err) assert.True(t, configured) assert.Nil(t, condition) } @@ -49,7 +50,7 @@ func TestConfigurePrometheusTraitInWrongPhaseDoesNotSucceed(t *testing.T) { configured, condition, err := trait.Configure(environment) - assert.Nil(t, err) + require.NoError(t, err) assert.False(t, configured) assert.Nil(t, condition) } @@ -59,7 +60,7 @@ func TestApplyNominalPrometheusTraitDoesSucceed(t *testing.T) { err := trait.Apply(environment) - assert.Nil(t, err) + require.NoError(t, err) container := environment.Resources.GetContainerByName(defaultContainerName) assert.NotNil(t, container) @@ -88,7 +89,7 @@ func TestApplyPrometheusTraitWithoutContainerDoesNotSucceed(t *testing.T) { err := trait.Apply(environment) - assert.Nil(t, err) + require.NoError(t, err) assert.Len(t, environment.Integration.Status.Conditions, 1) condition := environment.Integration.Status.Conditions[0] @@ -101,7 +102,7 @@ func TestPrometheusTraitGetPodMonitor(t *testing.T) { podMonitor, err := trait.getPodMonitorFor(environment, defaultContainerPortName) - assert.Nil(t, err) + require.NoError(t, err) assert.NotNil(t, podMonitor) assert.Equal(t, "PodMonitor", podMonitor.Kind) diff --git a/pkg/trait/pull_secret.go b/pkg/trait/pull_secret.go index 829a7920fc..c2fb33a679 100644 --- a/pkg/trait/pull_secret.go +++ b/pkg/trait/pull_secret.go @@ -49,7 +49,7 @@ func (t *pullSecretTrait) Configure(e *Environment) (bool, *TraitCondition, erro return false, nil, nil } if !pointer.BoolDeref(t.Enabled, true) { - return false, NewIntegrationConditionUserDisabled(), nil + return false, NewIntegrationConditionUserDisabled("PullSecret"), nil } if !e.IntegrationInRunningPhases() { return false, nil, nil diff --git a/pkg/trait/pull_secret_test.go b/pkg/trait/pull_secret_test.go index ded0281d59..e470c51f17 100644 --- a/pkg/trait/pull_secret_test.go +++ b/pkg/trait/pull_secret_test.go @@ -33,6 +33,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestPullSecret(t *testing.T) { @@ -41,12 +42,12 @@ func TestPullSecret(t *testing.T) { trait, _ := newPullSecretTrait().(*pullSecretTrait) trait.SecretName = "xxxy" enabled, condition, err := trait.Configure(e) - assert.Nil(t, err) + require.NoError(t, err) assert.True(t, enabled) assert.Nil(t, condition) err = trait.Apply(e) - assert.Nil(t, err) + require.NoError(t, err) assert.Contains(t, deployment.Spec.Template.Spec.ImagePullSecrets, corev1.LocalObjectReference{Name: "xxxy"}) } @@ -56,7 +57,7 @@ func TestPullSecretDoesNothingWhenNotSetOnPlatform(t *testing.T) { trait := newPullSecretTrait() enabled, condition, err := trait.Configure(e) - assert.Nil(t, err) + require.NoError(t, err) assert.False(t, enabled) assert.Nil(t, condition) } @@ -67,7 +68,7 @@ func TestPullSecretAuto(t *testing.T) { trait, _ := newPullSecretTrait().(*pullSecretTrait) trait.Auto = pointer.Bool(false) enabled, condition, err := trait.Configure(e) - assert.Nil(t, err) + require.NoError(t, err) assert.False(t, enabled) assert.Nil(t, condition) } @@ -79,13 +80,13 @@ func TestPullSecretImagePullerDelegation(t *testing.T) { trait.Auto = pointer.Bool(false) trait.ImagePullerDelegation = pointer.Bool(true) enabled, condition, err := trait.Configure(e) - assert.Nil(t, err) + require.NoError(t, err) assert.True(t, enabled) assert.Nil(t, condition) assert.True(t, *trait.ImagePullerDelegation) err = trait.Apply(e) - assert.NoError(t, err) + require.NoError(t, err) var roleBinding rbacv1.RoleBinding roleBindingKey := client.ObjectKey{ @@ -93,7 +94,7 @@ func TestPullSecretImagePullerDelegation(t *testing.T) { Name: "camel-k-puller-test-default", } err = e.Client.Get(e.Ctx, roleBindingKey, &roleBinding) - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, roleBinding.Subjects, 1) } @@ -127,7 +128,7 @@ func getEnvironmentAndDeployment(t *testing.T) (*Environment, *appsv1.Deployment var err error e.Ctx = context.TODO() e.Client, err = test.NewFakeClient(e.Integration, &deployment) - assert.NoError(t, err) + require.NoError(t, err) return e, &deployment } diff --git a/pkg/trait/quarkus.go b/pkg/trait/quarkus.go index 52ca72399d..1140029bee 100644 --- a/pkg/trait/quarkus.go +++ b/pkg/trait/quarkus.go @@ -36,8 +36,7 @@ import ( ) const ( - quarkusTraitID = "quarkus" - + quarkusTraitID = "quarkus" QuarkusNativeDefaultBaseImageName = "quay.io/quarkus/quarkus-micro-image:2.0" ) @@ -110,23 +109,14 @@ func (t *quarkusTrait) InfluencesKit() bool { return true } -// InfluencesBuild overrides base class method. -func (t *quarkusTrait) InfluencesBuild(this, prev map[string]interface{}) bool { - return true -} - -var _ ComparableTrait = &quarkusTrait{} - func (t *quarkusTrait) Matches(trait Trait) bool { qt, ok := trait.(*quarkusTrait) if !ok { return false } - if len(t.Modes) == 0 && len(qt.Modes) != 0 && !qt.containsMode(traitv1.JvmQuarkusMode) { return false } - for _, md := range t.Modes { if md == traitv1.JvmQuarkusMode && len(qt.Modes) == 0 { continue @@ -136,8 +126,17 @@ func (t *quarkusTrait) Matches(trait Trait) bool { } return false } + // We need to check if the native base image used is the same + thisNativeBaseImage := t.NativeBaseImage + if thisNativeBaseImage == "" { + thisNativeBaseImage = QuarkusNativeDefaultBaseImageName + } + otherNativeBaseImage := qt.NativeBaseImage + if otherNativeBaseImage == "" { + otherNativeBaseImage = QuarkusNativeDefaultBaseImageName + } - return true + return thisNativeBaseImage == otherNativeBaseImage } func (t *quarkusTrait) Configure(e *Environment) (bool, *TraitCondition, error) { @@ -162,7 +161,7 @@ func (t *quarkusTrait) adaptDeprecatedFields() *TraitCondition { t.Modes = append(t.Modes, traitv1.JvmQuarkusMode) } } - return NewIntegrationCondition(v1.IntegrationConditionTraitInfo, corev1.ConditionTrue, traitConfigurationReason, message) + return NewIntegrationCondition("Quarkus", v1.IntegrationConditionTraitInfo, corev1.ConditionTrue, traitConfigurationReason, message) } return nil @@ -274,27 +273,26 @@ func (t *quarkusTrait) newIntegrationKit(e *Environment, packageType quarkusPack v1.SetAnnotation(&kit.ObjectMeta, v1.IntegrationProfileNamespaceAnnotation, e.Integration.Namespace) } } - for k, v := range integration.Annotations { if strings.HasPrefix(k, v1.TraitAnnotationPrefix) { v1.SetAnnotation(&kit.ObjectMeta, k, v) } } - operatorID := defaults.OperatorID() if operatorID != "" { kit.SetOperatorID(operatorID) } - kit.Spec = v1.IntegrationKitSpec{ Dependencies: e.Integration.Status.Dependencies, Repositories: e.Integration.Spec.Repositories, Traits: propagateKitTraits(e), } - if packageType == nativeSourcesPackageType { kit.Spec.Sources = propagateSourcesRequiredAtBuildTime(e) } + if e.Integration.Status.Capabilities != nil { + kit.Spec.Capabilities = e.Integration.Status.Capabilities + } return kit } @@ -316,9 +314,10 @@ func propagateKitTraits(e *Environment) v1.IntegrationKitTraits { func propagate(traitSource string, traits v1.Traits, kitTraits *v1.IntegrationKitTraits, e *Environment) { ikt := v1.IntegrationKitTraits{ - Builder: traits.Builder.DeepCopy(), - Camel: traits.Camel.DeepCopy(), - Quarkus: traits.Quarkus.DeepCopy(), + Builder: traits.Builder.DeepCopy(), + Camel: traits.Camel.DeepCopy(), + Quarkus: traits.Quarkus.DeepCopy(), + // nolint: staticcheck Registry: traits.Registry.DeepCopy(), } diff --git a/pkg/trait/quarkus_test.go b/pkg/trait/quarkus_test.go index d924811670..5d681a3097 100644 --- a/pkg/trait/quarkus_test.go +++ b/pkg/trait/quarkus_test.go @@ -23,6 +23,7 @@ import ( traitv1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1/trait" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" "github.com/apache/camel-k/v2/pkg/builder" @@ -37,11 +38,11 @@ func TestConfigureQuarkusTraitBuildSubmitted(t *testing.T) { configured, condition, err := quarkusTrait.Configure(environment) assert.True(t, configured) - assert.Nil(t, err) + require.NoError(t, err) assert.Nil(t, condition) err = quarkusTrait.Apply(environment) - assert.Nil(t, err) + require.NoError(t, err) build := getBuilderTask(environment.Pipeline) assert.NotNil(t, t, build) @@ -58,11 +59,11 @@ func TestApplyQuarkusTraitDefaultKitLayout(t *testing.T) { configured, condition, err := quarkusTrait.Configure(environment) assert.True(t, configured) - assert.Nil(t, err) + require.NoError(t, err) assert.Nil(t, condition) err = quarkusTrait.Apply(environment) - assert.Nil(t, err) + require.NoError(t, err) assert.Len(t, environment.IntegrationKits, 1) assert.Equal(t, environment.IntegrationKits[0].Labels[v1.IntegrationKitLayoutLabel], v1.IntegrationKitLayoutFastJar) } @@ -75,11 +76,11 @@ func TestApplyQuarkusTraitAnnotationKitConfiguration(t *testing.T) { configured, condition, err := quarkusTrait.Configure(environment) assert.True(t, configured) - assert.Nil(t, err) + require.NoError(t, err) assert.Nil(t, condition) err = quarkusTrait.Apply(environment) - assert.Nil(t, err) + require.NoError(t, err) assert.Len(t, environment.IntegrationKits, 1) assert.Equal(t, v1.IntegrationKitLayoutFastJar, environment.IntegrationKits[0].Labels[v1.IntegrationKitLayoutLabel]) assert.Equal(t, "camel-k", environment.IntegrationKits[0].Annotations[v1.TraitAnnotationPrefix+"quarkus.foo"]) @@ -97,7 +98,7 @@ func TestQuarkusTraitBuildModeOrder(t *testing.T) { } err := quarkusTrait.Apply(environment) - assert.Nil(t, err) + require.NoError(t, err) assert.Len(t, environment.IntegrationKits, 2) // assure jvm mode is executed before native mode assert.Equal(t, environment.IntegrationKits[0].Labels[v1.IntegrationKitLayoutLabel], v1.IntegrationKitLayoutFastJar) @@ -224,3 +225,31 @@ func TestGetLanguageSettingsWithLoaders(t *testing.T) { assert.Equal(t, languageSettings{native: false, sourcesRequiredAtBuildTime: true}, getLanguageSettings(environment, v1.LanguageKotlin)) assert.Equal(t, languageSettings{native: true, sourcesRequiredAtBuildTime: false}, getLanguageSettings(environment, v1.LanguageJavaShell)) } + +func TestQuarkusMatches(t *testing.T) { + qt := quarkusTrait{ + BasePlatformTrait: NewBasePlatformTrait("quarkus", 600), + QuarkusTrait: traitv1.QuarkusTrait{ + Modes: []traitv1.QuarkusMode{traitv1.JvmQuarkusMode}, + }, + } + qt2 := quarkusTrait{ + BasePlatformTrait: NewBasePlatformTrait("quarkus", 600), + QuarkusTrait: traitv1.QuarkusTrait{ + Modes: []traitv1.QuarkusMode{traitv1.JvmQuarkusMode}, + NativeBaseImage: QuarkusNativeDefaultBaseImageName, + }, + } + + assert.True(t, qt.Matches(&qt2)) + qt2.Modes = append(qt2.Modes, traitv1.NativeQuarkusMode) + assert.True(t, qt.Matches(&qt2)) + qt2.Modes = []traitv1.QuarkusMode{traitv1.NativeQuarkusMode} + assert.False(t, qt.Matches(&qt2)) + qt2.Modes = nil + assert.True(t, qt.Matches(&qt2)) + qt2.Modes = []traitv1.QuarkusMode{} + assert.True(t, qt.Matches(&qt2)) + qt2.NativeBaseImage = "docker.io/my-new-native-base" + assert.False(t, qt.Matches(&qt2)) +} diff --git a/pkg/trait/registry.go b/pkg/trait/registry.go index 3efd76510b..29c9c3497e 100644 --- a/pkg/trait/registry.go +++ b/pkg/trait/registry.go @@ -54,18 +54,23 @@ func (t *registryTrait) InfluencesKit() bool { return true } -// InfluencesBuild overrides base class method. -func (t *registryTrait) InfluencesBuild(this, prev map[string]interface{}) bool { - return true -} - func (t *registryTrait) Configure(e *Environment) (bool, *TraitCondition, error) { // disabled by default if e.IntegrationKit == nil || !pointer.BoolDeref(t.Enabled, false) { return false, nil, nil } - - return e.IntegrationKitInPhase(v1.IntegrationKitPhaseBuildSubmitted), nil, nil + enabled := e.IntegrationKitInPhase(v1.IntegrationKitPhaseBuildSubmitted) + if enabled { + condition := NewIntegrationCondition( + "Registry", + v1.IntegrationConditionTraitInfo, + corev1.ConditionTrue, + traitConfigurationReason, + "Registry trait is deprecated. It may be removed in future version. Read documentation to find alternatives (likely JVM trait).", + ) + return true, condition, nil + } + return false, nil, nil } func (t *registryTrait) Apply(e *Environment) error { diff --git a/pkg/trait/route.go b/pkg/trait/route.go index 101f5c326a..6816352e77 100644 --- a/pkg/trait/route.go +++ b/pkg/trait/route.go @@ -60,6 +60,7 @@ func (t *routeTrait) Configure(e *Environment) (bool, *TraitCondition, error) { } if !pointer.BoolDeref(t.Enabled, true) { return false, NewIntegrationCondition( + "Route", v1.IntegrationConditionExposureAvailable, corev1.ConditionFalse, v1.IntegrationConditionRouteNotAvailableReason, diff --git a/pkg/trait/route_test.go b/pkg/trait/route_test.go index 145054f1aa..0c1bd22381 100644 --- a/pkg/trait/route_test.go +++ b/pkg/trait/route_test.go @@ -23,6 +23,7 @@ import ( "github.com/rs/xid" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" routev1 "github.com/openshift/api/route/v1" @@ -108,7 +109,7 @@ func createTestRouteEnvironment(t *testing.T, name string) *Environment { t.Helper() catalog, err := camel.DefaultCatalog() - assert.Nil(t, err) + require.NoError(t, err) client, _ := test.NewFakeClient( &corev1.Secret{ TypeMeta: metav1.TypeMeta{ @@ -206,8 +207,8 @@ func TestRoute_Default(t *testing.T) { traitsCatalog := environment.Catalog conditions, err := traitsCatalog.apply(environment) - assert.Nil(t, err) - assert.Empty(t, conditions) + require.NoError(t, err) + assert.NotEmpty(t, conditions) assert.NotEmpty(t, environment.ExecutedTraits) assert.NotNil(t, environment.GetTrait("container")) assert.NotNil(t, environment.GetTrait("route")) @@ -234,15 +235,15 @@ func TestRoute_Disabled(t *testing.T) { } expectedCondition := NewIntegrationCondition( + "Route", v1.IntegrationConditionExposureAvailable, corev1.ConditionFalse, - "routeTraitConfiguration", + "RouteNotAvailable", "explicitly disabled", ) traitsCatalog := environment.Catalog conditions, err := traitsCatalog.apply(environment) - assert.Nil(t, err) - assert.Len(t, conditions, 1) + require.NoError(t, err) assert.Contains(t, conditions, expectedCondition) assert.NotEmpty(t, environment.ExecutedTraits) assert.Nil(t, environment.GetTrait("route")) @@ -265,7 +266,7 @@ func TestRoute_Configure_IntegrationKitOnly(t *testing.T) { result, condition, err := routeTrait.Configure(environment) assert.False(t, result) - assert.Nil(t, err) + require.NoError(t, err) assert.Nil(t, condition) } @@ -282,8 +283,8 @@ func TestRoute_Host(t *testing.T) { conditions, err := traitsCatalog.apply(environment) - assert.Nil(t, err) - assert.Empty(t, conditions) + require.NoError(t, err) + assert.NotEmpty(t, conditions) assert.NotEmpty(t, environment.ExecutedTraits) assert.NotNil(t, environment.GetTrait("route")) @@ -313,8 +314,8 @@ func TestRoute_TLS_From_Secret_reencrypt(t *testing.T) { } conditions, err := traitsCatalog.apply(environment) - assert.Nil(t, err) - assert.Empty(t, conditions) + require.NoError(t, err) + assert.NotEmpty(t, conditions) assert.NotEmpty(t, environment.ExecutedTraits) assert.NotNil(t, environment.GetTrait("route")) @@ -350,7 +351,7 @@ func TestRoute_TLS_wrong_secret(t *testing.T) { conditions, err := traitsCatalog.apply(environment) assert.Empty(t, conditions) // there must be errors as the trait has wrong configuration - assert.NotNil(t, err) + require.Error(t, err) assert.Nil(t, environment.GetTrait("route")) route := environment.Resources.GetRoute(func(r *routev1.Route) bool { @@ -378,7 +379,7 @@ func TestRoute_TLS_secret_wrong_key(t *testing.T) { conditions, err := traitsCatalog.apply(environment) assert.Empty(t, conditions) // there must be errors as the trait has wrong configuration - assert.NotNil(t, err) + require.Error(t, err) assert.Nil(t, environment.GetTrait("route")) route := environment.Resources.GetRoute(func(r *routev1.Route) bool { @@ -406,7 +407,7 @@ func TestRoute_TLS_secret_missing_key(t *testing.T) { conditions, err := traitsCatalog.apply(environment) assert.Empty(t, conditions) // there must be errors as the trait has wrong configuration - assert.NotNil(t, err) + require.Error(t, err) assert.Nil(t, environment.GetTrait("route")) route := environment.Resources.GetRoute(func(r *routev1.Route) bool { @@ -433,8 +434,8 @@ func TestRoute_TLS_reencrypt(t *testing.T) { }, } conditions, err := traitsCatalog.apply(environment) - assert.Nil(t, err) - assert.Empty(t, conditions) + require.NoError(t, err) + assert.NotEmpty(t, conditions) assert.NotEmpty(t, environment.ExecutedTraits) assert.NotNil(t, environment.GetTrait("route")) @@ -467,8 +468,8 @@ func TestRoute_TLS_edge(t *testing.T) { }, } conditions, err := traitsCatalog.apply(environment) - assert.Nil(t, err) - assert.Empty(t, conditions) + require.NoError(t, err) + assert.NotEmpty(t, conditions) assert.NotEmpty(t, environment.ExecutedTraits) assert.NotNil(t, environment.GetTrait("route")) @@ -499,8 +500,8 @@ func TestRoute_TLS_passthrough(t *testing.T) { }, } conditions, err := traitsCatalog.apply(environment) - assert.Nil(t, err) - assert.Empty(t, conditions) + require.NoError(t, err) + assert.NotEmpty(t, conditions) assert.NotEmpty(t, environment.ExecutedTraits) assert.NotNil(t, environment.GetTrait("route")) @@ -529,8 +530,8 @@ func TestRoute_WithCustomServicePort(t *testing.T) { traitsCatalog := environment.Catalog conditions, err := traitsCatalog.apply(environment) - assert.Nil(t, err) - assert.Empty(t, conditions) + require.NoError(t, err) + assert.NotEmpty(t, conditions) assert.NotEmpty(t, environment.ExecutedTraits) assert.NotNil(t, environment.GetTrait("container")) assert.NotNil(t, environment.GetTrait("route")) @@ -563,8 +564,8 @@ func TestRouteAnnotation(t *testing.T) { traitsCatalog := environment.Catalog conditions, err := traitsCatalog.apply(environment) - assert.Nil(t, err) - assert.Empty(t, conditions) + require.NoError(t, err) + assert.NotEmpty(t, conditions) route := environment.Resources.GetRoute(func(r *routev1.Route) bool { return r.ObjectMeta.Name == name diff --git a/pkg/trait/service.go b/pkg/trait/service.go index 1bcb499e52..b2e081ab2b 100644 --- a/pkg/trait/service.go +++ b/pkg/trait/service.go @@ -49,6 +49,7 @@ func (t *serviceTrait) Configure(e *Environment) (bool, *TraitCondition, error) } if !pointer.BoolDeref(t.Enabled, true) { return false, NewIntegrationCondition( + "Service", v1.IntegrationConditionServiceAvailable, corev1.ConditionFalse, v1.IntegrationConditionServiceNotAvailableReason, @@ -61,7 +62,7 @@ func (t *serviceTrait) Configure(e *Environment) (bool, *TraitCondition, error) if e.GetTrait(knativeServiceTraitID) != nil { knativeServiceTrait, _ := e.GetTrait(knativeServiceTraitID).(*knativeServiceTrait) if pointer.BoolDeref(knativeServiceTrait.Enabled, true) { - return false, newIntegrationConditionPlatformDisabledWithMessage("knative-service trait has priority over this trait"), nil + return false, newIntegrationConditionPlatformDisabledWithMessage("Service", "knative-service trait has priority over this trait"), nil } } @@ -74,6 +75,7 @@ func (t *serviceTrait) Configure(e *Environment) (bool, *TraitCondition, error) var condition *TraitCondition if err != nil { condition = NewIntegrationCondition( + "Service", v1.IntegrationConditionServiceAvailable, corev1.ConditionFalse, v1.IntegrationConditionServiceNotAvailableReason, diff --git a/pkg/trait/service_binding.go b/pkg/trait/service_binding.go index 2bb1758ee4..5921499af6 100644 --- a/pkg/trait/service_binding.go +++ b/pkg/trait/service_binding.go @@ -68,7 +68,7 @@ func (t *serviceBindingTrait) Configure(e *Environment) (bool, *TraitCondition, return false, nil, nil } if !pointer.BoolDeref(t.Enabled, true) { - return false, NewIntegrationConditionUserDisabled(), nil + return false, NewIntegrationConditionUserDisabled("ServiceBinding"), nil } if len(t.Services) == 0 { return false, nil, nil diff --git a/pkg/trait/service_binding_test.go b/pkg/trait/service_binding_test.go index c80f22b5bf..c62bec13ac 100644 --- a/pkg/trait/service_binding_test.go +++ b/pkg/trait/service_binding_test.go @@ -22,6 +22,7 @@ import ( "github.com/redhat-developer/service-binding-operator/pkg/reconcile/pipeline" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" "github.com/apache/camel-k/v2/pkg/util/camel" @@ -36,13 +37,13 @@ func TestServiceBinding(t *testing.T) { configured, condition, err := sbTrait.Configure(environment) assert.True(t, configured) - assert.Nil(t, err) + require.NoError(t, err) assert.Nil(t, condition) // Required for local testing purposes only handlers = []pipeline.Handler{} err = sbTrait.Apply(environment) - assert.Nil(t, err) + require.NoError(t, err) // TODO we should make the service binding trait to easily work with fake client // and test the apply result in the environment accordingly. } diff --git a/pkg/trait/service_test.go b/pkg/trait/service_test.go index debe27434e..1769110f96 100644 --- a/pkg/trait/service_test.go +++ b/pkg/trait/service_test.go @@ -21,6 +21,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" @@ -42,13 +43,13 @@ const ( func TestServiceWithDefaults(t *testing.T) { catalog, err := camel.DefaultCatalog() - assert.Nil(t, err) + require.NoError(t, err) client, _ := test.NewFakeClient() traitCatalog := NewCatalog(nil) compressedRoute, err := gzip.CompressBase64([]byte(`from("netty-http:test").log("hello")`)) - assert.NoError(t, err) + require.NoError(t, err) environment := Environment{ CamelCatalog: catalog, @@ -108,10 +109,9 @@ func TestServiceWithDefaults(t *testing.T) { } environment.Platform.ResyncStatusFullConfig() - conditions, err := traitCatalog.apply(&environment) + _, err = traitCatalog.apply(&environment) - assert.Nil(t, err) - assert.Empty(t, conditions) + require.NoError(t, err) assert.NotEmpty(t, environment.ExecutedTraits) assert.NotNil(t, environment.GetTrait("deployment")) assert.NotNil(t, environment.GetTrait("service")) @@ -142,13 +142,13 @@ func TestServiceWithDefaults(t *testing.T) { func TestService(t *testing.T) { catalog, err := camel.DefaultCatalog() - assert.Nil(t, err) + require.NoError(t, err) client, _ := test.NewFakeClient() traitCatalog := NewCatalog(nil) compressedRoute, err := gzip.CompressBase64([]byte(`from("netty-http:test").log("hello")`)) - assert.NoError(t, err) + require.NoError(t, err) environment := Environment{ CamelCatalog: catalog, @@ -216,10 +216,9 @@ func TestService(t *testing.T) { } environment.Platform.ResyncStatusFullConfig() - conditions, err := traitCatalog.apply(&environment) + _, err = traitCatalog.apply(&environment) - assert.Nil(t, err) - assert.Empty(t, conditions) + require.NoError(t, err) assert.NotEmpty(t, environment.ExecutedTraits) assert.NotNil(t, environment.GetTrait("deployment")) assert.NotNil(t, environment.GetTrait("service")) @@ -248,7 +247,7 @@ func TestService(t *testing.T) { func TestServiceWithCustomContainerName(t *testing.T) { catalog, err := camel.DefaultCatalog() - assert.Nil(t, err) + require.NoError(t, err) client, _ := test.NewFakeClient() traitCatalog := NewCatalog(nil) @@ -304,10 +303,9 @@ func TestServiceWithCustomContainerName(t *testing.T) { } environment.Platform.ResyncStatusFullConfig() - conditions, err := traitCatalog.apply(&environment) + _, err = traitCatalog.apply(&environment) - assert.Nil(t, err) - assert.Empty(t, conditions) + require.NoError(t, err) assert.NotEmpty(t, environment.ExecutedTraits) assert.NotNil(t, environment.GetTrait("deployment")) assert.NotNil(t, environment.GetTrait("service")) @@ -328,13 +326,13 @@ func TestServiceWithCustomContainerName(t *testing.T) { func TestServiceWithNodePort(t *testing.T) { catalog, err := camel.DefaultCatalog() - assert.Nil(t, err) + require.NoError(t, err) client, _ := test.NewFakeClient() traitCatalog := NewCatalog(nil) compressedRoute, err := gzip.CompressBase64([]byte(`from("netty-http:test").log("hello")`)) - assert.NoError(t, err) + require.NoError(t, err) serviceType := traitv1.ServiceTypeNodePort environment := Environment{ @@ -396,10 +394,9 @@ func TestServiceWithNodePort(t *testing.T) { } environment.Platform.ResyncStatusFullConfig() - conditions, err := traitCatalog.apply(&environment) + _, err = traitCatalog.apply(&environment) - assert.Nil(t, err) - assert.Empty(t, conditions) + require.NoError(t, err) assert.NotEmpty(t, environment.ExecutedTraits) assert.NotNil(t, environment.GetTrait("deployment")) assert.NotNil(t, environment.GetTrait("service")) @@ -425,13 +422,13 @@ func TestServiceWithNodePort(t *testing.T) { // knative-service has the priority and the k8s service is not run. func TestServiceWithKnativeServiceEnabled(t *testing.T) { catalog, err := camel.DefaultCatalog() - assert.Nil(t, err) + require.NoError(t, err) client, _ := test.NewFakeClient() traitCatalog := NewCatalog(nil) compressedRoute, err := gzip.CompressBase64([]byte(`from("netty-http:test").log("hello")`)) - assert.NoError(t, err) + require.NoError(t, err) environment := Environment{ CamelCatalog: catalog, @@ -492,21 +489,22 @@ func TestServiceWithKnativeServiceEnabled(t *testing.T) { environment.Platform.ResyncStatusFullConfig() deploymentCondition := NewIntegrationCondition( + "Deployment", v1.IntegrationConditionDeploymentAvailable, corev1.ConditionFalse, - "deploymentTraitConfiguration", + "DeploymentAvailable", "controller strategy: knative-service", ) serviceCondition := NewIntegrationCondition( + "Service", v1.IntegrationConditionTraitInfo, corev1.ConditionTrue, - "serviceTraitConfiguration", + "TraitConfiguration", "explicitly disabled by the platform: knative-service trait has priority over this trait", ) conditions, err := traitCatalog.apply(&environment) - assert.Nil(t, err) - assert.Len(t, conditions, 2) + require.NoError(t, err) assert.Contains(t, conditions, deploymentCondition) assert.Contains(t, conditions, serviceCondition) assert.NotEmpty(t, environment.ExecutedTraits) @@ -516,13 +514,13 @@ func TestServiceWithKnativeServiceEnabled(t *testing.T) { func TestServicesWithKnativeProfile(t *testing.T) { catalog, err := camel.DefaultCatalog() - assert.Nil(t, err) + require.NoError(t, err) client, _ := test.NewFakeClient() traitCatalog := NewCatalog(nil) compressedRoute, err := gzip.CompressBase64([]byte(`from("netty-http:test").log("hello")`)) - assert.NoError(t, err) + require.NoError(t, err) environment := Environment{ CamelCatalog: catalog, @@ -570,21 +568,22 @@ func TestServicesWithKnativeProfile(t *testing.T) { environment.Platform.ResyncStatusFullConfig() deploymentCondition := NewIntegrationCondition( + "Deployment", v1.IntegrationConditionDeploymentAvailable, corev1.ConditionFalse, - "deploymentTraitConfiguration", + "DeploymentAvailable", "controller strategy: knative-service", ) serviceCondition := NewIntegrationCondition( + "Service", v1.IntegrationConditionTraitInfo, corev1.ConditionTrue, - "serviceTraitConfiguration", + "TraitConfiguration", "explicitly disabled by the platform: knative-service trait has priority over this trait", ) conditions, err := traitCatalog.apply(&environment) - assert.Nil(t, err) - assert.Len(t, conditions, 2) + require.NoError(t, err) assert.Contains(t, conditions, deploymentCondition) assert.Contains(t, conditions, serviceCondition) assert.NotEmpty(t, environment.ExecutedTraits) @@ -595,13 +594,13 @@ func TestServicesWithKnativeProfile(t *testing.T) { // When the knative-service is disabled at the IntegrationPlatform, the k8s service is enabled. func TestServiceWithKnativeServiceDisabledInIntegrationPlatform(t *testing.T) { catalog, err := camel.DefaultCatalog() - assert.Nil(t, err) + require.NoError(t, err) client, _ := test.NewFakeClient() traitCatalog := NewCatalog(nil) compressedRoute, err := gzip.CompressBase64([]byte(`from("netty-http:test").log("hello")`)) - assert.NoError(t, err) + require.NoError(t, err) environment := Environment{ CamelCatalog: catalog, @@ -656,15 +655,15 @@ func TestServiceWithKnativeServiceDisabledInIntegrationPlatform(t *testing.T) { environment.Platform.ResyncStatusFullConfig() expectedCondition := NewIntegrationCondition( + "KnativeService", v1.IntegrationConditionKnativeServiceAvailable, corev1.ConditionFalse, - "knative-serviceTraitConfiguration", + "KnativeServiceNotAvailable", "explicitly disabled", ) conditions, err := traitCatalog.apply(&environment) - assert.Nil(t, err) - assert.Len(t, conditions, 1) + require.NoError(t, err) assert.Contains(t, conditions, expectedCondition) assert.NotEmpty(t, environment.ExecutedTraits) assert.NotNil(t, environment.GetTrait(serviceTraitID)) diff --git a/pkg/trait/test_support.go b/pkg/trait/test_support.go index cec5ea0f69..32c14c8dda 100644 --- a/pkg/trait/test_support.go +++ b/pkg/trait/test_support.go @@ -31,7 +31,6 @@ import ( v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" "github.com/apache/camel-k/v2/pkg/util/kubernetes" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -140,11 +139,11 @@ func ToAddonTrait(t *testing.T, config map[string]interface{}) v1.AddonTrait { t.Helper() data, err := json.Marshal(config) - assert.NoError(t, err) + require.NoError(t, err) var addon v1.AddonTrait err = json.Unmarshal(data, &addon) - assert.NoError(t, err) + require.NoError(t, err) return addon } diff --git a/pkg/trait/toleration_test.go b/pkg/trait/toleration_test.go index 48b472113d..184a671cf8 100644 --- a/pkg/trait/toleration_test.go +++ b/pkg/trait/toleration_test.go @@ -21,6 +21,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" "k8s.io/utils/pointer" @@ -32,8 +33,8 @@ func TestConfigureTolerationTraitMissingTaint(t *testing.T) { success, condition, err := tolerationTrait.Configure(environment) - assert.Equal(t, false, success) - assert.NotNil(t, err) + assert.False(t, success) + require.Error(t, err) assert.Nil(t, condition) } @@ -44,7 +45,7 @@ func TestApplyTolerationTraitMalformedTaint(t *testing.T) { err := tolerationTrait.Apply(environment) - assert.NotNil(t, err) + require.Error(t, err) } func TestApplyPodTolerationMissingDeployment(t *testing.T) { @@ -54,7 +55,7 @@ func TestApplyPodTolerationMissingDeployment(t *testing.T) { environment := createNominalMissingDeploymentTraitTest() err := tolerationTrait.Apply(environment) - assert.NotNil(t, err) + require.Error(t, err) } func TestApplyPodTolerationLabelsDefault(t *testing.T) { @@ -76,7 +77,7 @@ func testApplyPodTolerationLabelsDefault(t *testing.T, trait *tolerationTrait, e err := trait.Apply(environment) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, 1, len(*tolerations)) toleration := (*tolerations)[0] assert.Equal(t, "my-toleration", toleration.Key) @@ -104,7 +105,7 @@ func testApplyPodTolerationLabelsTolerationSeconds(t *testing.T, trait *tolerati err := trait.Apply(environment) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, 1, len(*tolerations)) toleration := (*tolerations)[0] assert.Equal(t, "my-toleration", toleration.Key) @@ -127,7 +128,7 @@ func TestTolerationValidTaints(t *testing.T) { err := tolerationTrait.Apply(environment) - assert.Nil(t, err) + require.NoError(t, err) } func createNominalTolerationTrait() *tolerationTrait { diff --git a/pkg/trait/trait.go b/pkg/trait/trait.go index 4ac35aa147..48e45b4d03 100644 --- a/pkg/trait/trait.go +++ b/pkg/trait/trait.go @@ -85,14 +85,8 @@ func Apply(ctx context.Context, c client.Client, integration *v1.Integration, ki switch { case integration != nil: ilog.Debug("Applied traits to Integration", "integration", integration.Name, "namespace", integration.Namespace) - // The spec.traits may have been altered by other traits execution. We can save here the status for future - // reference - integration.Status.Traits = integration.Spec.Traits case kit != nil: ilog.Debug("Applied traits to Integration kit", "integration kit", kit.Name, "namespace", kit.Namespace) - // The spec.traits may have been altered by other traits execution We can save here the status for future - // reference - kit.Status.Traits = kit.Spec.Traits default: ilog.Debug("Applied traits") } diff --git a/pkg/trait/trait_catalog.go b/pkg/trait/trait_catalog.go index 3169f563c9..867c758143 100644 --- a/pkg/trait/trait_catalog.go +++ b/pkg/trait/trait_catalog.go @@ -26,6 +26,7 @@ import ( v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" "github.com/apache/camel-k/v2/pkg/client" "github.com/apache/camel-k/v2/pkg/util/log" + corev1 "k8s.io/api/core/v1" ) // Catalog collects all information about traits in one place. @@ -103,7 +104,6 @@ func (c *Catalog) apply(environment *Environment) ([]*TraitCondition, error) { applicable = true enabled, condition, err := trait.Configure(environment) if condition != nil { - condition.reason = fmt.Sprintf("%sTraitConfiguration", trait.ID()) traitsConditions = append(traitsConditions, condition) } if err != nil { @@ -115,9 +115,7 @@ func (c *Catalog) apply(environment *Environment) ([]*TraitCondition, error) { if err != nil { return traitsConditions, fmt.Errorf("%s trait execution failed: %w", trait.ID(), err) } - environment.ExecutedTraits = append(environment.ExecutedTraits, trait) - // execute post step processors for _, processor := range environment.PostStepProcessors { err := processor(environment) @@ -127,12 +125,7 @@ func (c *Catalog) apply(environment *Environment) ([]*TraitCondition, error) { } } } - - traitIds := make([]string, 0) - for _, trait := range environment.ExecutedTraits { - traitIds = append(traitIds, string(trait.ID())) - } - c.L.Debugf("Applied traits: %s", strings.Join(traitIds, ",")) + traitsConditions = append(traitsConditions, c.executedTraitCondition(environment.ExecutedTraits)) if !applicable && environment.PlatformInPhase(v1.IntegrationPlatformPhaseReady) { return traitsConditions, errors.New("no trait can be executed because of no ready platform found") @@ -148,6 +141,17 @@ func (c *Catalog) apply(environment *Environment) ([]*TraitCondition, error) { return traitsConditions, nil } +func (c *Catalog) executedTraitCondition(executedTrait []Trait) *TraitCondition { + traitIds := make([]string, 0) + for _, trait := range executedTrait { + traitIds = append(traitIds, string(trait.ID())) + } + message := fmt.Sprintf("Applied traits: %s", strings.Join(traitIds, ",")) + c.L.Debugf(message) + + return NewIntegrationCondition("", v1.IntegrationConditionTraitInfo, corev1.ConditionTrue, traitConfigurationReason, message) +} + // GetTrait returns the trait with the given ID. func (c *Catalog) GetTrait(id string) Trait { for _, t := range c.AllTraits() { diff --git a/pkg/trait/trait_condition_types.go b/pkg/trait/trait_condition_types.go index 05f9ac4a40..2f245ea8ea 100644 --- a/pkg/trait/trait_condition_types.go +++ b/pkg/trait/trait_condition_types.go @@ -35,6 +35,7 @@ const ( // TraitCondition is used to get all information/warning about a trait configuration. // It should either use an IntegrationConditionType or IntegrationKitConditionType. type TraitCondition struct { + traitID string integrationConditionType v1.IntegrationConditionType integrationKitConditionType v1.IntegrationKitConditionType conditionStatus corev1.ConditionStatus @@ -42,8 +43,9 @@ type TraitCondition struct { reason string } -func NewIntegrationCondition(ict v1.IntegrationConditionType, cs corev1.ConditionStatus, reason, message string) *TraitCondition { +func NewIntegrationCondition(traitID string, ict v1.IntegrationConditionType, cs corev1.ConditionStatus, reason, message string) *TraitCondition { return &TraitCondition{ + traitID: traitID, integrationConditionType: ict, conditionStatus: cs, reason: reason, @@ -51,22 +53,28 @@ func NewIntegrationCondition(ict v1.IntegrationConditionType, cs corev1.Conditio } } -func NewIntegrationConditionUserDisabled() *TraitCondition { - return NewIntegrationCondition(v1.IntegrationConditionTraitInfo, corev1.ConditionTrue, traitConfigurationReason, userDisabledMessage) +func NewIntegrationConditionUserDisabled(traitID string) *TraitCondition { + return NewIntegrationCondition(traitID, v1.IntegrationConditionTraitInfo, corev1.ConditionTrue, traitConfigurationReason, userDisabledMessage) } -func NewIntegrationConditionUserEnabledWithMessage(message string) *TraitCondition { - return NewIntegrationCondition(v1.IntegrationConditionTraitInfo, corev1.ConditionTrue, traitConfigurationReason, fmt.Sprintf("%s: %s", userEnabledMessage, message)) +func NewIntegrationConditionUserEnabledWithMessage(traitID string, message string) *TraitCondition { + return NewIntegrationCondition(traitID, v1.IntegrationConditionTraitInfo, corev1.ConditionTrue, traitConfigurationReason, fmt.Sprintf("%s: %s", userEnabledMessage, message)) } -func newIntegrationConditionPlatformDisabledWithMessage(message string) *TraitCondition { - return NewIntegrationCondition(v1.IntegrationConditionTraitInfo, corev1.ConditionTrue, traitConfigurationReason, fmt.Sprintf("%s: %s", platformDisabledMessage, message)) +func newIntegrationConditionPlatformDisabledWithMessage(traitID string, message string) *TraitCondition { + return NewIntegrationCondition(traitID, v1.IntegrationConditionTraitInfo, corev1.ConditionTrue, traitConfigurationReason, fmt.Sprintf("%s: %s", platformDisabledMessage, message)) } func (tc *TraitCondition) integrationCondition() (v1.IntegrationConditionType, corev1.ConditionStatus, string, string) { - return tc.integrationConditionType, tc.conditionStatus, tc.reason, tc.message + return v1.IntegrationConditionType(fmt.Sprintf("%s%s", tc.traitID, tc.integrationConditionType)), + tc.conditionStatus, + tc.reason, + tc.message } func (tc *TraitCondition) integrationKitCondition() (v1.IntegrationKitConditionType, corev1.ConditionStatus, string, string) { - return tc.integrationKitConditionType, tc.conditionStatus, tc.reason, tc.message + return v1.IntegrationKitConditionType(fmt.Sprintf("%s%s", tc.traitID, tc.integrationKitConditionType)), + tc.conditionStatus, + tc.reason, + tc.message } diff --git a/pkg/trait/trait_configure_test.go b/pkg/trait/trait_configure_test.go index 18b410a269..eaac55f5bf 100644 --- a/pkg/trait/trait_configure_test.go +++ b/pkg/trait/trait_configure_test.go @@ -52,7 +52,7 @@ func TestTraitConfiguration(t *testing.T) { }, } c := NewCatalog(nil) - assert.NoError(t, c.Configure(&env)) + require.NoError(t, c.Configure(&env)) logging, ok := c.GetTrait("logging").(*loggingTrait) require.True(t, ok) assert.True(t, *logging.JSON) @@ -85,7 +85,7 @@ func TestTraitConfigurationFromAnnotations(t *testing.T) { }, } c := NewCatalog(nil) - assert.NoError(t, c.Configure(&env)) + require.NoError(t, c.Configure(&env)) ct, _ := c.GetTrait("cron").(*cronTrait) assert.True(t, *ct.Fallback) assert.Equal(t, "annotated-policy", ct.ConcurrencyPolicy) @@ -163,7 +163,7 @@ func TestTraitConfigurationOverrideRulesFromAnnotations(t *testing.T) { }, } c := NewCatalog(nil) - assert.NoError(t, c.Configure(&env)) + require.NoError(t, c.Configure(&env)) ct, _ := c.GetTrait("cron").(*cronTrait) assert.Equal(t, "schedule2", ct.Schedule) assert.Equal(t, "cmp4", ct.Components) @@ -187,7 +187,7 @@ func TestTraitListConfigurationFromAnnotations(t *testing.T) { }, } c := NewCatalog(nil) - assert.NoError(t, c.Configure(&env)) + require.NoError(t, c.Configure(&env)) jt, _ := c.GetTrait("jolokia").(*jolokiaTrait) assert.Equal(t, []string{"opt1", "opt2"}, jt.Options) sbt, _ := c.GetTrait("service-binding").(*serviceBindingTrait) @@ -208,7 +208,7 @@ func TestTraitSplitConfiguration(t *testing.T) { }, } c := NewCatalog(nil) - assert.NoError(t, c.Configure(&env)) + require.NoError(t, c.Configure(&env)) ot, _ := c.GetTrait("owner").(*ownerTrait) assert.Equal(t, []string{"opt1", "opt2"}, ot.TargetLabels) } @@ -228,5 +228,5 @@ func TestTraitDecode(t *testing.T) { assert.Equal(t, "test-container", target.Name) assert.Equal(t, 7071, target.Port) - assert.Equal(t, false, pointer.BoolDeref(target.Auto, true)) + assert.False(t, pointer.BoolDeref(target.Auto, true)) } diff --git a/pkg/trait/trait_test.go b/pkg/trait/trait_test.go index 1acb07f5ae..db1dc7cf85 100644 --- a/pkg/trait/trait_test.go +++ b/pkg/trait/trait_test.go @@ -22,6 +22,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" routev1 "github.com/openshift/api/route/v1" @@ -161,7 +162,7 @@ func TestTraitHierarchyDecode(t *testing.T) { c := NewTraitTestCatalog() err := c.Configure(env) - assert.Nil(t, err) + require.NoError(t, err) knt := c.GetTrait("knative-service") assert.NotNil(t, knt) @@ -486,7 +487,7 @@ func processTestEnv(t *testing.T, env *Environment) *kubernetes.Collection { catalog := NewTraitTestCatalog() _, err := catalog.apply(env) - assert.Nil(t, err) + require.NoError(t, err) return env.Resources } @@ -495,7 +496,7 @@ func createTestEnv(t *testing.T, cluster v1.IntegrationPlatformCluster, script s client, _ := test.NewFakeClient() catalog, err := camel.DefaultCatalog() - assert.Nil(t, err) + require.NoError(t, err) res := &Environment{ CamelCatalog: catalog, @@ -548,3 +549,19 @@ func createTestEnv(t *testing.T, cluster v1.IntegrationPlatformCluster, script s func NewTraitTestCatalog() *Catalog { return NewCatalog(nil) } + +func TestExecutedTraitsCondition(t *testing.T) { + env := createTestEnv(t, v1.IntegrationPlatformClusterOpenShift, "camel:core") + catalog := NewTraitTestCatalog() + conditions, err := catalog.apply(env) + require.NoError(t, err) + + expectedCondition := NewIntegrationCondition( + "", + v1.IntegrationConditionTraitInfo, + corev1.ConditionTrue, + "TraitConfiguration", + "Applied traits: camel,environment,logging,deployer,deployment,gc,container,mount,quarkus,jvm,owner", + ) + assert.Contains(t, conditions, expectedCondition) +} diff --git a/pkg/trait/trait_types.go b/pkg/trait/trait_types.go index b2e2ba7f9c..46690b28b2 100644 --- a/pkg/trait/trait_types.go +++ b/pkg/trait/trait_types.go @@ -22,6 +22,7 @@ import ( "fmt" "path" "path/filepath" + "regexp" "sort" "strings" @@ -51,6 +52,8 @@ const ( sourceCompressionAnnotation = "camel.apache.org/source.compression" ) +var capabilityDynamicProperty = regexp.MustCompile(`(\$\{([^}]*)\})`) + // Identifiable represent an identifiable type. type Identifiable interface { ID() ID @@ -73,11 +76,6 @@ type Trait interface { // InfluencesKit determines if the trait has any influence on Integration Kits InfluencesKit() bool - // InfluencesBuild defines a low level of granularity for those traits which influences the build. - // The trait can specify if any particular trait configuration influences a build or not. - // Note: You must override this method if you override `InfluencesKit()` - InfluencesBuild(this, prev map[string]interface{}) bool - // IsPlatformTrait marks all fundamental traits that allow the platform to work IsPlatformTrait() bool @@ -85,16 +83,18 @@ type Trait interface { RequiresIntegrationPlatform() bool // IsAllowedInProfile tells if the trait supports the given profile - IsAllowedInProfile(v1.TraitProfile) bool + IsAllowedInProfile(traitProfile v1.TraitProfile) bool // Order is the order in which the trait should be executed in the normal flow Order() int } +// Comparable is the interface exposing comparable funcs. type Comparable interface { - Matches(Trait) bool + Matches(trait Trait) bool } +// ComparableTrait is the interface used to compare two traits between them. type ComparableTrait interface { Trait Comparable @@ -154,12 +154,6 @@ func (trait *BaseTrait) InfluencesKit() bool { return false } -// InfluencesBuild defines a low level of granularity for those traits which influences the build. -// The trait can specify if any particular trait configuration influences a build or not. -func (trait *BaseTrait) InfluencesBuild(this, prev map[string]interface{}) bool { - return false -} - // IsPlatformTrait marks all fundamental traits that allow the platform to work. func (trait *BaseTrait) IsPlatformTrait() bool { return false @@ -194,7 +188,7 @@ func (trait *BasePlatformTrait) IsPlatformTrait() bool { // ControllerStrategySelector is the interface for traits that can determine the kind of controller that will run the integration. type ControllerStrategySelector interface { // SelectControllerStrategy tells if the trait with current configuration can select a specific controller to use - SelectControllerStrategy(*Environment) (*ControllerStrategy, error) + SelectControllerStrategy(env *Environment) (*ControllerStrategy, error) // ControllerStrategySelectorOrder returns the order (priority) of the controller strategy selector ControllerStrategySelectorOrder() int } @@ -736,3 +730,17 @@ func (e *Environment) getIntegrationContainerPort() *corev1.ContainerPort { return nil } + +// CapabilityPropertyKey returns the key or expand any variable provided in it. vars variable contain the +// possible dynamic values to use. +func CapabilityPropertyKey(camelPropertyKey string, vars map[string]string) string { + if capabilityDynamicProperty.MatchString(camelPropertyKey) && vars != nil { + match := capabilityDynamicProperty.FindStringSubmatch(camelPropertyKey) + if len(match) < 2 { + // Should not happen, but fallback to the key not expanded instead of panic if it comes to happen + return camelPropertyKey + } + return strings.ReplaceAll(camelPropertyKey, match[1], vars[match[2]]) + } + return camelPropertyKey +} diff --git a/pkg/trait/trait_types_test.go b/pkg/trait/trait_types_test.go index 6ea8ea9a0d..978487b741 100644 --- a/pkg/trait/trait_types_test.go +++ b/pkg/trait/trait_types_test.go @@ -21,6 +21,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" ) @@ -33,7 +34,7 @@ func TestMultilinePropertiesHandled(t *testing.T) { Integration: &v1.Integration{}, } cm, err := e.computeApplicationProperties() - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, cm) assert.Equal(t, "prop = multi\\nline\n", cm.Data["application.properties"]) } @@ -153,3 +154,13 @@ func TestVolumeWithKeyOnly(t *testing.T) { assert.Equal(t, "SomeKey", items[0].Key) assert.Equal(t, "SomeKey", items[0].Path) } + +func TestCapabilityPropertyKey(t *testing.T) { + camelPropertyKeyStatic := CapabilityPropertyKey("quarkus.camel.cluster.kubernetes.resource-name", nil) + assert.Equal(t, "quarkus.camel.cluster.kubernetes.resource-name", camelPropertyKeyStatic) + vars := map[string]string{ + "camel.k.master.labelKey": "org.apache.camel/integration", + } + camelPropertyKeyDynamic := CapabilityPropertyKey(`quarkus.camel.cluster.kubernetes.labels."${camel.k.master.labelKey}"`, vars) + assert.Equal(t, `quarkus.camel.cluster.kubernetes.labels."org.apache.camel/integration"`, camelPropertyKeyDynamic) +} diff --git a/pkg/trait/util.go b/pkg/trait/util.go index 19089baac3..374d90e48b 100644 --- a/pkg/trait/util.go +++ b/pkg/trait/util.go @@ -492,10 +492,6 @@ func newTraitsOptionsForIntegrationKit(i *v1.IntegrationKit, traits v1.Integrati return newTraitsOptions(m1, &i.ObjectMeta) } -func NewStatusTraitsOptionsForIntegrationKit(i *v1.IntegrationKit) (Options, error) { - return newTraitsOptionsForIntegrationKit(i, i.Status.Traits) -} - func NewSpecTraitsOptionsForIntegrationKit(i *v1.IntegrationKit) (Options, error) { return newTraitsOptionsForIntegrationKit(i, i.Spec.Traits) } @@ -537,7 +533,6 @@ func NewTraitsOptionsForKameletBinding(kb *v1alpha1.KameletBinding) (Options, er func FromAnnotations(meta *metav1.ObjectMeta) (Options, error) { options := make(Options) - for k, v := range meta.Annotations { if strings.HasPrefix(k, v1.TraitAnnotationPrefix) { configKey := strings.TrimPrefix(k, v1.TraitAnnotationPrefix) @@ -548,22 +543,7 @@ func FromAnnotations(meta *metav1.ObjectMeta) (Options, error) { if _, ok := options[id]; !ok { options[id] = make(map[string]interface{}) } - - propParts := util.ConfigTreePropertySplit(prop) - var current = options[id] - if len(propParts) > 1 { - c, err := util.NavigateConfigTree(current, propParts[0:len(propParts)-1]) - if err != nil { - return options, err - } - if cc, ok := c.(map[string]interface{}); ok { - current = cc - } else { - return options, errors.New(`invalid array specification: to set an array value use the ["v1", "v2"] format`) - } - } - current[prop] = v - + options[id][prop] = stringOrSlice(v) } else { return options, fmt.Errorf("wrong format for trait annotation %q: missing trait ID", k) } @@ -573,6 +553,24 @@ func FromAnnotations(meta *metav1.ObjectMeta) (Options, error) { return options, nil } +// stringOrSlice returns either a string or a slice with trimmed values when the input is +// represented as an array style (ie, [a,b,c]). +func stringOrSlice(val string) interface{} { + if val == "[]" { + // empty array + return []string{} + } + if strings.HasPrefix(val, "[") && strings.HasSuffix(val, "]") { + slice := strings.Split(val[1:len(val)-1], ",") + for i := range slice { + slice[i] = strings.Trim(slice[i], " ") + } + return slice + } else { + return val + } +} + // verify if the integration in the Environment contains an endpoint. func containsEndpoint(name string, e *Environment, c client.Client) (bool, error) { sources, err := kubernetes.ResolveIntegrationSources(e.Ctx, c, e.Integration, e.Resources) @@ -597,3 +595,56 @@ func containsEndpoint(name string, e *Environment, c client.Client) (bool, error } return hasKnativeEndpoint, nil } + +// HasMatchingTraits verifies if two traits options match. +func HasMatchingTraits(traitMap Options, kitTraitMap Options) (bool, error) { + catalog := NewCatalog(nil) + + for _, t := range catalog.AllTraits() { + if t == nil || !t.InfluencesKit() { + // We don't store the trait configuration if the trait cannot influence the kit behavior + continue + } + id := string(t.ID()) + it, _ := traitMap.Get(id) + kt, _ := kitTraitMap.Get(id) + if ct, ok := t.(ComparableTrait); ok { + // if it's match trait use its matches method to determine the match + if match, err := matchesComparableTrait(ct, it, kt); !match || err != nil { + return false, err + } + } else { + if !matchesTrait(it, kt) { + return false, nil + } + } + } + + return true, nil +} + +func matchesComparableTrait(ct ComparableTrait, it map[string]interface{}, kt map[string]interface{}) (bool, error) { + t1 := reflect.New(reflect.TypeOf(ct).Elem()).Interface() + if err := ToTrait(it, &t1); err != nil { + return false, err + } + t2 := reflect.New(reflect.TypeOf(ct).Elem()).Interface() + if err := ToTrait(kt, &t2); err != nil { + return false, err + } + ct2, ok := t2.(ComparableTrait) + if !ok { + return false, fmt.Errorf("type assertion failed: %v", t2) + } + tt1, ok := t1.(Trait) + if !ok { + return false, fmt.Errorf("type assertion failed: %v", t1) + } + + return ct2.Matches(tt1), nil +} + +func matchesTrait(it map[string]interface{}, kt map[string]interface{}) bool { + // perform exact match on the two trait maps + return reflect.DeepEqual(it, kt) +} diff --git a/pkg/trait/util_test.go b/pkg/trait/util_test.go index aeaffa0379..d89262bbf9 100644 --- a/pkg/trait/util_test.go +++ b/pkg/trait/util_test.go @@ -27,6 +27,7 @@ import ( traitv1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1/trait" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestToTraitMap(t *testing.T) { @@ -74,7 +75,7 @@ func TestToTraitMap(t *testing.T) { traitMap, err := ToTraitMap(traits) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, expected, traitMap) } @@ -101,7 +102,7 @@ func TestToPropertyMap(t *testing.T) { propMap, err := ToPropertyMap(trait) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, expected, propMap) } @@ -129,7 +130,7 @@ func TestMigrateLegacyConfiguration(t *testing.T) { err := MigrateLegacyConfiguration(trait) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, expected, trait) } @@ -141,7 +142,7 @@ func TestMigrateLegacyConfiguration_invalidConfiguration(t *testing.T) { err := MigrateLegacyConfiguration(trait) - assert.Error(t, err) + require.Error(t, err) } func TestToTrait(t *testing.T) { @@ -168,7 +169,7 @@ func TestToTrait(t *testing.T) { trait := traitv1.ContainerTrait{} err := ToTrait(config, &trait) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, expected, trait) } @@ -190,7 +191,7 @@ func TestSameTraits(t *testing.T) { } ok, err := PipesHaveSameTraits(oldKlb, newKlb) - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, ok) }) @@ -219,7 +220,7 @@ func TestSameTraits(t *testing.T) { } ok, err := PipesHaveSameTraits(oldKlb, newKlb) - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, ok) }) @@ -248,7 +249,7 @@ func TestSameTraits(t *testing.T) { } ok, err := PipesHaveSameTraits(oldKlb, newKlb) - assert.NoError(t, err) + require.NoError(t, err) assert.False(t, ok) }) @@ -273,7 +274,7 @@ func TestSameTraits(t *testing.T) { } ok, err := PipesHaveSameTraits(oldKlb, newKlb) - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, ok) }) @@ -294,7 +295,7 @@ func TestSameTraits(t *testing.T) { } ok, err := PipesHaveSameTraits(oldKlb, newKlb) - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, ok) }) @@ -319,7 +320,7 @@ func TestSameTraits(t *testing.T) { } ok, err := PipesHaveSameTraits(oldKlb, newKlb) - assert.NoError(t, err) + require.NoError(t, err) assert.False(t, ok) }) @@ -340,7 +341,97 @@ func TestSameTraits(t *testing.T) { } ok, err := PipesHaveSameTraits(oldKlb, newKlb) - assert.NoError(t, err) + require.NoError(t, err) assert.False(t, ok) }) } + +func TestHasMathchingTraitsEmpty(t *testing.T) { + opt1 := Options{ + "builder": {}, + "camel": { + "runtimeVersion": "1.2.3", + }, + "quarkus": {}, + } + opt2 := Options{ + "camel": { + "runtimeVersion": "1.2.3", + }, + } + opt3 := Options{ + "camel": { + "runtimeVersion": "1.2.3", + }, + } + opt4 := Options{ + "camel": { + "runtimeVersion": "3.2.1", + }, + } + b1, err := HasMatchingTraits(opt1, opt2) + assert.Nil(t, err) + assert.True(t, b1) + b2, err := HasMatchingTraits(opt1, opt4) + assert.Nil(t, err) + assert.False(t, b2) + b3, err := HasMatchingTraits(opt2, opt3) + assert.Nil(t, err) + assert.True(t, b3) +} + +func TestHasMathchingTraitsMissing(t *testing.T) { + opt1 := Options{} + opt2 := Options{ + "camel": { + "properties": []string{"a=1"}, + }, + } + b1, err := HasMatchingTraits(opt1, opt2) + assert.Nil(t, err) + assert.True(t, b1) +} + +func TestFromAnnotationsPlain(t *testing.T) { + meta := metav1.ObjectMeta{ + Annotations: map[string]string{ + "trait.camel.apache.org/trait.prop1": "hello1", + "trait.camel.apache.org/trait.prop2": "hello2", + }, + } + opt, err := FromAnnotations(&meta) + require.NoError(t, err) + tt, ok := opt.Get("trait") + assert.True(t, ok) + assert.Equal(t, "hello1", tt["prop1"]) + assert.Equal(t, "hello2", tt["prop2"]) +} + +func TestFromAnnotationsArray(t *testing.T) { + meta := metav1.ObjectMeta{ + Annotations: map[string]string{ + "trait.camel.apache.org/trait.prop1": "[hello,world]", + // The func should trim empty spaces as well + "trait.camel.apache.org/trait.prop2": "[\"hello=1\", \"world=2\"]", + }, + } + opt, err := FromAnnotations(&meta) + require.NoError(t, err) + tt, ok := opt.Get("trait") + assert.True(t, ok) + assert.Equal(t, []string{"hello", "world"}, tt["prop1"]) + assert.Equal(t, []string{"\"hello=1\"", "\"world=2\""}, tt["prop2"]) +} + +func TestFromAnnotationsArrayEmpty(t *testing.T) { + meta := metav1.ObjectMeta{ + Annotations: map[string]string{ + "trait.camel.apache.org/trait.prop": "[]", + }, + } + opt, err := FromAnnotations(&meta) + require.NoError(t, err) + tt, ok := opt.Get("trait") + assert.True(t, ok) + assert.Equal(t, []string{}, tt["prop"]) +} diff --git a/pkg/util/bindings/bindings_test.go b/pkg/util/bindings/bindings_test.go index 49c9ee63cc..7cfa78c868 100644 --- a/pkg/util/bindings/bindings_test.go +++ b/pkg/util/bindings/bindings_test.go @@ -31,6 +31,7 @@ import ( "github.com/apache/camel-k/v2/pkg/util/test" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestBindings(t *testing.T) { @@ -212,7 +213,7 @@ func TestBindings(t *testing.T) { defer cancel() client, err := test.NewFakeClient() - assert.NoError(t, err) + require.NoError(t, err) profile := tc.profile if profile == "" { @@ -229,7 +230,7 @@ func TestBindings(t *testing.T) { binding, err := Translate(bindingContext, EndpointContext{ Type: tc.endpointType, }, tc.endpoint) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, binding) assert.Equal(t, tc.uri, binding.URI) assert.Equal(t, tc.traits, binding.Traits) diff --git a/pkg/util/bindings/catalog_test.go b/pkg/util/bindings/catalog_test.go index b2b59f4202..00c996749f 100644 --- a/pkg/util/bindings/catalog_test.go +++ b/pkg/util/bindings/catalog_test.go @@ -27,7 +27,7 @@ import ( eventing "knative.dev/eventing/pkg/apis/eventing/v1" "github.com/apache/camel-k/v2/pkg/util/test" - "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestValidateEndpoint(t *testing.T) { @@ -108,7 +108,7 @@ func TestValidateEndpoint(t *testing.T) { defer cancel() client, err := test.NewFakeClient() - assert.NoError(t, err) + require.NoError(t, err) bindingContext := BindingContext{ Ctx: ctx, @@ -118,7 +118,7 @@ func TestValidateEndpoint(t *testing.T) { } err = validateEndpoint(bindingContext, tc.endpoint) - assert.NoError(t, err) + require.NoError(t, err) }) } } @@ -181,7 +181,7 @@ func TestValidateEndpointError(t *testing.T) { defer cancel() client, err := test.NewFakeClient() - assert.NoError(t, err) + require.NoError(t, err) bindingContext := BindingContext{ Ctx: ctx, @@ -191,7 +191,7 @@ func TestValidateEndpointError(t *testing.T) { } err = validateEndpoint(bindingContext, tc.endpoint) - assert.Error(t, err, "cross-namespace references are not allowed in Pipe") + require.Error(t, err, "cross-namespace references are not allowed in Pipe") }) } } diff --git a/pkg/util/bindings/kamelet_test.go b/pkg/util/bindings/kamelet_test.go index d8826efdfa..848dccb6d2 100644 --- a/pkg/util/bindings/kamelet_test.go +++ b/pkg/util/bindings/kamelet_test.go @@ -28,6 +28,7 @@ import ( "github.com/apache/camel-k/v2/pkg/util/test" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestBindingConverter(t *testing.T) { @@ -81,7 +82,7 @@ func TestBindingConverter(t *testing.T) { defer cancel() client, err := test.NewFakeClient() - assert.NoError(t, err) + require.NoError(t, err) endpoint := v1.Endpoint{ Ref: &corev1.ObjectReference{ @@ -108,7 +109,7 @@ func TestBindingConverter(t *testing.T) { }, endpoint) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, binding) assert.Equal(t, tc.step, binding.Step) assert.Equal(t, tc.uri, binding.URI) @@ -116,7 +117,7 @@ func TestBindingConverter(t *testing.T) { if len(tc.applicationProperties) > 0 { assert.Equal(t, tc.applicationProperties, binding.ApplicationProperties) } else { - assert.True(t, len(binding.ApplicationProperties) == 0) + assert.Empty(t, binding.ApplicationProperties) } }) } @@ -243,7 +244,7 @@ func TestBindingConverterWithDataTypes(t *testing.T) { defer cancel() client, err := test.NewFakeClient() - assert.NoError(t, err) + require.NoError(t, err) endpoint := v1.Endpoint{ Ref: &corev1.ObjectReference{ @@ -286,7 +287,7 @@ func TestBindingConverterWithDataTypes(t *testing.T) { }, endpoint) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, binding) assert.Equal(t, tc.step, binding.Step) assert.Equal(t, tc.uri, binding.URI) @@ -294,7 +295,7 @@ func TestBindingConverterWithDataTypes(t *testing.T) { if len(tc.applicationProperties) > 0 { assert.Equal(t, tc.applicationProperties, binding.ApplicationProperties) } else { - assert.True(t, len(binding.ApplicationProperties) == 0) + assert.Empty(t, binding.ApplicationProperties) } }) } @@ -336,7 +337,7 @@ func TestBindingConverterWithDataTypesOverridden(t *testing.T) { defer cancel() client, err := test.NewFakeClient() - assert.NoError(t, err) + require.NoError(t, err) endpoint := v1.Endpoint{ Ref: &corev1.ObjectReference{ @@ -382,7 +383,7 @@ func TestBindingConverterWithDataTypesOverridden(t *testing.T) { }, endpoint) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, binding) assert.Equal(t, tc.step, binding.Step) assert.Equal(t, tc.uri, binding.URI) @@ -390,7 +391,7 @@ func TestBindingConverterWithDataTypesOverridden(t *testing.T) { if len(tc.applicationProperties) > 0 { assert.Equal(t, tc.applicationProperties, binding.ApplicationProperties) } else { - assert.True(t, len(binding.ApplicationProperties) == 0) + assert.Empty(t, binding.ApplicationProperties) } }) } diff --git a/pkg/util/bindings/knative_ref_test.go b/pkg/util/bindings/knative_ref_test.go index 6cd63cbe19..6ddadad491 100644 --- a/pkg/util/bindings/knative_ref_test.go +++ b/pkg/util/bindings/knative_ref_test.go @@ -24,6 +24,7 @@ import ( "github.com/apache/camel-k/v2/pkg/util/test" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" v1 "k8s.io/api/core/v1" camelv1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" @@ -72,7 +73,7 @@ func TestKnativeRefBinding(t *testing.T) { defer cancel() client, err := test.NewFakeClient() - assert.NoError(t, err) + require.NoError(t, err) bindingContext := BindingContext{ Ctx: ctx, @@ -84,7 +85,7 @@ func TestKnativeRefBinding(t *testing.T) { binding, err := KnativeRefBindingProvider{}.Translate(bindingContext, EndpointContext{ Type: camelv1.EndpointTypeSink, }, tc.endpoint) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, binding) assert.Equal(t, tc.uri, binding.URI) assert.Equal(t, camelv1.Traits{}, binding.Traits) @@ -97,7 +98,7 @@ func TestUnsupportedKnativeResource(t *testing.T) { defer cancel() client, err := test.NewFakeClient() - assert.NoError(t, err) + require.NoError(t, err) bindingContext := BindingContext{ Ctx: ctx, @@ -117,7 +118,7 @@ func TestUnsupportedKnativeResource(t *testing.T) { binding, err := KnativeRefBindingProvider{}.Translate(bindingContext, EndpointContext{ Type: camelv1.EndpointTypeSink, }, endpoint) - assert.NoError(t, err) + require.NoError(t, err) assert.Nil(t, binding) } @@ -126,7 +127,7 @@ func TestKnativeNotInstalled(t *testing.T) { defer cancel() client, err := test.NewFakeClient() - assert.NoError(t, err) + require.NoError(t, err) // disable the knative eventing api fakeClient := client.(*test.FakeClient) //nolint @@ -150,6 +151,6 @@ func TestKnativeNotInstalled(t *testing.T) { binding, err := KnativeRefBindingProvider{}.Translate(bindingContext, EndpointContext{ Type: camelv1.EndpointTypeSink, }, endpoint) - assert.Error(t, err, "integration referencing Knative endpoint 'default' that cannot run, because Knative is not installed on the cluster") + require.Error(t, err, "integration referencing Knative endpoint 'default' that cannot run, because Knative is not installed on the cluster") assert.Nil(t, binding) } diff --git a/pkg/util/camel/camel_dependencies.go b/pkg/util/camel/camel_dependencies.go index 535f1fe339..c0c0d6a862 100644 --- a/pkg/util/camel/camel_dependencies.go +++ b/pkg/util/camel/camel_dependencies.go @@ -21,6 +21,7 @@ import ( "fmt" "io" "path/filepath" + "strconv" "strings" v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" @@ -226,7 +227,7 @@ func addRegistryMavenDependency(project *maven.Project, dependency string) error properties.Add("type", gav.Type) exec := maven.Execution{ - ID: fmt.Sprint(len(plugin.Executions)), + ID: strconv.Itoa(len(plugin.Executions)), Phase: "validate", Goals: []string{ "artifact", diff --git a/pkg/util/camel/camel_dependencies_test.go b/pkg/util/camel/camel_dependencies_test.go index 2e817546e4..04ad25eca6 100644 --- a/pkg/util/camel/camel_dependencies_test.go +++ b/pkg/util/camel/camel_dependencies_test.go @@ -24,6 +24,7 @@ import ( "github.com/apache/camel-k/v2/pkg/util/maven" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestNormalizeDependency(t *testing.T) { @@ -40,7 +41,7 @@ func TestNormalizeDependency(t *testing.T) { func TestValidateDependency(t *testing.T) { catalog, err := DefaultCatalog() - assert.Nil(t, err) + require.NoError(t, err) output := strings.Builder{} ValidateDependency(catalog, "", &output) @@ -73,7 +74,7 @@ func TestValidateDependency(t *testing.T) { func TestManageIntegrationDependencies(t *testing.T) { catalog, err := DefaultCatalog() - assert.Nil(t, err) + require.NoError(t, err) tests := []struct { name string @@ -143,16 +144,16 @@ func TestManageIntegrationDependencies(t *testing.T) { project := maven.Project{} err = ManageIntegrationDependencies(&project, test.dependencies, catalog) - assert.Nil(t, err) + require.NoError(t, err) coordinates := strings.Builder{} for i, d := range project.Dependencies { if i == 0 { _, err = fmt.Fprintf(&coordinates, "%s:%s", d.GroupID, d.ArtifactID) - assert.Nil(t, err) + require.NoError(t, err) } else { _, err = fmt.Fprintf(&coordinates, ",%s:%s", d.GroupID, d.ArtifactID) - assert.Nil(t, err) + require.NoError(t, err) } } assert.Equal(t, test.coordinates, coordinates.String(), coordinates) diff --git a/pkg/util/camel/camel_runtime_test.go b/pkg/util/camel/camel_runtime_test.go index 3e18a83bd2..6e6c18a845 100644 --- a/pkg/util/camel/camel_runtime_test.go +++ b/pkg/util/camel/camel_runtime_test.go @@ -20,13 +20,16 @@ package camel import ( "context" "os" + "strings" "testing" "time" v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" "github.com/apache/camel-k/v2/pkg/util/defaults" + "github.com/apache/camel-k/v2/pkg/util/maven" "github.com/apache/camel-k/v2/pkg/util/test" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -36,20 +39,23 @@ func TestCreateCatalog(t *testing.T) { Duration: 5 * time.Minute, } c, err := test.NewFakeClient() - assert.Nil(t, err) + require.NoError(t, err) // use local Maven executable in tests t.Setenv("MAVEN_WRAPPER", "false") _, ok := os.LookupEnv("MAVEN_CMD") if !ok { t.Setenv("MAVEN_CMD", "mvn") } + if strings.Contains(defaults.DefaultRuntimeVersion, "SNAPSHOT") { + maven.DefaultMavenRepositories += ",https://repository.apache.org/content/repositories/snapshots-group@snapshots@id=apache-snapshots" + } catalog, err := CreateCatalog( context.TODO(), c, "", &ip, v1.RuntimeSpec{Provider: v1.RuntimeProviderQuarkus, Version: defaults.DefaultRuntimeVersion}) - assert.Nil(t, err) + require.NoError(t, err) assert.NotNil(t, catalog) assert.Equal(t, defaults.DefaultRuntimeVersion, catalog.Runtime.Version) assert.Equal(t, v1.RuntimeProviderQuarkus, catalog.Runtime.Provider) diff --git a/pkg/util/camel/camel_util_test.go b/pkg/util/camel/camel_util_test.go index d696dab958..d11f15144d 100644 --- a/pkg/util/camel/camel_util_test.go +++ b/pkg/util/camel/camel_util_test.go @@ -23,6 +23,7 @@ import ( "github.com/Masterminds/semver" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" ) @@ -34,7 +35,7 @@ func TestFindBestMatch(t *testing.T) { } c, err := findBestMatch(catalogs, v1.RuntimeSpec{Version: "~1.0.x", Provider: v1.RuntimeProviderQuarkus}) - assert.Nil(t, err) + require.NoError(t, err) assert.NotNil(t, c) assert.Equal(t, "1.0.1", c.Runtime.Version) assert.Equal(t, v1.RuntimeProviderQuarkus, c.Runtime.Provider) @@ -47,7 +48,7 @@ func TestFindExactSemVerMatch(t *testing.T) { } c, err := findBestMatch(catalogs, v1.RuntimeSpec{Version: "1.0.0", Provider: v1.RuntimeProviderQuarkus}) - assert.Nil(t, err) + require.NoError(t, err) assert.NotNil(t, c) assert.Equal(t, "1.0.0", c.Runtime.Version) assert.Equal(t, v1.RuntimeProviderQuarkus, c.Runtime.Provider) @@ -61,7 +62,7 @@ func TestFindRangeMatch(t *testing.T) { } c, err := findBestMatch(catalogs, v1.RuntimeSpec{Version: "> 1.0.1, < 1.0.3", Provider: v1.RuntimeProviderQuarkus}) - assert.Nil(t, err) + require.NoError(t, err) assert.NotNil(t, c) assert.Equal(t, "1.0.2", c.Runtime.Version) assert.Equal(t, v1.RuntimeProviderQuarkus, c.Runtime.Provider) @@ -73,7 +74,7 @@ func TestMissingMatch(t *testing.T) { } c, err := findBestMatch(catalogs, v1.RuntimeSpec{Version: "1.0.1", Provider: v1.RuntimeProviderQuarkus}) - assert.Nil(t, err) + require.NoError(t, err) assert.Nil(t, c) } @@ -104,7 +105,7 @@ func TestIncorrectConstraint(t *testing.T) { {Spec: v1.CamelCatalogSpec{Runtime: v1.RuntimeSpec{Version: "1.A.0", Provider: v1.RuntimeProviderQuarkus}}}, } c, err := findBestMatch(catalogs, v1.RuntimeSpec{Version: "1.0.0", Provider: v1.RuntimeProviderQuarkus}) - assert.Nil(t, err) + require.NoError(t, err) assert.Nil(t, c) } diff --git a/pkg/util/command_test.go b/pkg/util/command_test.go index 782f1804ea..ab9170af0d 100644 --- a/pkg/util/command_test.go +++ b/pkg/util/command_test.go @@ -24,6 +24,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) var ( @@ -41,13 +42,13 @@ func TestRunAndLog(t *testing.T) { cmd := exec.CommandContext(context.Background(), "date") err := RunAndLog(context.Background(), cmd, loggerInfo, loggerError) - assert.Nil(t, err) + require.NoError(t, err) } func TestRunAndLogInvalid(t *testing.T) { cmd := exec.CommandContext(context.Background(), "go", "help", "dsa") err := RunAndLog(context.Background(), cmd, loggerInfo, loggerError) - assert.NotNil(t, err) + require.Error(t, err) assert.Equal(t, "go help dsa: unknown help topic. Run 'go help'.: exit status 2", err.Error()) } diff --git a/pkg/util/defaults/defaults_test.go b/pkg/util/defaults/defaults_test.go index de9d4f58e3..6975665600 100644 --- a/pkg/util/defaults/defaults_test.go +++ b/pkg/util/defaults/defaults_test.go @@ -23,6 +23,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestDefaultBaseImage(t *testing.T) { @@ -34,29 +35,29 @@ func TestOverriddenBaseImage(t *testing.T) { env := "RELATED_IMAGE_BASE" oldEnvVal := os.Getenv(env) overriddenImage := "xxx" - assert.NoError(t, os.Setenv(env, overriddenImage)) + require.NoError(t, os.Setenv(env, overriddenImage)) assert.Equal(t, overriddenImage, BaseImage()) assert.False(t, IsBaseImageDefault()) - assert.NoError(t, os.Setenv(env, oldEnvVal)) + require.NoError(t, os.Setenv(env, oldEnvVal)) } func TestOverriddenInstallDefaultKamelets(t *testing.T) { env := "KAMEL_INSTALL_DEFAULT_KAMELETS" oldEnvVal := os.Getenv(env) - assert.NoError(t, os.Setenv(env, strconv.FormatBool(false))) + require.NoError(t, os.Setenv(env, strconv.FormatBool(false))) assert.False(t, InstallDefaultKamelets()) - assert.NoError(t, os.Setenv(env, strconv.FormatBool(true))) + require.NoError(t, os.Setenv(env, strconv.FormatBool(true))) assert.True(t, InstallDefaultKamelets()) - assert.NoError(t, os.Setenv(env, "wrongval")) + require.NoError(t, os.Setenv(env, "wrongval")) assert.False(t, InstallDefaultKamelets()) - assert.NoError(t, os.Setenv(env, oldEnvVal)) + require.NoError(t, os.Setenv(env, oldEnvVal)) } func TestOverriddenOperatorID(t *testing.T) { env := "KAMEL_OPERATOR_ID" oldEnvVal := os.Getenv(env) overriddenID := "operator-1" - assert.NoError(t, os.Setenv(env, overriddenID)) + require.NoError(t, os.Setenv(env, overriddenID)) assert.Equal(t, overriddenID, OperatorID()) - assert.NoError(t, os.Setenv(env, oldEnvVal)) + require.NoError(t, os.Setenv(env, oldEnvVal)) } diff --git a/pkg/util/digest/digest.go b/pkg/util/digest/digest.go index 1aed64a1f1..50978725af 100644 --- a/pkg/util/digest/digest.go +++ b/pkg/util/digest/digest.go @@ -35,7 +35,6 @@ import ( "github.com/apache/camel-k/v2/pkg/util" "github.com/apache/camel-k/v2/pkg/util/defaults" "github.com/apache/camel-k/v2/pkg/util/dsl" - corev1 "k8s.io/api/core/v1" "fmt" ) @@ -47,7 +46,7 @@ const ( // ComputeForIntegration a digest of the fields that are relevant for the deployment // Produces a digest that can be used as docker image tag. -func ComputeForIntegration(integration *v1.Integration, configmaps []*corev1.ConfigMap, secrets []*corev1.Secret) (string, error) { +func ComputeForIntegration(integration *v1.Integration, configmapVersions []string, secretVersions []string) (string, error) { hash := sha256.New() // Integration version is relevant if _, err := hash.Write([]byte(integration.Status.Version)); err != nil { @@ -119,9 +118,6 @@ func ComputeForIntegration(integration *v1.Integration, configmaps []*corev1.Con if err := computeForTraits(hash, integration.Spec.Traits); err != nil { return "", err } - if err := computeForTraits(hash, integration.Status.Traits); err != nil { - return "", err - } // Integration traits as annotations for _, k := range sortedTraitAnnotationsKeys(integration) { @@ -131,63 +127,19 @@ func ComputeForIntegration(integration *v1.Integration, configmaps []*corev1.Con } } - // Configmap content - for _, cm := range configmaps { - if cm != nil { - // prepare string from cm - var cmToString strings.Builder - // name, ns - cmToString.WriteString(fmt.Sprintf("%s/%s", cm.Name, cm.Namespace)) - // Data with sorted keys - if cm.Data != nil { - // sort keys - keys := make([]string, 0, len(cm.Data)) - for k := range cm.Data { - keys = append(keys, k) - } - sort.Strings(keys) - for _, k := range keys { - cmToString.WriteString(fmt.Sprintf("%s=%v,", k, cm.Data[k])) - } - } - // BinaryData with sorted keys - if cm.BinaryData != nil { - keys := make([]string, 0, len(cm.BinaryData)) - for k := range cm.BinaryData { - keys = append(keys, k) - } - sort.Strings(keys) - for _, k := range keys { - cmToString.WriteString(fmt.Sprintf("%s=%v,", k, cm.BinaryData[k])) - } - } - // write prepared string to hash - if _, err := hash.Write([]byte(cmToString.String())); err != nil { + // Configmap versions + for _, cm := range configmapVersions { + if cm != "" { + if _, err := hash.Write([]byte(cm)); err != nil { return "", err } } } - // Secret content - for _, s := range secrets { - if s != nil { - // prepare string from secret - var secretToString strings.Builder - // name, ns - secretToString.WriteString(fmt.Sprintf("%s/%s", s.Name, s.Namespace)) - // Data with sorted keys - if s.Data != nil { - keys := make([]string, 0, len(s.Data)) - for k := range s.Data { - keys = append(keys, k) - } - sort.Strings(keys) - for _, k := range keys { - secretToString.WriteString(fmt.Sprintf("%s=%v,", k, s.Data[k])) - } - } - // write prepared secret to hash - if _, err := hash.Write([]byte(secretToString.String())); err != nil { + // Secret versions + for _, s := range secretVersions { + if s != "" { + if _, err := hash.Write([]byte(s)); err != nil { return "", err } } diff --git a/pkg/util/digest/digest_test.go b/pkg/util/digest/digest_test.go index a08036bb59..dd019fe60b 100644 --- a/pkg/util/digest/digest_test.go +++ b/pkg/util/digest/digest_test.go @@ -21,26 +21,24 @@ import ( "os" "testing" - "github.com/stretchr/testify/require" - "github.com/apache/camel-k/v2/pkg/apis/camel/v1/trait" - corev1 "k8s.io/api/core/v1" "k8s.io/utils/pointer" v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestDigestUsesAnnotations(t *testing.T) { it := v1.Integration{} digest1, err := ComputeForIntegration(&it, nil, nil) - assert.NoError(t, err) + require.NoError(t, err) it.Annotations = map[string]string{ "another.annotation": "hello", } digest2, err := ComputeForIntegration(&it, nil, nil) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, digest1, digest2) it.Annotations = map[string]string{ @@ -48,7 +46,7 @@ func TestDigestUsesAnnotations(t *testing.T) { "trait.camel.apache.org/cron.fallback": "true", } digest3, err := ComputeForIntegration(&it, nil, nil) - assert.NoError(t, err) + require.NoError(t, err) assert.NotEqual(t, digest1, digest3) } @@ -60,10 +58,10 @@ func TestDigestSHA1FromTempFile(t *testing.T) { } assert.Nil(t, tmpFile.Close()) - assert.Nil(t, os.WriteFile(tmpFile.Name(), []byte("hello test!"), 0o400)) + require.NoError(t, os.WriteFile(tmpFile.Name(), []byte("hello test!"), 0o400)) sha1, err := ComputeSHA1(tmpFile.Name()) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, "OXPdxTeLf5rqnsqvTi0CgmWoN/0=", sha1) } @@ -81,19 +79,13 @@ func TestDigestUsesConfigmap(t *testing.T) { digest1, err := ComputeForIntegration(&it, nil, nil) require.NoError(t, err) - - cm := corev1.ConfigMap{ - Data: map[string]string{ - "foo": "bar", - }, - } - cms := []*corev1.ConfigMap{&cm} + cms := []string{"123456"} digest2, err := ComputeForIntegration(&it, cms, nil) require.NoError(t, err) assert.NotEqual(t, digest1, digest2) - cm.Data["foo"] = "bar updated" + cms = []string{"1234567"} digest3, err := ComputeForIntegration(&it, cms, nil) require.NoError(t, err) assert.NotEqual(t, digest2, digest3) @@ -117,23 +109,12 @@ func TestDigestUsesSecret(t *testing.T) { digest1, err := ComputeForIntegration(&it, nil, nil) require.NoError(t, err) - - sec := corev1.Secret{ - Data: map[string][]byte{ - "foo": []byte("bar"), - }, - StringData: map[string]string{ - "foo2": "bar2", - }, - } - - secrets := []*corev1.Secret{&sec} - + secrets := []string{"123456"} digest2, err := ComputeForIntegration(&it, nil, secrets) require.NoError(t, err) assert.NotEqual(t, digest1, digest2) - sec.Data["foo"] = []byte("bar updated") + secrets = []string{"1234567"} digest3, err := ComputeForIntegration(&it, nil, secrets) require.NoError(t, err) assert.NotEqual(t, digest2, digest3) @@ -160,44 +141,10 @@ func TestDigestMatchingTraitsUpdated(t *testing.T) { }, } - itStatusOnlyTraitUpdated := v1.Integration{ - Spec: v1.IntegrationSpec{}, - Status: v1.IntegrationStatus{ - Traits: v1.Traits{ - Camel: &trait.CamelTrait{ - Properties: []string{"hello=world2"}, - }, - }, - }, - } - itDigest, err := ComputeForIntegration(&it, nil, nil) - assert.Nil(t, err) + require.NoError(t, err) itSpecOnlyTraitUpdatedDigest, err := ComputeForIntegration(&itSpecOnlyTraitUpdated, nil, nil) - assert.Nil(t, err) - itStatusOnlyTraitUpdatedDigest, err := ComputeForIntegration(&itStatusOnlyTraitUpdated, nil, nil) - assert.Nil(t, err) + require.NoError(t, err) assert.NotEqual(t, itSpecOnlyTraitUpdatedDigest, itDigest, "Digests must not be equal") - assert.NotEqual(t, itStatusOnlyTraitUpdatedDigest, itDigest, "Digests must not be equal") - assert.Equal(t, itSpecOnlyTraitUpdatedDigest, itStatusOnlyTraitUpdatedDigest, "Digests must be equal") -} - -func TestSpecStatusDrift(t *testing.T) { - it := v1.Integration{} - it.Spec.Traits.Camel = &trait.CamelTrait{} - it.Status.Traits.Camel = &trait.CamelTrait{} - - it.Spec.Traits.Camel.Properties = []string{"hello=world1"} - d1, err := ComputeForIntegration(&it, nil, nil) - assert.Nil(t, err) - it.Status.Traits.Camel.Properties = []string{"hello=world2"} - d2, err := ComputeForIntegration(&it, nil, nil) - assert.Nil(t, err) - it.Spec.Traits.Camel.Properties = []string{"hello=world3"} - d3, err := ComputeForIntegration(&it, nil, nil) - assert.Nil(t, err) - - assert.NotEqual(t, d2, d1, "d2 must not be equal to d1") - assert.NotEqual(t, d3, d2, "d3 must not be equal to d2") } diff --git a/pkg/util/docker/docker_base_test.go b/pkg/util/docker/docker_base_test.go index 23aa58db56..537d31408c 100644 --- a/pkg/util/docker/docker_base_test.go +++ b/pkg/util/docker/docker_base_test.go @@ -21,6 +21,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestBuildImageArgs(t *testing.T) { @@ -37,7 +38,7 @@ func TestBuildImageArgs(t *testing.T) { func TestRunImageArgs(t *testing.T) { args, err := RunImageArgs("imagePath") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "run", args[0]) assert.Equal(t, "--network="+NetworkName, args[1]) assert.Equal(t, "-t", args[2]) diff --git a/pkg/util/docker/docker_test.go b/pkg/util/docker/docker_test.go index 7d15caa367..be83afd1de 100644 --- a/pkg/util/docker/docker_test.go +++ b/pkg/util/docker/docker_test.go @@ -27,6 +27,7 @@ import ( "github.com/apache/camel-k/v2/pkg/util" "github.com/apache/camel-k/v2/pkg/util/defaults" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestCreateBaseImageDockerFile(t *testing.T) { @@ -44,12 +45,12 @@ func TestCreateBaseImageDockerFile(t *testing.T) { BaseWorkingDirectory = "/tmp/" err := CreateBaseImageDockerFile() - assert.Nil(t, err) + require.NoError(t, err) baseDockerFilePath := filepath.Join(BaseWorkingDirectory, "Dockerfile") c, err := util.ReadFile(baseDockerFilePath) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, expected, string(c)) os.Remove("/tmp/Dockerfile") @@ -91,10 +92,10 @@ func TestCreateIntegrationImageDockerFile(t *testing.T) { expected := strings.Join(dockerFile1, "\n") err := CreateIntegrationImageDockerFile(&cmd, false) - assert.Nil(t, err) + require.NoError(t, err) c, err := util.ReadFile("/tmp/Dockerfile") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, expected, string(c)) os.Remove("/tmp/Dockerfile") @@ -102,10 +103,10 @@ func TestCreateIntegrationImageDockerFile(t *testing.T) { expected = strings.Join(dockerFile2, "\n") err = CreateIntegrationImageDockerFile(&cmd, true) - assert.Nil(t, err) + require.NoError(t, err) c, err = util.ReadFile("/tmp/Dockerfile") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, expected, string(c)) os.Remove("/tmp/Dockerfile") @@ -136,9 +137,9 @@ func TestExtractRegistryName(t *testing.T) { expected := "localhost:5000" result, err := ExtractRegistryName("localhost:5000/imageName") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, expected, result) _, err = ExtractRegistryName("imageName") - assert.NotNil(t, err) + require.Error(t, err) } diff --git a/pkg/util/dsl/flow_test.go b/pkg/util/dsl/flow_test.go index e67880f535..4a2b62642e 100644 --- a/pkg/util/dsl/flow_test.go +++ b/pkg/util/dsl/flow_test.go @@ -23,6 +23,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestReadWriteYaml(t *testing.T) { @@ -37,19 +38,19 @@ func TestReadWriteYaml(t *testing.T) { yamlReader := bytes.NewReader([]byte(yaml)) flows, err := FromYamlDSL(yamlReader) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, flows) assert.Len(t, flows, 1) flow := map[string]interface{}{} err = json.Unmarshal(flows[0].RawMessage, &flow) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, flow["from"]) assert.Nil(t, flow["xx"]) data, err := ToYamlDSL(flows) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, data) assert.Equal(t, yaml, string(data)) } diff --git a/pkg/util/dsl/template_test.go b/pkg/util/dsl/template_test.go index ff8104c04d..8753cd7a26 100644 --- a/pkg/util/dsl/template_test.go +++ b/pkg/util/dsl/template_test.go @@ -22,6 +22,7 @@ import ( v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestTemplateReadWrite(t *testing.T) { @@ -47,7 +48,7 @@ func TestTemplateReadWrite(t *testing.T) { } yamlBytes, err := TemplateToYamlDSL(templateJSON, "myid") - assert.NoError(t, err) + require.NoError(t, err) yaml := string(yamlBytes) expected := `- routeTemplate: beans: diff --git a/pkg/util/gzip/compress_test.go b/pkg/util/gzip/compress_test.go index 2ea281b4cb..e60cfafbbd 100644 --- a/pkg/util/gzip/compress_test.go +++ b/pkg/util/gzip/compress_test.go @@ -22,24 +22,25 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestCompression(t *testing.T) { source := "this is a script" var compressed bytes.Buffer err := Compress(&compressed, []byte(source)) - assert.Nil(t, err) + require.NoError(t, err) var uncompressed bytes.Buffer err = Uncompress(&uncompressed, compressed.Bytes()) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, source, uncompressed.String()) } func TestCompression64(t *testing.T) { source := "this is a script" compressed, err := CompressBase64([]byte(source)) - assert.Nil(t, err) + require.NoError(t, err) uncompressed, err := UncompressBase64(compressed) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, source, string(uncompressed)) } diff --git a/pkg/util/jib/configuration.go b/pkg/util/jib/configuration.go index 1fb9bf2782..2b483f3cff 100644 --- a/pkg/util/jib/configuration.go +++ b/pkg/util/jib/configuration.go @@ -36,9 +36,10 @@ import ( const JibMavenGoal = "jib:build" const JibMavenToImageParam = "-Djib.to.image=" const JibMavenFromImageParam = "-Djib.from.image=" +const JibMavenFromPlatforms = "-Djib.from.platforms=" const JibMavenInsecureRegistries = "-Djib.allowInsecureRegistries=" const JibDigestFile = "target/jib-image.digest" -const JibMavenPluginVersionDefault = "3.3.2" +const JibMavenPluginVersionDefault = "3.4.1" const JibLayerFilterExtensionMavenVersionDefault = "0.3.0" // See: https://github.com/GoogleContainerTools/jib/blob/master/jib-maven-plugin/README.md#using-docker-configuration-files @@ -93,7 +94,7 @@ func CreateProfileConfigmap(ctx context.Context, c client.Client, kit *v1.Integr return nil } -// Create a maven profile defining jib plugin build. +// JibMavenProfile creates a maven profile defining jib plugin build. func JibMavenProfile(jibMavenPluginVersion string, jibLayerFilterExtensionMavenVersion string) (string, error) { jibVersion := JibMavenPluginVersionDefault if jibMavenPluginVersion != "" { diff --git a/pkg/util/jib/configuration_test.go b/pkg/util/jib/configuration_test.go index 418885f57a..9461083d46 100644 --- a/pkg/util/jib/configuration_test.go +++ b/pkg/util/jib/configuration_test.go @@ -25,6 +25,7 @@ import ( v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" "github.com/apache/camel-k/v2/pkg/util/test" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" @@ -34,7 +35,7 @@ import ( func TestJibMavenProfile(t *testing.T) { profile, err := JibMavenProfile("3.3.0", "0.2.0") - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, strings.HasPrefix(profile, "")) assert.True(t, strings.HasSuffix(profile, "")) assert.True(t, strings.Contains(profile, "3.3.0")) @@ -45,7 +46,7 @@ func TestJibMavenProfile(t *testing.T) { func TestJibMavenProfileDefaultValues(t *testing.T) { profile, err := JibMavenProfile("", "") - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, strings.HasPrefix(profile, "")) assert.True(t, strings.HasSuffix(profile, "")) assert.True(t, strings.Contains(profile, ""+JibMavenPluginVersionDefault+"")) @@ -72,7 +73,7 @@ func TestJibConfigMap(t *testing.T) { } err := CreateProfileConfigmap(ctx, c, kit, "awesomeprofile") - assert.NoError(t, err) + require.NoError(t, err) key := ctrl.ObjectKey{ Namespace: "ns", @@ -80,8 +81,8 @@ func TestJibConfigMap(t *testing.T) { } cm := &corev1.ConfigMap{} err = c.Get(ctx, key, cm) - assert.NoError(t, err) - assert.Equal(t, cm.OwnerReferences[0].Name, "test") + require.NoError(t, err) + assert.Equal(t, "test", cm.OwnerReferences[0].Name) assert.Equal(t, cm.OwnerReferences[0].UID, types.UID("8dc44a2b-063c-490e-ae02-1fab285ac70a")) assert.NotNil(t, cm.Data["profile.xml"]) assert.True(t, strings.Contains(cm.Data["profile.xml"], "awesome")) diff --git a/pkg/util/jvm/keystore_test.go b/pkg/util/jvm/keystore_test.go index ffeed96217..a6b15b6be9 100644 --- a/pkg/util/jvm/keystore_test.go +++ b/pkg/util/jvm/keystore_test.go @@ -23,7 +23,7 @@ import ( "testing" "github.com/apache/camel-k/v2/pkg/util" - "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestGenerateKeystore(t *testing.T) { @@ -32,16 +32,16 @@ func TestGenerateKeystore(t *testing.T) { var data [][]byte ctx := context.Background() err := GenerateKeystore(ctx, "", "/tmp/keystore", NewKeystorePassword(), data) - assert.Nil(t, err) + require.NoError(t, err) // Non-Nil Data data = [][]byte{{0}, {1}} err = GenerateKeystore(ctx, "", "/tmp/keystore", NewKeystorePassword(), data) - assert.NotNil(t, err) + require.Error(t, err) // Incorrect password format err = GenerateKeystore(ctx, "", "/tmp/keystore", "", data) - assert.NotNil(t, err) + require.Error(t, err) testFileExists, _ := util.FileExists("/tmp/keystore") if testFileExists { diff --git a/pkg/util/knative/apis_test.go b/pkg/util/knative/apis_test.go index a2284b54c7..4cea26e723 100644 --- a/pkg/util/knative/apis_test.go +++ b/pkg/util/knative/apis_test.go @@ -22,12 +22,13 @@ import ( "github.com/apache/camel-k/v2/pkg/apis/camel/v1/knative" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" v1 "k8s.io/api/core/v1" ) func TestAPIs(t *testing.T) { ref, err := ExtractObjectReference("knative:endpoint/ciao") - assert.Nil(t, err) + require.NoError(t, err) refs := FillMissingReferenceData(knative.CamelServiceTypeEndpoint, ref) checkValidRefs(t, refs) assert.Equal(t, v1.ObjectReference{ @@ -37,10 +38,10 @@ func TestAPIs(t *testing.T) { }, refs[0]) ref, err = ExtractObjectReference("knative:endpoint/ciao?apiVersion=serving.knative.dev/v1") - assert.Nil(t, err) + require.NoError(t, err) refs = FillMissingReferenceData(knative.CamelServiceTypeEndpoint, ref) checkValidRefs(t, refs) - assert.Equal(t, 1, len(refs)) + assert.Len(t, refs, 1) assert.Equal(t, v1.ObjectReference{ Kind: "Service", APIVersion: "serving.knative.dev/v1", @@ -48,10 +49,10 @@ func TestAPIs(t *testing.T) { }, refs[0]) ref, err = ExtractObjectReference("knative:endpoint/ciao?apiVersion=serving.knative.dev/v1&kind=Xxx") - assert.Nil(t, err) + require.NoError(t, err) refs = FillMissingReferenceData(knative.CamelServiceTypeEndpoint, ref) checkValidRefs(t, refs) - assert.Equal(t, 1, len(refs)) + assert.Len(t, refs, 1) assert.Equal(t, v1.ObjectReference{ Kind: "Xxx", APIVersion: "serving.knative.dev/v1", @@ -59,10 +60,10 @@ func TestAPIs(t *testing.T) { }, refs[0]) ref, err = ExtractObjectReference("knative:endpoint/ciao?apiVersion=yyy&kind=Xxx") - assert.Nil(t, err) + require.NoError(t, err) refs = FillMissingReferenceData(knative.CamelServiceTypeEndpoint, ref) checkValidRefs(t, refs) - assert.Equal(t, 1, len(refs)) + assert.Len(t, refs, 1) assert.Equal(t, v1.ObjectReference{ Kind: "Xxx", APIVersion: "yyy", @@ -70,7 +71,7 @@ func TestAPIs(t *testing.T) { }, refs[0]) ref, err = ExtractObjectReference("knative:endpoint/ciao?kind=Service") - assert.Nil(t, err) + require.NoError(t, err) refs = FillMissingReferenceData(knative.CamelServiceTypeEndpoint, ref) checkValidRefs(t, refs) assert.Equal(t, v1.ObjectReference{ @@ -80,7 +81,7 @@ func TestAPIs(t *testing.T) { }, refs[0]) ref, err = ExtractObjectReference("knative:endpoint/ciao?kind=Channel") - assert.Nil(t, err) + require.NoError(t, err) refs = FillMissingReferenceData(knative.CamelServiceTypeEndpoint, ref) checkValidRefs(t, refs) assert.Equal(t, v1.ObjectReference{ @@ -90,7 +91,7 @@ func TestAPIs(t *testing.T) { }, refs[0]) ref, err = ExtractObjectReference("knative:endpoint/ciao?kind=KafkaChannel") - assert.Nil(t, err) + require.NoError(t, err) refs = FillMissingReferenceData(knative.CamelServiceTypeEndpoint, ref) checkValidRefs(t, refs) assert.Equal(t, v1.ObjectReference{ @@ -100,7 +101,7 @@ func TestAPIs(t *testing.T) { }, refs[0]) ref, err = ExtractObjectReference("knative:channel/ciao") - assert.Nil(t, err) + require.NoError(t, err) refs = FillMissingReferenceData(knative.CamelServiceTypeChannel, ref) checkValidRefs(t, refs) assert.Equal(t, v1.ObjectReference{ @@ -110,7 +111,7 @@ func TestAPIs(t *testing.T) { }, refs[0]) ref, err = ExtractObjectReference("knative:channel/ciao?apiVersion=messaging.knative.dev/v1") - assert.Nil(t, err) + require.NoError(t, err) refs = FillMissingReferenceData(knative.CamelServiceTypeChannel, ref) checkValidRefs(t, refs) assert.Equal(t, v1.ObjectReference{ @@ -120,12 +121,12 @@ func TestAPIs(t *testing.T) { }, refs[0]) ref, err = ExtractObjectReference("knative:channel/ciao?apiVersion=xxx.knative.dev/v1alpha1") - assert.Nil(t, err) + require.NoError(t, err) refs = FillMissingReferenceData(knative.CamelServiceTypeChannel, ref) - assert.Equal(t, 0, len(refs)) + assert.Empty(t, refs) ref, err = ExtractObjectReference("knative:event/ciao") - assert.Nil(t, err) + require.NoError(t, err) refs = FillMissingReferenceData(knative.CamelServiceTypeEvent, ref) checkValidRefs(t, refs) assert.Equal(t, v1.ObjectReference{ @@ -135,7 +136,7 @@ func TestAPIs(t *testing.T) { }, refs[0]) ref, err = ExtractObjectReference("knative:event/ciao?apiVersion=xxx") - assert.Nil(t, err) + require.NoError(t, err) refs = FillMissingReferenceData(knative.CamelServiceTypeEvent, ref) checkValidRefs(t, refs) assert.Equal(t, v1.ObjectReference{ @@ -145,7 +146,7 @@ func TestAPIs(t *testing.T) { }, refs[0]) ref, err = ExtractObjectReference("knative:event/ciao?name=aaa") - assert.Nil(t, err) + require.NoError(t, err) refs = FillMissingReferenceData(knative.CamelServiceTypeEvent, ref) checkValidRefs(t, refs) assert.Equal(t, v1.ObjectReference{ @@ -158,7 +159,7 @@ func TestAPIs(t *testing.T) { func checkValidRefs(t *testing.T, refs []v1.ObjectReference) { t.Helper() - assert.True(t, len(refs) > 0) + assert.Greater(t, len(refs), 0) for _, ref := range refs { assert.NotNil(t, ref.Name) assert.NotNil(t, ref.Kind) diff --git a/pkg/util/knative/uri_test.go b/pkg/util/knative/uri_test.go index 04d0647787..1b8a9f7790 100644 --- a/pkg/util/knative/uri_test.go +++ b/pkg/util/knative/uri_test.go @@ -22,12 +22,13 @@ import ( "github.com/apache/camel-k/v2/pkg/apis/camel/v1/knative" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" v1 "k8s.io/api/core/v1" ) func TestChannelUri(t *testing.T) { ref, err := ExtractObjectReference("knative:endpoint/ciao") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, v1.ObjectReference{ Kind: "", APIVersion: "", @@ -35,7 +36,7 @@ func TestChannelUri(t *testing.T) { }, ref) ref, err = ExtractObjectReference("knative:endpoint/ciao?apiVersion=xxx") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, v1.ObjectReference{ Kind: "", APIVersion: "xxx", @@ -43,7 +44,7 @@ func TestChannelUri(t *testing.T) { }, ref) ref, err = ExtractObjectReference("knative:endpoint/ciao?x=y&apiVersion=xxx") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, v1.ObjectReference{ Kind: "", APIVersion: "xxx", @@ -51,7 +52,7 @@ func TestChannelUri(t *testing.T) { }, ref) ref, err = ExtractObjectReference("knative:channel/ciao2?x=y&apiVersion=eventing.knative.dev/v1&kind=KafkaChannel") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, v1.ObjectReference{ Kind: "KafkaChannel", APIVersion: "eventing.knative.dev/v1", @@ -59,7 +60,7 @@ func TestChannelUri(t *testing.T) { }, ref) ref, err = ExtractObjectReference("knative:endpoint/ciao?aapiVersion=xxx&kind=Broker") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, v1.ObjectReference{ Kind: "Broker", APIVersion: "", @@ -67,7 +68,7 @@ func TestChannelUri(t *testing.T) { }, ref) ref, err = ExtractObjectReference("knative://endpoint/ciao?&apiVersion=serving.knative.dev/v1alpha1&kind=Service&1=1") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, v1.ObjectReference{ Kind: "Service", APIVersion: "serving.knative.dev/v1alpha1", @@ -75,7 +76,7 @@ func TestChannelUri(t *testing.T) { }, ref) ref, err = ExtractObjectReference("knative://event/chuck?&apiVersion=eventing.knative.dev/v1beta1&name=broker2") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, v1.ObjectReference{ APIVersion: "eventing.knative.dev/v1beta1", Name: "broker2", @@ -83,14 +84,14 @@ func TestChannelUri(t *testing.T) { }, ref) ref, err = ExtractObjectReference("knative://event/chuck?&brokerApxxiVersion=eventing.knative.dev/v1beta1&brokxerName=broker2") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, v1.ObjectReference{ Name: "default", Kind: "Broker", }, ref) ref, err = ExtractObjectReference("knative://event?&apiVersion=eventing.knative.dev/v1beta13&brokxerName=broker2") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, v1.ObjectReference{ APIVersion: "eventing.knative.dev/v1beta13", Name: "default", diff --git a/pkg/util/kubernetes/factory_test.go b/pkg/util/kubernetes/factory_test.go index 581e2d82e6..9d1c107100 100644 --- a/pkg/util/kubernetes/factory_test.go +++ b/pkg/util/kubernetes/factory_test.go @@ -22,6 +22,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" ) @@ -43,7 +44,7 @@ func TestValidTolerations(t *testing.T) { } for _, vd := range validTolerations { _, err := NewTolerations(vd) - assert.Nil(t, err) + require.NoError(t, err) } } @@ -60,7 +61,7 @@ func TestInvalidTolerations(t *testing.T) { } for _, vd := range validTolerations { _, err := NewTolerations(vd) - assert.NotNil(t, err) + require.Error(t, err) } } @@ -72,7 +73,7 @@ func TestValueTolerations(t *testing.T) { "existKey:NoSchedule:120", } toleration, err := NewTolerations(tolerations) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, 4, len(toleration)) assert.Equal(t, "key", toleration[0].Key) @@ -108,7 +109,7 @@ func TestValidNodeSelectors(t *testing.T) { } for _, vds := range validNodeSelectors { _, err := NewNodeSelectors(vds) - assert.Nil(t, err) + require.NoError(t, err) } } @@ -120,7 +121,7 @@ func TestInvalidNodeSelectors(t *testing.T) { } for _, vds := range validNodeSelectors { _, err := NewNodeSelectors(vds) - assert.NotNil(t, err) + require.Error(t, err) } } @@ -130,7 +131,7 @@ func TestValueNodeSelectors(t *testing.T) { "kubernetes.io/hostname=worker0", } nodeSelectors, err := NewNodeSelectors(nodeSelectorsArray) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, 2, len(nodeSelectors)) assert.Equal(t, "value", nodeSelectors["key"]) @@ -140,7 +141,7 @@ func TestValueNodeSelectors(t *testing.T) { func TestAllResourceRequirements(t *testing.T) { resReq := "limits.memory=256Mi,requests.memory=128Mi,limits.cpu=1000m,requests.cpu=500m" resourceRequirements, err := NewResourceRequirements(strings.Split(resReq, ",")) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, resource.MustParse("256Mi"), *resourceRequirements.Limits.Memory()) assert.Equal(t, resource.MustParse("128Mi"), *resourceRequirements.Requests.Memory()) @@ -151,36 +152,36 @@ func TestAllResourceRequirements(t *testing.T) { func TestSomeResourceRequirements(t *testing.T) { resReq := "limits.memory=128Mi,requests.cpu=500m" resourceRequirements, err := NewResourceRequirements(strings.Split(resReq, ",")) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, resource.MustParse("128Mi"), *resourceRequirements.Limits.Memory()) - assert.Equal(t, true, resourceRequirements.Requests.Memory().IsZero()) - assert.Equal(t, true, resourceRequirements.Limits.Cpu().IsZero()) + assert.True(t, resourceRequirements.Requests.Memory().IsZero()) + assert.True(t, resourceRequirements.Limits.Cpu().IsZero()) assert.Equal(t, resource.MustParse("500m"), *resourceRequirements.Requests.Cpu()) } func TestErrorResourceRequirements(t *testing.T) { resReq := "limits.memory=expectSomeError!" _, err := NewResourceRequirements(strings.Split(resReq, ",")) - assert.NotNil(t, err) + require.Error(t, err) } func TestMissingResourceRequirements(t *testing.T) { resReq := "" _, err := NewResourceRequirements(strings.Split(resReq, ",")) - assert.NotNil(t, err) + require.Error(t, err) } func TestConfigureResources(t *testing.T) { requestsList := make(v1.ResourceList) requestsList, err := ConfigureResource("500m", requestsList, v1.ResourceCPU) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "500m", requestsList.Cpu().String()) requestsList, err = ConfigureResource("5Gi", requestsList, v1.ResourceMemory) - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, "5Gi", requestsList.Memory().String()) requestsList, err = ConfigureResource("5ss", requestsList, v1.ResourceCPU) - assert.NotNil(t, err) + require.Error(t, err) // Assert previous values haven't changed assert.Equal(t, "500m", requestsList.Cpu().String()) assert.Equal(t, "5Gi", requestsList.Memory().String()) diff --git a/pkg/util/kubernetes/lookup.go b/pkg/util/kubernetes/lookup.go index e757291102..7b69880dab 100644 --- a/pkg/util/kubernetes/lookup.go +++ b/pkg/util/kubernetes/lookup.go @@ -52,6 +52,15 @@ func LookupConfigmap(ctx context.Context, c client.Client, ns string, name strin return &cm } +// LookupResourceVersion will look for any k8s resource with a given name in a given namespace, returning its resource version only. +// It makes this safe against any resource that the operator is not allowed to inspect. +func LookupResourceVersion(ctx context.Context, c client.Client, object ctrl.Object) string { + if err := c.Get(ctx, ctrl.ObjectKeyFromObject(object), object); err != nil { + return "" + } + return object.GetResourceVersion() +} + // LookupSecret will look for any k8s Secret with a given name in a given namespace. func LookupSecret(ctx context.Context, c client.Client, ns string, name string) *corev1.Secret { secret := corev1.Secret{ diff --git a/pkg/util/kubernetes/util_test.go b/pkg/util/kubernetes/util_test.go index 19be65da6a..c217234a22 100644 --- a/pkg/util/kubernetes/util_test.go +++ b/pkg/util/kubernetes/util_test.go @@ -21,6 +21,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -42,10 +43,10 @@ func TestToYAMLNoManagedFields(t *testing.T) { } yaml, err := ToYAML(deploy) - assert.Nil(t, err) + require.NoError(t, err) assert.Contains(t, string(yaml), "managedFields") yaml, err = ToYAMLNoManagedFields(deploy) - assert.Nil(t, err) + require.NoError(t, err) assert.NotContains(t, string(yaml), "managedFields") } diff --git a/pkg/util/log/log.go b/pkg/util/log/log.go index a57e722c48..c1eb490961 100644 --- a/pkg/util/log/log.go +++ b/pkg/util/log/log.go @@ -43,7 +43,7 @@ func InitForCmd() { // Injectable identifies objects that can receive a Logger. type Injectable interface { - InjectLogger(Logger) + InjectLogger(logger Logger) } // Logger --. diff --git a/pkg/util/maven/maven_log_test.go b/pkg/util/maven/maven_log_test.go index d31ba257a7..2fa74dd2af 100644 --- a/pkg/util/maven/maven_log_test.go +++ b/pkg/util/maven/maven_log_test.go @@ -24,7 +24,7 @@ import ( "testing" "github.com/apache/camel-k/v2/pkg/util" - "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestRunAndLogErrorMvn(t *testing.T) { @@ -36,6 +36,6 @@ func TestRunAndLogErrorMvn(t *testing.T) { cmd := exec.CommandContext(context.Background(), mavenCmd, "package", "-B") err := util.RunAndLog(context.Background(), cmd, MavenLogHandler, MavenLogHandler) - assert.NotNil(t, err) - assert.ErrorContains(t, err, "[ERROR] The goal you specified requires a project to execute but there is no POM in this directory") + require.Error(t, err) + require.ErrorContains(t, err, "[ERROR] The goal you specified requires a project to execute but there is no POM in this directory") } diff --git a/pkg/util/maven/maven_project_test.go b/pkg/util/maven/maven_project_test.go index cf9adbb1dc..9cc12a5cc3 100644 --- a/pkg/util/maven/maven_project_test.go +++ b/pkg/util/maven/maven_project_test.go @@ -24,6 +24,7 @@ import ( "github.com/apache/camel-k/v2/pkg/util" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) const expectedPom = ` @@ -134,7 +135,7 @@ func TestPomGeneration(t *testing.T) { pom, err := util.EncodeXML(project) - assert.Nil(t, err) + require.NoError(t, err) assert.NotNil(t, pom) assert.Equal(t, expectedPom, string(pom)) @@ -142,15 +143,15 @@ func TestPomGeneration(t *testing.T) { func TestParseGAV(t *testing.T) { dep, err := ParseGAV("org.apache.camel:camel-core:2.21.1") - assert.Nil(t, err) - assert.Equal(t, dep.GroupID, "org.apache.camel") - assert.Equal(t, dep.ArtifactID, "camel-core") + require.NoError(t, err) + assert.Equal(t, "org.apache.camel", dep.GroupID) + assert.Equal(t, "camel-core", dep.ArtifactID) assert.Empty(t, dep.Type) - assert.Equal(t, dep.Version, "2.21.1") + assert.Equal(t, "2.21.1", dep.Version) assert.Empty(t, dep.Classifier) dep, err = ParseGAV("org.apache.camel:camel-core:war:2.21.1") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, dep.GroupID, "org.apache.camel") assert.Equal(t, dep.ArtifactID, "camel-core") assert.Equal(t, dep.Type, "war") @@ -158,7 +159,7 @@ func TestParseGAV(t *testing.T) { assert.Empty(t, dep.Classifier) dep, err = ParseGAV("org.apache.camel:camel-core:war:2.21.1:test") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, dep.GroupID, "org.apache.camel") assert.Equal(t, dep.ArtifactID, "camel-core") assert.Equal(t, dep.Type, "war") @@ -166,7 +167,7 @@ func TestParseGAV(t *testing.T) { assert.Equal(t, dep.Classifier, "test") dep, err = ParseGAV("org.apache.camel:camel-core") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, dep.GroupID, "org.apache.camel") assert.Equal(t, dep.ArtifactID, "camel-core") assert.Empty(t, dep.Type) @@ -174,7 +175,7 @@ func TestParseGAV(t *testing.T) { assert.Empty(t, dep.Classifier) dep, err = ParseGAV("org.apache.camel:camel-k-core:jar::custom") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, dep.GroupID, "org.apache.camel") assert.Equal(t, dep.ArtifactID, "camel-k-core") assert.Equal(t, dep.Type, "jar") @@ -182,7 +183,7 @@ func TestParseGAV(t *testing.T) { assert.Equal(t, dep.Classifier, "custom") // dep, err = ParseGAV("org.apache.camel:camel-k-core::1.2.3:foo") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, dep.GroupID, "org.apache.camel") assert.Equal(t, dep.ArtifactID, "camel-k-core") assert.Empty(t, dep.Type) @@ -190,7 +191,7 @@ func TestParseGAV(t *testing.T) { assert.Equal(t, dep.Classifier, "foo") dep, err = ParseGAV("org.apache.camel:camel-k-core:::custom") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, dep.GroupID, "org.apache.camel") assert.Equal(t, dep.ArtifactID, "camel-k-core") assert.Empty(t, dep.Type) @@ -198,7 +199,7 @@ func TestParseGAV(t *testing.T) { assert.Equal(t, dep.Classifier, "custom") dep, err = ParseGAV("org.apache.camel:camel-k-core:jar") - assert.Nil(t, err) + require.NoError(t, err) assert.Equal(t, dep.GroupID, "org.apache.camel") assert.Equal(t, dep.ArtifactID, "camel-k-core") assert.Equal(t, dep.Type, "jar") @@ -209,7 +210,7 @@ func TestParseGAV(t *testing.T) { func TestParseGAVErrorNoColumn(t *testing.T) { dep, err := ParseGAV("org.apache.camel.k.camel-k-runtime-noop-0.2.1-SNAPSHOT.jar") - assert.EqualError(t, err, "GAV must match :[:]:()[:]") + require.EqualError(t, err, "GAV must match :[:]:()[:]") assert.Equal(t, Dependency{}, dep) } diff --git a/pkg/util/maven/maven_repositories.go b/pkg/util/maven/maven_repositories.go index f3ddb83863..de0b8821fa 100644 --- a/pkg/util/maven/maven_repositories.go +++ b/pkg/util/maven/maven_repositories.go @@ -28,6 +28,7 @@ var DefaultRepositories = defaultRepositories{} type defaultRepositories struct{} +// nolint: unparam func (o defaultRepositories) apply(settings *Settings) error { for _, repository := range defaultMavenRepositories() { upsertRepository(repository, &settings.Profiles[0].Repositories) diff --git a/pkg/util/maven/maven_settings_test.go b/pkg/util/maven/maven_settings_test.go index bef0875388..ea12f3a0f3 100644 --- a/pkg/util/maven/maven_settings_test.go +++ b/pkg/util/maven/maven_settings_test.go @@ -21,6 +21,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" "github.com/apache/camel-k/v2/pkg/util" @@ -181,7 +182,7 @@ const expectedDefaultSettingsWithExtraRepo = ` /dev/null)) go install github.com/gotesttools/gotestfmt/v2/cmd/gotestfmt@latest endif +# Build images without running unit tests +# NOTEST=1 make images test: do-build +ifndef NOTEST @echo "####### Running unit test..." go test ./... $(COVERAGE_OPTS) +else + @echo "####### Skipping unit test..." +endif # # Common tests that do not require any customized operator setting. They can leverage a unique namespaced operator installation to reduce @@ -247,14 +256,7 @@ test: do-build # test-common: do-build FAILED=0; STAGING_RUNTIME_REPO="$(STAGING_RUNTIME_REPO)"; \ - go test -timeout 10m -v ./e2e/common/support/startup_test.go -tags=integration $(TEST_INTEGRATION_COMMON_LANG_RUN) $(GOTESTFMT) || FAILED=1; \ - go test -timeout 30m -v ./e2e/common/languages -tags=integration $(TEST_INTEGRATION_COMMON_LANG_RUN) $(GOTESTFMT) || FAILED=1; \ - go test -timeout 30m -v ./e2e/common/cli -tags=integration $(TEST_INTEGRATION_COMMON_LANG_RUN) $(GOTESTFMT) || FAILED=1; \ - go test -timeout 30m -v ./e2e/common/config -tags=integration $(TEST_INTEGRATION_COMMON_LANG_RUN) $(GOTESTFMT) || FAILED=1; \ - go test -timeout 30m -v ./e2e/common/misc -tags=integration $(TEST_INTEGRATION_COMMON_LANG_RUN) $(GOTESTFMT) || FAILED=1; \ - go test -timeout 60m -v ./e2e/common/traits -tags=integration $(TEST_INTEGRATION_COMMON_LANG_RUN) $(GOTESTFMT) || FAILED=1; \ - go test -timeout 20m -v ./e2e/common/runtimes -tags=integration $(TEST_INTEGRATION_COMMON_LANG_RUN) $(GOTESTFMT) || FAILED=1; \ - go test -timeout 10m -v ./e2e/common/support/teardown_test.go -tags=integration $(TEST_INTEGRATION_COMMON_LANG_RUN) $(GOTESTFMT) || FAILED=1; \ + go test -timeout 90m -v ./e2e/common/... -tags=integration -parallel=$(TEST_COMMON_PARALLEL_COUNT) $(TEST_INTEGRATION_COMMON_LANG_RUN) $(GOTESTFMT) || FAILED=1; \ exit $${FAILED} # @@ -262,22 +264,19 @@ test-common: do-build # test-smoke: do-build FAILED=0; STAGING_RUNTIME_REPO="$(STAGING_RUNTIME_REPO)"; \ - go test -timeout 10m -v ./e2e/common/support/startup_test.go -tags=integration $(TEST_INTEGRATION_COMMON_LANG_RUN) $(GOTESTFMT) || FAILED=1; \ - go test -timeout 30m -v ./e2e/common/languages -tags=integration $(TEST_INTEGRATION_COMMON_LANG_RUN) $(GOTESTFMT) || FAILED=1; \ + go test -timeout 10m -v ./e2e/common/main_test.go -tags=integration $(TEST_INTEGRATION_COMMON_LANG_RUN) $(GOTESTFMT) || FAILED=1; \ + go test -timeout 30m -v ./e2e/common/languages -tags=integration -parallel=$(TEST_COMMON_PARALLEL_COUNT) $(TEST_INTEGRATION_COMMON_LANG_RUN) $(GOTESTFMT) || FAILED=1; \ go test -timeout 30m -v \ - ./e2e/common/misc/default.go \ ./e2e/common/misc/cron_test.go \ ./e2e/common/misc/kamelet_test.go \ ./e2e/common/misc/pipe_test.go \ - -tags=integration $(TEST_INTEGRATION_COMMON_LANG_RUN) $(GOTESTFMT) || FAILED=1; \ + -tags=integration -parallel=$(TEST_COMMON_PARALLEL_COUNT) $(TEST_INTEGRATION_COMMON_LANG_RUN) $(GOTESTFMT) || FAILED=1; \ go test -timeout 30m -v \ - ./e2e/common/traits/default.go \ ./e2e/common/traits/camel_test.go \ ./e2e/common/traits/container_test.go \ ./e2e/common/traits/openapi_test.go \ ./e2e/common/traits/service_test.go \ - -tags=integration $(TEST_INTEGRATION_COMMON_LANG_RUN) $(GOTESTFMT) || FAILED=1; \ - go test -timeout 10m -v ./e2e/common/support/teardown_test.go -tags=integration $(TEST_INTEGRATION_COMMON_LANG_RUN) $(GOTESTFMT) || FAILED=1; \ + -tags=integration -parallel=$(TEST_COMMON_PARALLEL_COUNT) $(TEST_INTEGRATION_COMMON_LANG_RUN) $(GOTESTFMT) || FAILED=1; \ exit $${FAILED} # @@ -285,7 +284,7 @@ test-smoke: do-build # test-advanced: do-build FAILED=0; STAGING_RUNTIME_REPO="$(STAGING_RUNTIME_REPO)"; \ - go test -timeout 90m -v ./e2e/advanced -tags=integration $(TEST_INSTALL_RUN) $(GOTESTFMT) || FAILED=1; \ + go test -timeout 90m -v ./e2e/advanced -tags=integration -parallel=$(TEST_ADVANCED_PARALLEL_COUNT) $(TEST_INSTALL_RUN) $(GOTESTFMT) || FAILED=1; \ exit $${FAILED} # @@ -317,9 +316,7 @@ test-install-upgrade: do-build # test-knative: do-build STAGING_RUNTIME_REPO="$(STAGING_RUNTIME_REPO)"; \ - go test -timeout 10m -v ./e2e/knative/support/startup_test.go -tags=integration $(TEST_INTEGRATION_COMMON_LANG_RUN) $(GOTESTFMT) || FAILED=1; \ go test -timeout 60m -v ./e2e/knative -tags=integration $(TEST_KNATIVE_RUN) $(GOTESTFMT) || FAILED=1; \ - go test -timeout 10m -v ./e2e/knative/support/teardown_test.go -tags=integration $(TEST_INTEGRATION_COMMON_LANG_RUN) $(GOTESTFMT) || FAILED=1; \ exit $${FAILED} # @@ -351,8 +348,8 @@ test-quarkus-native-high-memory: do-build go test -timeout 180m -v ./e2e/native -tags=integration,high_memory $(TEST_QUARKUS_RUN) $(GOTESTFMT) build-kamel: - @echo "####### Building kamel CLI for $(GOOS) $(IMAGE_ARCH) architecture..." - CGO_ENABLED=0 GOARCH=$(IMAGE_ARCH) go build $(GOFLAGS) -o build/_output/bin/kamel-$(IMAGE_ARCH) ./cmd/kamel/*.go + @echo "####### Building kamel CLI for linux/$(IMAGE_ARCH) architecture..." + CGO_ENABLED=0 GOOS=linux GOARCH=$(IMAGE_ARCH) go build $(GOFLAGS) -o build/_output/bin/kamel-$(IMAGE_ARCH) ./cmd/kamel/*.go # Symbolic link to a local CLI ln -sf build/_output/bin/kamel-$(IMAGE_ARCH) ./kamel @@ -371,6 +368,7 @@ endif build-compile-integration-tests: @echo "####### Compiling integration tests..." + export CAMEL_K_E2E_JUST_COMPILE="true"; \ go test -run nope -tags="integration" ./e2e/... clean: @@ -424,57 +422,66 @@ maven-overlay: mkdir -p build/_maven_overlay ./script/maven_overlay.sh build/_maven_overlay -kamel-overlay: - mkdir -p build/_output/bin -ifeq ($(shell uname -s 2>/dev/null || echo Unknown),Linux) - @echo "####### Copying Linux platform arch $(IMAGE_ARCH) CLI into output build directory..." -else - @echo "####### (Re)Building a Linux platform arch $(IMAGE_ARCH) CLI " - @echo "####### Likely you're on a non Linux host, so I need to build a Linux CLI to bundle in the container image" - GOOS=linux GOARCH=$(IMAGE_ARCH) go build $(GOFLAGS) -o build/_output/bin/kamel-$(IMAGE_ARCH) ./cmd/kamel/*.go -endif - cp build/_output/bin/kamel-$(IMAGE_ARCH) build/_output/bin/kamel - TARGET_STAGE := base ifeq ($(DEBUG_MODE),true) TARGET_STAGE := debug CUSTOM_IMAGE := $(CUSTOM_IMAGE)-debug endif -DOCKER_TAG := $(CUSTOM_IMAGE):$(CUSTOM_VERSION) -ifneq ($(IMAGE_ARCH), amd64) - DOCKER_TAG := $(DOCKER_TAG)-$(IMAGE_ARCH) -endif +DOCKER_TAG := $(CUSTOM_IMAGE):$(CUSTOM_VERSION)-$(IMAGE_ARCH) -images: build kamel-overlay maven-overlay bundle-kamelets +images: build maven-overlay bundle-kamelets ifneq (,$(findstring SNAPSHOT,$(DEFAULT_RUNTIME_VERSION))) ./script/package_maven_artifacts.sh -s "$(STAGING_RUNTIME_REPO)" -d "$(CAMEL_K_RUNTIME_DIR)" $(DEFAULT_RUNTIME_VERSION) endif @echo "####### Building Camel K operator arch $(IMAGE_ARCH) container image..." mkdir -p build/_maven_output - docker buildx build --target $(TARGET_STAGE) --platform=linux/$(IMAGE_ARCH) -t $(DOCKER_TAG) -f build/Dockerfile . + docker buildx build --target $(TARGET_STAGE) --platform=linux/$(IMAGE_ARCH) --build-arg IMAGE_ARCH=$(IMAGE_ARCH) --load -t $(DOCKER_TAG) -f build/Dockerfile . + docker tag $(DOCKER_TAG) $(CUSTOM_IMAGE):$(CUSTOM_VERSION) # Mainly used for internal CI purposes image-push: docker push $(CUSTOM_IMAGE):$(CUSTOM_VERSION) -images-all: images +# Make sure the current docker builder must supports the wanted platform list, which may not be the case for the default builder +# +# docker buildx inspect +# ... +# Platforms: linux/amd64*, linux/arm64* +# +# +# docker buildx create --name mybuilder --platform linux/amd64,linux/arm64 +# docker buildx use mybuilder +images-all: make IMAGE_ARCH=arm64 images + make IMAGE_ARCH=amd64 images images-push: + docker push $(CUSTOM_IMAGE):$(CUSTOM_VERSION)-amd64 docker push $(CUSTOM_IMAGE):$(CUSTOM_VERSION) - docker push $(CUSTOM_IMAGE):$(CUSTOM_VERSION)-arm64 + @if docker inspect $(CUSTOM_IMAGE):$(CUSTOM_VERSION)-arm64 &> /dev/null; then \ + echo "Image $(CUSTOM_IMAGE):$(CUSTOM_VERSION)-arm64 exists, building the multiarch manifest"; \ + docker push $(CUSTOM_IMAGE):$(CUSTOM_VERSION)-arm64; \ + docker manifest create $(CUSTOM_IMAGE):$(CUSTOM_VERSION) --amend $(CUSTOM_IMAGE):$(CUSTOM_VERSION)-amd64 --amend $(CUSTOM_IMAGE):$(CUSTOM_VERSION)-arm64; \ + docker manifest push --purge $(CUSTOM_IMAGE):$(CUSTOM_VERSION); \ + else \ + echo "Image $(CUSTOM_IMAGE):$(CUSTOM_VERSION)-arm64 does not exist"; \ + fi images-push-staging: - docker tag $(CUSTOM_IMAGE):$(CUSTOM_VERSION) $(STAGING_IMAGE_NAME):$(CUSTOM_VERSION) - docker tag $(CUSTOM_IMAGE):$(CUSTOM_VERSION)-arm64 $(STAGING_IMAGE_NAME):$(CUSTOM_VERSION)-arm64 - docker push $(STAGING_IMAGE_NAME):$(CUSTOM_VERSION) - docker push $(STAGING_IMAGE_NAME):$(CUSTOM_VERSION)-arm64 - # TODO: we can evaluate the usage of manifest and try the following - # docker manifest create $(CUSTOM_IMAGE):$(CUSTOM_VERSION) \ - # --amend $(CUSTOM_IMAGE):$(CUSTOM_VERSION)-amd64 \ - # --amend $(CUSTOM_IMAGE):$(CUSTOM_VERSION)-arm64 - # docker manifest push --purge $(CUSTOM_IMAGE):$(CUSTOM_VERSION) + docker tag $(CUSTOM_IMAGE):$(CUSTOM_VERSION)-amd64 $(STAGING_IMAGE):$(CUSTOM_VERSION)-amd64 + docker tag $(CUSTOM_IMAGE):$(CUSTOM_VERSION)-amd64 $(STAGING_IMAGE):$(CUSTOM_VERSION) + docker push $(STAGING_IMAGE):$(CUSTOM_VERSION)-amd64 + docker push $(STAGING_IMAGE):$(CUSTOM_VERSION) + @if docker inspect $(CUSTOM_IMAGE):$(CUSTOM_VERSION)-arm64 &> /dev/null; then \ + echo "Image $(CUSTOM_IMAGE):$(CUSTOM_VERSION)-arm64 exists, building the multiarch manifest"; \ + docker tag $(CUSTOM_IMAGE):$(CUSTOM_VERSION)-arm64 $(STAGING_IMAGE):$(CUSTOM_VERSION)-arm64; \ + docker push $(STAGING_IMAGE):$(CUSTOM_VERSION)-arm64; \ + docker manifest create $(STAGING_IMAGE):$(CUSTOM_VERSION) --amend $(STAGING_IMAGE):$(CUSTOM_VERSION)-amd64 --amend $(STAGING_IMAGE):$(CUSTOM_VERSION)-arm64; \ + docker manifest push --purge $(STAGING_IMAGE):$(CUSTOM_VERSION); \ + else \ + echo "Image $(CUSTOM_IMAGE):$(CUSTOM_VERSION)-arm64 does not exist"; \ + fi get-image: @echo $(CUSTOM_IMAGE) @@ -513,7 +520,7 @@ sbomgen: cyclonedx-gomod mod -licenses -json -output sbom.json # Build images -images-nightly: clean codegen set-version build-resources images +images-nightly: clean codegen set-version build-resources images-all # Release artifacts release-nightly: cross-compile images-push diff --git a/script/get_catalog.sh b/script/get_catalog.sh index 3c5d94c82b..e7fbb2817c 100755 --- a/script/get_catalog.sh +++ b/script/get_catalog.sh @@ -34,7 +34,7 @@ if [ ! -z $2 ]; then fi # Refresh catalog sets. We can clean any leftover as well. -rm -f ${rootdir}/resources/camel-catalog-* +rm -f ${rootdir}/pkg/resources/resources/camel-catalog-* mvn -q dependency:copy -Dartifact="org.apache.camel.k:camel-k-catalog:$runtime_version:yaml:catalog" \ -Dmdep.useBaseVersion=true \