From e62deff17ad6357339a497b90aa1fc0d798b470b Mon Sep 17 00:00:00 2001 From: Tate Date: Tue, 9 Apr 2024 07:51:23 -0600 Subject: [PATCH] [TT-1042] Add nix shell support (#898) * Add nix shell support * Fix CGO issue * Update messed up readme * Use nix in CI * Debug complete, only show errors again in test outputs * cleanup helm and go mod downloads in ci * Bump flake lock to get updated versions * Fix go build issues by putting in the newer apple sdk by default. Does not affect other platforms --- .envrc | 1 + .github/workflows/k8s-e2e.yaml | 43 ++++++++++-- .github/workflows/test.yaml | 19 +++--- .gitignore | 4 +- .helm-repositories.yaml | 30 +++++++++ .pre-commit-config.yaml | 7 +- Makefile | 29 ++++----- README.md | 18 +++++ flake.lock | 61 +++++++++++++++++ flake.nix | 23 +++++++ nix.conf | 1 + shell.nix | 65 +++++++++++++++++++ tools/gotestloghelper/Makefile | 5 ++ tools/gotestloghelper/README.md | 8 +-- .../gotestevent/gotestevent_test.go | 3 - 15 files changed, 277 insertions(+), 40 deletions(-) create mode 100644 .envrc create mode 100644 .helm-repositories.yaml create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 nix.conf create mode 100644 shell.nix create mode 100644 tools/gotestloghelper/Makefile diff --git a/.envrc b/.envrc new file mode 100644 index 000000000..a5dbbcba7 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use flake . diff --git a/.github/workflows/k8s-e2e.yaml b/.github/workflows/k8s-e2e.yaml index 77d656d10..6352eec78 100644 --- a/.github/workflows/k8s-e2e.yaml +++ b/.github/workflows/k8s-e2e.yaml @@ -66,15 +66,30 @@ jobs: TEST_SUITE: local-runner steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - name: Install Nix + uses: cachix/install-nix-action@8887e596b4ee1134dae06b98d573bd674693f47c # v26 + with: + nix_path: nixpkgs=channel:nixos-unstable + - name: Load Nix + run: nix develop -c sh -c "go mod download" + - name: Setup environment + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/setup-run-tests-environment@5bee84d30d90295010bda68b0cd46be3a1eea917 # v2.3.9 + with: + go_mod_path: go.mod + QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} + QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} + QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} + go_necessary: false - name: Run Tests env: LOCAL_CHARTS: true - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@ce87f8986ca18336cc5015df75916c2ec0a7c4b3 # v2.1.2 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@5bee84d30d90295010bda68b0cd46be3a1eea917 # v2.3.9 with: cl_repo: ${{ env.CHAINLINK_IMAGE }} cl_image_tag: ${{ env.CHAINLINK_VERSION }} - test_command_to_run: make gotestloghelper_build && unset ENV_JOB_IMAGE && helm repo update && make k8s_test_e2e_ci - test_download_vendor_packages_command: go mod download + test_command_to_run: | + unset ENV_JOB_IMAGE + nix develop -c sh -c "make k8s_test_e2e_ci" artifacts_location: ./e2e/logs publish_check_name: E2E Test Results token: ${{ secrets.GITHUB_TOKEN }} @@ -82,6 +97,7 @@ jobs: QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} + run_setup: false - name: Upload test log uses: actions/upload-artifact@v3 if: failure() @@ -101,13 +117,27 @@ jobs: TEST_TRIGGERED_BY: chainlink-testing-framework-remote-runner-ci steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - name: Install Nix + uses: cachix/install-nix-action@8887e596b4ee1134dae06b98d573bd674693f47c # v26 + with: + nix_path: nixpkgs=channel:nixos-unstable + - name: Load Nix + run: nix develop -c sh -c "go mod download" + - name: Setup environment + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/setup-run-tests-environment@5bee84d30d90295010bda68b0cd46be3a1eea917 # v2.3.9 + with: + go_mod_path: go.mod + QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} + QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} + QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} + go_necessary: false - name: Run Remote Runner Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@ce87f8986ca18336cc5015df75916c2ec0a7c4b3 # v2.1.2 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@5bee84d30d90295010bda68b0cd46be3a1eea917 # v2.3.9 with: cl_repo: ${{ env.CHAINLINK_IMAGE }} cl_image_tag: ${{ env.CHAINLINK_VERSION }} - test_command_to_run: make gotestloghelper_build && helm repo update && make k8s_test_e2e_ci_remote_runner - test_download_vendor_packages_command: go mod download + test_command_to_run: | + nix develop -c sh -c "make k8s_test_e2e_ci_remote_runner" artifacts_location: ./k8s/logs publish_check_name: E2E Remote Runner Test Results token: ${{ secrets.GITHUB_TOKEN }} @@ -115,6 +145,7 @@ jobs: QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} + run_setup: false - name: Upload test log uses: actions/upload-artifact@v2 if: failure() diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 307bf3116..e9968283a 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -19,15 +19,16 @@ jobs: steps: - name: Checkout the Repo uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - - name: Install Go - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/setup-go@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12 - with: - test_download_vendor_packages_command: go mod download - go_mod_path: ${{ matrix.project.path }}go.mod - cache_key_id: ctf-go - cache_restore_only: 'false' - name: Install gotestloghelper run: make gotestloghelper_build + - name: Install Nix + uses: cachix/install-nix-action@8887e596b4ee1134dae06b98d573bd674693f47c # v26 + with: + nix_path: nixpkgs=channel:nixos-unstable + - name: Load Nix + run: | + nix develop -c sh -c "cd ${{ matrix.project.path }} && \ + go mod download" - name: Run Tests run: | PATH=$PATH:$(go env GOPATH)/bin @@ -35,8 +36,8 @@ jobs: set -euo pipefail # disabled, because we want to use a multiline output of go list command # shellcheck disable=SC2046 - cd ${{ matrix.project.path }} - go test -timeout 5m -json -cover -covermode=count -coverprofile=unit-test-coverage.out $(go list ./... | grep -v /k8s/e2e/ | grep -v /k8s/examples/ | grep -v /docker/test_env) 2>&1 | tee /tmp/gotest.log | /home/runner/work/chainlink-testing-framework/chainlink-testing-framework/gotestloghelper -ci + nix develop -c sh -c "cd ${{ matrix.project.path }} && \ + make test_unit" - name: Code Coverage uses: codecov/codecov-action@v3 with: diff --git a/.gitignore b/.gitignore index d4db78044..885f956fe 100644 --- a/.gitignore +++ b/.gitignore @@ -70,4 +70,6 @@ k3dvolume/ charts/**/*.tgz __debug* # saved private chain configuration -.private_chains/* \ No newline at end of file +.private_chains/* + +.direnv diff --git a/.helm-repositories.yaml b/.helm-repositories.yaml new file mode 100644 index 000000000..4f875a2b7 --- /dev/null +++ b/.helm-repositories.yaml @@ -0,0 +1,30 @@ +apiVersion: '' +generated: '0001-01-01T00:00:00Z' +repositories: + - caFile: '' + certFile: '' + insecure_skip_tls_verify: false + keyFile: '' + name: bitnami + pass_credentials_all: false + password: '' + url: https://charts.bitnami.com/bitnami + username: '' + - caFile: '' + certFile: '' + insecure_skip_tls_verify: false + keyFile: '' + name: chainlink-qa + pass_credentials_all: false + password: '' + url: https://raw.githubusercontent.com/smartcontractkit/qa-charts/gh-pages/ + username: '' + - caFile: '' + certFile: '' + insecure_skip_tls_verify: false + keyFile: '' + name: grafana + pass_credentials_all: false + password: '' + url: https://grafana.github.io/helm-charts + username: '' diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 19be725e8..e3389422f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -19,7 +19,10 @@ repos: hooks: - name: Prettier id: prettier - - repo: https://github.com/golangci/golangci-lint - rev: v1.54.2 # Use the version of golangci-lint you want + - repo: local hooks: - id: golangci-lint + name: golangci-lint + entry: golangci-lint run + language: system + types: [go] diff --git a/Makefile b/Makefile index 3908c50a8..72154cccf 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,3 @@ -BIN_DIR = bin export GOPATH ?= $(shell go env GOPATH) export GO111MODULE ?= on CDK8S_CLI_VERSION=2.1.48 @@ -30,14 +29,10 @@ tidy: cd ./tools/gotestloghelper && go mod tidy && cd - cd ./k8s-test-runner && go mod tidy && cd - -go_mod: tidy +.PHONY: go_mod +go_mod: go mod download -.PHONY: install_gotestfmt -install_gotestfmt: - go install github.com/gotesttools/gotestfmt/v2/cmd/gotestfmt@latest - set -euo pipefail - install_tools: ifeq ($(OSFLAG),$(WINDOWS)) echo "If you are running windows and know how to install what is needed, please contribute by adding it here!" @@ -80,11 +75,11 @@ docker_prune: compile_contracts: python3 ./utils/compile_contracts.py -test_unit: install_gotestfmt - go test -json -cover -covermode=count -coverprofile=unit-test-coverage.out ./client ./gauntlet ./testreporters ./k8s/config ./utils/osutil 2 2>&1 | tee /tmp/gotest.log | gotestfmt +test_unit: go_mod + go test -timeout 5m -json -cover -covermode=count -coverprofile=unit-test-coverage.out $(shell go list ./... | grep -v /k8s/e2e/ | grep -v /k8s/examples/ | grep -v /docker/test_env) 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -test_docker: install_gotestfmt - go test -timeout 20m -json -failfast -parallel 3 -cover -covermode=atomic -coverprofile=unit-test-coverage.out ./docker/test_env 2>&1 | tee /tmp/gotest.log | gotestfmt +test_docker: go_mod + go test -timeout 20m -json -failfast -parallel 3 -cover -covermode=atomic -coverprofile=unit-test-coverage.out ./docker/test_env 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci ####################### @@ -132,11 +127,11 @@ k8s_test: k8s_test_e2e: go test ./k8s/e2e/local-runner -count 1 -test.parallel=12 -v $(args) -k8s_test_e2e_ci: - go test ./k8s/e2e/local-runner -count 1 -v -test.parallel=14 -test.timeout=1h -json 2>&1 | tee /tmp/gotest.log | ./gotestloghelper -ci -singlepackage +k8s_test_e2e_ci: go_mod + go test ./k8s/e2e/local-runner -count 1 -test.parallel=14 -test.timeout=1h -json 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -k8s_test_e2e_ci_remote_runner: - go test ./k8s/e2e/remote-runner -count 1 -v -test.parallel=20 -test.timeout=1h -json 2>&1 | tee /tmp/remoterunnergotest.log | ./gotestloghelper -ci -singlepackage +k8s_test_e2e_ci_remote_runner: go_mod + go test ./k8s/e2e/remote-runner -count 1 -test.parallel=20 -test.timeout=1h -json 2>&1 | tee /tmp/remoterunnergotest.log | gotestloghelper -ci -singlepackage .PHONY: examples examples: @@ -157,3 +152,7 @@ chaosmesh: ## there is currently a bug on JS side to import all CRDs from one ya .PHONY: tools_build gotestloghelper_build: cd ./tools/gotestloghelper && go build -o ../../gotestloghelper . && cd - + +.PHONY: nix_shell +nix_shell: + nix develop diff --git a/README.md b/README.md index a1c7718ac..aedbfa746 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,22 @@ Then use make install_deps ``` +##### Optional Nix + +We have setup a nix shell which will produce a reliable environment that will behave the same locally and in ci. To use it instead of the above you will need to [install nix](https://nixos.org/download/) + +To start the nix shell run: + +```shell +make nix_shell +``` + +If you install [direnv](https://github.com/direnv/direnv/blob/master/docs/installation.md) you wil be able to have your environment start the nix shell as soon as you cd into it once you have allowed the directory via: + +```shell +direnv allow +``` + ### Running tests in k8s To read how to run a test in k8s, read [here](./k8s/REMOTE_RUN.md) @@ -161,6 +177,7 @@ cfg, err: = builder. ``` When using a custom image you can even further simplify the builder by calling only `WithCustomDockerImages` method. Based on the image name and version we will determine which execution layer client it is and whether it's `eth1` or `eth2` client: + ```go builder := NewEthereumNetworkBuilder() cfg, err: = builder. @@ -168,6 +185,7 @@ cfg, err: = builder. ContainerType_Geth: "ethereum/client-go:v1.13.10"}). Build() ``` + In the case above we would launch a `Geth` client with `eth2` network and `Prysm` consensus layer. You can also configure epochs at which hardforks will happen. Currently only `Deneb` is supported. Epoch must be >= 1. Example: diff --git a/flake.lock b/flake.lock new file mode 100644 index 000000000..94ed89310 --- /dev/null +++ b/flake.lock @@ -0,0 +1,61 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1712439257, + "narHash": "sha256-aSpiNepFOMk9932HOax0XwNxbA38GOUVOiXfUVPOrck=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "ff0dbd94265ac470dda06a657d5fe49de93b4599", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 000000000..e86a1f225 --- /dev/null +++ b/flake.nix @@ -0,0 +1,23 @@ +{ + description = "chainlink-testing-framework developement shell"; + + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; + flake-utils.url = "github:numtide/flake-utils"; + }; + + outputs = inputs@{ self, nixpkgs, flake-utils, ... }: + flake-utils.lib.eachDefaultSystem (system: + let + pkgs = import nixpkgs { inherit system; overlays = [ ]; }; + # The current default sdk for macOS fails to compile go projects, so we use a newer one for now. + # This has no effect on other platforms. + callPackage = pkgs.darwin.apple_sdk_11_0.callPackage or pkgs.callPackage; + in rec { + devShell = callPackage ./shell.nix { + inherit pkgs; + scriptDir = toString ./.; # This converts the flake's root directory to a string + }; + formatter = pkgs.nixpkgs-fmt; + }); +} diff --git a/nix.conf b/nix.conf new file mode 100644 index 000000000..c7d7291eb --- /dev/null +++ b/nix.conf @@ -0,0 +1 @@ +experimental-features = nix-command flakes diff --git a/shell.nix b/shell.nix new file mode 100644 index 000000000..3f4f8bc65 --- /dev/null +++ b/shell.nix @@ -0,0 +1,65 @@ +{ pkgs, scriptDir }: +with pkgs; +let + go = pkgs.go_1_21; + postgresql = postgresql_15; + nodejs = nodejs-18_x; + nodePackages = pkgs.nodePackages.override { inherit nodejs; }; +in +mkShell { + nativeBuildInputs = [ + go + goreleaser + postgresql + + python3 + python3Packages.pip + + curl + nodejs + nodePackages.pnpm + nodePackages.yarn + pre-commit + go-ethereum # geth + go-mockery + + # tooling + gotools + gopls + delve + golangci-lint + github-cli + jq + dasel + + # deployment + awscli2 + devspace + kubectl + kubernetes-helm + k9s + ] ++ lib.optionals stdenv.isLinux [ + # some dependencies needed for node-gyp on pnpm install + pkg-config + libudev-zero + libusb1 + ]; + + LD_LIBRARY_PATH = lib.makeLibraryPath [pkgs.zlib stdenv.cc.cc.lib]; # lib64 + GOROOT = "${go}/share/go"; + CGO_ENABLED = 0; + HELM_REPOSITORY_CONFIG = "${scriptDir}/.helm-repositories.yaml"; + + shellHook = '' + # enable pre-commit hooks + pre-commit install > /dev/null + # Update helm repositories + helm repo update > /dev/null + # setup go bin for nix + export GOBIN=$HOME/.nix-go/bin + mkdir -p $GOBIN + export PATH=$GOBIN:$PATH + # install gotestloghelper + go install github.com/smartcontractkit/chainlink-testing-framework/tools/gotestloghelper@latest + ''; +} diff --git a/tools/gotestloghelper/Makefile b/tools/gotestloghelper/Makefile new file mode 100644 index 000000000..7a53b93be --- /dev/null +++ b/tools/gotestloghelper/Makefile @@ -0,0 +1,5 @@ +lint: + golangci-lint --color=always run ./... --fix -v + +test_unit: + go test -timeout 5m -json -cover -covermode=count -coverprofile=unit-test-coverage.out ./... 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci diff --git a/tools/gotestloghelper/README.md b/tools/gotestloghelper/README.md index 855b8457e..d9bfe6e9b 100644 --- a/tools/gotestloghelper/README.md +++ b/tools/gotestloghelper/README.md @@ -7,7 +7,7 @@ gotestloghelper CLI is a command-line interface tool designed to enhance the out To install gotestloghelper CLI, you need to have Go installed on your machine. With Go installed, run the following command: ```sh -go intstall github.com/smartcontractkit/chainlink-testing-framework/tools/gotestloghelper +go install github.com/smartcontractkit/chainlink-testing-framework/tools/gotestloghelper@latest ``` ## Usage @@ -15,7 +15,7 @@ go intstall github.com/smartcontractkit/chainlink-testing-framework/tools/gotest After installation, you can run gotestloghelper CLI using the following syntax: ```sh -go test ./... -json | gotestevent [flags] +go test ./... -json | gotestloghelper [flags] ``` ## Available Flags @@ -33,13 +33,13 @@ go test ./... -json | gotestevent [flags] To run gotestloghelper CLI with color output: ```sh -go test ./... -json | gotestevent -json -color +go test ./... -json | gotestloghelper -json -color ``` To filter only errors from JSON-formatted test output: ```sh -go test -json ./... | gotestevent -json -onlyerrors +go test -json ./... | gotestloghelper -json -onlyerrors ``` ## Additional Notes diff --git a/tools/gotestloghelper/gotestevent/gotestevent_test.go b/tools/gotestloghelper/gotestevent/gotestevent_test.go index 36025e081..3121d11b6 100644 --- a/tools/gotestloghelper/gotestevent/gotestevent_test.go +++ b/tools/gotestloghelper/gotestevent/gotestevent_test.go @@ -1,7 +1,6 @@ package gotestevent import ( - "fmt" "io" "os" "testing" @@ -367,8 +366,6 @@ func TestBasicPassAndFail(t *testing.T) { errorAtTopLength = test.errotAtTopLength } t.Run(name, func(t *testing.T) { - fmt.Println("Logging that happens in the test") - c := &TestLogModifierConfig{ IsJsonInput: ptr.Ptr(true), RemoveTLogPrefix: ptr.Ptr(true),