-
Notifications
You must be signed in to change notification settings - Fork 2k
[CRE] Mixed-env topology + automatic non-determinism detection #23290
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 2 commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
63aada7
[CRE] Add mixed-env topology + automatic non-determinism detection
prashantkumar1982 d68fd40
[CRE] Move mixed-env into its own workflow (cre-mixed-env-tests.yaml)
prashantkumar1982 00cb082
[CRE] mixed-env review fixes: fail-fast image check + reuse Go scanne…
prashantkumar1982 efe0751
Merge remote-tracking branch 'origin/develop' into cre/mixed-env-non-…
prashantkumar1982 f35a596
[CRE] mixed-env: baseline against the PR's own develop base to kill f…
prashantkumar1982 f6042c0
[CRE] mixed-env: handle release-branch PRs (correct baseline, safe skip)
prashantkumar1982 f1772f7
[CRE] mixed-env: make it a required merge check + add skip-mixed-env …
prashantkumar1982 1ccb14a
[CRE] mixed-env: skip Go cache restore (reuse precompiled binary for …
prashantkumar1982 8341421
Merge branch 'develop' of https://github.com/smartcontractkit/chainli…
prashantkumar1982 2b557ab
[CRE] mixed-env: cover stacked PRs (develop-nightly fallback; skip on…
prashantkumar1982 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,338 @@ | ||
| name: CRE Mixed-Env Tests | ||
|
|
||
| # Dedicated workflow for the "mixed-env" topology (2 nodes on the PR image, 2 on a | ||
| # develop image) that fails a job if PR and develop nodes disagree — see | ||
| # core/scripts/cre/environment/docs/mixed-env.md. Kept separate from | ||
| # cre-system-tests.yaml so that workflow stays simple; this one is 100% mixed-env | ||
| # so it needs no per-topology conditionals. | ||
|
|
||
| on: | ||
| workflow_dispatch: | ||
| inputs: | ||
| chainlink_image_repository_path: | ||
| description: | ||
| "ECR repository name used to compose the PR image with chainlink_image_tag." | ||
| required: true | ||
| type: string | ||
| chainlink_image_tag: | ||
| required: true | ||
| type: string | ||
| description: "Chainlink (PR) image tag to use." | ||
| ecr: | ||
| required: false | ||
| type: choice | ||
| options: | ||
| - "sdlc" | ||
| - "public" | ||
| default: "sdlc" | ||
| description: "SDLC or public ECR registry for the Chainlink image." | ||
| chainlink_version: | ||
| required: false | ||
| type: string | ||
| default: "" | ||
| description: "Chainlink repo ref to check out. Defaults to github.sha." | ||
| mixed_env_baseline_image: | ||
| required: false | ||
| type: string | ||
| default: "" | ||
| description: | ||
| "Full baseline (develop) chainlink image ref. If empty, defaults to the | ||
| develop nightly image." | ||
| workflow_call: | ||
| inputs: | ||
| chainlink_image_repository_path: | ||
| description: | ||
| "ECR repository name used to compose the PR image with chainlink_image_tag." | ||
| required: true | ||
| type: string | ||
| chainlink_image_tag: | ||
| required: true | ||
| type: string | ||
| description: "Chainlink (PR) image tag to use." | ||
| ecr: | ||
| type: string | ||
| required: true | ||
| description: "SDLC (sdlc) or public (public) ECR registry for the Chainlink image." | ||
| chainlink_version: | ||
| required: false | ||
| type: string | ||
| default: "" | ||
| description: "Chainlink repo ref to check out. Defaults to github.sha." | ||
| mixed_env_baseline_image: | ||
| required: false | ||
| type: string | ||
| default: "" | ||
| description: | ||
| "Full baseline (develop) chainlink image ref. If empty, defaults to the | ||
| develop nightly image." | ||
|
|
||
| jobs: | ||
| define-test-matrix: | ||
| runs-on: ubuntu-latest | ||
| outputs: | ||
| matrix: ${{ steps.define-matrix.outputs.matrix }} | ||
| permissions: | ||
| contents: read | ||
| steps: | ||
| - name: Define mixed-env test matrix | ||
| id: define-matrix | ||
| shell: bash | ||
| run: | | ||
| # Tests worth running under mixed-env: the OCR3/DON2DON-heavy ones. | ||
| TESTS='[ | ||
| "Test_CRE_V2_Suite_Bucket_A", | ||
| "Test_CRE_V2_Suite_Bucket_B", | ||
| "Test_CRE_V2_EVM_Read_HeavyCalls", | ||
| "Test_CRE_V2_EVM_Read_StateQueries", | ||
| "Test_CRE_V2_EVM_Read_TxArtifacts" | ||
| ]' | ||
| matrix=$(jq -c -n \ | ||
| --argjson tests "$TESTS" \ | ||
| --argjson run_id "${{ github.run_id }}" \ | ||
| --arg run_attempt "${{ github.run_attempt }}" ' | ||
| $tests | to_entries | map({ | ||
| test_name: .value, | ||
| test_id: .key, | ||
| runs_on: "runs-on=\($run_id)-\(.key)-\($run_attempt)/cpu=16/ram=64/family=m7i+m8i/spot=co/image=ubuntu24-full-x64/extras=s3-cache+tmpfs" | ||
| })') | ||
| echo "matrix=$matrix" | tee -a "${GITHUB_OUTPUT}" | ||
|
|
||
| run-mixed-env-tests: | ||
| name: ${{ matrix.tests.test_name }} (mixed-env) | ||
| permissions: | ||
| contents: read | ||
| id-token: write | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| tests: ${{ fromJson(needs.define-test-matrix.outputs.matrix) }} | ||
| needs: [define-test-matrix] | ||
| runs-on: ${{ matrix.tests.runs_on }} | ||
| environment: | ||
| name: integration | ||
| deployment: false | ||
| timeout-minutes: 10 | ||
| env: | ||
| ENABLE_AUTO_QUARANTINE: "true" | ||
| # PR image; the develop/baseline image is resolved in the render step below. | ||
| CHAINLINK_IMAGE_FULL: ${{ inputs.ecr == 'public' && format('public.ecr.aws/{0}:{1}', inputs.chainlink_image_repository_path, inputs.chainlink_image_tag) || format('{0}.dkr.ecr.{1}.amazonaws.com/{2}:{3}', secrets.QA_AWS_ACCOUNT_NUMBER, secrets.QA_AWS_REGION, inputs.chainlink_image_repository_path, inputs.chainlink_image_tag) }} | ||
| CTF_CHIP_INGRESS_IMAGE: ${{ secrets.AWS_ACCOUNT_ID_PROD }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/atlas-chip-ingress:da84cb72d3a160e02896247d46ab4b9806ebee2f | ||
| CTF_CHIP_CONFIG_IMAGE: ${{ secrets.AWS_ACCOUNT_ID_PROD }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/atlas-chip-config:7b4e9ee68fd1c737dd3480b5a3ced0188f29b969 | ||
|
|
||
| steps: | ||
| - name: Enable S3 Cache for Self-Hosted Runners | ||
| uses: runs-on/action@4e5f72399b6b17f2e79c511c1b38a315a64d22dc # v2.2.0 | ||
|
|
||
| - name: Checkout | ||
| uses: actions/checkout@v7 | ||
| with: | ||
| ref: ${{ inputs.chainlink_version || github.sha }} | ||
| persist-credentials: false | ||
|
|
||
| - name: Set up Go | ||
| id: setup-go | ||
| uses: smartcontractkit/.github/actions/ctf-setup-go@fa1d48a33e24f9b3b9f8c52e99a578a4597cb2a5 # v0.4.0 | ||
| with: | ||
| go_mod_path: system-tests/tests/go.mod | ||
| cache_key_id: integration-tests-v1 | ||
| cache_builds: true | ||
| cache_restore_only: "true" | ||
|
|
||
| - name: Restore Pre-Compiled Test Binaries from S3 Cache | ||
| uses: actions/cache/restore@v6 | ||
| with: | ||
| path: system-tests/tests/bin/ | ||
| key: test-binaries-cre-${{ inputs.chainlink_version || github.sha }} | ||
|
|
||
| - name: Configure AWS Credentials | ||
| uses: aws-actions/configure-aws-credentials@e6de054238d6b7531b4efff3b6587d9aade6a06c # v6.2.3 | ||
| with: | ||
| aws-region: ${{ secrets.QA_AWS_REGION }} | ||
| role-to-assume: ${{ secrets.AWS_CTF_READ_ACCESS_ROLE_ARN }} | ||
| role-duration-seconds: 1800 | ||
| mask-aws-account-id: true | ||
|
|
||
| - name: Login to Amazon ECR | ||
| id: login-ecr | ||
| uses: aws-actions/amazon-ecr-login@d539f0932e70871a027e9d5a9d8fc38589180a64 # v2.1.6 | ||
| with: | ||
| registries: ${{ format('{0},{1}', secrets.QA_AWS_ACCOUNT_NUMBER, | ||
| secrets.AWS_ACCOUNT_ID_PROD) }} | ||
| env: | ||
| AWS_REGION: ${{ secrets.QA_AWS_REGION }} | ||
|
|
||
| - name: Authenticate to ECR (public) | ||
| id: login-ecr-public | ||
| uses: aws-actions/amazon-ecr-login@d539f0932e70871a027e9d5a9d8fc38589180a64 # v2.1.6 | ||
| with: | ||
| registry-type: public | ||
| env: | ||
| AWS_REGION: us-east-1 | ||
|
|
||
| - name: Cache gotestsum | ||
| id: cache-gotestsum | ||
| uses: actions/cache@v6 | ||
| with: | ||
| path: ~/go/bin/gotestsum | ||
| key: ${{ runner.os }}-${{ runner.arch }}-gotestsum-1.13.0 | ||
|
|
||
| - name: Set up gotestsum | ||
| shell: bash | ||
| run: | | ||
| if [ -f ~/go/bin/gotestsum ]; then | ||
| echo "Using cached gotestsum" | ||
| else | ||
| echo "::group::Install gotestsum" | ||
| go install gotest.tools/gotestsum@v1.13.0 | ||
| echo "::endgroup::" | ||
| fi | ||
|
|
||
| - name: Render mixed-env topology | ||
| working-directory: core/scripts/cre/environment | ||
| shell: bash | ||
| env: | ||
| CRE_PR_IMAGE: ${{ env.CHAINLINK_IMAGE_FULL }} | ||
| BASELINE_IMAGE_OVERRIDE: ${{ inputs.mixed_env_baseline_image }} | ||
| ECR_ACCOUNT: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} | ||
| ECR_REGION: ${{ secrets.QA_AWS_REGION }} | ||
| run: | | ||
| if [[ -n "${BASELINE_IMAGE_OVERRIDE}" ]]; then | ||
| CRE_BASELINE_IMAGE="${BASELINE_IMAGE_OVERRIDE}" | ||
| else | ||
| # Default to the develop nightly image (built daily + on develop pushes). | ||
| # Core variant (no -plugins) to match the PR image built by integration-tests. | ||
| DATE="$(date +'%Y%m%d')" | ||
| CRE_BASELINE_IMAGE="${ECR_ACCOUNT}.dkr.ecr.${ECR_REGION}.amazonaws.com/chainlink:nightly-${DATE}" | ||
|
Tofel marked this conversation as resolved.
Outdated
|
||
| fi | ||
| export CRE_PR_IMAGE CRE_BASELINE_IMAGE | ||
| echo "PR image: ${CRE_PR_IMAGE}" | ||
| echo "Baseline image: ${CRE_BASELINE_IMAGE}" | ||
| bash configs/render-mixed-env.sh | ||
|
|
||
| - name: Start local CRE | ||
| id: start-local-cre | ||
| uses: ./.github/actions/start-local-cre-environment | ||
| with: | ||
| jd-image: | ||
| "${{ secrets.AWS_ACCOUNT_ID_PROD }}.dkr.ecr.${{ secrets.QA_AWS_REGION | ||
| }}.amazonaws.com/job-distributor:0.28.0" | ||
| # Empty on purpose: images are baked per-node into the rendered TOML, and a | ||
| # non-empty CTF_CHAINLINK_IMAGE would force every node onto one image. | ||
| chainlink-image: "" | ||
| chip-router-image: "${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ | ||
| secrets.QA_AWS_REGION }}.amazonaws.com/local-cre-chip-router:v1.0.1" | ||
| ctf-configs: configs/mixed-env-don.toml | ||
| retry-count: "3" | ||
| retry-delay-seconds: "15" | ||
| cleanup-on-error: "false" | ||
| working-directory: core/scripts/cre/environment | ||
|
|
||
| - name: Setup GitHub token using GATI | ||
| id: github-token | ||
| uses: smartcontractkit/.github/actions/setup-github-token@setup-github-token/v1 | ||
| with: | ||
| aws-role-arn: ${{ secrets.AWS_OIDC_CHAINLINK_READ_ONLY_TOKEN_ISSUER_ROLE_ARN }} | ||
| aws-lambda-url: ${{ secrets.AWS_INFRA_RELENG_TOKEN_ISSUER_LAMBDA_URL }} | ||
| aws-region: us-west-2 | ||
| aws-role-duration-seconds: "1800" | ||
| set-git-config: "true" | ||
|
|
||
| - name: Run CRE Smoke system tests (mixed-env) | ||
| id: run-tests | ||
| shell: bash | ||
| working-directory: system-tests/tests | ||
| continue-on-error: ${{ env.ENABLE_AUTO_QUARANTINE == 'true' }} | ||
| env: | ||
| TEST_NAME: ${{ matrix.tests.test_name }} | ||
| TEST_TIMEOUT: 7m | ||
| RUN_QUARANTINED_TESTS: "true" | ||
| TOPOLOGY_NAME: mixed-env | ||
| GITHUB_TOKEN: ${{ steps.github-token.outputs.access-token || '' }} | ||
| PARALLEL_COUNT: "10" | ||
| CRE_TEST_PARALLEL_ENABLED: "true" | ||
| run: | | ||
| echo "Starting test: '${TEST_NAME}' (mixed-env)" | ||
| if [ -f "./bin/cre-smoke.test" ]; then | ||
| echo "Using precompiled binary" | ||
| ( | ||
| cd smoke/cre && \ | ||
| gotestsum \ | ||
| --jsonfile=/tmp/gotest.log \ | ||
| --junitfile=/tmp/junit-report.xml \ | ||
| --format=github-actions \ | ||
| --raw-command -- \ | ||
| go tool test2json -t -p github.com/smartcontractkit/chainlink/system-tests/tests/smoke/cre ../../bin/cre-smoke.test -test.v -test.run "^(${TEST_NAME})$" -test.timeout "${TEST_TIMEOUT}" -test.count=1 -test.parallel="${PARALLEL_COUNT}" | ||
| ) | ||
| else | ||
| echo "No precompiled binary found. Building from scratch..." | ||
| gotestsum \ | ||
| --jsonfile=/tmp/gotest.log \ | ||
| --junitfile=/tmp/junit-report.xml \ | ||
| --format=github-actions \ | ||
| -- \ | ||
| -v -run "^(${TEST_NAME})$" -timeout "${TEST_TIMEOUT}" -count=1 -parallel="${PARALLEL_COUNT}" \ | ||
| github.com/smartcontractkit/chainlink/system-tests/tests/smoke/cre | ||
| fi | ||
|
|
||
| exit_code="$?" | ||
| if [ "$exit_code" -eq 0 ]; then | ||
| echo "tests_result=✅ Tests passed" >> "${GITHUB_OUTPUT}" | ||
| fi | ||
|
|
||
| - name: Check for non-determinism | ||
| # Hard gate. The smoke step above is continue-on-error (auto-quarantine), | ||
| # which would swallow the in-test TestMain scan, so re-scan the live node | ||
| # containers here and fail the job on any marker. | ||
| if: ${{ always() }} | ||
| shell: bash | ||
| run: | | ||
| set -uo pipefail | ||
| markers=( | ||
| "This is commonly caused by non-determinism" | ||
| "received messages with the same id and different payloads" | ||
| "received multiple unique responses for the same request" | ||
| "response quorum unreachable" | ||
| ) | ||
| hit=0 | ||
| for c in $(docker ps -a --format '{{.Names}}'); do | ||
| logs="$(docker logs "$c" 2>&1 || true)" | ||
| for m in "${markers[@]}"; do | ||
| if grep -qF -- "$m" <<<"$logs"; then | ||
| echo "::error::Non-Determinism introduced — container=${c} marker=\"${m}\"" | ||
| hit=1 | ||
| fi | ||
| done | ||
| done | ||
| if [[ "${hit}" -ne 0 ]]; then | ||
| echo "Non-Determinism introduced: PR and develop nodes disagreed." | ||
| exit 1 | ||
| fi | ||
| echo "mixed-env non-determinism check: no markers found" | ||
|
Tofel marked this conversation as resolved.
Outdated
|
||
|
|
||
| - name: | ||
| Analyze and upload test results (${{ steps.run-tests.outputs.tests_result | ||
| }}) | ||
| if: ${{ !cancelled() }} | ||
| uses: smartcontractkit/.github/actions/branch-out-upload@branch-out-upload/v1 | ||
| with: | ||
| junit-file-path: "/tmp/junit-report.xml" | ||
| trunk-org-slug: chainlink | ||
| trunk-token: ${{ secrets.TRUNK_API_KEY }} | ||
| trunk-previous-step-outcome: ${{ steps.run-tests.outcome }} | ||
| trunk-upload-only: ${{ env.ENABLE_AUTO_QUARANTINE != 'true' }} | ||
| artifact-name: mixed-env-${{ matrix.tests.test_id }}_test_logs | ||
|
|
||
| - name: Show Docker containers status | ||
| if: failure() || cancelled() | ||
| shell: bash | ||
| run: docker ps -a | ||
|
|
||
| - name: Save Smoke tests Docker logs | ||
| if: failure() || cancelled() | ||
| shell: bash | ||
| working-directory: system-tests/tests/smoke/cre | ||
| run: | | ||
| mkdir -p logs | ||
| for c in $(docker ps -a --format '{{.Names}}'); do | ||
| docker logs "$c" > "logs/${c}.log" 2>&1 | ||
| done | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.