Skip to content

Commit

Permalink
Move citool from CTF to Core repo
Browse files Browse the repository at this point in the history
  • Loading branch information
lukaszcl committed Jul 17, 2024
1 parent a67341d commit 2536d2c
Show file tree
Hide file tree
Showing 15 changed files with 1,142 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,11 @@ inputs:
runs:
using: 'composite'
steps:
- name: Checkout chainlink-testing-framework to use citool
uses: actions/checkout@v3
with:
repository: 'smartcontractkit/chainlink-testing-framework'
ref: 4800d2033f951af46f8829367d6f565f45baaff8
path: 'chainlink-testing-framework'

- name: Create default E2E test config override
id: build-args
shell: bash
run: |
cd chainlink-testing-framework/tools/citool/
cd integration-tests/citool/
create_args=()
if [ -n "${{ inputs.chainlink_version }}" ]; then
Expand Down
20 changes: 3 additions & 17 deletions .github/workflows/run-e2e-tests-reusable-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -126,17 +126,11 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
- name: Checkout chainlink-testing-framework to use citool
uses: actions/checkout@v3
with:
repository: 'smartcontractkit/chainlink-testing-framework'
ref: 4800d2033f951af46f8829367d6f565f45baaff8
path: 'chainlink-testing-framework'
- name: Setup Go
uses: ./.github/actions/setup-go
- name: Run Check Tests Command
run: |
if ! go run chainlink-testing-framework/tools/citool/main.go check-tests ./integration-tests .github/e2e-tests.yml; then
if ! go run integration-tests/citool/main.go check-tests ./integration-tests .github/e2e-tests.yml; then
echo "::error::Some E2E test configurations have to be added to .github/e2e-tests.yml. This file defines Github CI configuration for each E2E test or set of E2E tests." && exit 1
fi
Expand Down Expand Up @@ -172,29 +166,21 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
- name: Checkout chainlink-testing-framework to use citool
uses: actions/checkout@v3
with:
repository: 'smartcontractkit/chainlink-testing-framework'
ref: 4800d2033f951af46f8829367d6f565f45baaff8
path: 'chainlink-testing-framework'
- name: Setup Go
uses: ./.github/actions/setup-go
- name: Install jq
run: sudo apt-get install jq
- name: Generate Docker Tests Matrix
id: set-docker-matrix
run: |
cd chainlink-testing-framework/tools/citool/
MATRIX_JSON=$(go run main.go filter --file ${{ github.workspace }}/.github/e2e-tests.yml --test-env-type 'docker' --test-list '${{ inputs.test_list }}' --test-ids '${{ inputs.test_ids }}' --workflow '${{ inputs.test_workflow }}')
MATRIX_JSON=$(go run integration-tests/citool/main.go filter --file ${{ github.workspace }}/.github/e2e-tests.yml --test-env-type 'docker' --test-list '${{ inputs.test_list }}' --test-ids '${{ inputs.test_ids }}' --workflow '${{ inputs.test_workflow }}')
echo "Docker tests:"
echo "$MATRIX_JSON" | jq
echo "matrix=$MATRIX_JSON" >> $GITHUB_OUTPUT
- name: Generate K8s Tests Matrix
id: set-k8s-runner-matrix
run: |
cd chainlink-testing-framework/tools/citool/
MATRIX_JSON=$(go run main.go filter --file ${{ github.workspace }}/.github/e2e-tests.yml --test-env-type 'k8s-remote-runner' --test-list '${{ inputs.test_list }}' --test-ids '${{ inputs.test_ids }}' --workflow '${{ inputs.test_workflow }}')
MATRIX_JSON=$(go run integration-tests/citool/main.go filter --file ${{ github.workspace }}/.github/e2e-tests.yml --test-env-type 'k8s-remote-runner' --test-list '${{ inputs.test_list }}' --test-ids '${{ inputs.test_ids }}' --workflow '${{ inputs.test_workflow }}')
echo "K8s tests:"
echo "$MATRIX_JSON" | jq
echo "matrix=$MATRIX_JSON" >> $GITHUB_OUTPUT
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ __debug_bin*
integration-tests/**/traces/
benchmark_report.csv
benchmark_summary.json
integration-tests/citool/output.csv

# goreleaser builds
cosign.*
Expand Down
128 changes: 128 additions & 0 deletions integration-tests/citool/cmd/check_tests_cmd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
package cmd

import (
"fmt"
"os"
"path/filepath"
"regexp"
"strings"

"github.com/spf13/cobra"
"gopkg.in/yaml.v3"
)

type JobConfig struct {
Jobs map[string]struct {
Strategy struct {
Matrix struct {
Test []struct {
Path string `yaml:"path"`
TestOpts string `yaml:"testOpts"`
} `yaml:"test"`
} `yaml:"matrix"`
} `yaml:"strategy"`
} `yaml:"jobs"`
}

var checkTestsCmd = &cobra.Command{
Use: "check-tests [directory] [yaml file]",
Short: "Check if all tests in a directory are included in the test configurations YAML file",
Args: cobra.ExactArgs(2),
Run: func(_ *cobra.Command, args []string) {
directory := args[0]
yamlFile := args[1]
tests, err := extractTests(directory)
if err != nil {
fmt.Println("Error extracting tests:", err)
os.Exit(1)
}

checkTestsInPipeline(yamlFile, tests)
},
}

func extractTests(dir string) ([]Test, error) {
var tests []Test
err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if !info.IsDir() && strings.HasSuffix(info.Name(), "_test.go") {
content, err := os.ReadFile(path)
if err != nil {
return err
}
re := regexp.MustCompile(`func (Test\w+)`)
matches := re.FindAllSubmatch(content, -1)
for _, match := range matches {
tests = append(tests, Test{
Name: string(match[1]),
Path: path,
})
}
}
return nil
})
return tests, err
}

func checkTestsInPipeline(yamlFile string, tests []Test) {
data, err := os.ReadFile(yamlFile)
if err != nil {
fmt.Printf("Error reading YAML file: %s\n", err)
return
}

var config Config
err = yaml.Unmarshal(data, &config)
if err != nil {
fmt.Printf("Error parsing YAML: %s\n", err)
return
}

missingTests := []string{} // Track missing tests

for _, test := range tests {
found := false
for _, item := range config.Tests {
if item.Path == test.Path {
if strings.Contains(item.TestCmd, "-test.run") {
if matchTestNameInCmd(item.TestCmd, test.Name) {
found = true
break
}
} else {
found = true
break
}
}
}
if !found {
missingTests = append(missingTests, fmt.Sprintf("ERROR: Test '%s' in file '%s' does not have CI configuration in '%s'", test.Name, test.Path, yamlFile))
}
}

if len(missingTests) > 0 {
for _, missing := range missingTests {
fmt.Println(missing)
}
os.Exit(1) // Exit with a failure status
}
}

// matchTestNameInCmd checks if the given test name matches the -test.run pattern in the command string.
func matchTestNameInCmd(cmd string, testName string) bool {
testRunRegex := regexp.MustCompile(`-test\.run ([^\s]+)`)
matches := testRunRegex.FindStringSubmatch(cmd)
if len(matches) > 1 {
// Extract the regex pattern used in the -test.run command
pattern := matches[1]

// Escape regex metacharacters in the testName before matching
escapedTestName := regexp.QuoteMeta(testName)

// Check if the escaped test name matches the extracted pattern
return regexp.MustCompile(pattern).MatchString(escapedTestName)
}
return false
}
47 changes: 47 additions & 0 deletions integration-tests/citool/cmd/check_tests_cmd_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package cmd

import (
"testing"
)

func TestMatchTestNameInCmd(t *testing.T) {
tests := []struct {
cmd string
testName string
expected bool
}{
{"go test -test.run ^TestExample$", "TestExample", true},
{"go test -test.run ^TestExample$", "TestAnother", false},
{"go test -test.run ^TestExample$ -v", "TestExample", true},
{"go test -test.run ^TestExamplePart$", "TestExample", false},
{"go test -test.run ^TestWithNumbers123$", "TestWithNumbers123", true},
{"go test -test.run ^Test_With_Underscores$", "Test_With_Underscores", true},
{"go test -test.run ^Test-With-Dash$", "Test-With-Dash", true},
{"go test -test.run ^TestWithSpace Space$", "TestWithSpace Space", true},
{"go test -test.run ^TestWithNewline\nNewline$", "TestWithNewline\nNewline", true},
{"go test -test.run ^TestOne$|^TestTwo$", "TestOne", true},
{"go test -test.run ^TestOne$|^TestTwo$", "TestTwo", true},
{"go test -test.run ^TestOne$|^TestTwo$", "TestThree", false},
{"go test -test.run TestOne|TestTwo", "TestTwo", true},
{"go test -test.run TestOne|TestTwo", "TestOne", true},
{"go test -test.run TestOne|TestTwo|TestThree", "TestFour", false},
{"go test -test.run ^TestOne$|TestTwo$", "TestTwo", true},
{"go test -test.run ^TestOne$|TestTwo|TestThree$", "TestThree", true},
{"go test -test.run TestOne|TestTwo|TestThree", "TestOne", true},
{"go test -test.run TestOne|TestTwo|TestThree", "TestThree", true},
{"go test -test.run ^TestA$|^TestB$|^TestC$", "TestA", true},
{"go test -test.run ^TestA$|^TestB$|^TestC$", "TestB", true},
{"go test -test.run ^TestA$|^TestB$|^TestC$", "TestD", false},
{"go test -test.run TestA|^TestB$|TestC", "TestB", true},
{"go test -test.run ^TestA|^TestB|TestC$", "TestA", true},
{"go test -test.run ^TestA|^TestB|TestC$", "TestC", true},
{"go test -test.run ^TestA|^TestB|TestC$", "TestD", false},
}

for _, tt := range tests {
result := matchTestNameInCmd(tt.cmd, tt.testName)
if result != tt.expected {
t.Errorf("matchTestNameInCmd(%s, %s) = %t; expected %t", tt.cmd, tt.testName, result, tt.expected)
}
}
}
Loading

0 comments on commit 2536d2c

Please sign in to comment.