From ea77787896101d2b621cc01421f3b288642dec37 Mon Sep 17 00:00:00 2001 From: ytimocin Date: Tue, 25 Jun 2024 00:28:56 +0300 Subject: [PATCH 1/5] Splitting functional tests as cloud and non-cloud Signed-off-by: ytimocin --- .../workflows/functional-test-noncloud.yaml | 741 ++++++++++++++++++ .github/workflows/functional-test.yaml | 4 +- .github/workflows/long-running-azure.yaml | 2 +- build/test.mk | 12 +- .../contributing-code-building/README.md | 7 +- .../running-functional-tests.md | 43 +- test/executeFunctionalTest.sh | 22 +- 7 files changed, 788 insertions(+), 43 deletions(-) create mode 100644 .github/workflows/functional-test-noncloud.yaml diff --git a/.github/workflows/functional-test-noncloud.yaml b/.github/workflows/functional-test-noncloud.yaml new file mode 100644 index 0000000000..dcf4ab26cc --- /dev/null +++ b/.github/workflows/functional-test-noncloud.yaml @@ -0,0 +1,741 @@ +# ------------------------------------------------------------ +# Copyright 2023 The Radius Authors. +# +# Licensed 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. +# ------------------------------------------------------------ + +name: Functional tests - Non-Cloud + +permissions: + id-token: write # Required for requesting the JWT + contents: read # Required for listing the commits + packages: write # Required for uploading the package + +on: + # Enable manual trigger + workflow_dispatch: + schedule: + # Run every 4 hours on weekdays. + - cron: "30 0,4,8,12,16,20 * * 1-5" + # Run every 12 hours on weekends. + - cron: "30 0,12 * * 0,6" + # Dispatch on external events + repository_dispatch: + types: [de-functional-test] + push: + branches: + - main + - release/* + tags: + - v* + pull_request: + branches: + - main + - features/* + - release/* + +env: + # Go version + GOVER: "1.22.2" + # Go proxy + GOPROXY: https://proxy.golang.org + # gotestsum version - see: https://github.com/gotestyourself/gotestsum + GOTESTSUM_VER: 1.10.0 + # Helm version + HELM_VER: "v3.12.0" + # KinD cluster version + KIND_VER: "v0.20.0" + # Dapr version + DAPR_VER: "1.12.0" + # Dapr dashboard version + DAPR_DASHBOARD_VER: "0.14.0" + # Kubectl version + KUBECTL_VER: "v1.25.0" + # Azure Keyvault CSI driver chart version + AZURE_KEYVAULT_CSI_DRIVER_VER: "1.4.2" + # Azure workload identity webhook chart version + AZURE_WORKLOAD_IDENTITY_WEBHOOK_VER: "1.1.0" + # Container registry for storing container images + CONTAINER_REGISTRY: ghcr.io/radius-project/dev + # Container registry for storing Bicep recipe artifacts + BICEP_RECIPE_REGISTRY: ghcr.io/radius-project/dev + # The radius functional test timeout + FUNCTIONALTEST_TIMEOUT: 30m + # The base directory for storing test logs + RADIUS_CONTAINER_LOG_BASE: dist/container_logs + # The Radius helm chart location. + RADIUS_CHART_LOCATION: deploy/Chart/ + # The current GitHub action link + ACTION_LINK: "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" + # Server where terraform test modules are deployed + TF_RECIPE_MODULE_SERVER_URL: "http://tf-module-server.radius-test-tf-module-server.svc.cluster.local" + # The functional test GitHub app id + FUNCTIONAL_TEST_APP_ID: 425843 + # Private Git repository where terraform module for testing is stored. + TF_RECIPE_PRIVATE_GIT_SOURCE: "git::https://github.com/radius-project/terraform-private-modules//kubernetes-redis" + # The number of failed tests to report. + ISSUE_CREATE_THRESHOLD: 2 + +jobs: + build: + name: Build Radius for test + runs-on: ubuntu-latest + env: + DE_IMAGE: "ghcr.io/radius-project/deployment-engine" + DE_TAG: "latest" + outputs: + REL_VERSION: ${{ steps.gen-id.outputs.REL_VERSION }} + UNIQUE_ID: ${{ steps.gen-id.outputs.UNIQUE_ID }} + PR_NUMBER: ${{ steps.gen-id.outputs.PR_NUMBER }} + CHECKOUT_REPO: ${{ steps.gen-id.outputs.CHECKOUT_REPO }} + CHECKOUT_REF: ${{ steps.gen-id.outputs.CHECKOUT_REF }} + RAD_CLI_ARTIFACT_NAME: ${{ steps.gen-id.outputs.RAD_CLI_ARTIFACT_NAME }} + DE_IMAGE: ${{ steps.gen-id.outputs.DE_IMAGE }} + DE_TAG: ${{ steps.gen-id.outputs.DE_TAG }} + steps: + - name: Get GitHub app token + uses: tibdex/github-app-token@v2 + id: get_installation_token + with: + app_id: ${{ env.FUNCTIONAL_TEST_APP_ID }} + private_key: ${{ secrets.FUNCTIONAL_TEST_APP_PRIVATE_KEY }} + - name: Set up checkout target (scheduled) + if: github.event_name == 'schedule' + run: | + echo "CHECKOUT_REPO=${{ github.repository }}" >> $GITHUB_ENV + echo "CHECKOUT_REF=refs/heads/main" >> $GITHUB_ENV + - name: Set up checkout target (pull_request) + if: github.event_name == 'pull_request' + run: | + echo "CHECKOUT_REPO=${{ github.repository }}" >> $GITHUB_ENV + echo "CHECKOUT_REF=${{ github.ref }}" >> $GITHUB_ENV + echo "PR_NUMBER=${{ github.event.pull_request.number }}" >> $GITHUB_ENV + - name: Use custom actions + uses: actions/checkout@v4 + - name: Set up checkout target (pull_request) + if: github.event_name == 'pull_request' + run: | + echo "CHECKOUT_REPO=${{ github.event.pull_request.head.repo.full_name }}" >> $GITHUB_ENV + echo "CHECKOUT_REF=${{ github.event.pull_request.head.sha }}" >> $GITHUB_ENV + echo "PR_NUMBER=${{ github.event.pull_request.number }}" >> $GITHUB_ENV + - name: Set DE image and tag (repository_dispatch from de-functional-test) + if: github.event_name == 'repository_dispatch' + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.GH_RAD_CI_BOT_PAT }} + script: | + const clientPayload = context.payload.client_payload; + if (clientPayload && clientPayload.event_type === `de-functional-test`) { + var fs = require('fs'); + // Set environment variables + fs.appendFileSync(process.env.GITHUB_ENV, + `DE_IMAGE=${clientPayload.de_image}\n`+ + `DE_TAG=${clientPayload.de_tag}\n`+ + `CHECKOUT_REPO=${{ github.repository }}\n`+ + `CHECKOUT_REF=refs/heads/main` + ); + } + - name: Check out code + uses: actions/checkout@v4 + with: + repository: ${{ env.CHECKOUT_REPO }} + ref: ${{ env.CHECKOUT_REF }} + - name: Set up Go ${{ env.GOVER }} + uses: actions/setup-go@v5 + with: + go-version: ${{ env.GOVER }} + - name: Generate ID for release + id: gen-id + run: | + BASE_STR="RADIUS|${GITHUB_SHA}|${GITHUB_SERVER_URL}|${GITHUB_REPOSITORY}|${GITHUB_RUN_ID}|${GITHUB_RUN_ATTEMPT}" + if [ "$GITHUB_EVENT_NAME" == "schedule" ]; then + # Add run number to randomize unique id for scheduled runs. + BASE_STR="${GITHUB_RUN_NUMBER}|${BASE_STR}" + fi + UNIQUE_ID=func$(echo $BASE_STR | sha1sum | head -c 10) + # `-nc` stands for non-cloud. + echo "REL_VERSION=pr-${UNIQUE_ID}" >> $GITHUB_ENV + + # Set output variables to be used in the other jobs + echo "REL_VERSION=pr-${UNIQUE_ID}" >> $GITHUB_OUTPUT + echo "UNIQUE_ID=${UNIQUE_ID}" >> $GITHUB_OUTPUT + echo "CHECKOUT_REPO=${{ env.CHECKOUT_REPO }}" >> $GITHUB_OUTPUT + echo "CHECKOUT_REF=${{ env.CHECKOUT_REF }}" >> $GITHUB_OUTPUT + echo "RAD_CLI_ARTIFACT_NAME=rad_cli_linux_amd64" >> $GITHUB_OUTPUT + echo "PR_NUMBER=${{ env.PR_NUMBER }}" >> $GITHUB_OUTPUT + echo "DE_IMAGE=${{ env.DE_IMAGE }}" >> $GITHUB_OUTPUT + echo "DE_TAG=${{ env.DE_TAG }}" >> $GITHUB_OUTPUT + - uses: marocchino/sticky-pull-request-comment@v2 + if: env.PR_NUMBER != '' + continue-on-error: true + with: + GITHUB_TOKEN: ${{ steps.get_installation_token.outputs.token }} + header: teststatus-${{ github.run_id }} + number: ${{ env.PR_NUMBER }} + hide: true + hide_classify: "OUTDATED" + message: | + ## Radius functional test (non-cloud) overview + + :mag: **[Go to test action run](${{ env.ACTION_LINK }})** + + | Name | Value | + |------|-------| + |**Repository** | ${{ steps.gen-id.outputs.CHECKOUT_REPO }} | + |**Commit ref** | ${{ steps.gen-id.outputs.CHECKOUT_REF }} | + |**Unique ID** | ${{ steps.gen-id.outputs.UNIQUE_ID }} | + |**Image tag** | ${{ steps.gen-id.outputs.REL_VERSION }} | + +
+ Click here to see the list of tools in the current test run + + * gotestsum ${{ env.GOTESTSUM_VER }} + * KinD: ${{ env.KIND_VER }} + * Dapr: ${{ env.DAPR_VER }} + * Azure KeyVault CSI driver: ${{ env.AZURE_KEYVAULT_CSI_DRIVER_VER }} + * Azure Workload identity webhook: ${{ env.AZURE_WORKLOAD_IDENTITY_WEBHOOK_VER }} + * Bicep recipe location `${{ env.BICEP_RECIPE_REGISTRY }}/test/testrecipes/test-bicep-recipes/:${{ env.REL_VERSION }}` + * Terraform recipe location `${{ env.TF_RECIPE_MODULE_SERVER_URL }}/.zip` (in cluster) + * applications-rp test image location: `${{ env.CONTAINER_REGISTRY }}/applications-rp:${{ env.REL_VERSION }}` + * controller test image location: `${{ env.CONTAINER_REGISTRY }}/controller:${{ env.REL_VERSION }}` + * ucp test image location: `${{ env.CONTAINER_REGISTRY }}/ucpd:${{ env.REL_VERSION }}` + * deployment-engine test image location: `${{ env.DE_IMAGE }}:${{ env.DE_TAG }}` + +
+ + ## Test Status + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - uses: marocchino/sticky-pull-request-comment@v2 + if: env.PR_NUMBER != '' + continue-on-error: true + with: + GITHUB_TOKEN: ${{ steps.get_installation_token.outputs.token }} + header: teststatus-${{ github.run_id }} + number: ${{ env.PR_NUMBER }} + append: true + message: | + :hourglass: Building Radius and pushing container images for functional tests... + - name: Build and Push container images + run: | + make build && make docker-build && make docker-push + env: + DOCKER_REGISTRY: ${{ env.CONTAINER_REGISTRY }} + DOCKER_TAG_VERSION: ${{ env.REL_VERSION }} + - name: Upload CLI binary + uses: actions/upload-artifact@v4 + with: + name: ${{ steps.gen-id.outputs.RAD_CLI_ARTIFACT_NAME }} + path: | + ./dist/linux_amd64/release/rad + - uses: marocchino/sticky-pull-request-comment@v2 + if: success() && env.PR_NUMBER != '' + continue-on-error: true + with: + GITHUB_TOKEN: ${{ steps.get_installation_token.outputs.token }} + header: teststatus-${{ github.run_id }} + number: ${{ env.PR_NUMBER }} + append: true + message: | + :white_check_mark: Container images build succeeded + - uses: marocchino/sticky-pull-request-comment@v2 + if: failure() && env.PR_NUMBER != '' + continue-on-error: true + with: + GITHUB_TOKEN: ${{ steps.get_installation_token.outputs.token }} + header: teststatus-${{ github.run_id }} + number: ${{ env.PR_NUMBER }} + append: true + message: | + :x: Container images build failed + - uses: marocchino/sticky-pull-request-comment@v2 + if: env.PR_NUMBER != '' + continue-on-error: true + with: + GITHUB_TOKEN: ${{ steps.get_installation_token.outputs.token }} + header: teststatus-${{ github.run_id }} + number: ${{ env.PR_NUMBER }} + append: true + message: | + :hourglass: Publishing Bicep Recipes for functional tests... + - name: Publish Bicep Test Recipes + run: | + mkdir ./bin + cp ./dist/linux_amd64/release/rad ./bin/rad + chmod +x ./bin/rad + export PATH=$GITHUB_WORKSPACE/bin:$PATH + which rad || { echo "cannot find rad"; exit 1; } + rad bicep download + rad version + make publish-test-bicep-recipes + env: + BICEP_RECIPE_REGISTRY: ${{ env.BICEP_RECIPE_REGISTRY }} + BICEP_RECIPE_TAG_VERSION: ${{ env.REL_VERSION }} + - uses: marocchino/sticky-pull-request-comment@v2 + if: success() && env.PR_NUMBER != '' + continue-on-error: true + with: + GITHUB_TOKEN: ${{ steps.get_installation_token.outputs.token }} + header: teststatus-${{ github.run_id }} + number: ${{ env.PR_NUMBER }} + append: true + message: | + :white_check_mark: Recipe publishing succeeded + - uses: marocchino/sticky-pull-request-comment@v2 + if: failure() && env.PR_NUMBER != '' + continue-on-error: true + with: + GITHUB_TOKEN: ${{ steps.get_installation_token.outputs.token }} + header: teststatus-${{ github.run_id }} + number: ${{ env.PR_NUMBER }} + append: true + message: | + :x: Test recipe publishing failed + tests: + name: Run ${{ matrix.name }} functional tests + needs: build + strategy: + fail-fast: true + matrix: + os: [ubuntu-latest] + name: + [ + cli-noncloud, + corerp-noncloud, + daprrp-noncloud, + datastoresrp-noncloud, + kubernetes-noncloud, + msgrp-noncloud, + samples-noncloud, + ucp-noncloud, + ] + runs-on: ${{ matrix.os }} + env: + UNIQUE_ID: ${{ needs.build.outputs.UNIQUE_ID }} + REL_VERSION: ${{ needs.build.outputs.REL_VERSION }} + CHECKOUT_REPO: ${{ needs.build.outputs.CHECKOUT_REPO }} + CHECKOUT_REF: ${{ needs.build.outputs.CHECKOUT_REF }} + PR_NUMBER: ${{ needs.build.outputs.PR_NUMBER }} + RAD_CLI_ARTIFACT_NAME: ${{ needs.build.outputs.RAD_CLI_ARTIFACT_NAME }} + BICEP_RECIPE_TAG_VERSION: ${{ needs.build.outputs.REL_VERSION }} + DE_IMAGE: ${{ needs.build.outputs.DE_IMAGE }} + DE_TAG: ${{ needs.build.outputs.DE_TAG }} + steps: + - name: Get GitHub app token + uses: tibdex/github-app-token@v2 + id: get_installation_token + with: + app_id: ${{ env.FUNCTIONAL_TEST_APP_ID }} + private_key: ${{ secrets.FUNCTIONAL_TEST_APP_PRIVATE_KEY }} + - uses: LouisBrunner/checks-action@v2.0.0 + if: always() + with: + token: ${{ steps.get_installation_token.outputs.token }} + name: "Functional Test Run" + status: in_progress + repo: ${{ github.repository }} + sha: ${{ env.CHECKOUT_REF }} + details_url: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + - name: Checkout + uses: actions/checkout@v4 + with: + repository: ${{ env.CHECKOUT_REPO }} + ref: ${{ env.CHECKOUT_REF }} + - name: Checkout samples repo + uses: actions/checkout@v4 + if: matrix.name == 'samples' + with: + repository: radius-project/samples + ref: refs/heads/edge + path: samples + - name: Set up Go ${{ env.GOVER }} + uses: actions/setup-go@v5 + with: + go-version: ${{ env.GOVER }} + - name: Get Go Cache path + id: go-cache-paths + run: | + echo "go-build=$(go env GOCACHE)" >> $GITHUB_OUTPUT + sudo rm -rf $(go env GOCACHE) + + echo "go-mod=$(go env GOMODCACHE)" >> $GITHUB_OUTPUT + sudo rm -rf $(go env GOMODCACHE) + - uses: actions/cache@v4 + with: + path: | + ${{ steps.go-cache-paths.outputs.go-build }} + ${{ steps.go-cache-paths.outputs.go-mod }} + key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} + restore-keys: | + ${{ runner.os }}-go- + - name: Download rad CLI + uses: actions/download-artifact@v4 + with: + name: ${{ env.RAD_CLI_ARTIFACT_NAME }} + path: bin + - name: Login to Azure + uses: azure/login@v2 + with: + client-id: ${{ secrets.AZURE_SP_TESTS_APPID }} + tenant-id: ${{ secrets.AZURE_SP_TESTS_TENANTID }} + subscription-id: ${{ secrets.AZURE_SUBSCRIPTIONID_TESTS }} + - uses: marocchino/sticky-pull-request-comment@v2 + continue-on-error: true + with: + GITHUB_TOKEN: ${{ steps.get_installation_token.outputs.token }} + header: teststatus-${{ github.run_id }} + number: ${{ env.PR_NUMBER }} + append: true + message: | + :hourglass: Starting ${{ matrix.name }} functional tests... + - uses: azure/setup-helm@v4 + with: + version: ${{ env.HELM_VER }} + - name: Create KinD cluster + run: | + curl -sSLo "kind" "https://github.com/kubernetes-sigs/kind/releases/download/${{ env.KIND_VER }}/kind-linux-amd64" + chmod +x ./kind + + # Populate the following environment variables for Azure workload identity from secrets. + # AZURE_OIDC_ISSUER_PUBLIC_KEY + # AZURE_OIDC_ISSUER_PRIVATE_KEY + # AZURE_OIDC_ISSUER + eval "export $(echo "${{ secrets.FUNCTEST_AZURE_OIDC_JSON }}" | jq -r 'to_entries | map("\(.key)=\(.value)") | @sh')" + + AUTHKEY=$(echo -n "${{ github.actor }}:${{ secrets.GH_RAD_CI_BOT_PAT }}" | base64) + echo "{\"auths\":{\"ghcr.io\":{\"auth\":\"${AUTHKEY}\"}}}" > "./ghcr_secret.json" + + # Create KinD cluster with OIDC Issuer keys + echo $AZURE_OIDC_ISSUER_PUBLIC_KEY | base64 -d > sa.pub + echo $AZURE_OIDC_ISSUER_PRIVATE_KEY | base64 -d > sa.key + cat </dev/null 2>&1; then + echo "The release 'radius' exists. Deleting the release..." + helm delete radius -n radius-system + if [ $? -eq 0 ]; then + echo "Release 'radius' deleted successfully." + else + echo "Failed to delete the release 'radius'." + exit 1 + fi + else + echo "Radius release not found. Proceeding with installation." + fi + + echo "*** Installing Radius to Kubernetes ***" + rad install kubernetes \ + --chart ${{ env.RADIUS_CHART_LOCATION }} \ + --set rp.image=${{ env.CONTAINER_REGISTRY }}/applications-rp,rp.tag=${{ env.REL_VERSION }},controller.image=${{ env.CONTAINER_REGISTRY }}/controller,controller.tag=${{ env.REL_VERSION }},ucp.image=${{ env.CONTAINER_REGISTRY }}/ucpd,ucp.tag=${{ env.REL_VERSION }},de.image=${{ env.DE_IMAGE }},de.tag=${{ env.DE_TAG }} + + echo "*** Create workspace, group and environment for test ***" + rad workspace create kubernetes + rad group create kind-radius + rad group switch kind-radius + + # The functional test is designed to use default namespace. So you must create the environment for default namespace. + rad env create kind-radius --namespace default + rad env switch kind-radius + - uses: marocchino/sticky-pull-request-comment@v2 + if: failure() && env.PR_NUMBER != '' + continue-on-error: true + with: + GITHUB_TOKEN: ${{ steps.get_installation_token.outputs.token }} + header: teststatus-${{ github.run_id }} + number: ${{ env.PR_NUMBER }} + append: true + message: | + :x: Failed to install Radius for ${{ matrix.name }} functional test. Please check [the logs](${{ env.ACTION_LINK }}) for more details + - name: Publish Terraform test recipes + run: | + make publish-test-terraform-recipes + - name: Run functional tests + run: | + # Ensure rad cli is in path before running tests. + export PATH=$GITHUB_WORKSPACE/bin:$PATH + # Make directory to capture functional test results + mkdir -p ./dist/functional_test + cd $GITHUB_WORKSPACE + + which rad || { echo "cannot find rad"; exit 1; } + + make test-functional-${{ matrix.name }} + env: + DOCKER_REGISTRY: ${{ env.CONTAINER_REGISTRY }} + TEST_TIMEOUT: ${{ env.FUNCTIONALTEST_TIMEOUT }} + RADIUS_CONTAINER_LOG_PATH: ${{ github.workspace }}/${{ env.RADIUS_CONTAINER_LOG_BASE }} + RADIUS_SAMPLES_REPO_ROOT: ${{ github.workspace }}/samples + BICEP_RECIPE_REGISTRY: ${{ env.BICEP_RECIPE_REGISTRY }} + BICEP_RECIPE_TAG_VERSION: ${{ env.BICEP_RECIPE_TAG_VERSION }} + GH_TOKEN: ${{ steps.get_installation_token.outputs.token }} + GOTESTSUM_OPTS: "--junitfile ./dist/functional_test/results.xml" + - name: Process Functional Test Results + uses: ./.github/actions/process-test-results + # In case of failure, upload functional_test_results to artifacts so that they are not erased by subsequent runs. + if: failure() && github.repository == 'radius-project/radius' + with: + test_group_name: "Functional Tests - ${{ matrix.name }}" + artifact_name: "functional_test_results_${{ matrix.name }}" + result_directory: "dist/functional_test/" + - uses: azure/setup-kubectl@v4 + if: always() + with: + version: ${{ env.KUBECTL_VER }} + - name: Collect detailed Radius logs and events + id: radius-logs-events + if: always() + run: | + # Create Radius logs directory + mkdir -p func-nc/radius-logs-events/${{ matrix.name }} + + # Get pod logs and save to file + namespace="radius-system" + pod_names=($(kubectl get pods -n $namespace -o jsonpath='{.items[*].metadata.name}')) + for pod_name in "${pod_names[@]}"; do + kubectl logs $pod_name -n $namespace > func-nc/radius-logs-events/${{ matrix.name }}/${pod_name}.txt + done + echo "Pod logs saved to func-nc/radius-logs-events/${{ matrix.name }}/" + # Get kubernetes events and save to file + kubectl get events -n $namespace > func-nc/radius-logs-events/${{ matrix.name }}/events.txt + - name: Upload Pod logs for failed tests + uses: actions/upload-artifact@v4 + if: always() && steps.radius-logs-events.outcome == 'success' + with: + name: ${{ matrix.name }}-radius-pod-logs + path: func-nc/radius-logs-events/${{ matrix.name }} + retention-days: 30 + if-no-files-found: error + - name: Collect Pod details + if: always() + run: | + POD_STATE_LOG_FILENAME='${{ env.RADIUS_CONTAINER_LOG_BASE }}/${{ matrix.name }}-tests-pod-states.log' + mkdir -p $(dirname $POD_STATE_LOG_FILENAME) + echo "kubectl get pods -A" >> $POD_STATE_LOG_FILENAME + kubectl get pods -A >> $POD_STATE_LOG_FILENAME + echo "kubectl describe pods -A" >> $POD_STATE_LOG_FILENAME + kubectl describe pods -A >> $POD_STATE_LOG_FILENAME + - name: Upload container logs + if: always() + uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.name }}_container_logs + path: ./${{ env.RADIUS_CONTAINER_LOG_BASE }} + - name: Get Terraform recipe publishing logs + if: always() + run: | + # Create pod-logs directory + mkdir -p recipes/pod-logs + # Get pod logs and save to file + namespace="radius-test-tf-module-server" + label="app.kubernetes.io/name=tf-module-server" + pod_names=($(kubectl get pods -l $label -n $namespace -o jsonpath='{.items[*].metadata.name}')) + for pod_name in "${pod_names[@]}"; do + kubectl logs $pod_name -n $namespace > recipes/pod-logs/${pod_name}.txt + done + echo "Pod logs saved to recipes/pod-logs/" + # Get kubernetes events and save to file + kubectl get events -n $namespace > recipes/pod-logs/events.txt + - name: Upload Terraform recipe publishing logs + uses: actions/upload-artifact@v4 + if: always() + with: + name: ${{ matrix.name }}_recipes-pod-logs + path: recipes/pod-logs + if-no-files-found: error + - uses: marocchino/sticky-pull-request-comment@v2 + if: success() && env.PR_NUMBER != '' + continue-on-error: true + with: + GITHUB_TOKEN: ${{ steps.get_installation_token.outputs.token }} + header: teststatus-${{ github.run_id }} + number: ${{ env.PR_NUMBER }} + append: true + message: | + :white_check_mark: ${{ matrix.name }} functional tests succeeded + - uses: marocchino/sticky-pull-request-comment@v2 + if: failure() && env.PR_NUMBER != '' + continue-on-error: true + with: + GITHUB_TOKEN: ${{ steps.get_installation_token.outputs.token }} + header: teststatus-${{ github.run_id }} + number: ${{ env.PR_NUMBER }} + append: true + message: | + :x: ${{ matrix.name }} functional test failed. Please check [the logs](${{ env.ACTION_LINK }}) for more details + - uses: marocchino/sticky-pull-request-comment@v2 + if: cancelled() && env.PR_NUMBER != '' + continue-on-error: true + with: + GITHUB_TOKEN: ${{ steps.get_installation_token.outputs.token }} + header: teststatus-${{ github.run_id }} + number: ${{ env.PR_NUMBER }} + append: true + message: | + :x: ${{ matrix.name }} functional test cancelled. Please check [the logs](${{ env.ACTION_LINK }}) for more details + report-test-results: + name: Report test results + needs: [build, tests] + runs-on: ubuntu-latest + if: always() + env: + CHECKOUT_REF: ${{ needs.build.outputs.CHECKOUT_REF }} + steps: + - name: Get GitHub app token + uses: tibdex/github-app-token@v2 + id: get_installation_token + with: + app_id: ${{ env.FUNCTIONAL_TEST_APP_ID }} + private_key: ${{ secrets.FUNCTIONAL_TEST_APP_PRIVATE_KEY }} + - name: Get tests job status + id: get_test_status + run: | + # from: https://github.com/orgs/community/discussions/26526#discussioncomment-3252209 + ALL_JOBS_STATUS=$(curl -X GET -s -u "admin:${{ steps.get_installation_token.outputs.token }}" https://api.github.com/repos/${{ github.repository }}/actions/runs/${{ github.run_id }}/jobs | jq ".jobs[] | {job_status: .conclusion}") + echo "All jobs status: $ALL_JOBS_STATUS" + TEST_STATUS="success" + for job_status in $(echo "$ALL_JOBS_STATUS" | jq -r '.[]'); do + echo "Job Status: $job_status" + if [[ "$job_status" == "failure" ]]; then + echo "Found failed test. Setting test status to failure" + TEST_STATUS="failure" + break + elif [[ "$job_status" == "cancelled" ]]; then + echo "Found cancelled test. Setting test status to cancelled" + TEST_STATUS="cancelled" + fi + done + echo "Test Status: $TEST_STATUS" + echo "test_status=$TEST_STATUS" >> $GITHUB_OUTPUT + - uses: LouisBrunner/checks-action@v2.0.0 + if: always() + with: + token: ${{ steps.get_installation_token.outputs.token }} + name: "Functional Test Run" + repo: ${{ github.repository }} + sha: ${{ env.CHECKOUT_REF }} + status: completed + conclusion: ${{ steps.get_test_status.outputs.test_status }} + output: | + {"summary":"Functional Test run completed. See links for more information.","title":"Functional Test Run"} + details_url: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + report-failure: + name: Report test failure + needs: [build, tests] + runs-on: ubuntu-latest + if: failure() && github.event_name == 'schedule' && github.repository == 'radius-project/radius' + steps: + - name: Count recently failed tests + id: count_failures + uses: actions/github-script@v7 + with: + script: | + response = await github.rest.actions.listWorkflowRuns({ + owner: context.repo.owner, + repo: context.repo.repo, + workflow_id: 'functional-test.yaml', + event: 'schedule', + per_page: 10 + }); + + failureCount = 1; + for (const run of response.data.workflow_runs) { + if (run.conclusion === 'failure') { + failureCount++; + } else { + break; + } + } + return failureCount; + - name: Create failure issue for failing scheduled run + uses: actions/github-script@v7 + # Only create an issue if there are (env.ISSUE_CREATE_THRESHOLD) failures of the recent tests. + if: steps.count_failures.outputs.result >= env.ISSUE_CREATE_THRESHOLD + with: + github-token: ${{ secrets.GH_RAD_CI_BOT_PAT }} + script: | + github.rest.issues.create({ + ...context.repo, + title: `Scheduled functional test (noncloud) failed - Run ID: ${context.runId}`, + labels: ['bug', 'test-failure'], + body: `## Bug information \n\nThis bug is generated automatically if the scheduled functional test fails at least ${process.env.ISSUE_CREATE_THRESHOLD} times in a row. The Radius functional test operates on a schedule of every 4 hours during weekdays and every 12 hours over the weekend. It's important to understand that the test may fail due to workflow infrastructure issues, like network problems, rather than the flakiness of the test itself. For the further investigation, please visit [here](${process.env.ACTION_LINK}).` + }) diff --git a/.github/workflows/functional-test.yaml b/.github/workflows/functional-test.yaml index bcf12e2b91..d522955fe5 100644 --- a/.github/workflows/functional-test.yaml +++ b/.github/workflows/functional-test.yaml @@ -324,11 +324,11 @@ jobs: fail-fast: true matrix: os: [ubuntu-latest] - name: [ucp,kubernetes,shared,msgrp,daprrp,samples,cli] + name: [corerp-cloud, ucp-cloud] include: # datastorerp functional tests need the larger VM. - os: ubuntu-latest-m - name: datastoresrp + name: datastoresrp-cloud runs-on: ${{ matrix.os }} env: UNIQUE_ID: ${{ needs.build.outputs.UNIQUE_ID }} diff --git a/.github/workflows/long-running-azure.yaml b/.github/workflows/long-running-azure.yaml index b1f242ce30..93cbd797a7 100644 --- a/.github/workflows/long-running-azure.yaml +++ b/.github/workflows/long-running-azure.yaml @@ -185,7 +185,7 @@ jobs: continue-on-error: true run: | cat < summary.md - ## Radius functional test overview + ## Radius long-running test overview | Name | Value | |------|-------| diff --git a/build/test.mk b/build/test.mk index 8c26c71422..06eca889e1 100644 --- a/build/test.mk +++ b/build/test.mk @@ -58,7 +58,13 @@ test-get-envtools: test-validate-cli: ## Run cli integration tests CGO_ENABLED=1 $(GOTEST_TOOL) -coverpkg= ./pkg/cli/cmd/... ./cmd/rad/... -timeout ${TEST_TIMEOUT} -v -parallel 5 $(GOTEST_OPTS) -test-functional-all: test-functional-ucp test-functional-kubernetes test-functional-shared test-functional-cli test-functional-msgrp test-functional-daprrp test-functional-datastoresrp test-functional-samples ## Runs all functional tests +test-functional-all: test-functional-ucp test-functional-kubernetes test-functional-corerp test-functional-cli test-functional-msgrp test-functional-daprrp test-functional-datastoresrp test-functional-samples ## Runs all functional tests + +# Run all functional tests that do not require cloud resources +test-functional-all-noncloud: test-functional-ucp-noncloud test-functional-kubernetes-noncloud test-functional-corerp-noncloud test-functional-cli-noncloud test-functional-msgrp-noncloud test-functional-daprrp-noncloud test-functional-datastoresrp-noncloud test-functional-samples-noncloud ## Runs all functional tests that do not require cloud resources + +# Run all functional tests that require cloud resources +test-functional-all-cloud: test-functional-ucp-cloud test-functional-corerp-cloud test-functional-datastoresrp-cloud test-functional-ucp: test-functional-ucp-noncloud test-functional-ucp-cloud ## Runs all UCP functional tests (both cloud and non-cloud) @@ -74,7 +80,7 @@ test-functional-kubernetes: test-functional-kubernetes-noncloud ## Runs all Kube test-functional-kubernetes-noncloud: ## Runs Kubernetes functional tests that do not require cloud resources CGO_ENABLED=1 $(GOTEST_TOOL) ./test/functional-portable/kubernetes/noncloud/... -timeout ${TEST_TIMEOUT} -v -parallel 5 $(GOTEST_OPTS) -test-functional-shared: test-functional-corerp-noncloud test-functional-corerp-cloud ## Runs all Core RP functional tests (both cloud and non-cloud) +test-functional-corerp: test-functional-corerp-noncloud test-functional-corerp-cloud ## Runs all Core RP functional tests (both cloud and non-cloud) test-functional-corerp-noncloud: ## Runs corerp functional tests that do not require cloud resources CGO_ENABLED=1 $(GOTEST_TOOL) ./test/functional-portable/corerp/noncloud/... -timeout ${TEST_TIMEOUT} -v -parallel 10 $(GOTEST_OPTS) @@ -95,7 +101,7 @@ test-functional-cli-noncloud: ## Runs cli functional tests that do not require c test-functional-daprrp: test-functional-daprrp-noncloud ## Runs all Dapr RP functional tests (both cloud and non-cloud) test-functional-daprrp-noncloud: ## Runs Dapr RP functional tests that do not require cloud resources - CGO_ENABLED=1 $(GOTEST_TOOL) ./test/functional-portable/daprrp/noncloud/... -timeout ${TEST_TIMEOUT} -v -parallel 3 $(GOTEST_OPTS) +CGO_ENABLED=1 $(GOTEST_TOOL) ./test/functional-portable/daprrp/noncloud/... -timeout ${TEST_TIMEOUT} -v -parallel 3 $(GOTEST_OPTS) test-functional-datastoresrp: test-functional-datastoresrp-noncloud test-functional-datastoresrp-cloud ## Runs all Datastores RP functional tests (non-cloud and cloud) diff --git a/docs/contributing/contributing-code/contributing-code-building/README.md b/docs/contributing/contributing-code/contributing-code-building/README.md index 06af524228..69868dbaa3 100644 --- a/docs/contributing/contributing-code/contributing-code-building/README.md +++ b/docs/contributing/contributing-code/contributing-code-building/README.md @@ -38,7 +38,7 @@ If you work with Radius frequently, you may want to define a shell variable as p ## Generating code -If you are updating API schemas, or updating Go APIs that have mocks, you will need to update the generated code as part of your commit. It is our policy that we **check in** generated code. This minimizes the number of people that have to install the generators and wait for them to run. We validate as part of our PR process that the generated files are up to date. +If you are updating API schemas, or updating Go APIs that have mocks, you will need to update the generated code as part of your commit. It is our policy that we **check in** generated code. This minimizes the number of people that have to install the generators and wait for them to run. We validate as part of our PR process that the generated files are up to date. If you need to do this, first see the [prerequisites](../contributing-code-prerequisites/) for code generation. @@ -48,15 +48,14 @@ Once you have installed the prerequisites, run the following command and then ** make generate ``` -This may take a few minutes as there are several steps. +This may take a few minutes as there are several steps. If you encounter problems please [open an issue](https://github.com/radius-project/radius/issues/new/choose) so we can help. We're trying to make these instructions as streamlined as possible for contributors, your help in identifying problems with the tools and instructions is very much appreciated! - ## Troubleshooting and getting help You might encounter error messages while running various `make` commands due to missing dependencies. Review the [prerequisites](./../contributing-code-prerequisites/) page for installation instructions. If you get stuck working with the repository, please ask for help in our [forum](https://discordapp.com/channels/1113519723347456110/1115302284356767814). We're always interested in ways to improve the tooling, so please feel free to report problems and suggest improvements. -If you need to report an issue with the Makefile, we may ask you for a dump of the variables. You can see the state of all of the variables our Makefile defines with `make dump`. The output will be quite large so you might want to redirect this to a file. \ No newline at end of file +If you need to report an issue with the Makefile, we may ask you for a dump of the variables. You can see the state of all of the variables our Makefile defines with `make dump`. The output will be quite large so you might want to redirect this to a file. diff --git a/docs/contributing/contributing-code/contributing-code-tests/running-functional-tests.md b/docs/contributing/contributing-code/contributing-code-tests/running-functional-tests.md index a0f7943609..80143faa6a 100644 --- a/docs/contributing/contributing-code/contributing-code-tests/running-functional-tests.md +++ b/docs/contributing/contributing-code/contributing-code-tests/running-functional-tests.md @@ -5,8 +5,7 @@ You can find the functional tests under `./test/functional`. A functional test ( These tests verify whether: - That Radius Environment can be created successfully. -- That Bicep templates of sample applications ca be deployed to the Radius Environment. - +- That Bicep templates of sample applications ca be deployed to the Radius Environment. ## Running via GitHub workflow @@ -14,7 +13,7 @@ These tests automatically run for every PR in the `functional-tests.yml` github We do not run these tests for commits to `main` or tags since they might block the build if they fail. -### How this works +### How this works For each PR we run the following set of steps: @@ -40,45 +39,45 @@ As much as possible, the tests use product functionality such as the Radius CLI 2. Make sure `rad-bicep` is downloaded (`rad bicep download`) 3. Make sure your [local dev environment is setup](../contributing-code-control-plane/running-controlplane-locally.md) 4. Log into your Github account and [Generate PAT](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens) -5. Log-in to the container registry of your Github organization. - - `export CR_PAT=` - - `echo $CR_PAT | docker login ghcr.io -u --password-stdin` +5. Log-in to the container registry of your Github organization. + + `export CR_PAT=` + + `echo $CR_PAT | docker login ghcr.io -u --password-stdin` 6. Publish Bicep test recipes by running `BICEP_RECIPE_REGISTRY= make publish-test-bicep-recipes` 7. Publish Terraform test recipes by running `make publish-test-terraform-recipes` 8. Change the visibility of the published packages to 'public' - > ⚠️ The tests assume the Kubernetes namespace in use is `default`. If your environment is set up differently you will see > test failures. > ⚠️ If you set environment variables for functional tests you may need to restart VS Code or other editors for them to take effect. - -### Run + +### Run 1. Run: - ```sh - .{workspace}/radius/test/executeFunctionalTest.sh - ``` + ```sh + .{workspace}/radius/test/executeFunctionalTest.sh + ``` When you're running locally with this configuration, the tests will use your locally selected Radius Environment and your local copy of `rad`. The executeFunctionalTest.sh scripts creates the azure resources and exports the values to be used in the functional test and runs: - ```sh - make test-functional-shared - make test-functional-msgrp - make test-functional-daprrp - make test-functional-datastoresrp - ``` + +```sh + make test-functional-corerp + make test-functional-msgrp + make test-functional-daprrp + make test-functional-datastoresrp +``` You can also run/debug individual tests from VSCode. ### Tips -> 💡 If you make changes to recipes, make sure to re-run the *publish test recipe* step from prerequisites. +> 💡 If you make changes to recipes, make sure to re-run the _publish test recipe_ step from prerequisites. > 💡 Make sure the packages published to your organization have their visibility set to "public" -> 💡 If you make changes to the `rad` CLI make sure to copy it to your path. +> 💡 If you make changes to the `rad` CLI make sure to copy it to your path. ### Seeing log output diff --git a/test/executeFunctionalTest.sh b/test/executeFunctionalTest.sh index c0b72c0ac3..5a389c7835 100755 --- a/test/executeFunctionalTest.sh +++ b/test/executeFunctionalTest.sh @@ -6,7 +6,7 @@ # Licensed 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 @@ -15,12 +15,12 @@ # See the License for the specific language governing permissions and # limitations under the License. # ------------------------------------------------------------ -usage(){ +usage() { echo -e "$0 requires \n" exit 1 } -if [ $# -lt 1 ];then +if [ $# -lt 1 ]; then usage fi @@ -29,17 +29,17 @@ echo $resourcegroup # set the username and password for msqlDB to be passed as parameters to the bicep template adminUser='coolUser' adminPassword=$(uuidgen) -resp=`az deployment group create --resource-group $resourcegroup --template-file createAzureTestResources.bicep --parameters 'adminUsername=$adminUser' --parameters 'adminPassword=$adminPassword'` +resp=$(az deployment group create --resource-group $resourcegroup --template-file createAzureTestResources.bicep --parameters 'adminUsername=$adminUser' --parameters 'adminPassword=$adminPassword') cat resp -export AZURE_SERVICEBUS_RESOURCE_ID=$( jq -r '.properties.outputs.namespaceId.value' <<< "${resp}" ) -export AZURE_MSSQL_RESOURCE_ID=$( jq -r '.properties.outputs.sqlServerId.value' <<< "${resp}" ) +export AZURE_SERVICEBUS_RESOURCE_ID=$(jq -r '.properties.outputs.namespaceId.value' <<<"${resp}") +export AZURE_MSSQL_RESOURCE_ID=$(jq -r '.properties.outputs.sqlServerId.value' <<<"${resp}") export AZURE_MSSQL_USERNAME=$adminUser export AZURE_MSSQL_PASSWORD=$adminPassword -export AZURE_MONGODB_RESOURCE_ID=$( jq -r '.properties.outputs.mongoDatabaseId.value' <<< "${resp}" ) -export AZURE_REDIS_RESOURCE_ID=$( jq -r '.properties.outputs.redisCacheId.value' <<< "${resp}" ) -export AZURE_TABLESTORAGE_RESOURCE_ID=$( jq -r '.properties.outputs.tableStorageAccId.value' <<< "${resp}" ) -export AZURE_COSMOS_MONGODB_ACCOUNT_ID=$( jq -r '.properties.outputs.cosmosMongoAccountID.value' <<< "${resp}" ) -make test-functional-shared +export AZURE_MONGODB_RESOURCE_ID=$(jq -r '.properties.outputs.mongoDatabaseId.value' <<<"${resp}") +export AZURE_REDIS_RESOURCE_ID=$(jq -r '.properties.outputs.redisCacheId.value' <<<"${resp}") +export AZURE_TABLESTORAGE_RESOURCE_ID=$(jq -r '.properties.outputs.tableStorageAccId.value' <<<"${resp}") +export AZURE_COSMOS_MONGODB_ACCOUNT_ID=$(jq -r '.properties.outputs.cosmosMongoAccountID.value' <<<"${resp}") +make test-functional-corerp make test-functional-msgrp make test-functional-daprrp make test-functional-datastoresrp From e70efa96a0981a01037ba6b7632daada7596c43c Mon Sep 17 00:00:00 2001 From: ytimocin Date: Tue, 9 Jul 2024 14:50:40 -0700 Subject: [PATCH 2/5] Fixing a format issue Signed-off-by: ytimocin --- .../actions/process-test-results/action.yaml | 18 +- .../scripts/publish-test-terraform-recipes.py | 18 +- ...l-test.yaml => functional-test-cloud.yaml} | 79 +-- .../workflows/functional-test-noncloud.yaml | 461 +++--------------- .github/workflows/long-running-azure.yaml | 10 +- build/recipes.mk | 1 - build/test.mk | 2 +- .../cloud/resources/microsoftsql_test.go | 1 + .../cloud/resources/mongodb_test.go | 72 +++ .../cloud/resources/redis_test.go | 101 ++++ ...atastoresrp-resources-mongodb-recipe.bicep | 18 +- ...resrp-resources-redis-default-recipe.bicep | 0 .../datastoresrp-resources-redis-recipe.bicep | 12 +- .../noncloud/resources/mongodb_test.go | 46 -- .../noncloud/resources/redis_test.go | 75 --- ...srp-resources-mongodb-recipe-context.bicep | 83 ---- .../datastoresrp-resources-redis-manual.bicep | 6 +- ...oresrp-resources-simulatedenv-recipe.bicep | 18 +- .../datastoresrp-resources-sqldb-manual.bicep | 2 +- .../datastoresrp-rs-mongodb-manual.bicep | 2 - 20 files changed, 345 insertions(+), 680 deletions(-) rename .github/workflows/{functional-test.yaml => functional-test-cloud.yaml} (95%) create mode 100644 test/functional-portable/datastoresrp/cloud/resources/mongodb_test.go create mode 100644 test/functional-portable/datastoresrp/cloud/resources/redis_test.go rename test/functional-portable/datastoresrp/{noncloud => cloud}/resources/testdata/datastoresrp-resources-mongodb-recipe.bicep (83%) rename test/functional-portable/datastoresrp/{noncloud => cloud}/resources/testdata/datastoresrp-resources-redis-default-recipe.bicep (100%) rename test/functional-portable/datastoresrp/{noncloud => cloud}/resources/testdata/datastoresrp-resources-redis-recipe.bicep (79%) delete mode 100644 test/functional-portable/datastoresrp/noncloud/resources/testdata/datastoresrp-resources-mongodb-recipe-context.bicep diff --git a/.github/actions/process-test-results/action.yaml b/.github/actions/process-test-results/action.yaml index 4ed388cd6a..43463d5b54 100644 --- a/.github/actions/process-test-results/action.yaml +++ b/.github/actions/process-test-results/action.yaml @@ -10,30 +10,30 @@ description: | test results format which is what we require. GOTESTSUM_OPTS: '--junitfile ./dist/unit_test_results_raw.xml' - + Then running 'make ' will do the right thing :) inputs: test_group_name: - description: 'Name to use for reporting (eg: Unit Tests)' + description: "Name to use for reporting (eg: Unit Tests)" required: true artifact_name: - description: 'Name to use for uploading artifacts (eg: unit_test_results)' + description: "Name to use for uploading artifacts (eg: unit_test_results)" required: true result_directory: - description: 'Directory containing result XML files. These should be in jUnit format. See the description of the action.' + description: "Directory containing result XML files. These should be in jUnit format. See the description of the action." required: true runs: using: "composite" steps: # The test results file output by gotestsum is missing file and line number on the XML elements # which is needed for the annotations to work. This script adds the missing information. - - name: 'Transform ${{ inputs.test_group_name }} Results' + - name: "Transform ${{ inputs.test_group_name }} Results" # Always is REQUIRED here. Otherwise, the action will be skipped when the unit tests fail, which # defeats the purpose. YES it is counterintuitive. This applies to all of the actions in this file. if: always() - id: 'process_files' - shell: 'bash' + id: "process_files" + shell: "bash" working-directory: ${{ github.workspace }} env: INPUT_DIRECTORY: ${{ inputs.result_directory }} @@ -52,14 +52,14 @@ runs: python3 ./.github/scripts/transform_test_results.py $GITHUB_WORKSPACE "$INPUT_FILE" "$OUTPUT_FILE" echo "wrote ${OUTPUT_FILE}" done - - name: 'Create ${{ inputs.test_group_name }} Result Report' + - name: "Create ${{ inputs.test_group_name }} Result Report" uses: EnricoMi/publish-unit-test-result-action@v2 if: always() with: check_name: ${{ inputs.test_group_name }} files: | ${{ inputs.result_directory }}/processed/*.xml - - name: 'Upload ${{ inputs.test_group_name }} Results' + - name: "Upload ${{ inputs.test_group_name }} Results" uses: actions/upload-artifact@v4 if: always() with: diff --git a/.github/scripts/publish-test-terraform-recipes.py b/.github/scripts/publish-test-terraform-recipes.py index 5b272036c7..15a64d907c 100755 --- a/.github/scripts/publish-test-terraform-recipes.py +++ b/.github/scripts/publish-test-terraform-recipes.py @@ -5,7 +5,7 @@ # Licensed 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 @@ -35,13 +35,14 @@ # Write output to stdout all of the time, and the step summary if we're in Github Actions. step_summary = os.getenv("GITHUB_STEP_SUMMARY") with open(step_summary, "a") if step_summary else contextlib.suppress() as output: - + def log(message): print(message, flush=True) if step_summary: output.write(message + "\n") - log("Publishing recipes from " + recipe_root + " to " + namespace + "/" + config_map_name) + log("Publishing recipes from " + recipe_root + + " to " + namespace + "/" + config_map_name) # Get the list of subfolders in the recipe root. Each one is a recipe. recipe_dirs = [f.path for f in os.scandir(recipe_root) if f.is_dir()] @@ -60,22 +61,25 @@ def log(message): log("Processing recipe: " + recipe_dir) # Make the zip. - output_filename = shutil.make_archive(os.path.join(tmp_dir, os.path.basename(recipe_dir)), 'zip', recipe_dir) + output_filename = shutil.make_archive(os.path.join( + tmp_dir, os.path.basename(recipe_dir)), 'zip', recipe_dir) log("Created zip file: " + output_filename) # Add to config entries config_entries[os.path.basename(recipe_dir)] = output_filename # Delete the configmap if it already exists - args = ["kubectl", "delete", "configmap", config_map_name, "--namespace", namespace, "--ignore-not-found=true"] + args = ["kubectl", "delete", "configmap", config_map_name, + "--namespace", namespace, "--ignore-not-found=true"] process = subprocess.run(args) process.check_returncode() # Create the configmap - args = ["kubectl", "create", "configmap", config_map_name, "--namespace", namespace] + args = ["kubectl", "create", "configmap", + config_map_name, "--namespace", namespace] for recipe_name, zip_file in config_entries.items(): args.append("--from-file=" + recipe_name + ".zip=" + zip_file) process = subprocess.run(args) process.check_returncode() - log("Created configmap: " + namespace + "/" + config_map_name) \ No newline at end of file + log("Created configmap: " + namespace + "/" + config_map_name) diff --git a/.github/workflows/functional-test.yaml b/.github/workflows/functional-test-cloud.yaml similarity index 95% rename from .github/workflows/functional-test.yaml rename to .github/workflows/functional-test-cloud.yaml index d522955fe5..71a8e0aa05 100644 --- a/.github/workflows/functional-test.yaml +++ b/.github/workflows/functional-test-cloud.yaml @@ -4,7 +4,7 @@ # Licensed 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 @@ -14,12 +14,13 @@ # limitations under the License. # ------------------------------------------------------------ -name: Functional tests +name: Functional Tests (with Cloud Resources) permissions: id-token: write # Required for requesting the JWT - contents: read # Required for listing the commits + contents: read # Required for listing the commits packages: write # Required for uploading the package + checks: write # Required for creating a check run on: # Enable manual trigger @@ -33,31 +34,31 @@ on: repository_dispatch: types: [de-functional-test] workflow_run: - workflows: ['Approve Functional Tests'] + workflows: ["Approve Functional Tests"] types: - completed env: # Go version - GOVER: '1.22.2' + GOVER: "1.22.2" GOPROXY: https://proxy.golang.org # gotestsum version - see: https://github.com/gotestyourself/gotestsum - GOTESTSUM_VER: 1.10.0 + GOTESTSUM_VER: 1.12.0 # Helm version - HELM_VER: 'v3.12.0' + HELM_VER: "v3.12.0" # KinD cluster version - KIND_VER: 'v0.20.0' + KIND_VER: "v0.20.0" # Dapr version - DAPR_VER: '1.12.0' - DAPR_DASHBOARD_VER: '0.14.0' + DAPR_VER: "1.12.0" + DAPR_DASHBOARD_VER: "0.14.0" # Kubectl version - KUBECTL_VER: 'v1.25.0' + KUBECTL_VER: "v1.25.0" # Azure Keyvault CSI driver chart version - AZURE_KEYVAULT_CSI_DRIVER_VER: '1.4.2' + AZURE_KEYVAULT_CSI_DRIVER_VER: "1.4.2" # Azure workload identity webhook chart version - AZURE_WORKLOAD_IDENTITY_WEBHOOK_VER: '1.1.0' + AZURE_WORKLOAD_IDENTITY_WEBHOOK_VER: "1.1.0" # Container registry for storing container images CONTAINER_REGISTRY: ghcr.io/radius-project/dev # Container registry for storing Bicep recipe artifacts @@ -71,11 +72,11 @@ env: # The Radius helm chart location. RADIUS_CHART_LOCATION: deploy/Chart/ # The region for AWS resources - AWS_REGION: 'us-west-2' + AWS_REGION: "us-west-2" # The AWS account ID - AWS_ACCOUNT_ID: '${{ secrets.FUNCTEST_AWS_ACCOUNT_ID }}' + AWS_ACCOUNT_ID: "${{ secrets.FUNCTEST_AWS_ACCOUNT_ID }}" # The current GitHub action link - ACTION_LINK: '${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}' + ACTION_LINK: "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" # Server where terraform test modules are deployed TF_RECIPE_MODULE_SERVER_URL: "http://tf-module-server.radius-test-tf-module-server.svc.cluster.local" # The functional test GitHub app id @@ -91,8 +92,8 @@ jobs: runs-on: ubuntu-latest if: github.event_name == 'repository_dispatch' || (github.event_name == 'schedule' && github.repository == 'radius-project/radius') || github.event_name == 'workflow_run' env: - DE_IMAGE: 'ghcr.io/radius-project/deployment-engine' - DE_TAG: 'latest' + DE_IMAGE: "ghcr.io/radius-project/deployment-engine" + DE_TAG: "latest" outputs: REL_VERSION: ${{ steps.gen-id.outputs.REL_VERSION }} UNIQUE_ID: ${{ steps.gen-id.outputs.UNIQUE_ID }} @@ -106,7 +107,7 @@ jobs: - name: Get GitHub app token uses: tibdex/github-app-token@v2 id: get_installation_token - with: + with: app_id: ${{ env.FUNCTIONAL_TEST_APP_ID }} private_key: ${{ secrets.FUNCTIONAL_TEST_APP_PRIVATE_KEY }} - name: Set up checkout target (scheduled) @@ -117,16 +118,16 @@ jobs: - name: Set up checkout target (pull_request) if: github.event_name == 'pull_request' run: | - echo "CHECKOUT_REPO=${{ github.repository }}" >> $GITHUB_ENV - echo "CHECKOUT_REF=${{ github.ref }}" >> $GITHUB_ENV - echo "PR_NUMBER=${{ github.event.pull_request.number }}" >> $GITHUB_ENV + echo "CHECKOUT_REPO=${{ github.repository }}" >> $GITHUB_ENV + echo "CHECKOUT_REF=${{ github.ref }}" >> $GITHUB_ENV + echo "PR_NUMBER=${{ github.event.pull_request.number }}" >> $GITHUB_ENV - name: Use custom actions uses: actions/checkout@v4 - - name: 'Download PR data artifacts' + - name: "Download PR data artifacts" if: github.event_name == 'workflow_run' uses: ./.github/actions/download-pr-data-artifact id: get-pr-number - - name: 'Set PR context (workflow_run)' + - name: "Set PR context (workflow_run)" if: github.event_name == 'workflow_run' uses: actions/github-script@v7 with: @@ -175,7 +176,7 @@ jobs: fi UNIQUE_ID=func$(echo $BASE_STR | sha1sum | head -c 10) echo "REL_VERSION=pr-${UNIQUE_ID}" >> $GITHUB_ENV - + # Set output variables to be used in the other jobs echo "REL_VERSION=pr-${UNIQUE_ID}" >> $GITHUB_OUTPUT echo "UNIQUE_ID=${UNIQUE_ID}" >> $GITHUB_OUTPUT @@ -194,7 +195,7 @@ jobs: header: teststatus-${{ github.run_id }} number: ${{ env.PR_NUMBER }} hide: true - hide_classify: 'OUTDATED' + hide_classify: "OUTDATED" message: | ## Radius functional test overview @@ -223,7 +224,7 @@ jobs: * deployment-engine test image location: `${{ env.DE_IMAGE }}:${{ env.DE_TAG }}` - + ## Test Status - name: Login to GitHub Container Registry uses: docker/login-action@v3 @@ -345,14 +346,14 @@ jobs: - name: Get GitHub app token uses: tibdex/github-app-token@v2 id: get_installation_token - with: + with: app_id: ${{ env.FUNCTIONAL_TEST_APP_ID }} private_key: ${{ secrets.FUNCTIONAL_TEST_APP_PRIVATE_KEY }} - uses: LouisBrunner/checks-action@v2.0.0 if: always() with: token: ${{ steps.get_installation_token.outputs.token }} - name: 'Functional Test Run' + name: "Functional Test Run" status: in_progress repo: ${{ github.repository }} sha: ${{ env.CHECKOUT_REF }} @@ -577,15 +578,15 @@ jobs: BICEP_RECIPE_REGISTRY: ${{ env.BICEP_RECIPE_REGISTRY }} BICEP_RECIPE_TAG_VERSION: ${{ env.BICEP_RECIPE_TAG_VERSION }} GH_TOKEN: ${{ steps.get_installation_token.outputs.token }} - GOTESTSUM_OPTS: '--junitfile ./dist/functional_test/results.xml' + GOTESTSUM_OPTS: "--junitfile ./dist/functional_test/results.xml" - name: Process Functional Test Results uses: ./.github/actions/process-test-results # In case of failure, upload functional_test_results to artifacts so that they are not erased by subsequent runs. if: failure() && github.repository == 'radius-project/radius' with: - test_group_name: 'Functional Tests - ${{ matrix.name }}' - artifact_name: 'functional_test_results_${{ matrix.name }}' - result_directory: 'dist/functional_test/' + test_group_name: "Functional Tests - ${{ matrix.name }}" + artifact_name: "functional_test_results_${{ matrix.name }}" + result_directory: "dist/functional_test/" - uses: azure/setup-kubectl@v4 if: always() with: @@ -620,7 +621,7 @@ jobs: echo "Pod logs saved to recipes/pod-logs/" # Get kubernetes events and save to file kubectl get events -n $namespace > recipes/pod-logs/events.txt - - name: Upload Terraform recipe publishing logs + - name: Upload Terraform recipe publishing logs uses: actions/upload-artifact@v4 if: always() with: @@ -676,7 +677,7 @@ jobs: - name: Get GitHub app token uses: tibdex/github-app-token@v2 id: get_installation_token - with: + with: app_id: ${{ env.FUNCTIONAL_TEST_APP_ID }} private_key: ${{ secrets.FUNCTIONAL_TEST_APP_PRIVATE_KEY }} - name: Get tests job status @@ -703,7 +704,7 @@ jobs: if: always() with: token: ${{ steps.get_installation_token.outputs.token }} - name: 'Functional Test Run' + name: "Functional Test Run" repo: ${{ github.repository }} sha: ${{ env.CHECKOUT_REF }} status: completed @@ -725,11 +726,11 @@ jobs: response = await github.rest.actions.listWorkflowRuns({ owner: context.repo.owner, repo: context.repo.repo, - workflow_id: 'functional-test.yaml', + workflow_id: 'functional-test-cloud.yaml', event: 'schedule', per_page: 10 }); - + failureCount = 1; for (const run of response.data.workflow_runs) { if (run.conclusion === 'failure') { @@ -751,4 +752,4 @@ jobs: title: `Scheduled functional test failed - Run ID: ${context.runId}`, labels: ['bug', 'test-failure'], body: `## Bug information \n\nThis bug is generated automatically if the scheduled functional test fails at least ${process.env.ISSUE_CREATE_THRESHOLD} times in a row. The Radius functional test operates on a schedule of every 4 hours during weekdays and every 12 hours over the weekend. It's important to understand that the test may fail due to workflow infrastructure issues, like network problems, rather than the flakiness of the test itself. For the further investigation, please visit [here](${process.env.ACTION_LINK}).` - }) \ No newline at end of file + }) diff --git a/.github/workflows/functional-test-noncloud.yaml b/.github/workflows/functional-test-noncloud.yaml index dcf4ab26cc..881961cd7a 100644 --- a/.github/workflows/functional-test-noncloud.yaml +++ b/.github/workflows/functional-test-noncloud.yaml @@ -14,12 +14,13 @@ # limitations under the License. # ------------------------------------------------------------ -name: Functional tests - Non-Cloud +name: Functional Tests (with Non-Cloud Resources) permissions: id-token: write # Required for requesting the JWT contents: read # Required for listing the commits packages: write # Required for uploading the package + checks: write # Required for creating a check run on: # Enable manual trigger @@ -47,28 +48,20 @@ on: env: # Go version GOVER: "1.22.2" - # Go proxy - GOPROXY: https://proxy.golang.org - # gotestsum version - see: https://github.com/gotestyourself/gotestsum - GOTESTSUM_VER: 1.10.0 # Helm version HELM_VER: "v3.12.0" # KinD cluster version - KIND_VER: "v0.20.0" + KIND_VER: "v0.23.0" # Dapr version DAPR_VER: "1.12.0" # Dapr dashboard version DAPR_DASHBOARD_VER: "0.14.0" # Kubectl version KUBECTL_VER: "v1.25.0" - # Azure Keyvault CSI driver chart version - AZURE_KEYVAULT_CSI_DRIVER_VER: "1.4.2" - # Azure workload identity webhook chart version - AZURE_WORKLOAD_IDENTITY_WEBHOOK_VER: "1.1.0" # Container registry for storing container images - CONTAINER_REGISTRY: ghcr.io/radius-project/dev + CONTAINER_REGISTRY: ghcr.io/${{ github.repository_owner }}/dev # Container registry for storing Bicep recipe artifacts - BICEP_RECIPE_REGISTRY: ghcr.io/radius-project/dev + BICEP_RECIPE_REGISTRY: ghcr.io/${{ github.repository_owner }}/dev # The radius functional test timeout FUNCTIONALTEST_TIMEOUT: 30m # The base directory for storing test logs @@ -79,8 +72,6 @@ env: ACTION_LINK: "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" # Server where terraform test modules are deployed TF_RECIPE_MODULE_SERVER_URL: "http://tf-module-server.radius-test-tf-module-server.svc.cluster.local" - # The functional test GitHub app id - FUNCTIONAL_TEST_APP_ID: 425843 # Private Git repository where terraform module for testing is stored. TF_RECIPE_PRIVATE_GIT_SOURCE: "git::https://github.com/radius-project/terraform-private-modules//kubernetes-redis" # The number of failed tests to report. @@ -95,39 +86,9 @@ jobs: DE_TAG: "latest" outputs: REL_VERSION: ${{ steps.gen-id.outputs.REL_VERSION }} - UNIQUE_ID: ${{ steps.gen-id.outputs.UNIQUE_ID }} - PR_NUMBER: ${{ steps.gen-id.outputs.PR_NUMBER }} - CHECKOUT_REPO: ${{ steps.gen-id.outputs.CHECKOUT_REPO }} - CHECKOUT_REF: ${{ steps.gen-id.outputs.CHECKOUT_REF }} - RAD_CLI_ARTIFACT_NAME: ${{ steps.gen-id.outputs.RAD_CLI_ARTIFACT_NAME }} DE_IMAGE: ${{ steps.gen-id.outputs.DE_IMAGE }} DE_TAG: ${{ steps.gen-id.outputs.DE_TAG }} steps: - - name: Get GitHub app token - uses: tibdex/github-app-token@v2 - id: get_installation_token - with: - app_id: ${{ env.FUNCTIONAL_TEST_APP_ID }} - private_key: ${{ secrets.FUNCTIONAL_TEST_APP_PRIVATE_KEY }} - - name: Set up checkout target (scheduled) - if: github.event_name == 'schedule' - run: | - echo "CHECKOUT_REPO=${{ github.repository }}" >> $GITHUB_ENV - echo "CHECKOUT_REF=refs/heads/main" >> $GITHUB_ENV - - name: Set up checkout target (pull_request) - if: github.event_name == 'pull_request' - run: | - echo "CHECKOUT_REPO=${{ github.repository }}" >> $GITHUB_ENV - echo "CHECKOUT_REF=${{ github.ref }}" >> $GITHUB_ENV - echo "PR_NUMBER=${{ github.event.pull_request.number }}" >> $GITHUB_ENV - - name: Use custom actions - uses: actions/checkout@v4 - - name: Set up checkout target (pull_request) - if: github.event_name == 'pull_request' - run: | - echo "CHECKOUT_REPO=${{ github.event.pull_request.head.repo.full_name }}" >> $GITHUB_ENV - echo "CHECKOUT_REF=${{ github.event.pull_request.head.sha }}" >> $GITHUB_ENV - echo "PR_NUMBER=${{ github.event.pull_request.number }}" >> $GITHUB_ENV - name: Set DE image and tag (repository_dispatch from de-functional-test) if: github.event_name == 'repository_dispatch' uses: actions/github-script@v7 @@ -145,15 +106,13 @@ jobs: `CHECKOUT_REF=refs/heads/main` ); } + - name: Check out code uses: actions/checkout@v4 with: repository: ${{ env.CHECKOUT_REPO }} ref: ${{ env.CHECKOUT_REF }} - - name: Set up Go ${{ env.GOVER }} - uses: actions/setup-go@v5 - with: - go-version: ${{ env.GOVER }} + - name: Generate ID for release id: gen-id run: | @@ -163,148 +122,13 @@ jobs: BASE_STR="${GITHUB_RUN_NUMBER}|${BASE_STR}" fi UNIQUE_ID=func$(echo $BASE_STR | sha1sum | head -c 10) - # `-nc` stands for non-cloud. echo "REL_VERSION=pr-${UNIQUE_ID}" >> $GITHUB_ENV # Set output variables to be used in the other jobs echo "REL_VERSION=pr-${UNIQUE_ID}" >> $GITHUB_OUTPUT - echo "UNIQUE_ID=${UNIQUE_ID}" >> $GITHUB_OUTPUT - echo "CHECKOUT_REPO=${{ env.CHECKOUT_REPO }}" >> $GITHUB_OUTPUT - echo "CHECKOUT_REF=${{ env.CHECKOUT_REF }}" >> $GITHUB_OUTPUT - echo "RAD_CLI_ARTIFACT_NAME=rad_cli_linux_amd64" >> $GITHUB_OUTPUT - echo "PR_NUMBER=${{ env.PR_NUMBER }}" >> $GITHUB_OUTPUT echo "DE_IMAGE=${{ env.DE_IMAGE }}" >> $GITHUB_OUTPUT echo "DE_TAG=${{ env.DE_TAG }}" >> $GITHUB_OUTPUT - - uses: marocchino/sticky-pull-request-comment@v2 - if: env.PR_NUMBER != '' - continue-on-error: true - with: - GITHUB_TOKEN: ${{ steps.get_installation_token.outputs.token }} - header: teststatus-${{ github.run_id }} - number: ${{ env.PR_NUMBER }} - hide: true - hide_classify: "OUTDATED" - message: | - ## Radius functional test (non-cloud) overview - - :mag: **[Go to test action run](${{ env.ACTION_LINK }})** - - | Name | Value | - |------|-------| - |**Repository** | ${{ steps.gen-id.outputs.CHECKOUT_REPO }} | - |**Commit ref** | ${{ steps.gen-id.outputs.CHECKOUT_REF }} | - |**Unique ID** | ${{ steps.gen-id.outputs.UNIQUE_ID }} | - |**Image tag** | ${{ steps.gen-id.outputs.REL_VERSION }} | - -
- Click here to see the list of tools in the current test run - - * gotestsum ${{ env.GOTESTSUM_VER }} - * KinD: ${{ env.KIND_VER }} - * Dapr: ${{ env.DAPR_VER }} - * Azure KeyVault CSI driver: ${{ env.AZURE_KEYVAULT_CSI_DRIVER_VER }} - * Azure Workload identity webhook: ${{ env.AZURE_WORKLOAD_IDENTITY_WEBHOOK_VER }} - * Bicep recipe location `${{ env.BICEP_RECIPE_REGISTRY }}/test/testrecipes/test-bicep-recipes/:${{ env.REL_VERSION }}` - * Terraform recipe location `${{ env.TF_RECIPE_MODULE_SERVER_URL }}/.zip` (in cluster) - * applications-rp test image location: `${{ env.CONTAINER_REGISTRY }}/applications-rp:${{ env.REL_VERSION }}` - * controller test image location: `${{ env.CONTAINER_REGISTRY }}/controller:${{ env.REL_VERSION }}` - * ucp test image location: `${{ env.CONTAINER_REGISTRY }}/ucpd:${{ env.REL_VERSION }}` - * deployment-engine test image location: `${{ env.DE_IMAGE }}:${{ env.DE_TAG }}` - -
- - ## Test Status - - name: Login to GitHub Container Registry - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - uses: marocchino/sticky-pull-request-comment@v2 - if: env.PR_NUMBER != '' - continue-on-error: true - with: - GITHUB_TOKEN: ${{ steps.get_installation_token.outputs.token }} - header: teststatus-${{ github.run_id }} - number: ${{ env.PR_NUMBER }} - append: true - message: | - :hourglass: Building Radius and pushing container images for functional tests... - - name: Build and Push container images - run: | - make build && make docker-build && make docker-push - env: - DOCKER_REGISTRY: ${{ env.CONTAINER_REGISTRY }} - DOCKER_TAG_VERSION: ${{ env.REL_VERSION }} - - name: Upload CLI binary - uses: actions/upload-artifact@v4 - with: - name: ${{ steps.gen-id.outputs.RAD_CLI_ARTIFACT_NAME }} - path: | - ./dist/linux_amd64/release/rad - - uses: marocchino/sticky-pull-request-comment@v2 - if: success() && env.PR_NUMBER != '' - continue-on-error: true - with: - GITHUB_TOKEN: ${{ steps.get_installation_token.outputs.token }} - header: teststatus-${{ github.run_id }} - number: ${{ env.PR_NUMBER }} - append: true - message: | - :white_check_mark: Container images build succeeded - - uses: marocchino/sticky-pull-request-comment@v2 - if: failure() && env.PR_NUMBER != '' - continue-on-error: true - with: - GITHUB_TOKEN: ${{ steps.get_installation_token.outputs.token }} - header: teststatus-${{ github.run_id }} - number: ${{ env.PR_NUMBER }} - append: true - message: | - :x: Container images build failed - - uses: marocchino/sticky-pull-request-comment@v2 - if: env.PR_NUMBER != '' - continue-on-error: true - with: - GITHUB_TOKEN: ${{ steps.get_installation_token.outputs.token }} - header: teststatus-${{ github.run_id }} - number: ${{ env.PR_NUMBER }} - append: true - message: | - :hourglass: Publishing Bicep Recipes for functional tests... - - name: Publish Bicep Test Recipes - run: | - mkdir ./bin - cp ./dist/linux_amd64/release/rad ./bin/rad - chmod +x ./bin/rad - export PATH=$GITHUB_WORKSPACE/bin:$PATH - which rad || { echo "cannot find rad"; exit 1; } - rad bicep download - rad version - make publish-test-bicep-recipes - env: - BICEP_RECIPE_REGISTRY: ${{ env.BICEP_RECIPE_REGISTRY }} - BICEP_RECIPE_TAG_VERSION: ${{ env.REL_VERSION }} - - uses: marocchino/sticky-pull-request-comment@v2 - if: success() && env.PR_NUMBER != '' - continue-on-error: true - with: - GITHUB_TOKEN: ${{ steps.get_installation_token.outputs.token }} - header: teststatus-${{ github.run_id }} - number: ${{ env.PR_NUMBER }} - append: true - message: | - :white_check_mark: Recipe publishing succeeded - - uses: marocchino/sticky-pull-request-comment@v2 - if: failure() && env.PR_NUMBER != '' - continue-on-error: true - with: - GITHUB_TOKEN: ${{ steps.get_installation_token.outputs.token }} - header: teststatus-${{ github.run_id }} - number: ${{ env.PR_NUMBER }} - append: true - message: | - :x: Test recipe publishing failed + tests: name: Run ${{ matrix.name }} functional tests needs: build @@ -317,55 +141,48 @@ jobs: cli-noncloud, corerp-noncloud, daprrp-noncloud, - datastoresrp-noncloud, kubernetes-noncloud, msgrp-noncloud, samples-noncloud, ucp-noncloud, + datastoresrp-noncloud, ] runs-on: ${{ matrix.os }} env: - UNIQUE_ID: ${{ needs.build.outputs.UNIQUE_ID }} REL_VERSION: ${{ needs.build.outputs.REL_VERSION }} - CHECKOUT_REPO: ${{ needs.build.outputs.CHECKOUT_REPO }} - CHECKOUT_REF: ${{ needs.build.outputs.CHECKOUT_REF }} - PR_NUMBER: ${{ needs.build.outputs.PR_NUMBER }} - RAD_CLI_ARTIFACT_NAME: ${{ needs.build.outputs.RAD_CLI_ARTIFACT_NAME }} BICEP_RECIPE_TAG_VERSION: ${{ needs.build.outputs.REL_VERSION }} DE_IMAGE: ${{ needs.build.outputs.DE_IMAGE }} DE_TAG: ${{ needs.build.outputs.DE_TAG }} steps: - - name: Get GitHub app token - uses: tibdex/github-app-token@v2 - id: get_installation_token - with: - app_id: ${{ env.FUNCTIONAL_TEST_APP_ID }} - private_key: ${{ secrets.FUNCTIONAL_TEST_APP_PRIVATE_KEY }} - - uses: LouisBrunner/checks-action@v2.0.0 - if: always() - with: - token: ${{ steps.get_installation_token.outputs.token }} - name: "Functional Test Run" - status: in_progress - repo: ${{ github.repository }} - sha: ${{ env.CHECKOUT_REF }} - details_url: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} - - name: Checkout + - name: Set up checkout target (scheduled) + if: github.event_name == 'schedule' + run: | + echo "CHECKOUT_REPO=${{ github.repository }}" >> $GITHUB_ENV + echo "CHECKOUT_REF=refs/heads/main" >> $GITHUB_ENV + + - name: Set up checkout target (pull_request) + if: github.event_name == 'pull_request' + run: | + echo "CHECKOUT_REPO=${{ github.repository }}" >> $GITHUB_ENV + echo "CHECKOUT_REF=${{ github.ref }}" >> $GITHUB_ENV + echo "PR_NUMBER=${{ github.event.pull_request.number }}" >> $GITHUB_ENV + + - name: Use custom actions uses: actions/checkout@v4 - with: - repository: ${{ env.CHECKOUT_REPO }} - ref: ${{ env.CHECKOUT_REF }} + - name: Checkout samples repo uses: actions/checkout@v4 - if: matrix.name == 'samples' + if: matrix.name == 'samples-noncloud' with: repository: radius-project/samples ref: refs/heads/edge path: samples + - name: Set up Go ${{ env.GOVER }} uses: actions/setup-go@v5 with: go-version: ${{ env.GOVER }} + - name: Get Go Cache path id: go-cache-paths run: | @@ -374,6 +191,7 @@ jobs: echo "go-mod=$(go env GOMODCACHE)" >> $GITHUB_OUTPUT sudo rm -rf $(go env GOMODCACHE) + - uses: actions/cache@v4 with: path: | @@ -382,108 +200,50 @@ jobs: key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} restore-keys: | ${{ runner.os }}-go- - - name: Download rad CLI - uses: actions/download-artifact@v4 - with: - name: ${{ env.RAD_CLI_ARTIFACT_NAME }} - path: bin - - name: Login to Azure - uses: azure/login@v2 - with: - client-id: ${{ secrets.AZURE_SP_TESTS_APPID }} - tenant-id: ${{ secrets.AZURE_SP_TESTS_TENANTID }} - subscription-id: ${{ secrets.AZURE_SUBSCRIPTIONID_TESTS }} - - uses: marocchino/sticky-pull-request-comment@v2 - continue-on-error: true + + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 with: - GITHUB_TOKEN: ${{ steps.get_installation_token.outputs.token }} - header: teststatus-${{ github.run_id }} - number: ${{ env.PR_NUMBER }} - append: true - message: | - :hourglass: Starting ${{ matrix.name }} functional tests... + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and Push container images + run: | + make build && make docker-build && make docker-push + env: + DOCKER_REGISTRY: ${{ env.CONTAINER_REGISTRY }} + DOCKER_TAG_VERSION: ${{ env.REL_VERSION }} + + - name: Install rad CLI + run: | + mkdir ./bin + cp ./dist/linux_amd64/release/rad ./bin/rad + chmod +x ./bin/rad + export PATH=$GITHUB_WORKSPACE/bin:$PATH + which rad || { echo "cannot find rad"; exit 1; } + rad bicep download + rad version + - uses: azure/setup-helm@v4 with: version: ${{ env.HELM_VER }} + - name: Create KinD cluster run: | curl -sSLo "kind" "https://github.com/kubernetes-sigs/kind/releases/download/${{ env.KIND_VER }}/kind-linux-amd64" chmod +x ./kind - # Populate the following environment variables for Azure workload identity from secrets. - # AZURE_OIDC_ISSUER_PUBLIC_KEY - # AZURE_OIDC_ISSUER_PRIVATE_KEY - # AZURE_OIDC_ISSUER - eval "export $(echo "${{ secrets.FUNCTEST_AZURE_OIDC_JSON }}" | jq -r 'to_entries | map("\(.key)=\(.value)") | @sh')" - - AUTHKEY=$(echo -n "${{ github.actor }}:${{ secrets.GH_RAD_CI_BOT_PAT }}" | base64) - echo "{\"auths\":{\"ghcr.io\":{\"auth\":\"${AUTHKEY}\"}}}" > "./ghcr_secret.json" - - # Create KinD cluster with OIDC Issuer keys - echo $AZURE_OIDC_ISSUER_PUBLIC_KEY | base64 -d > sa.pub - echo $AZURE_OIDC_ISSUER_PRIVATE_KEY | base64 -d > sa.key - cat < func-nc/radius-logs-events/${{ matrix.name }}/events.txt + - name: Upload Pod logs for failed tests uses: actions/upload-artifact@v4 if: always() && steps.radius-logs-events.outcome == 'success' @@ -585,6 +349,7 @@ jobs: path: func-nc/radius-logs-events/${{ matrix.name }} retention-days: 30 if-no-files-found: error + - name: Collect Pod details if: always() run: | @@ -594,12 +359,14 @@ jobs: kubectl get pods -A >> $POD_STATE_LOG_FILENAME echo "kubectl describe pods -A" >> $POD_STATE_LOG_FILENAME kubectl describe pods -A >> $POD_STATE_LOG_FILENAME + - name: Upload container logs if: always() uses: actions/upload-artifact@v4 with: name: ${{ matrix.name }}_container_logs path: ./${{ env.RADIUS_CONTAINER_LOG_BASE }} + - name: Get Terraform recipe publishing logs if: always() run: | @@ -615,6 +382,7 @@ jobs: echo "Pod logs saved to recipes/pod-logs/" # Get kubernetes events and save to file kubectl get events -n $namespace > recipes/pod-logs/events.txt + - name: Upload Terraform recipe publishing logs uses: actions/upload-artifact@v4 if: always() @@ -622,82 +390,7 @@ jobs: name: ${{ matrix.name }}_recipes-pod-logs path: recipes/pod-logs if-no-files-found: error - - uses: marocchino/sticky-pull-request-comment@v2 - if: success() && env.PR_NUMBER != '' - continue-on-error: true - with: - GITHUB_TOKEN: ${{ steps.get_installation_token.outputs.token }} - header: teststatus-${{ github.run_id }} - number: ${{ env.PR_NUMBER }} - append: true - message: | - :white_check_mark: ${{ matrix.name }} functional tests succeeded - - uses: marocchino/sticky-pull-request-comment@v2 - if: failure() && env.PR_NUMBER != '' - continue-on-error: true - with: - GITHUB_TOKEN: ${{ steps.get_installation_token.outputs.token }} - header: teststatus-${{ github.run_id }} - number: ${{ env.PR_NUMBER }} - append: true - message: | - :x: ${{ matrix.name }} functional test failed. Please check [the logs](${{ env.ACTION_LINK }}) for more details - - uses: marocchino/sticky-pull-request-comment@v2 - if: cancelled() && env.PR_NUMBER != '' - continue-on-error: true - with: - GITHUB_TOKEN: ${{ steps.get_installation_token.outputs.token }} - header: teststatus-${{ github.run_id }} - number: ${{ env.PR_NUMBER }} - append: true - message: | - :x: ${{ matrix.name }} functional test cancelled. Please check [the logs](${{ env.ACTION_LINK }}) for more details - report-test-results: - name: Report test results - needs: [build, tests] - runs-on: ubuntu-latest - if: always() - env: - CHECKOUT_REF: ${{ needs.build.outputs.CHECKOUT_REF }} - steps: - - name: Get GitHub app token - uses: tibdex/github-app-token@v2 - id: get_installation_token - with: - app_id: ${{ env.FUNCTIONAL_TEST_APP_ID }} - private_key: ${{ secrets.FUNCTIONAL_TEST_APP_PRIVATE_KEY }} - - name: Get tests job status - id: get_test_status - run: | - # from: https://github.com/orgs/community/discussions/26526#discussioncomment-3252209 - ALL_JOBS_STATUS=$(curl -X GET -s -u "admin:${{ steps.get_installation_token.outputs.token }}" https://api.github.com/repos/${{ github.repository }}/actions/runs/${{ github.run_id }}/jobs | jq ".jobs[] | {job_status: .conclusion}") - echo "All jobs status: $ALL_JOBS_STATUS" - TEST_STATUS="success" - for job_status in $(echo "$ALL_JOBS_STATUS" | jq -r '.[]'); do - echo "Job Status: $job_status" - if [[ "$job_status" == "failure" ]]; then - echo "Found failed test. Setting test status to failure" - TEST_STATUS="failure" - break - elif [[ "$job_status" == "cancelled" ]]; then - echo "Found cancelled test. Setting test status to cancelled" - TEST_STATUS="cancelled" - fi - done - echo "Test Status: $TEST_STATUS" - echo "test_status=$TEST_STATUS" >> $GITHUB_OUTPUT - - uses: LouisBrunner/checks-action@v2.0.0 - if: always() - with: - token: ${{ steps.get_installation_token.outputs.token }} - name: "Functional Test Run" - repo: ${{ github.repository }} - sha: ${{ env.CHECKOUT_REF }} - status: completed - conclusion: ${{ steps.get_test_status.outputs.test_status }} - output: | - {"summary":"Functional Test run completed. See links for more information.","title":"Functional Test Run"} - details_url: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + report-failure: name: Report test failure needs: [build, tests] @@ -712,7 +405,7 @@ jobs: response = await github.rest.actions.listWorkflowRuns({ owner: context.repo.owner, repo: context.repo.repo, - workflow_id: 'functional-test.yaml', + workflow_id: 'functional-test-noncloud.yaml', event: 'schedule', per_page: 10 }); diff --git a/.github/workflows/long-running-azure.yaml b/.github/workflows/long-running-azure.yaml index 93cbd797a7..7774309384 100644 --- a/.github/workflows/long-running-azure.yaml +++ b/.github/workflows/long-running-azure.yaml @@ -34,13 +34,13 @@ # the previous build is still valid. If valid, the workflow skips the build steps # and uses the cached 'rad cli' for testing. # -# Grafana dashboard URL: https://radlrtest00-dashboard-e4ffc0cwggchdhba.wus3.grafana.azure.com +# Grafana dashboard URL: https://radlrtest00-dashboard-e4ffc0cwggchdhba.wus3.grafana.azure.com name: Long-running test on Azure permissions: id-token: write # Required for requesting the JWT - contents: read # Required for actions/checkout + contents: read # Required for actions/checkout packages: write # Required for uploading the package on: @@ -56,7 +56,7 @@ env: GOPROXY: https://proxy.golang.org # gotestsum version - see: https://github.com/gotestyourself/gotestsum - GOTESTSUM_VER: 1.10.0 + GOTESTSUM_VER: 1.12.0 # Container registry for storing container images CONTAINER_REGISTRY: ghcr.io/radius-project/dev @@ -313,7 +313,7 @@ jobs: - name: Get GitHub app token uses: tibdex/github-app-token@v2 id: get_installation_token - with: + with: app_id: ${{ env.FUNCTIONAL_TEST_APP_ID }} private_key: ${{ secrets.FUNCTIONAL_TEST_APP_PRIVATE_KEY }} - name: Checkout @@ -534,7 +534,7 @@ jobs: event: 'schedule', per_page: 10 }); - + failureCount = 1; for (const run of response.data.workflow_runs) { if (run.conclusion === 'failure') { diff --git a/build/recipes.mk b/build/recipes.mk index 60173f8a4f..2584cc8b1b 100644 --- a/build/recipes.mk +++ b/build/recipes.mk @@ -15,7 +15,6 @@ # ------------------------------------------------------------ BICEP_RECIPE_TAG_VERSION?=latest -RAD_BICEP_PATH?=$${HOME}/.rad/bin TERRAFORM_MODULE_SERVER_NAMESPACE=radius-test-tf-module-server TERRAFORM_MODULE_SERVER_DEPLOYMENT_NAME=tf-module-server diff --git a/build/test.mk b/build/test.mk index 06eca889e1..7db7d8e82c 100644 --- a/build/test.mk +++ b/build/test.mk @@ -101,7 +101,7 @@ test-functional-cli-noncloud: ## Runs cli functional tests that do not require c test-functional-daprrp: test-functional-daprrp-noncloud ## Runs all Dapr RP functional tests (both cloud and non-cloud) test-functional-daprrp-noncloud: ## Runs Dapr RP functional tests that do not require cloud resources -CGO_ENABLED=1 $(GOTEST_TOOL) ./test/functional-portable/daprrp/noncloud/... -timeout ${TEST_TIMEOUT} -v -parallel 3 $(GOTEST_OPTS) + CGO_ENABLED=1 $(GOTEST_TOOL) ./test/functional-portable/daprrp/noncloud/... -timeout ${TEST_TIMEOUT} -v -parallel 3 $(GOTEST_OPTS) test-functional-datastoresrp: test-functional-datastoresrp-noncloud test-functional-datastoresrp-cloud ## Runs all Datastores RP functional tests (non-cloud and cloud) diff --git a/test/functional-portable/datastoresrp/cloud/resources/microsoftsql_test.go b/test/functional-portable/datastoresrp/cloud/resources/microsoftsql_test.go index 1b836fc42a..57ad918316 100644 --- a/test/functional-portable/datastoresrp/cloud/resources/microsoftsql_test.go +++ b/test/functional-portable/datastoresrp/cloud/resources/microsoftsql_test.go @@ -44,6 +44,7 @@ func Test_MicrosoftSQL_Manual(t *testing.T) { } else { t.Error("AZURE_MSSQL_USERNAME and AZURE_MSSQL_PASSWORD environment variable must be set to run this test.") } + mssqlresourceid := "mssqlresourceid=" + os.Getenv("AZURE_MSSQL_RESOURCE_ID") sqlDatabse := "database=" + os.Getenv("AZURE_MSSQL_DATABASE") sqlServer := "server=" + os.Getenv("AZURE_MSSQL_SERVER") diff --git a/test/functional-portable/datastoresrp/cloud/resources/mongodb_test.go b/test/functional-portable/datastoresrp/cloud/resources/mongodb_test.go new file mode 100644 index 0000000000..b176975655 --- /dev/null +++ b/test/functional-portable/datastoresrp/cloud/resources/mongodb_test.go @@ -0,0 +1,72 @@ +/* +Copyright 2023 The Radius Authors. + +Licensed 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 resource_test + +import ( + "testing" + + "github.com/radius-project/radius/test/rp" + "github.com/radius-project/radius/test/step" + "github.com/radius-project/radius/test/testutil" + "github.com/radius-project/radius/test/validation" +) + +// Test_MongoDB_Recipe validates: +// the creation of a mongoDB from a recipe that uses an Azure resource +func Test_MongoDB_Recipe(t *testing.T) { + template := "testdata/datastoresrp-resources-mongodb-recipe.bicep" + name := "dsrp-resources-mongodb-recipe" + appNamespace := "dsrp-resources-mongodb-recipe-app" + + test := rp.NewRPTest(t, name, []rp.TestStep{ + { + Executor: step.NewDeployExecutor(template, testutil.GetMagpieImage(), testutil.GetBicepRecipeRegistry(), testutil.GetBicepRecipeVersion()), + RPResources: &validation.RPResourceSet{ + Resources: []validation.RPResource{ + { + Name: "dsrp-resources-mongodb-recipe-env", + Type: validation.EnvironmentsResource, + }, + { + Name: "dsrp-resources-mongodb-recipe", + Type: validation.ApplicationsResource, + App: name, + }, + { + Name: "mongodb-app-ctnr", + Type: validation.ContainersResource, + App: name, + }, + { + Name: "mongodb-db", + Type: validation.MongoDatabasesResource, + App: name, + }, + }, + }, + K8sObjects: &validation.K8sObjectSet{ + Namespaces: map[string][]validation.K8sObject{ + appNamespace: { + validation.NewK8sPodForResource(name, "mongodb-app-ctnr").ValidateLabels(false), + }, + }, + }, + }, + }) + + test.Test(t) +} diff --git a/test/functional-portable/datastoresrp/cloud/resources/redis_test.go b/test/functional-portable/datastoresrp/cloud/resources/redis_test.go new file mode 100644 index 0000000000..ffeb6b8eb5 --- /dev/null +++ b/test/functional-portable/datastoresrp/cloud/resources/redis_test.go @@ -0,0 +1,101 @@ +/* +Copyright 2023 The Radius Authors. + +Licensed 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 resource_test + +import ( + "context" + "strings" + "testing" + + "github.com/radius-project/radius/test/rp" + "github.com/radius-project/radius/test/step" + "github.com/radius-project/radius/test/testutil" + "github.com/radius-project/radius/test/validation" + "github.com/stretchr/testify/require" +) + +func Test_Redis_Recipe(t *testing.T) { + template := "testdata/datastoresrp-resources-redis-recipe.bicep" + name := "dsrp-resources-redis-recipe" + + test := rp.NewRPTest(t, name, []rp.TestStep{ + { + Executor: step.NewDeployExecutor(template, testutil.GetBicepRecipeRegistry(), testutil.GetBicepRecipeVersion()), + RPResources: &validation.RPResourceSet{ + Resources: []validation.RPResource{ + { + Name: "dsrp-resources-env-recipe-env", + Type: validation.EnvironmentsResource, + }, + { + Name: name, + Type: validation.ApplicationsResource, + }, + { + Name: "rds-recipe", + Type: validation.RedisCachesResource, + App: name, + }, + }, + }, + SkipObjectValidation: true, + PostStepVerify: func(ctx context.Context, t *testing.T, test rp.RPTest) { + redis, err := test.Options.ManagementClient.GetResource(ctx, "Applications.Datastores/redisCaches", "rds-recipe") + require.NoError(t, err) + require.NotNil(t, redis) + status := redis.Properties["status"].(map[string]any) + recipe := status["recipe"].(map[string]interface{}) + require.Equal(t, "bicep", recipe["templateKind"].(string)) + templatePath := strings.Split(recipe["templatePath"].(string), ":")[0] + require.Equal(t, "ghcr.io/radius-project/dev/test/testrecipes/test-bicep-recipes/redis-recipe-value-backed", templatePath) + }, + }, + }) + + test.Test(t) +} + +func Test_Redis_DefaultRecipe(t *testing.T) { + template := "testdata/datastoresrp-resources-redis-default-recipe.bicep" + name := "dsrp-resources-redis-default-recipe" + + test := rp.NewRPTest(t, name, []rp.TestStep{ + { + Executor: step.NewDeployExecutor(template, testutil.GetBicepRecipeRegistry(), testutil.GetBicepRecipeVersion()), + RPResources: &validation.RPResourceSet{ + Resources: []validation.RPResource{ + { + Name: "dsrp-resources-env-default-recipe-env", + Type: validation.EnvironmentsResource, + }, + { + Name: name, + Type: validation.ApplicationsResource, + }, + { + Name: "rds-default-recipe", + Type: validation.RedisCachesResource, + App: name, + }, + }, + }, + SkipObjectValidation: true, + }, + }) + + test.Test(t) +} diff --git a/test/functional-portable/datastoresrp/noncloud/resources/testdata/datastoresrp-resources-mongodb-recipe.bicep b/test/functional-portable/datastoresrp/cloud/resources/testdata/datastoresrp-resources-mongodb-recipe.bicep similarity index 83% rename from test/functional-portable/datastoresrp/noncloud/resources/testdata/datastoresrp-resources-mongodb-recipe.bicep rename to test/functional-portable/datastoresrp/cloud/resources/testdata/datastoresrp-resources-mongodb-recipe.bicep index ccdc10dd63..8495e68ef4 100644 --- a/test/functional-portable/datastoresrp/noncloud/resources/testdata/datastoresrp-resources-mongodb-recipe.bicep +++ b/test/functional-portable/datastoresrp/cloud/resources/testdata/datastoresrp-resources-mongodb-recipe.bicep @@ -4,11 +4,11 @@ param rg string = resourceGroup().name param sub string = subscription().subscriptionId -param registry string +param registry string param version string -param magpieimage string +param magpieimage string resource env 'Applications.Core/environments@2023-10-01-preview' = { name: 'dsrp-resources-mongodb-recipe-env' @@ -25,10 +25,10 @@ resource env 'Applications.Core/environments@2023-10-01-preview' = { } } recipes: { - 'Applications.Datastores/mongoDatabases':{ + 'Applications.Datastores/mongoDatabases': { mongoazure: { templateKind: 'bicep' - templatePath: '${registry}/test/testrecipes/test-bicep-recipes/mongodb-recipe-kubernetes:${version}' + templatePath: '${registry}/test/testrecipes/test-bicep-recipes/mongodb-recipe-kubernetes:${version}' } } } @@ -42,8 +42,8 @@ resource app 'Applications.Core/applications@2023-10-01-preview' = { environment: env.id extensions: [ { - kind: 'kubernetesNamespace' - namespace: 'dsrp-resources-mongodb-recipe-app' + kind: 'kubernetesNamespace' + namespace: 'dsrp-resources-mongodb-recipe-app' } ] } @@ -64,9 +64,9 @@ resource webapp 'Applications.Core/containers@2023-10-01-preview' = { env: { DBCONNECTION: recipedb.connectionString() } - readinessProbe:{ - kind:'httpGet' - containerPort:3000 + readinessProbe: { + kind: 'httpGet' + containerPort: 3000 path: '/healthz' } } diff --git a/test/functional-portable/datastoresrp/noncloud/resources/testdata/datastoresrp-resources-redis-default-recipe.bicep b/test/functional-portable/datastoresrp/cloud/resources/testdata/datastoresrp-resources-redis-default-recipe.bicep similarity index 100% rename from test/functional-portable/datastoresrp/noncloud/resources/testdata/datastoresrp-resources-redis-default-recipe.bicep rename to test/functional-portable/datastoresrp/cloud/resources/testdata/datastoresrp-resources-redis-default-recipe.bicep diff --git a/test/functional-portable/datastoresrp/noncloud/resources/testdata/datastoresrp-resources-redis-recipe.bicep b/test/functional-portable/datastoresrp/cloud/resources/testdata/datastoresrp-resources-redis-recipe.bicep similarity index 79% rename from test/functional-portable/datastoresrp/noncloud/resources/testdata/datastoresrp-resources-redis-recipe.bicep rename to test/functional-portable/datastoresrp/cloud/resources/testdata/datastoresrp-resources-redis-recipe.bicep index 99304a666a..a97261e63f 100644 --- a/test/functional-portable/datastoresrp/noncloud/resources/testdata/datastoresrp-resources-redis-recipe.bicep +++ b/test/functional-portable/datastoresrp/cloud/resources/testdata/datastoresrp-resources-redis-recipe.bicep @@ -2,7 +2,7 @@ import radius as radius param scope string = resourceGroup().id -param registry string +param registry string param version string @@ -13,7 +13,7 @@ resource env 'Applications.Core/environments@2023-10-01-preview' = { compute: { kind: 'kubernetes' resourceId: 'self' - namespace: 'dsrp-resources-env-recipe-env' + namespace: 'dsrp-resources-env-recipe-env' } providers: { azure: { @@ -21,10 +21,10 @@ resource env 'Applications.Core/environments@2023-10-01-preview' = { } } recipes: { - 'Applications.Datastores/redisCaches':{ + 'Applications.Datastores/redisCaches': { rediscache: { templateKind: 'bicep' - templatePath: '${registry}/test/testrecipes/test-bicep-recipes/redis-recipe-value-backed:${version}' + templatePath: '${registry}/test/testrecipes/test-bicep-recipes/redis-recipe-value-backed:${version}' } } } @@ -38,8 +38,8 @@ resource app 'Applications.Core/applications@2023-10-01-preview' = { environment: env.id extensions: [ { - kind: 'kubernetesNamespace' - namespace: 'dsrp-resources-redis-recipe-app' + kind: 'kubernetesNamespace' + namespace: 'dsrp-resources-redis-recipe-app' } ] } diff --git a/test/functional-portable/datastoresrp/noncloud/resources/mongodb_test.go b/test/functional-portable/datastoresrp/noncloud/resources/mongodb_test.go index ee4a8de670..cd9c8d67c4 100644 --- a/test/functional-portable/datastoresrp/noncloud/resources/mongodb_test.go +++ b/test/functional-portable/datastoresrp/noncloud/resources/mongodb_test.go @@ -70,49 +70,3 @@ func Test_MongoDB_Manual(t *testing.T) { test.Test(t) } - -// Test_MongoDB_Recipe validates: -// the creation of a mongoDB from a recipe that uses an Azure resource -func Test_MongoDB_Recipe(t *testing.T) { - template := "testdata/datastoresrp-resources-mongodb-recipe.bicep" - name := "dsrp-resources-mongodb-recipe" - appNamespace := "dsrp-resources-mongodb-recipe-app" - - test := rp.NewRPTest(t, name, []rp.TestStep{ - { - Executor: step.NewDeployExecutor(template, testutil.GetMagpieImage(), testutil.GetBicepRecipeRegistry(), testutil.GetBicepRecipeVersion()), - RPResources: &validation.RPResourceSet{ - Resources: []validation.RPResource{ - { - Name: "dsrp-resources-mongodb-recipe-env", - Type: validation.EnvironmentsResource, - }, - { - Name: "dsrp-resources-mongodb-recipe", - Type: validation.ApplicationsResource, - App: name, - }, - { - Name: "mongodb-app-ctnr", - Type: validation.ContainersResource, - App: name, - }, - { - Name: "mongodb-db", - Type: validation.MongoDatabasesResource, - App: name, - }, - }, - }, - K8sObjects: &validation.K8sObjectSet{ - Namespaces: map[string][]validation.K8sObject{ - appNamespace: { - validation.NewK8sPodForResource(name, "mongodb-app-ctnr").ValidateLabels(false), - }, - }, - }, - }, - }) - - test.Test(t) -} diff --git a/test/functional-portable/datastoresrp/noncloud/resources/redis_test.go b/test/functional-portable/datastoresrp/noncloud/resources/redis_test.go index 45acdfc99f..4f672d2530 100644 --- a/test/functional-portable/datastoresrp/noncloud/resources/redis_test.go +++ b/test/functional-portable/datastoresrp/noncloud/resources/redis_test.go @@ -17,15 +17,12 @@ limitations under the License. package resource_test import ( - "context" - "strings" "testing" "github.com/radius-project/radius/test/rp" "github.com/radius-project/radius/test/step" "github.com/radius-project/radius/test/testutil" "github.com/radius-project/radius/test/validation" - "github.com/stretchr/testify/require" ) func Test_Redis_Manual(t *testing.T) { @@ -72,75 +69,3 @@ func Test_Redis_Manual(t *testing.T) { test.Test(t) } - -func Test_Redis_Recipe(t *testing.T) { - template := "testdata/datastoresrp-resources-redis-recipe.bicep" - name := "dsrp-resources-redis-recipe" - - test := rp.NewRPTest(t, name, []rp.TestStep{ - { - Executor: step.NewDeployExecutor(template, testutil.GetBicepRecipeRegistry(), testutil.GetBicepRecipeVersion()), - RPResources: &validation.RPResourceSet{ - Resources: []validation.RPResource{ - { - Name: "dsrp-resources-env-recipe-env", - Type: validation.EnvironmentsResource, - }, - { - Name: name, - Type: validation.ApplicationsResource, - }, - { - Name: "rds-recipe", - Type: validation.RedisCachesResource, - App: name, - }, - }, - }, - SkipObjectValidation: true, - PostStepVerify: func(ctx context.Context, t *testing.T, test rp.RPTest) { - redis, err := test.Options.ManagementClient.GetResource(ctx, "Applications.Datastores/redisCaches", "rds-recipe") - require.NoError(t, err) - require.NotNil(t, redis) - status := redis.Properties["status"].(map[string]any) - recipe := status["recipe"].(map[string]interface{}) - require.Equal(t, "bicep", recipe["templateKind"].(string)) - templatePath := strings.Split(recipe["templatePath"].(string), ":")[0] - require.Equal(t, "ghcr.io/radius-project/dev/test/testrecipes/test-bicep-recipes/redis-recipe-value-backed", templatePath) - }, - }, - }) - - test.Test(t) -} - -func Test_Redis_DefaultRecipe(t *testing.T) { - template := "testdata/datastoresrp-resources-redis-default-recipe.bicep" - name := "dsrp-resources-redis-default-recipe" - - test := rp.NewRPTest(t, name, []rp.TestStep{ - { - Executor: step.NewDeployExecutor(template, testutil.GetBicepRecipeRegistry(), testutil.GetBicepRecipeVersion()), - RPResources: &validation.RPResourceSet{ - Resources: []validation.RPResource{ - { - Name: "dsrp-resources-env-default-recipe-env", - Type: validation.EnvironmentsResource, - }, - { - Name: name, - Type: validation.ApplicationsResource, - }, - { - Name: "rds-default-recipe", - Type: validation.RedisCachesResource, - App: name, - }, - }, - }, - SkipObjectValidation: true, - }, - }) - - test.Test(t) -} diff --git a/test/functional-portable/datastoresrp/noncloud/resources/testdata/datastoresrp-resources-mongodb-recipe-context.bicep b/test/functional-portable/datastoresrp/noncloud/resources/testdata/datastoresrp-resources-mongodb-recipe-context.bicep deleted file mode 100644 index 5c7a0ef04d..0000000000 --- a/test/functional-portable/datastoresrp/noncloud/resources/testdata/datastoresrp-resources-mongodb-recipe-context.bicep +++ /dev/null @@ -1,83 +0,0 @@ -import radius as radius - -param rg string = resourceGroup().name - -param sub string = subscription().subscriptionId - -param registry string - -param version string - -param magpieimage string - -resource env 'Applications.Core/environments@2023-10-01-preview' = { - name: 'dsrp-resources-env-recipes-context-env' - location: 'global' - properties: { - compute: { - kind: 'kubernetes' - resourceId: 'self' - namespace: 'dsrp-resources-env-recipes-context-env' - } - providers: { - azure: { - scope: '/subscriptions/${sub}/resourceGroups/${rg}' - } - } - recipes: { - 'Applications.Datastores/mongoDatabases':{ - default: { - templateKind: 'bicep' - templatePath: '${registry}/test/testrecipes/test-bicep-recipes/mongodb-recipe-context:${version}' - } - } - } - } -} - -resource app 'Applications.Core/applications@2023-10-01-preview' = { - name: 'dsrp-resources-mongodb-recipe-context' - location: 'global' - properties: { - environment: env.id - extensions: [ - { - kind: 'kubernetesNamespace' - namespace: 'dsrp-resources-mongodb-recipe-context-app' - } - ] - } -} - -resource webapp 'Applications.Core/containers@2023-10-01-preview' = { - name: 'mdb-ctx-ctnr' - location: 'global' - properties: { - application: app.id - connections: { - mongodb: { - source: recipedb.id - } - } - container: { - image: magpieimage - env: { - DBCONNECTION: recipedb.connectionString() - } - readinessProbe:{ - kind:'httpGet' - containerPort:3000 - path: '/healthz' - } - } - } -} - -resource recipedb 'Applications.Datastores/mongoDatabases@2023-10-01-preview' = { - name: 'mdb-ctx' - location: 'global' - properties: { - application: app.id - environment: env.id - } -} diff --git a/test/functional-portable/datastoresrp/noncloud/resources/testdata/datastoresrp-resources-redis-manual.bicep b/test/functional-portable/datastoresrp/noncloud/resources/testdata/datastoresrp-resources-redis-manual.bicep index 6153c746ae..dc75968928 100644 --- a/test/functional-portable/datastoresrp/noncloud/resources/testdata/datastoresrp-resources-redis-manual.bicep +++ b/test/functional-portable/datastoresrp/noncloud/resources/testdata/datastoresrp-resources-redis-manual.bicep @@ -3,10 +3,10 @@ import radius as radius param magpieimage string param environment string -resource app 'Applications.Core/applications@2023-10-01-preview' = { +resource app 'Applications.Core/applications@2023-10-01-preview' = { name: 'dsrp-resources-redis-manual' location: 'global' - properties:{ + properties: { environment: environment } } @@ -21,7 +21,7 @@ resource webapp 'Applications.Core/containers@2023-10-01-preview' = { env: { DBCONNECTION: redis.connectionString() } - readinessProbe:{ + readinessProbe: { kind: 'httpGet' containerPort: 3000 path: '/healthz' diff --git a/test/functional-portable/datastoresrp/noncloud/resources/testdata/datastoresrp-resources-simulatedenv-recipe.bicep b/test/functional-portable/datastoresrp/noncloud/resources/testdata/datastoresrp-resources-simulatedenv-recipe.bicep index b590629c85..8b8e867ed5 100644 --- a/test/functional-portable/datastoresrp/noncloud/resources/testdata/datastoresrp-resources-simulatedenv-recipe.bicep +++ b/test/functional-portable/datastoresrp/noncloud/resources/testdata/datastoresrp-resources-simulatedenv-recipe.bicep @@ -1,10 +1,10 @@ import radius as radius -param registry string +param registry string param version string -param magpieimage string +param magpieimage string resource env 'Applications.Core/environments@2023-10-01-preview' = { name: 'dsrp-resources-simenv-recipe-env' @@ -16,10 +16,10 @@ resource env 'Applications.Core/environments@2023-10-01-preview' = { namespace: 'dsrp-resources-simenv-recipe-env' } recipes: { - 'Applications.Datastores/mongoDatabases':{ + 'Applications.Datastores/mongoDatabases': { 'mongodb-recipe-kubernetes': { templateKind: 'bicep' - templatePath: '${registry}/test/testrecipes/test-bicep-recipes/mongodb-recipe-kubernetes:${version}' + templatePath: '${registry}/test/testrecipes/test-bicep-recipes/mongodb-recipe-kubernetes:${version}' } } } @@ -34,8 +34,8 @@ resource app 'Applications.Core/applications@2023-10-01-preview' = { environment: env.id extensions: [ { - kind: 'kubernetesNamespace' - namespace: 'dsrp-resources-simenv-recipe-app' + kind: 'kubernetesNamespace' + namespace: 'dsrp-resources-simenv-recipe-app' } ] } @@ -56,9 +56,9 @@ resource webapp 'Applications.Core/containers@2023-10-01-preview' = { env: { DBCONNECTION: recipedb.connectionString() } - readinessProbe:{ - kind:'httpGet' - containerPort:3000 + readinessProbe: { + kind: 'httpGet' + containerPort: 3000 path: '/healthz' } } diff --git a/test/functional-portable/datastoresrp/noncloud/resources/testdata/datastoresrp-resources-sqldb-manual.bicep b/test/functional-portable/datastoresrp/noncloud/resources/testdata/datastoresrp-resources-sqldb-manual.bicep index e02020b0d8..fdcb0bcefb 100644 --- a/test/functional-portable/datastoresrp/noncloud/resources/testdata/datastoresrp-resources-sqldb-manual.bicep +++ b/test/functional-portable/datastoresrp/noncloud/resources/testdata/datastoresrp-resources-sqldb-manual.bicep @@ -68,7 +68,7 @@ resource db 'Applications.Datastores/sqlDatabases@2023-10-01-preview' = { resourceProvisioning: 'manual' port: sqlPort username: username - secrets:{ + secrets: { password: password } } diff --git a/test/functional-portable/datastoresrp/noncloud/resources/testdata/datastoresrp-rs-mongodb-manual.bicep b/test/functional-portable/datastoresrp/noncloud/resources/testdata/datastoresrp-rs-mongodb-manual.bicep index 857af3ae12..3f472f87e9 100644 --- a/test/functional-portable/datastoresrp/noncloud/resources/testdata/datastoresrp-rs-mongodb-manual.bicep +++ b/test/functional-portable/datastoresrp/noncloud/resources/testdata/datastoresrp-rs-mongodb-manual.bicep @@ -35,8 +35,6 @@ resource webapp 'Applications.Core/containers@2023-10-01-preview' = { } } - -// https://hub.docker.com/_/mongo/ resource mongoContainer 'Applications.Core/containers@2023-10-01-preview' = { name: 'mdb-us-ctnr' location: 'global' From f0720897fad559c6ae07d823f9168b5f52ce47b8 Mon Sep 17 00:00:00 2001 From: ytimocin Date: Tue, 16 Jul 2024 08:24:39 -0700 Subject: [PATCH 3/5] Reverting back to local registry Signed-off-by: ytimocin --- .github/scripts/publish-recipes.sh | 21 ++-- .../workflows/functional-test-noncloud.yaml | 113 ++++++++++++++++-- 2 files changed, 116 insertions(+), 18 deletions(-) diff --git a/.github/scripts/publish-recipes.sh b/.github/scripts/publish-recipes.sh index 74e6b72345..c839334b0d 100755 --- a/.github/scripts/publish-recipes.sh +++ b/.github/scripts/publish-recipes.sh @@ -6,7 +6,7 @@ # Licensed 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 @@ -50,12 +50,11 @@ if [[ -z "$GITHUB_STEP_SUMMARY" ]]; then GITHUB_STEP_SUMMARY=/dev/null fi -echo "## Recipes published to $REGISTRY_PATH" >> $GITHUB_STEP_SUMMARY -for RECIPE in $(find "$DIRECTORY" -type f -name "*.bicep") -do +echo "## Recipes published to $REGISTRY_PATH" >>$GITHUB_STEP_SUMMARY +for RECIPE in $(find "$DIRECTORY" -type f -name "*.bicep"); do FILENAME=$(basename $RECIPE) PUBLISH_REF="$REGISTRY_PATH/${FILENAME%.*}:$RECIPE_VERSION" - + # Skip files that start with _. These are not recipes, they are modules that are # used by the recipes. if [[ $(basename $RECIPE) =~ ^_.* ]]; then @@ -64,6 +63,14 @@ do fi echo "Publishing $RECIPE to $PUBLISH_REF" - echo "- $PUBLISH_REF" >> $GITHUB_STEP_SUMMARY - rad bicep publish --file $RECIPE --target "br:$PUBLISH_REF" + echo "- $PUBLISH_REF" >>$GITHUB_STEP_SUMMARY + + # Check if INSECURE_REGISTRY is set. If it is, we'll use the --plain-http flag when + # publishing the recipe. + if [[ -n "$INSECURE_REGISTRY" ]]; then + echo "INSECURE_REGISTRY is set. Using --plain-http flag." + rad bicep publish --file $RECIPE --target "br:$PUBLISH_REF" --plain-http + else + rad bicep publish --file $RECIPE --target "br:$PUBLISH_REF" + fi done diff --git a/.github/workflows/functional-test-noncloud.yaml b/.github/workflows/functional-test-noncloud.yaml index 881961cd7a..63d6fb8fdb 100644 --- a/.github/workflows/functional-test-noncloud.yaml +++ b/.github/workflows/functional-test-noncloud.yaml @@ -58,12 +58,18 @@ env: DAPR_DASHBOARD_VER: "0.14.0" # Kubectl version KUBECTL_VER: "v1.25.0" + # Container registry for storing container images - CONTAINER_REGISTRY: ghcr.io/${{ github.repository_owner }}/dev + CONTAINER_REGISTRY: "radius-registry:5000" # Container registry for storing Bicep recipe artifacts - BICEP_RECIPE_REGISTRY: ghcr.io/${{ github.repository_owner }}/dev + BICEP_RECIPE_REGISTRY: "radius-registry:5000" + # Local Docker registry name + LOCAL_REGISTRY_NAME: "radius-registry" + # Local Docker registry port + LOCAL_REGISTRY_PORT: "5000" + # The radius functional test timeout - FUNCTIONALTEST_TIMEOUT: 30m + FUNCTIONALTEST_TIMEOUT: 15m # The base directory for storing test logs RADIUS_CONTAINER_LOG_BASE: dist/container_logs # The Radius helm chart location. @@ -74,6 +80,7 @@ env: TF_RECIPE_MODULE_SERVER_URL: "http://tf-module-server.radius-test-tf-module-server.svc.cluster.local" # Private Git repository where terraform module for testing is stored. TF_RECIPE_PRIVATE_GIT_SOURCE: "git::https://github.com/radius-project/terraform-private-modules//kubernetes-redis" + # The number of failed tests to report. ISSUE_CREATE_THRESHOLD: 2 @@ -133,7 +140,7 @@ jobs: name: Run ${{ matrix.name }} functional tests needs: build strategy: - fail-fast: true + fail-fast: false matrix: os: [ubuntu-latest] name: @@ -201,12 +208,31 @@ jobs: restore-keys: | ${{ runner.os }}-go- - - name: Login to GitHub Container Registry - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} + - name: Create local Docker registry + run: | + # This is going to start an insecure registry on localhost:5000 on the host machine. + if [ "$(docker inspect -f '{{.State.Running}}' "${{ env.LOCAL_REGISTRY_NAME }}" 2>/dev/null || true)" != 'true' ]; then + docker run \ + -d --restart=always -p "127.0.0.1:${{ env.LOCAL_REGISTRY_PORT }}:5000" --network bridge --name "${{ env.LOCAL_REGISTRY_NAME }}" \ + registry:2 + fi + + - name: Add insecure registry to Docker daemon + run: | + # Check if /etc/docker/daemon.json exists + if [ ! -f /etc/docker/daemon.json ]; then + echo "daemon.json doesn't exist. Creating one..." + echo '{}' | sudo tee /etc/docker/daemon.json + fi + + # Add insecure registries to /etc/docker/daemon.json + echo '{"insecure-registries": ["radius-registry:5000"]}' | sudo tee /etc/docker/daemon.json + sudo systemctl daemon-reload + sudo systemctl restart docker + + - name: Add radius-registry to /etc/hosts + run: | + sudo sh -c 'echo "127.0.0.1 radius-registry" >> /etc/hosts' - name: Build and Push container images run: | @@ -234,11 +260,72 @@ jobs: curl -sSLo "kind" "https://github.com/kubernetes-sigs/kind/releases/download/${{ env.KIND_VER }}/kind-linux-amd64" chmod +x ./kind + # Create kind cluster with containerd registry config dir enabled cat < Date: Wed, 17 Jul 2024 22:01:42 -0700 Subject: [PATCH 4/5] Adding a secure local registry Signed-off-by: ytimocin --- .../actions/create-kind-cluster/action.yaml | 110 +++++++++++++ .../actions/create-local-registry/action.yaml | 110 +++++++++++++ .../actions/save-pr-as-artifact/action.yaml | 5 +- .github/actions/setup-rad-cli/action.yaml | 1 - .github/scripts/publish-recipes.sh | 10 +- .../workflows/functional-test-noncloud.yaml | 154 +++++------------- .github/workflows/purge-artifacts.yaml | 6 +- .github/workflows/release-verification.yaml | 8 +- .../cli/noncloud/cli_test.go | 4 +- 9 files changed, 270 insertions(+), 138 deletions(-) create mode 100644 .github/actions/create-kind-cluster/action.yaml create mode 100644 .github/actions/create-local-registry/action.yaml diff --git a/.github/actions/create-kind-cluster/action.yaml b/.github/actions/create-kind-cluster/action.yaml new file mode 100644 index 0000000000..c12797b35c --- /dev/null +++ b/.github/actions/create-kind-cluster/action.yaml @@ -0,0 +1,110 @@ +name: "Create a KinD cluster" +description: | + Create a KinD cluster. +inputs: + kind-version: + description: "The version of KinD to install" + required: false + default: "v0.23.0" + with-local-registry: + description: "Whether the KinD cluster should be created with a local registry configuration" + required: false + default: "false" + registry-name: + description: "The name of the local registry" + required: false + default: "radius-registry" + registry-server: + description: "The server name for the local registry" + required: false + default: "localhost" + registry-port: + description: "The port for the local registry" + required: false + default: "5000" +runs: + using: "composite" + steps: + - name: Install KinD + shell: bash + run: | + curl -sSLo "kind" "https://github.com/kubernetes-sigs/kind/releases/download/${{ inputs.kind-version }}/kind-linux-amd64" + chmod +x ./kind + + - name: Create a KinD cluster without a local registry + if: ${{ inputs.with-local-registry == 'false' }} + shell: bash + run: | + cat </dev/null || mktemp -d -t 'temp_cert_dir') + echo "TEMP_CERT_DIR=$temp_cert_dir" >> $GITHUB_ENV + + pushd $temp_cert_dir + # Create the directory for the certificates + mkdir -p certs/${{ inputs.registry-server }} + + echo "==== Generate the openssl config" + create_openssl_cfg >req.cnf + + echo "==== Create the self signed certificate certificate and client key files" + openssl req -x509 \ + -nodes \ + -days 365 \ + -newkey rsa:4096 \ + -keyout certs/${{ inputs.registry-server }}/client.key \ + -out certs/${{ inputs.registry-server }}/client.crt \ + -config req.cnf \ + -sha256 + + - name: Add the certificate to the system trust store + if: ${{ inputs.secure == 'true' }} + shell: bash + run: | + sudo apt install ca-certificates + sudo cp $TEMP_CERT_DIR/certs/${{ inputs.registry-server }}/client.crt /usr/local/share/ca-certificates/${{ inputs.registry-server }}.crt + sudo cp $TEMP_CERT_DIR/certs/${{ inputs.registry-server }}/client.crt /usr/local/share/ca-certificates/${{ inputs.registry-name }}.crt + sudo update-ca-certificates + + - name: Create secure Docker registry + if: ${{ inputs.secure == 'true' }} + shell: bash + run: | + echo "==== Create secure Docker registry" + docker run -d \ + -p ${{ inputs.registry-port }}:5000 \ + --restart=always \ + --name ${{ inputs.registry-name }} \ + -v $TEMP_CERT_DIR/certs/${{ inputs.registry-server }}:/certs \ + -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/client.crt \ + -e REGISTRY_HTTP_TLS_KEY=/certs/client.key \ + registry:2 + + - name: Create insecure Docker registry + if: ${{ inputs.secure == 'false' }} + shell: bash + run: | + echo "==== Create insecure Docker registry" + docker run -d \ + -p ${{ inputs.registry-port }}:5000 \ + --restart=always \ + --name ${{ inputs.registry-name }} \ + registry:2 diff --git a/.github/actions/save-pr-as-artifact/action.yaml b/.github/actions/save-pr-as-artifact/action.yaml index 10d58f1eba..10ba355d72 100644 --- a/.github/actions/save-pr-as-artifact/action.yaml +++ b/.github/actions/save-pr-as-artifact/action.yaml @@ -8,10 +8,9 @@ runs: env: PR_NUMBER: ${{ github.event.number }} run: | - mkdir -p ./pr - echo $PR_NUMBER > ./pr/pr_number + mkdir -p ./pr + echo $PR_NUMBER > ./pr/pr_number - uses: actions/upload-artifact@v4 with: name: pr_number path: pr/ - diff --git a/.github/actions/setup-rad-cli/action.yaml b/.github/actions/setup-rad-cli/action.yaml index bc6e20a957..1f1054acd5 100644 --- a/.github/actions/setup-rad-cli/action.yaml +++ b/.github/actions/setup-rad-cli/action.yaml @@ -35,4 +35,3 @@ runs: shell: bash run: chmod +x rad working-directory: dist - diff --git a/.github/scripts/publish-recipes.sh b/.github/scripts/publish-recipes.sh index c839334b0d..c065f911ea 100755 --- a/.github/scripts/publish-recipes.sh +++ b/.github/scripts/publish-recipes.sh @@ -64,13 +64,5 @@ for RECIPE in $(find "$DIRECTORY" -type f -name "*.bicep"); do echo "Publishing $RECIPE to $PUBLISH_REF" echo "- $PUBLISH_REF" >>$GITHUB_STEP_SUMMARY - - # Check if INSECURE_REGISTRY is set. If it is, we'll use the --plain-http flag when - # publishing the recipe. - if [[ -n "$INSECURE_REGISTRY" ]]; then - echo "INSECURE_REGISTRY is set. Using --plain-http flag." - rad bicep publish --file $RECIPE --target "br:$PUBLISH_REF" --plain-http - else - rad bicep publish --file $RECIPE --target "br:$PUBLISH_REF" - fi + rad bicep publish --file $RECIPE --target "br:$PUBLISH_REF" done diff --git a/.github/workflows/functional-test-noncloud.yaml b/.github/workflows/functional-test-noncloud.yaml index 63d6fb8fdb..854f981433 100644 --- a/.github/workflows/functional-test-noncloud.yaml +++ b/.github/workflows/functional-test-noncloud.yaml @@ -47,9 +47,9 @@ on: env: # Go version - GOVER: "1.22.2" + GOVER: "1.22.5" # Helm version - HELM_VER: "v3.12.0" + HELM_VER: "v3.15.3" # KinD cluster version KIND_VER: "v0.23.0" # Dapr version @@ -57,16 +57,7 @@ env: # Dapr dashboard version DAPR_DASHBOARD_VER: "0.14.0" # Kubectl version - KUBECTL_VER: "v1.25.0" - - # Container registry for storing container images - CONTAINER_REGISTRY: "radius-registry:5000" - # Container registry for storing Bicep recipe artifacts - BICEP_RECIPE_REGISTRY: "radius-registry:5000" - # Local Docker registry name - LOCAL_REGISTRY_NAME: "radius-registry" - # Local Docker registry port - LOCAL_REGISTRY_PORT: "5000" + KUBECTL_VER: "v1.30.0" # The radius functional test timeout FUNCTIONALTEST_TIMEOUT: 15m @@ -84,6 +75,13 @@ env: # The number of failed tests to report. ISSUE_CREATE_THRESHOLD: 2 + # Local Docker registry name + LOCAL_REGISTRY_NAME: "radius-registry" + # Local Docker registry server + LOCAL_REGISTRY_SERVER: "localhost" + # Local Docker registry port + LOCAL_REGISTRY_PORT: "5000" + jobs: build: name: Build Radius for test @@ -140,9 +138,9 @@ jobs: name: Run ${{ matrix.name }} functional tests needs: build strategy: - fail-fast: false + fail-fast: true matrix: - os: [ubuntu-latest] + os: [ubuntu-latest-m] name: [ cli-noncloud, @@ -208,37 +206,19 @@ jobs: restore-keys: | ${{ runner.os }}-go- - - name: Create local Docker registry - run: | - # This is going to start an insecure registry on localhost:5000 on the host machine. - if [ "$(docker inspect -f '{{.State.Running}}' "${{ env.LOCAL_REGISTRY_NAME }}" 2>/dev/null || true)" != 'true' ]; then - docker run \ - -d --restart=always -p "127.0.0.1:${{ env.LOCAL_REGISTRY_PORT }}:5000" --network bridge --name "${{ env.LOCAL_REGISTRY_NAME }}" \ - registry:2 - fi - - - name: Add insecure registry to Docker daemon - run: | - # Check if /etc/docker/daemon.json exists - if [ ! -f /etc/docker/daemon.json ]; then - echo "daemon.json doesn't exist. Creating one..." - echo '{}' | sudo tee /etc/docker/daemon.json - fi - - # Add insecure registries to /etc/docker/daemon.json - echo '{"insecure-registries": ["radius-registry:5000"]}' | sudo tee /etc/docker/daemon.json - sudo systemctl daemon-reload - sudo systemctl restart docker - - - name: Add radius-registry to /etc/hosts - run: | - sudo sh -c 'echo "127.0.0.1 radius-registry" >> /etc/hosts' + - name: Create a secure local registry + uses: ./.github/actions/create-local-registry + with: + secure: "true" + registry-name: ${{ env.LOCAL_REGISTRY_NAME }} + registry-server: ${{ env.LOCAL_REGISTRY_SERVER }} + registry-port: ${{ env.LOCAL_REGISTRY_PORT }} - name: Build and Push container images run: | make build && make docker-build && make docker-push env: - DOCKER_REGISTRY: ${{ env.CONTAINER_REGISTRY }} + DOCKER_REGISTRY: "${{ env.LOCAL_REGISTRY_SERVER }}:${{ env.LOCAL_REGISTRY_PORT }}" DOCKER_TAG_VERSION: ${{ env.REL_VERSION }} - name: Install rad CLI @@ -255,76 +235,14 @@ jobs: with: version: ${{ env.HELM_VER }} - - name: Create KinD cluster - run: | - curl -sSLo "kind" "https://github.com/kubernetes-sigs/kind/releases/download/${{ env.KIND_VER }}/kind-linux-amd64" - chmod +x ./kind - - # Create kind cluster with containerd registry config dir enabled - cat < Date: Fri, 19 Jul 2024 12:03:04 -0700 Subject: [PATCH 5/5] Addressing comments Signed-off-by: ytimocin --- .../actions/create-kind-cluster/action.yaml | 78 ++++++++++---- .../actions/create-local-registry/action.yaml | 21 +++- .../download-pr-data-artifact/action.yaml | 2 +- .github/workflows/functional-test-cloud.yaml | 89 ++++++++++++--- .../workflows/functional-test-noncloud.yaml | 60 ++++++----- .../workflows/functional-tests-approval.yaml | 13 +-- .../cloud/resources/mongodb_test.go | 72 ------------- .../cloud/resources/redis_test.go | 101 ------------------ ...datastoresrp-resources-microsoft-sql.bicep | 6 +- .../noncloud/resources/mongodb_test.go | 44 ++++++++ .../noncloud/resources/redis_test.go | 76 +++++++++++++ ...atastoresrp-resources-mongodb-recipe.bicep | 9 -- ...resrp-resources-redis-default-recipe.bicep | 7 -- .../datastoresrp-resources-redis-recipe.bicep | 7 -- test/testutil/testutil.go | 18 +++- 15 files changed, 328 insertions(+), 275 deletions(-) delete mode 100644 test/functional-portable/datastoresrp/cloud/resources/mongodb_test.go delete mode 100644 test/functional-portable/datastoresrp/cloud/resources/redis_test.go rename test/functional-portable/datastoresrp/{cloud => noncloud}/resources/testdata/datastoresrp-resources-mongodb-recipe.bicep (89%) rename test/functional-portable/datastoresrp/{cloud => noncloud}/resources/testdata/datastoresrp-resources-redis-default-recipe.bicep (91%) rename test/functional-portable/datastoresrp/{cloud => noncloud}/resources/testdata/datastoresrp-resources-redis-recipe.bicep (91%) diff --git a/.github/actions/create-kind-cluster/action.yaml b/.github/actions/create-kind-cluster/action.yaml index c12797b35c..c8e7d3d90b 100644 --- a/.github/actions/create-kind-cluster/action.yaml +++ b/.github/actions/create-kind-cluster/action.yaml @@ -2,6 +2,14 @@ name: "Create a KinD cluster" description: | Create a KinD cluster. inputs: + secure: + description: "Whether the KinD cluster should be created with a secure local registry configuration" + required: false + default: "false" + temp-cert-dir: + description: "The temporary directory where the certificates are stored" + required: false + default: "" kind-version: description: "The version of KinD to install" required: false @@ -12,15 +20,15 @@ inputs: default: "false" registry-name: description: "The name of the local registry" - required: false + required: true default: "radius-registry" registry-server: description: "The server name for the local registry" - required: false + required: true default: "localhost" registry-port: description: "The port for the local registry" - required: false + required: true default: "5000" runs: using: "composite" @@ -35,15 +43,56 @@ runs: if: ${{ inputs.with-local-registry == 'false' }} shell: bash run: | + # https://kind.sigs.k8s.io/docs/user/local-registry/ cat </dev/null || mktemp -d -t 'temp_cert_dir') + echo "TEMP_CERT_DIR=$temp_cert_dir" >> $GITHUB_OUTPUT + - name: Create certificates for local registry if: ${{ inputs.secure == 'true' }} shell: bash @@ -54,11 +67,9 @@ runs: echo "$CFG" } - # Create a temporary directory to store the certificates - temp_cert_dir=$(mktemp -d 2>/dev/null || mktemp -d -t 'temp_cert_dir') - echo "TEMP_CERT_DIR=$temp_cert_dir" >> $GITHUB_ENV + TEMP_CERT_DIR=${{ steps.create-temp-cert-dir.outputs.TEMP_CERT_DIR }} - pushd $temp_cert_dir + pushd $TEMP_CERT_DIR # Create the directory for the certificates mkdir -p certs/${{ inputs.registry-server }} @@ -79,6 +90,7 @@ runs: if: ${{ inputs.secure == 'true' }} shell: bash run: | + TEMP_CERT_DIR=${{ steps.create-temp-cert-dir.outputs.TEMP_CERT_DIR }} sudo apt install ca-certificates sudo cp $TEMP_CERT_DIR/certs/${{ inputs.registry-server }}/client.crt /usr/local/share/ca-certificates/${{ inputs.registry-server }}.crt sudo cp $TEMP_CERT_DIR/certs/${{ inputs.registry-server }}/client.crt /usr/local/share/ca-certificates/${{ inputs.registry-name }}.crt @@ -88,6 +100,7 @@ runs: if: ${{ inputs.secure == 'true' }} shell: bash run: | + TEMP_CERT_DIR=${{ steps.create-temp-cert-dir.outputs.TEMP_CERT_DIR }} echo "==== Create secure Docker registry" docker run -d \ -p ${{ inputs.registry-port }}:5000 \ diff --git a/.github/actions/download-pr-data-artifact/action.yaml b/.github/actions/download-pr-data-artifact/action.yaml index 04b0258adb..009a1ba34a 100644 --- a/.github/actions/download-pr-data-artifact/action.yaml +++ b/.github/actions/download-pr-data-artifact/action.yaml @@ -29,7 +29,7 @@ runs: }); let fs = require('fs'); fs.writeFileSync(`${process.env.GITHUB_WORKSPACE}/pr_number.zip`, Buffer.from(download.data)); - - name: 'Unzip artifact' + - name: "Unzip artifact" shell: bash run: unzip pr_number.zip - name: Set PR number diff --git a/.github/workflows/functional-test-cloud.yaml b/.github/workflows/functional-test-cloud.yaml index 71a8e0aa05..bc81a5a0fc 100644 --- a/.github/workflows/functional-test-cloud.yaml +++ b/.github/workflows/functional-test-cloud.yaml @@ -25,6 +25,11 @@ permissions: on: # Enable manual trigger workflow_dispatch: + inputs: + branch: + description: "Branch to run the workflow on" + required: true + default: "main" schedule: # Run every 4 hours on weekdays. - cron: "30 0,4,8,12,16,20 * * 1-5" @@ -110,23 +115,34 @@ jobs: with: app_id: ${{ env.FUNCTIONAL_TEST_APP_ID }} private_key: ${{ secrets.FUNCTIONAL_TEST_APP_PRIVATE_KEY }} + - name: Set up checkout target (scheduled) - if: github.event_name == 'schedule' + if: github.event_name == 'schedule' || github.event_name == 'repository_dispatch' run: | echo "CHECKOUT_REPO=${{ github.repository }}" >> $GITHUB_ENV echo "CHECKOUT_REF=refs/heads/main" >> $GITHUB_ENV + - name: Set up checkout target (pull_request) if: github.event_name == 'pull_request' run: | echo "CHECKOUT_REPO=${{ github.repository }}" >> $GITHUB_ENV echo "CHECKOUT_REF=${{ github.ref }}" >> $GITHUB_ENV echo "PR_NUMBER=${{ github.event.pull_request.number }}" >> $GITHUB_ENV - - name: Use custom actions + + - name: Set up checkout target (workflow_dispatch) + if: github.event_name == 'workflow_dispatch' + run: | + echo "CHECKOUT_REPO=${{ github.repository }}" >> $GITHUB_ENV + echo "CHECKOUT_REF=refs/heads/${{ github.event.inputs.branch }}" >> $GITHUB_ENV + + - name: Check out code uses: actions/checkout@v4 + - name: "Download PR data artifacts" if: github.event_name == 'workflow_run' uses: ./.github/actions/download-pr-data-artifact id: get-pr-number + - name: "Set PR context (workflow_run)" if: github.event_name == 'workflow_run' uses: actions/github-script@v7 @@ -140,6 +156,7 @@ jobs: `CHECKOUT_REPO=${payload.head_repository.full_name}\n`+ `CHECKOUT_REF=${payload.head_sha}\n` + `PR_NUMBER=${{ steps.get-pr-number.outputs.pr_number }}\n`); + - name: Set DE image and tag (repository_dispatch from de-functional-test) if: github.event_name == 'repository_dispatch' uses: actions/github-script@v7 @@ -157,15 +174,18 @@ jobs: `CHECKOUT_REF=refs/heads/main` ); } + - name: Check out code uses: actions/checkout@v4 with: repository: ${{ env.CHECKOUT_REPO }} ref: ${{ env.CHECKOUT_REF }} + - name: Set up Go ${{ env.GOVER }} uses: actions/setup-go@v5 with: go-version: ${{ env.GOVER }} + - name: Generate ID for release id: gen-id run: | @@ -187,6 +207,7 @@ jobs: echo "PR_NUMBER=${{ env.PR_NUMBER }}" >> $GITHUB_OUTPUT echo "DE_IMAGE=${{ env.DE_IMAGE }}" >> $GITHUB_OUTPUT echo "DE_TAG=${{ env.DE_TAG }}" >> $GITHUB_OUTPUT + - uses: marocchino/sticky-pull-request-comment@v2 if: env.PR_NUMBER != '' continue-on-error: true @@ -226,12 +247,14 @@ jobs: ## Test Status + - name: Login to GitHub Container Registry uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - uses: marocchino/sticky-pull-request-comment@v2 if: env.PR_NUMBER != '' continue-on-error: true @@ -242,18 +265,21 @@ jobs: append: true message: | :hourglass: Building Radius and pushing container images for functional tests... + - name: Build and Push container images run: | make build && make docker-build && make docker-push env: DOCKER_REGISTRY: ${{ env.CONTAINER_REGISTRY }} DOCKER_TAG_VERSION: ${{ env.REL_VERSION }} + - name: Upload CLI binary uses: actions/upload-artifact@v4 with: name: ${{ steps.gen-id.outputs.RAD_CLI_ARTIFACT_NAME }} path: | ./dist/linux_amd64/release/rad + - uses: marocchino/sticky-pull-request-comment@v2 if: success() && env.PR_NUMBER != '' continue-on-error: true @@ -264,6 +290,7 @@ jobs: append: true message: | :white_check_mark: Container images build succeeded + - uses: marocchino/sticky-pull-request-comment@v2 if: failure() && env.PR_NUMBER != '' continue-on-error: true @@ -274,6 +301,7 @@ jobs: append: true message: | :x: Container images build failed + - uses: marocchino/sticky-pull-request-comment@v2 if: env.PR_NUMBER != '' continue-on-error: true @@ -284,6 +312,7 @@ jobs: append: true message: | :hourglass: Publishing Bicep Recipes for functional tests... + - name: Publish Bicep Test Recipes run: | mkdir ./bin @@ -297,6 +326,7 @@ jobs: env: BICEP_RECIPE_REGISTRY: ${{ env.BICEP_RECIPE_REGISTRY }} BICEP_RECIPE_TAG_VERSION: ${{ env.REL_VERSION }} + - uses: marocchino/sticky-pull-request-comment@v2 if: success() && env.PR_NUMBER != '' continue-on-error: true @@ -307,6 +337,7 @@ jobs: append: true message: | :white_check_mark: Recipe publishing succeeded + - uses: marocchino/sticky-pull-request-comment@v2 if: failure() && env.PR_NUMBER != '' continue-on-error: true @@ -317,6 +348,7 @@ jobs: append: true message: | :x: Test recipe publishing failed + tests: name: Run ${{ matrix.name }} functional tests needs: build @@ -324,12 +356,8 @@ jobs: strategy: fail-fast: true matrix: - os: [ubuntu-latest] - name: [corerp-cloud, ucp-cloud] - include: - # datastorerp functional tests need the larger VM. - - os: ubuntu-latest-m - name: datastoresrp-cloud + os: [ubuntu-latest-m] + name: [corerp-cloud, ucp-cloud, datastoresrp-cloud] runs-on: ${{ matrix.os }} env: UNIQUE_ID: ${{ needs.build.outputs.UNIQUE_ID }} @@ -349,6 +377,7 @@ jobs: with: app_id: ${{ env.FUNCTIONAL_TEST_APP_ID }} private_key: ${{ secrets.FUNCTIONAL_TEST_APP_PRIVATE_KEY }} + - uses: LouisBrunner/checks-action@v2.0.0 if: always() with: @@ -358,27 +387,32 @@ jobs: repo: ${{ github.repository }} sha: ${{ env.CHECKOUT_REF }} details_url: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} - - name: Checkout + + - name: Checkout Radius repository uses: actions/checkout@v4 with: repository: ${{ env.CHECKOUT_REPO }} ref: ${{ env.CHECKOUT_REF }} - - name: Checkout samples repo + + - name: Checkout Samples repository uses: actions/checkout@v4 if: matrix.name == 'samples' with: repository: radius-project/samples ref: refs/heads/edge path: samples + - name: Set up Go ${{ env.GOVER }} uses: actions/setup-go@v5 with: go-version: ${{ env.GOVER }} + - name: Get Go Cache path id: go-cache-paths run: | echo "go-build=$(go env GOCACHE)" >> $GITHUB_OUTPUT echo "go-mod=$(go env GOMODCACHE)" >> $GITHUB_OUTPUT + - uses: actions/cache@v4 with: path: | @@ -387,17 +421,20 @@ jobs: key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} restore-keys: | ${{ runner.os }}-go- + - name: Download rad CLI uses: actions/download-artifact@v4 with: name: ${{ env.RAD_CLI_ARTIFACT_NAME }} path: bin + - name: Login to Azure uses: azure/login@v2 with: client-id: ${{ secrets.AZURE_SP_TESTS_APPID }} tenant-id: ${{ secrets.AZURE_SP_TESTS_TENANTID }} subscription-id: ${{ secrets.AZURE_SUBSCRIPTIONID_TESTS }} + - uses: marocchino/sticky-pull-request-comment@v2 continue-on-error: true with: @@ -407,6 +444,7 @@ jobs: append: true message: | :hourglass: Starting ${{ matrix.name }} functional tests... + - name: Create azure resource group - ${{ env.AZURE_TEST_RESOURCE_GROUP }} run: | current_time=$(date +%s) @@ -418,9 +456,11 @@ jobs: while [ $(az group exists --name $RESOURCE_GROUP) = false ]; do sleep 2; done env: RESOURCE_GROUP: ${{ env.AZURE_TEST_RESOURCE_GROUP }} + - uses: azure/setup-helm@v4 with: version: ${{ env.HELM_VER }} + - name: Create KinD cluster run: | curl -sSLo "kind" "https://github.com/kubernetes-sigs/kind/releases/download/${{ env.KIND_VER }}/kind-linux-amd64" @@ -462,24 +502,29 @@ jobs: extraArgs: service-account-private-key-file: /etc/kubernetes/pki/sa.key EOF + - name: Install dapr into cluster run: | wget -q https://raw.githubusercontent.com/dapr/cli/master/install/install.sh -O - | /bin/bash -s ${{ env.DAPR_VER }} dapr init -k --wait --timeout 600 --runtime-version ${{ env.DAPR_VER }} --dashboard-version ${{ env.DAPR_DASHBOARD_VER }} + - name: Install Azure Keyvault CSI driver chart run: | helm repo add csi-secrets-store-provider-azure https://azure.github.io/secrets-store-csi-driver-provider-azure/charts helm install csi csi-secrets-store-provider-azure/csi-secrets-store-provider-azure --version ${{ env.AZURE_KEYVAULT_CSI_DRIVER_VER }} + - name: Install azure workload identity webhook chart run: | helm repo add azure-workload-identity https://azure.github.io/azure-workload-identity/charts helm install workload-identity-webhook azure-workload-identity/workload-identity-webhook --namespace radius-default --create-namespace --version ${{ env.AZURE_WORKLOAD_IDENTITY_WEBHOOK_VER }} --set azureTenantID=${{ secrets.AZURE_SP_TESTS_TENANTID }} + - name: Login to GitHub Container Registry uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Download Bicep run: | chmod +x ./bin/rad @@ -487,9 +532,11 @@ jobs: which rad || { echo "cannot find rad"; exit 1; } rad bicep download rad version + - name: Install gotestsum (test reporting tool) run: | go install gotest.tools/gotestsum@v${{ env.GOTESTSUM_VER }} + - uses: marocchino/sticky-pull-request-comment@v2 if: failure() && env.PR_NUMBER != '' continue-on-error: true @@ -500,6 +547,7 @@ jobs: append: true message: | :x: Test tool installation for ${{ matrix.name }} failed. Please check [the logs](${{ env.ACTION_LINK }}) for more details + - name: Install Radius run: | export PATH=$GITHUB_WORKSPACE/bin:$PATH @@ -530,6 +578,7 @@ jobs: rad env update kind-radius --aws-region ${{ env.AWS_REGION }} --aws-account-id ${{ secrets.FUNCTEST_AWS_ACCOUNT_ID }} rad credential register aws \ --access-key-id ${{ secrets.FUNCTEST_AWS_ACCESS_KEY_ID }} --secret-access-key ${{ secrets.FUNCTEST_AWS_SECRET_ACCESS_KEY }} + - uses: marocchino/sticky-pull-request-comment@v2 if: failure() && env.PR_NUMBER != '' continue-on-error: true @@ -540,9 +589,11 @@ jobs: append: true message: | :x: Failed to install Radius for ${{ matrix.name }} functional test. Please check [the logs](${{ env.ACTION_LINK }}) for more details + - name: Publish Terraform test recipes run: | make publish-test-terraform-recipes + - name: Run functional tests run: | # Ensure rad cli is in path before running tests. @@ -579,6 +630,7 @@ jobs: BICEP_RECIPE_TAG_VERSION: ${{ env.BICEP_RECIPE_TAG_VERSION }} GH_TOKEN: ${{ steps.get_installation_token.outputs.token }} GOTESTSUM_OPTS: "--junitfile ./dist/functional_test/results.xml" + - name: Process Functional Test Results uses: ./.github/actions/process-test-results # In case of failure, upload functional_test_results to artifacts so that they are not erased by subsequent runs. @@ -587,10 +639,7 @@ jobs: test_group_name: "Functional Tests - ${{ matrix.name }}" artifact_name: "functional_test_results_${{ matrix.name }}" result_directory: "dist/functional_test/" - - uses: azure/setup-kubectl@v4 - if: always() - with: - version: ${{ env.KUBECTL_VER }} + - name: Collect Pod details if: always() run: | @@ -600,12 +649,14 @@ jobs: kubectl get pods -A >> $POD_STATE_LOG_FILENAME echo "kubectl describe pods -A" >> $POD_STATE_LOG_FILENAME kubectl describe pods -A >> $POD_STATE_LOG_FILENAME + - name: Upload container logs if: always() uses: actions/upload-artifact@v4 with: name: ${{ matrix.name }}_container_logs path: ./${{ env.RADIUS_CONTAINER_LOG_BASE }} + - name: Get Terraform recipe publishing logs if: always() run: | @@ -621,6 +672,7 @@ jobs: echo "Pod logs saved to recipes/pod-logs/" # Get kubernetes events and save to file kubectl get events -n $namespace > recipes/pod-logs/events.txt + - name: Upload Terraform recipe publishing logs uses: actions/upload-artifact@v4 if: always() @@ -628,6 +680,7 @@ jobs: name: ${{ matrix.name }}_recipes-pod-logs path: recipes/pod-logs if-no-files-found: error + - uses: marocchino/sticky-pull-request-comment@v2 if: success() && env.PR_NUMBER != '' continue-on-error: true @@ -638,6 +691,7 @@ jobs: append: true message: | :white_check_mark: ${{ matrix.name }} functional tests succeeded + - uses: marocchino/sticky-pull-request-comment@v2 if: failure() && env.PR_NUMBER != '' continue-on-error: true @@ -648,6 +702,7 @@ jobs: append: true message: | :x: ${{ matrix.name }} functional test failed. Please check [the logs](${{ env.ACTION_LINK }}) for more details + - uses: marocchino/sticky-pull-request-comment@v2 if: cancelled() && env.PR_NUMBER != '' continue-on-error: true @@ -658,6 +713,7 @@ jobs: append: true message: | :x: ${{ matrix.name }} functional test cancelled. Please check [the logs](${{ env.ACTION_LINK }}) for more details + - name: Delete azure resource group - ${{ env.AZURE_TEST_RESOURCE_GROUP }} if: always() run: | @@ -666,6 +722,7 @@ jobs: --subscription ${{ secrets.AZURE_SUBSCRIPTIONID_TESTS }} \ --name ${{ env.AZURE_TEST_RESOURCE_GROUP }} \ --yes --verbose + report-test-results: name: Report test results needs: [build, tests] @@ -680,6 +737,7 @@ jobs: with: app_id: ${{ env.FUNCTIONAL_TEST_APP_ID }} private_key: ${{ secrets.FUNCTIONAL_TEST_APP_PRIVATE_KEY }} + - name: Get tests job status id: get_test_status run: | @@ -700,6 +758,7 @@ jobs: done echo "Test Status: $TEST_STATUS" echo "test_status=$TEST_STATUS" >> $GITHUB_OUTPUT + - uses: LouisBrunner/checks-action@v2.0.0 if: always() with: @@ -712,6 +771,7 @@ jobs: output: | {"summary":"Functional Test run completed. See links for more information.","title":"Functional Test Run"} details_url: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + report-failure: name: Report test failure needs: [build, tests] @@ -740,6 +800,7 @@ jobs: } } return failureCount; + - name: Create failure issue for failing scheduled run uses: actions/github-script@v7 # Only create an issue if there are (env.ISSUE_CREATE_THRESHOLD) failures of the recent tests. diff --git a/.github/workflows/functional-test-noncloud.yaml b/.github/workflows/functional-test-noncloud.yaml index 854f981433..2fd8e98e73 100644 --- a/.github/workflows/functional-test-noncloud.yaml +++ b/.github/workflows/functional-test-noncloud.yaml @@ -25,6 +25,11 @@ permissions: on: # Enable manual trigger workflow_dispatch: + inputs: + branch: + description: "Branch to run the workflow on" + required: true + default: "main" schedule: # Run every 4 hours on weekdays. - cron: "30 0,4,8,12,16,20 * * 1-5" @@ -33,12 +38,6 @@ on: # Dispatch on external events repository_dispatch: types: [de-functional-test] - push: - branches: - - main - - release/* - tags: - - v* pull_request: branches: - main @@ -112,12 +111,6 @@ jobs: ); } - - name: Check out code - uses: actions/checkout@v4 - with: - repository: ${{ env.CHECKOUT_REPO }} - ref: ${{ env.CHECKOUT_REF }} - - name: Generate ID for release id: gen-id run: | @@ -160,7 +153,7 @@ jobs: DE_TAG: ${{ needs.build.outputs.DE_TAG }} steps: - name: Set up checkout target (scheduled) - if: github.event_name == 'schedule' + if: github.event_name == 'schedule' || github.event_name == 'repository_dispatch' run: | echo "CHECKOUT_REPO=${{ github.repository }}" >> $GITHUB_ENV echo "CHECKOUT_REF=refs/heads/main" >> $GITHUB_ENV @@ -172,7 +165,13 @@ jobs: echo "CHECKOUT_REF=${{ github.ref }}" >> $GITHUB_ENV echo "PR_NUMBER=${{ github.event.pull_request.number }}" >> $GITHUB_ENV - - name: Use custom actions + - name: Set up checkout target (workflow_dispatch) + if: github.event_name == 'workflow_dispatch' + run: | + echo "CHECKOUT_REPO=${{ github.repository }}" >> $GITHUB_ENV + echo "CHECKOUT_REF=refs/heads/${{ github.event.inputs.branch }}" >> $GITHUB_ENV + + - name: Check out code uses: actions/checkout@v4 - name: Checkout samples repo @@ -207,6 +206,7 @@ jobs: ${{ runner.os }}-go- - name: Create a secure local registry + id: create-local-registry uses: ./.github/actions/create-local-registry with: secure: "true" @@ -238,6 +238,8 @@ jobs: - name: Create a KinD cluster with a local registry uses: ./.github/actions/create-kind-cluster with: + secure: "true" + temp-cert-dir: ${{ steps.create-local-registry.outputs.temp-cert-dir }} kind-version: ${{ env.KIND_VER }} with-local-registry: "true" registry-name: ${{ env.LOCAL_REGISTRY_NAME }} @@ -268,14 +270,19 @@ jobs: echo "Radius release not found. Proceeding with installation." fi + RAD_COMMAND="rad install kubernetes \ + --chart ${{ env.RADIUS_CHART_LOCATION }} \ + --set rp.image=${{ env.LOCAL_REGISTRY_NAME }}:${{ env.LOCAL_REGISTRY_PORT }}/applications-rp,rp.tag=${{ env.REL_VERSION }} \ + --set controller.image=${{ env.LOCAL_REGISTRY_NAME }}:${{ env.LOCAL_REGISTRY_PORT }}/controller,controller.tag=${{ env.REL_VERSION }} \ + --set ucp.image=${{ env.LOCAL_REGISTRY_NAME }}:${{ env.LOCAL_REGISTRY_PORT }}/ucpd,ucp.tag=${{ env.REL_VERSION }} \ + --set de.image=${{ env.DE_IMAGE }},de.tag=${{ env.DE_TAG }}" + + if [ "${{ env.USE_CERT_FILE }}" = "true" ]; then + RAD_COMMAND="$RAD_COMMAND --set-file global.rootCA.cert=$TEMP_CERT_DIR/certs/${{ env.LOCAL_REGISTRY_SERVER }}/client.crt" + fi + echo "*** Installing Radius to Kubernetes ***" - rad install kubernetes \ - --chart ${{ env.RADIUS_CHART_LOCATION }} \ - --set rp.image=${{ env.LOCAL_REGISTRY_NAME }}:${{ env.LOCAL_REGISTRY_PORT }}/applications-rp,rp.tag=${{ env.REL_VERSION }} \ - --set controller.image=${{ env.LOCAL_REGISTRY_NAME }}:${{ env.LOCAL_REGISTRY_PORT }}/controller,controller.tag=${{ env.REL_VERSION }} \ - --set ucp.image=${{ env.LOCAL_REGISTRY_NAME }}:${{ env.LOCAL_REGISTRY_PORT }}/ucpd,ucp.tag=${{ env.REL_VERSION }} \ - --set de.image=${{ env.DE_IMAGE }},de.tag=${{ env.DE_TAG }} \ - --set-file global.rootCA.cert=$TEMP_CERT_DIR/certs/${{ env.LOCAL_REGISTRY_SERVER }}/client.crt + eval $RAD_COMMAND echo "*** Create workspace, group and environment for test ***" rad workspace create kubernetes @@ -285,6 +292,9 @@ jobs: # The functional test is designed to use default namespace. So you must create the environment for default namespace. rad env create kind-radius --namespace default rad env switch kind-radius + env: + USE_CERT_FILE: "true" + TEMP_CERT_DIR: ${{ steps.create-local-registry.outputs.temp-cert-dir }} - name: Publish Terraform test recipes run: | @@ -298,7 +308,8 @@ jobs: env: BICEP_RECIPE_REGISTRY: "${{ env.LOCAL_REGISTRY_SERVER }}:${{ env.LOCAL_REGISTRY_PORT }}" BICEP_RECIPE_TAG_VERSION: ${{ env.REL_VERSION }} - SSL_CERT_FILE: $TEMP_CERT_DIR/certs/${{ env.LOCAL_REGISTRY_SERVER }}/client.crt + TEMP_CERT_DIR: ${{ steps.create-local-registry.outputs.temp-cert-dir }} + SSL_CERT_FILE: ${{ steps.create-local-registry.outputs.temp-cert-dir }}/certs/${{ env.LOCAL_REGISTRY_SERVER }}/client.crt - name: Run functional tests run: | @@ -330,11 +341,6 @@ jobs: artifact_name: "functional_test_results_${{ matrix.name }}" result_directory: "dist/functional_test/" - - uses: azure/setup-kubectl@v4 - if: always() - with: - version: ${{ env.KUBECTL_VER }} - - name: Collect detailed Radius logs and events id: radius-logs-events if: always() diff --git a/.github/workflows/functional-tests-approval.yaml b/.github/workflows/functional-tests-approval.yaml index 2e8b6bfb11..50b022b40d 100644 --- a/.github/workflows/functional-tests-approval.yaml +++ b/.github/workflows/functional-tests-approval.yaml @@ -1,4 +1,4 @@ -name: 'Approve Functional Tests' +name: "Approve Functional Tests" on: pull_request: branches: @@ -7,11 +7,12 @@ on: - release/* jobs: approve-functional-tests-run: - name: 'Approve Functional Tests' + name: "Approve Functional Tests" runs-on: ubuntu-latest environment: functional-tests steps: - - name: Use custom actions - uses: actions/checkout@v4 - - name: Save PR number - uses: ./.github/actions/save-pr-as-artifact + - name: Checkout Radius repository + uses: actions/checkout@v4 + + - name: Save PR number + uses: ./.github/actions/save-pr-as-artifact diff --git a/test/functional-portable/datastoresrp/cloud/resources/mongodb_test.go b/test/functional-portable/datastoresrp/cloud/resources/mongodb_test.go deleted file mode 100644 index b176975655..0000000000 --- a/test/functional-portable/datastoresrp/cloud/resources/mongodb_test.go +++ /dev/null @@ -1,72 +0,0 @@ -/* -Copyright 2023 The Radius Authors. - -Licensed 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 resource_test - -import ( - "testing" - - "github.com/radius-project/radius/test/rp" - "github.com/radius-project/radius/test/step" - "github.com/radius-project/radius/test/testutil" - "github.com/radius-project/radius/test/validation" -) - -// Test_MongoDB_Recipe validates: -// the creation of a mongoDB from a recipe that uses an Azure resource -func Test_MongoDB_Recipe(t *testing.T) { - template := "testdata/datastoresrp-resources-mongodb-recipe.bicep" - name := "dsrp-resources-mongodb-recipe" - appNamespace := "dsrp-resources-mongodb-recipe-app" - - test := rp.NewRPTest(t, name, []rp.TestStep{ - { - Executor: step.NewDeployExecutor(template, testutil.GetMagpieImage(), testutil.GetBicepRecipeRegistry(), testutil.GetBicepRecipeVersion()), - RPResources: &validation.RPResourceSet{ - Resources: []validation.RPResource{ - { - Name: "dsrp-resources-mongodb-recipe-env", - Type: validation.EnvironmentsResource, - }, - { - Name: "dsrp-resources-mongodb-recipe", - Type: validation.ApplicationsResource, - App: name, - }, - { - Name: "mongodb-app-ctnr", - Type: validation.ContainersResource, - App: name, - }, - { - Name: "mongodb-db", - Type: validation.MongoDatabasesResource, - App: name, - }, - }, - }, - K8sObjects: &validation.K8sObjectSet{ - Namespaces: map[string][]validation.K8sObject{ - appNamespace: { - validation.NewK8sPodForResource(name, "mongodb-app-ctnr").ValidateLabels(false), - }, - }, - }, - }, - }) - - test.Test(t) -} diff --git a/test/functional-portable/datastoresrp/cloud/resources/redis_test.go b/test/functional-portable/datastoresrp/cloud/resources/redis_test.go deleted file mode 100644 index ffeb6b8eb5..0000000000 --- a/test/functional-portable/datastoresrp/cloud/resources/redis_test.go +++ /dev/null @@ -1,101 +0,0 @@ -/* -Copyright 2023 The Radius Authors. - -Licensed 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 resource_test - -import ( - "context" - "strings" - "testing" - - "github.com/radius-project/radius/test/rp" - "github.com/radius-project/radius/test/step" - "github.com/radius-project/radius/test/testutil" - "github.com/radius-project/radius/test/validation" - "github.com/stretchr/testify/require" -) - -func Test_Redis_Recipe(t *testing.T) { - template := "testdata/datastoresrp-resources-redis-recipe.bicep" - name := "dsrp-resources-redis-recipe" - - test := rp.NewRPTest(t, name, []rp.TestStep{ - { - Executor: step.NewDeployExecutor(template, testutil.GetBicepRecipeRegistry(), testutil.GetBicepRecipeVersion()), - RPResources: &validation.RPResourceSet{ - Resources: []validation.RPResource{ - { - Name: "dsrp-resources-env-recipe-env", - Type: validation.EnvironmentsResource, - }, - { - Name: name, - Type: validation.ApplicationsResource, - }, - { - Name: "rds-recipe", - Type: validation.RedisCachesResource, - App: name, - }, - }, - }, - SkipObjectValidation: true, - PostStepVerify: func(ctx context.Context, t *testing.T, test rp.RPTest) { - redis, err := test.Options.ManagementClient.GetResource(ctx, "Applications.Datastores/redisCaches", "rds-recipe") - require.NoError(t, err) - require.NotNil(t, redis) - status := redis.Properties["status"].(map[string]any) - recipe := status["recipe"].(map[string]interface{}) - require.Equal(t, "bicep", recipe["templateKind"].(string)) - templatePath := strings.Split(recipe["templatePath"].(string), ":")[0] - require.Equal(t, "ghcr.io/radius-project/dev/test/testrecipes/test-bicep-recipes/redis-recipe-value-backed", templatePath) - }, - }, - }) - - test.Test(t) -} - -func Test_Redis_DefaultRecipe(t *testing.T) { - template := "testdata/datastoresrp-resources-redis-default-recipe.bicep" - name := "dsrp-resources-redis-default-recipe" - - test := rp.NewRPTest(t, name, []rp.TestStep{ - { - Executor: step.NewDeployExecutor(template, testutil.GetBicepRecipeRegistry(), testutil.GetBicepRecipeVersion()), - RPResources: &validation.RPResourceSet{ - Resources: []validation.RPResource{ - { - Name: "dsrp-resources-env-default-recipe-env", - Type: validation.EnvironmentsResource, - }, - { - Name: name, - Type: validation.ApplicationsResource, - }, - { - Name: "rds-default-recipe", - Type: validation.RedisCachesResource, - App: name, - }, - }, - }, - SkipObjectValidation: true, - }, - }) - - test.Test(t) -} diff --git a/test/functional-portable/datastoresrp/cloud/resources/testdata/datastoresrp-resources-microsoft-sql.bicep b/test/functional-portable/datastoresrp/cloud/resources/testdata/datastoresrp-resources-microsoft-sql.bicep index 2cc83b1dde..75ef07e1f9 100644 --- a/test/functional-portable/datastoresrp/cloud/resources/testdata/datastoresrp-resources-microsoft-sql.bicep +++ b/test/functional-portable/datastoresrp/cloud/resources/testdata/datastoresrp-resources-microsoft-sql.bicep @@ -64,14 +64,14 @@ resource db 'Applications.Datastores/sqlDatabases@2023-10-01-preview' = { application: app.id environment: environment resourceProvisioning: 'manual' - resources:[ + resources: [ { - id:mssqlresourceid + id: mssqlresourceid } ] database: database server: server - port:1433 + port: 1433 username: adminUsername secrets: { password: adminPassword diff --git a/test/functional-portable/datastoresrp/noncloud/resources/mongodb_test.go b/test/functional-portable/datastoresrp/noncloud/resources/mongodb_test.go index cd9c8d67c4..d399e0bdd4 100644 --- a/test/functional-portable/datastoresrp/noncloud/resources/mongodb_test.go +++ b/test/functional-portable/datastoresrp/noncloud/resources/mongodb_test.go @@ -70,3 +70,47 @@ func Test_MongoDB_Manual(t *testing.T) { test.Test(t) } + +func Test_MongoDB_Recipe(t *testing.T) { + template := "testdata/datastoresrp-resources-mongodb-recipe.bicep" + name := "dsrp-resources-mongodb-recipe" + appNamespace := "dsrp-resources-mongodb-recipe-app" + + test := rp.NewRPTest(t, name, []rp.TestStep{ + { + Executor: step.NewDeployExecutor(template, testutil.GetMagpieImage(), testutil.GetBicepRecipeRegistry(), testutil.GetBicepRecipeVersion()), + RPResources: &validation.RPResourceSet{ + Resources: []validation.RPResource{ + { + Name: "dsrp-resources-mongodb-recipe-env", + Type: validation.EnvironmentsResource, + }, + { + Name: "dsrp-resources-mongodb-recipe", + Type: validation.ApplicationsResource, + App: name, + }, + { + Name: "mongodb-app-ctnr", + Type: validation.ContainersResource, + App: name, + }, + { + Name: "mongodb-db", + Type: validation.MongoDatabasesResource, + App: name, + }, + }, + }, + K8sObjects: &validation.K8sObjectSet{ + Namespaces: map[string][]validation.K8sObject{ + appNamespace: { + validation.NewK8sPodForResource(name, "mongodb-app-ctnr").ValidateLabels(false), + }, + }, + }, + }, + }) + + test.Test(t) +} diff --git a/test/functional-portable/datastoresrp/noncloud/resources/redis_test.go b/test/functional-portable/datastoresrp/noncloud/resources/redis_test.go index 4f672d2530..0397ec8bbf 100644 --- a/test/functional-portable/datastoresrp/noncloud/resources/redis_test.go +++ b/test/functional-portable/datastoresrp/noncloud/resources/redis_test.go @@ -17,12 +17,15 @@ limitations under the License. package resource_test import ( + "context" + "strings" "testing" "github.com/radius-project/radius/test/rp" "github.com/radius-project/radius/test/step" "github.com/radius-project/radius/test/testutil" "github.com/radius-project/radius/test/validation" + "github.com/stretchr/testify/require" ) func Test_Redis_Manual(t *testing.T) { @@ -69,3 +72,76 @@ func Test_Redis_Manual(t *testing.T) { test.Test(t) } + +func Test_Redis_Recipe(t *testing.T) { + template := "testdata/datastoresrp-resources-redis-recipe.bicep" + name := "dsrp-resources-redis-recipe" + + test := rp.NewRPTest(t, name, []rp.TestStep{ + { + Executor: step.NewDeployExecutor(template, testutil.GetBicepRecipeRegistry(), testutil.GetBicepRecipeVersion()), + RPResources: &validation.RPResourceSet{ + Resources: []validation.RPResource{ + { + Name: "dsrp-resources-env-recipe-env", + Type: validation.EnvironmentsResource, + }, + { + Name: name, + Type: validation.ApplicationsResource, + }, + { + Name: "rds-recipe", + Type: validation.RedisCachesResource, + App: name, + }, + }, + }, + SkipObjectValidation: true, + PostStepVerify: func(ctx context.Context, t *testing.T, test rp.RPTest) { + redis, err := test.Options.ManagementClient.GetResource(ctx, "Applications.Datastores/redisCaches", "rds-recipe") + require.NoError(t, err) + require.NotNil(t, redis) + status := redis.Properties["status"].(map[string]any) + recipe := status["recipe"].(map[string]interface{}) + require.Equal(t, "bicep", recipe["templateKind"].(string)) + templatePath := strings.Split(recipe["templatePath"].(string), ":")[0] + // TODO: Update this to the correct path + require.Equal(t, "radius-registry", templatePath) + }, + }, + }) + + test.Test(t) +} + +func Test_Redis_DefaultRecipe(t *testing.T) { + template := "testdata/datastoresrp-resources-redis-default-recipe.bicep" + name := "dsrp-resources-redis-default-recipe" + + test := rp.NewRPTest(t, name, []rp.TestStep{ + { + Executor: step.NewDeployExecutor(template, testutil.GetBicepRecipeRegistry(), testutil.GetBicepRecipeVersion()), + RPResources: &validation.RPResourceSet{ + Resources: []validation.RPResource{ + { + Name: "dsrp-resources-env-default-recipe-env", + Type: validation.EnvironmentsResource, + }, + { + Name: name, + Type: validation.ApplicationsResource, + }, + { + Name: "rds-default-recipe", + Type: validation.RedisCachesResource, + App: name, + }, + }, + }, + SkipObjectValidation: true, + }, + }) + + test.Test(t) +} diff --git a/test/functional-portable/datastoresrp/cloud/resources/testdata/datastoresrp-resources-mongodb-recipe.bicep b/test/functional-portable/datastoresrp/noncloud/resources/testdata/datastoresrp-resources-mongodb-recipe.bicep similarity index 89% rename from test/functional-portable/datastoresrp/cloud/resources/testdata/datastoresrp-resources-mongodb-recipe.bicep rename to test/functional-portable/datastoresrp/noncloud/resources/testdata/datastoresrp-resources-mongodb-recipe.bicep index 8495e68ef4..0cf26a0aca 100644 --- a/test/functional-portable/datastoresrp/cloud/resources/testdata/datastoresrp-resources-mongodb-recipe.bicep +++ b/test/functional-portable/datastoresrp/noncloud/resources/testdata/datastoresrp-resources-mongodb-recipe.bicep @@ -1,9 +1,5 @@ import radius as radius -param rg string = resourceGroup().name - -param sub string = subscription().subscriptionId - param registry string param version string @@ -19,11 +15,6 @@ resource env 'Applications.Core/environments@2023-10-01-preview' = { resourceId: 'self' namespace: 'dsrp-resources-mongodb-recipe-env' } - providers: { - azure: { - scope: '/subscriptions/${sub}/resourceGroups/${rg}' - } - } recipes: { 'Applications.Datastores/mongoDatabases': { mongoazure: { diff --git a/test/functional-portable/datastoresrp/cloud/resources/testdata/datastoresrp-resources-redis-default-recipe.bicep b/test/functional-portable/datastoresrp/noncloud/resources/testdata/datastoresrp-resources-redis-default-recipe.bicep similarity index 91% rename from test/functional-portable/datastoresrp/cloud/resources/testdata/datastoresrp-resources-redis-default-recipe.bicep rename to test/functional-portable/datastoresrp/noncloud/resources/testdata/datastoresrp-resources-redis-default-recipe.bicep index 81fed90878..ea374b0476 100644 --- a/test/functional-portable/datastoresrp/cloud/resources/testdata/datastoresrp-resources-redis-default-recipe.bicep +++ b/test/functional-portable/datastoresrp/noncloud/resources/testdata/datastoresrp-resources-redis-default-recipe.bicep @@ -1,7 +1,5 @@ import radius as radius -param scope string = resourceGroup().id - param registry string param version string @@ -15,11 +13,6 @@ resource env 'Applications.Core/environments@2023-10-01-preview' = { resourceId: 'self' namespace: 'dsrp-resources-env-default-recipe-env' } - providers: { - azure: { - scope: scope - } - } recipes: { 'Applications.Datastores/redisCaches': { default: { diff --git a/test/functional-portable/datastoresrp/cloud/resources/testdata/datastoresrp-resources-redis-recipe.bicep b/test/functional-portable/datastoresrp/noncloud/resources/testdata/datastoresrp-resources-redis-recipe.bicep similarity index 91% rename from test/functional-portable/datastoresrp/cloud/resources/testdata/datastoresrp-resources-redis-recipe.bicep rename to test/functional-portable/datastoresrp/noncloud/resources/testdata/datastoresrp-resources-redis-recipe.bicep index a97261e63f..730bca5f95 100644 --- a/test/functional-portable/datastoresrp/cloud/resources/testdata/datastoresrp-resources-redis-recipe.bicep +++ b/test/functional-portable/datastoresrp/noncloud/resources/testdata/datastoresrp-resources-redis-recipe.bicep @@ -1,7 +1,5 @@ import radius as radius -param scope string = resourceGroup().id - param registry string param version string @@ -15,11 +13,6 @@ resource env 'Applications.Core/environments@2023-10-01-preview' = { resourceId: 'self' namespace: 'dsrp-resources-env-recipe-env' } - providers: { - azure: { - scope: scope - } - } recipes: { 'Applications.Datastores/redisCaches': { rediscache: { diff --git a/test/testutil/testutil.go b/test/testutil/testutil.go index e09c62a8a4..f5a5d32f0d 100644 --- a/test/testutil/testutil.go +++ b/test/testutil/testutil.go @@ -69,16 +69,16 @@ func GetOIDCIssuer() string { // SetDefault sets the default Docker registry and image tag if they are not already set in the environment. func SetDefault() (string, string) { - defaultDockerReg := os.Getenv("DOCKER_REGISTRY") + dockerRegistry := os.Getenv("DOCKER_REGISTRY") imageTag := os.Getenv("REL_VERSION") - if defaultDockerReg == "" { - defaultDockerReg = "ghcr.io/radius-project" + if dockerRegistry == "" { + dockerRegistry = "ghcr.io/radius-project" } if imageTag == "" { imageTag = "latest" } - return defaultDockerReg, imageTag + return dockerRegistry, imageTag } type ProxyMetadata struct { @@ -335,3 +335,13 @@ func GetCreationTimestamp() string { func GenerateS3BucketName() string { return "radiusfunctionaltestbucket-" + uuid.New().String() } + +// GetDockerRegistry returns the Docker registry from the environment variable DOCKER_REGISTRY or the default value +// "ghcr.io/radius-project". +func GetDockerRegistry() string { + regName := os.Getenv("DOCKER_REGISTRY") + if regName == "" { + return "ghcr.io/radius-project" + } + return regName +}