Skip to content

Commit

Permalink
test(acctest): incremental run support
Browse files Browse the repository at this point in the history
  • Loading branch information
Serpentiel committed Feb 27, 2024
1 parent 80df024 commit fa31c27
Showing 1 changed file with 297 additions and 0 deletions.
297 changes: 297 additions & 0 deletions .github/workflows/incremental-acceptance-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,297 @@
name: Incremental Acceptance Tests

on:
pull_request:
branches:
- main
- v*
types:
- opened
- synchronize
- reopened
- labeled
- unlabeled
push:
branches:
- main
- v*
workflow_dispatch: {}

permissions: read-all

concurrency:
group: ci-${{ github.head_ref || github.ref }}
cancel-in-progress: true

jobs:
selproj:
name: Run selproj
runs-on: ubuntu-latest
if: >
(github.event_name == 'pull_request' && !contains(github.event.pull_request.labels.*.name, 'skip workflows')) ||
github.event_name == 'push'
outputs:
suffix: ${{ steps.selproj.outputs.suffix }}

steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- id: selproj
run: echo "suffix=$(make -s ci-selproj | tr -d '\n')" >> $GITHUB_OUTPUT
env:
AIVEN_TOKEN: ${{ secrets.AIVEN_TOKEN }}
AIVEN_PROJECT_NAME_PREFIX: ${{ secrets.AIVEN_PROJECT_NAME_PREFIX }}

parse_sdkv2_files:
name: Parse SDKv2 resource and datasource files
runs-on: ubuntu-latest
if: >
(github.event_name == 'pull_request' && !contains(github.event.pull_request.labels.*.name, 'skip workflows')) ||
github.event_name == 'push'
env:
SDKV2_IMPL_PATH: internal/sdkprovider

outputs:
files: ${{ steps.parse_files.outputs.files }}

steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Find provider.go file
id: find_provider_go_file
run: |
echo "path=$(find "$SDKV2_IMPL_PATH" -type f -name 'provider.go')" >> $GITHUB_OUTPUT
- name: Extract imports
id: extract_imports
run: |
provider_go_file=${{ steps.find_provider_go_file.outputs.path }}
imports=$(awk '/^import \(/{flag=1;next}/^\)/{flag=0}flag' "$provider_go_file")
imports=$(echo "$imports" | jq -R -s -c 'split("\n") | map(select(length > 0) | gsub("[[:space:]\"]";""))')
echo "imports=$imports" >> $GITHUB_OUTPUT
- name: Build import map
id: build_import_map
run: |
import_lines=$(echo '${{ steps.extract_imports.outputs.imports }}' | jq -r '.[]')
import_map="{}"
while IFS= read -r line; do
if [[ $line =~ ^(.*)"$SDKV2_IMPL_PATH"/(.*)$ ]]; then
package_path="${BASH_REMATCH[2]}"
package_name=$(basename "$package_path")
echo "Found package $package_name in $SDKV2_IMPL_PATH/$package_path"
import_map=$(
echo "$import_map" | jq -c --arg key "$package_name" --arg value "$package_path" \
'. + {($key): $value}'
)
fi
done <<< "$import_lines"
echo "import_map=$import_map" >> $GITHUB_OUTPUT
- name: Parse files
id: parse_files
run: |
provider_go_file=${{ steps.find_provider_go_file.outputs.path }}
import_map='${{ steps.build_import_map.outputs.import_map }}'
files="[]"
while read -r name type func_with_parentheses; do
if [[ -z "$name" || -z "$func_with_parentheses" ]]; then
continue
fi
func="${func_with_parentheses%)*}"
func="${func##*.}"
package_name="${func_with_parentheses%%.*}"
path=$(echo $import_map | jq -r --arg package_name "$package_name" '.[$package_name] // empty')
if [[ -n "$path" ]]; then
path="$SDKV2_IMPL_PATH/$path"
file=$(find "$path" -type f -name '*.go' -exec grep -l "$func" {} +)
if [[ -n "$file" ]]; then
echo "Found $type $name in $file"
files=$(
echo "$files" | jq -c --arg name "$name" --arg type "$type" --arg file "$file" \
'. + [{($name): {("type"): $type, ("file"): $file}}]'
)
fi
fi
done < <(awk -v file="$provider_go_file" '
/ResourcesMap: map\[string\]\*schema\.Resource{/ { type="resource"; capture = 1; next }
/DataSourcesMap: map\[string\]\*schema\.Resource{/ { type="datasource"; capture = 1; next }
capture && /\}/ { capture = 0 }
capture && NF {
gsub(/[\t "]+/, "")
split($0, a, ":")
print a[1], type, a[2]
}
' "$provider_go_file")
echo "files=$files" >> $GITHUB_OUTPUT
parse_plugin_framework_files:
name: Parse Plugin Framework resource and datasource files
runs-on: ubuntu-latest

needs: parse_sdkv2_files

env:
PLUGIN_FRAMEWORK_IMPL_PATH: internal/plugin

outputs:
files: ${{ steps.parse_files.outputs.files }}

steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Parse files
id: parse_files
run: |
files='${{ needs.parse_sdkv2_files.outputs.files }}'
while IFS= read -r file; do
while IFS=, read -r name type file; do
echo "Found $type $name in $file"
files=$(
echo "$files" | jq -c --arg name "$name" --arg type "$type" --arg file "$file" \
'. + [{($name): {("type"): $type, ("file"): $file}}]'
)
done < <(awk -v file="$file" '
/resp\.TypeName\s*=\s*req\.ProviderTypeName\s*\+\s*"/ {
match($0, /"(_[^"]+)"/, arr)
if (length(arr[1]) > 0) {
type = "datasource"
while((getline line < file) > 0) {
if (line ~ /_ resource\.Resource/) {
type = "resource"
break
}
}
close(file)
print "aiven" arr[1] "," type "," file
}
}
' "$file")
done < <(find "$PLUGIN_FRAMEWORK_IMPL_PATH" -type f -name '*.go')
echo "files=$files" >> $GITHUB_OUTPUT
find_tests:
name: Find tests
runs-on: ubuntu-latest

needs:
- parse_plugin_framework_files

outputs:
tests: ${{ steps.find_tests.outputs.tests }}

steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: go.mod

- name: Find tests
id: find_tests
run: |
tests=()
mapfile -t parsed_files < <(echo '${{ needs.parse_plugin_framework_files.outputs.files }}' | jq -c '.[]')
for parsed_file in "${parsed_files[@]}"; do
name=$(echo "$parsed_file" | jq -r 'keys[0]')
type=$(echo "$parsed_file" | jq -r --arg name "$name" '.[$name].type')
file=$(echo "$parsed_file" | jq -r --arg name "$name" '.[$name].file')
dir=$(dirname "$file")
file_changed=false
dep_changed=false
if git diff "origin/${{ github.base_ref || 'main' }}" --name-only | grep -q "^$file$"; then
echo "Definition of $name $type in $file changed"
file_changed=true
else
deps=$(go list -json "./$dir" | jq -r '.Deps[]' | grep -oP '^github.com/aiven/terraform-provider-aiven/\K.*')
for dep in $deps; do
if git diff "origin/${{ github.base_ref || 'main' }}" --name-only | grep -q "$dep"; then
echo "Dependency $dep of $name $type changed"
dep_changed=true
break
fi
done
fi
if [ "$file_changed" = true ] || [ "$dep_changed" = true ]; then
pattern=""
[[ "$type" == "resource" ]] && pattern="resource \"$name\""
[[ "$type" == "datasource" ]] && pattern="data \"$name\""
while IFS= read -r test; do
if grep -q "$pattern" "$test"; then
echo "Found test for $name $type in $test"
tests+=("$test")
fi
done < <(find internal -type f -name '*_test.go' -exec grep -l "$pattern" {} +)
fi
done
readarray -t unique_tests < <(printf '%s\n' "${tests[@]}" | awk '!seen[$0]++')
tests_json=$(printf '%s\n' "${unique_tests[@]}" | jq -R . | jq -s -c .)
echo "tests=$tests_json" >> $GITHUB_OUTPUT
run_tests:
name: Run tests
runs-on: ubuntu-latest

needs:
- selproj
- find_tests

env:
COUNT: 1
PARALLEL: 10
TIMEOUT: 180m

strategy:
max-parallel: 5
matrix:
test: ${{ fromJson(needs.find_tests.outputs.tests) }}

steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: go.mod

- name: Run tests
run: go test ${{ matrix.test }} -v -count $COUNT -parallel $PARALLEL -timeout $TIMEOUT
env:
TF_ACC: 1
CGO_ENABLED: 0
AIVEN_TOKEN: ${{ secrets.AIVEN_TOKEN }}
AIVEN_PROJECT_NAME: ${{ secrets.AIVEN_PROJECT_NAME_PREFIX }}${{ needs.selproj.outputs.suffix }}
AIVEN_ORGANIZATION_NAME: ${{ secrets.AIVEN_ORGANIZATION_NAME }}
AIVEN_ACCOUNT_NAME: ${{ secrets.AIVEN_ORGANIZATION_NAME }}

0 comments on commit fa31c27

Please sign in to comment.