Skip to content

ci: configure itests in build constraints, detect in Actions script #31

ci: configure itests in build constraints, detect in Actions script

ci: configure itests in build constraints, detect in Actions script #31

Workflow file for this run

name: Test
on:
pull_request:
push:
branches:
- master
- release/*
workflow_dispatch:
defaults:
run:
shell: bash
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
discover:
name: Discover Test Groups
runs-on: ubuntu-latest
outputs:
groups: ${{ steps.test.outputs.groups }}
steps:
- uses: actions/checkout@v4
with:
submodules: 'recursive'
- id: test
env:
# Unit test groups other than unit-rest
utests: |
[
{"name": "unit-cli", "packages": ["./cli/...", "./cmd/...", "./api/..."]},
{"name": "unit-storage", "packages": ["./storage/...", "./extern/..."]},
{"name": "unit-node", "packages": ["./node/..."]}
]
# Other tests that require special configuration
otests: |
[
{
"name": "multicore-sdr",
"packages": ["./storage/sealer/ffiwrapper"],
"go_test_flags": "-run=TestMulticoreSDR",
"test_rustproofs_logs": "1"
}, {
"name": "conformance",
"packages": ["./conformance"],
"go_test_flags": "-run=TestConformance",
"skip_conformance": "0"
}
]
run: |
# Mapping from test group names to custom runner labels
# The jobs default to running on the default hosted runners (4 CPU, 16 RAM).
# We use self-hosted xlarge (4 CPU, 8 RAM; and large - 2 CPU, 4 RAM) runners
# to extend the available runner capacity (60 default hosted runners).
# We use self-hosted 4xlarge (16 CPU, 32 RAM; and 2xlarge - 8 CPU, 16 RAM) self-hosted
# to support resource intensive jobs.
# In CircleCI, the jobs defaulted to running on medium+ runners (3 CPU, 6 RAM).
# The following jobs were scheduled to run on 2xlarge runners (16 CPU, 32 RAM):
# - itest-deals_concurrent (✅)
# - itest-sector_pledge (✅)
# - itest-wdpost_worker_config (❌)
# - itest-worker (✅)
# - unit-cli (❌)
# - unit-rest (❌)
runners='{
"unit-storage": ["self-hosted", "linux", "x64", "2xlarge"],
"multicore-sdr": ["self-hosted", "linux", "x64", "xlarge"],
"unit-node": ["self-hosted", "linux", "x64", "xlarge"],
'
# Detect integration test groups that require non-default runners
for file in $(find ./itests -name '*_test.go'); do
if grep -q '//go:build integration .*xlarge' $file; then
base_name=$(basename -- "$file")
test_name="${base_name%_test.go}"
runner_size=$(grep -o '.*xlarge' $file | awk '{print $NF}')
runners+=$'\n'"\"itest-$test_name\": [\"self-hosted\", \"linux\", \"x64\", \"$runner_size\"],"
fi
done
runners=${runners%?}
runners+=$'\n'"}"
# A list of test groups that require YugabyteDB to be started
yugabytedb=""
for file in $(find ./itests -name '*_test.go'); do
if grep -q '//go:build integration .* db' $file; then
base_name=$(basename -- "$file")
test_name="${base_name%_test.go}"
yugabytedb+=$'\n'"\"itest-$test_name\","
fi
done
yugabytedb="[${yugabytedb%?}]"
# A list of test groups that require Proof Parameters to be fetched
# In CircleCI, only the following jobs had get-params set:
# - unit-cli (✅)
# - unit-storage (✅)
# - itest-sector_pledge (✅)
# - itest-wdpost (✅)
parameters='
"conformance",
"multicore-sdr",
"unit-cli",
"unit-storage",'
for file in $(find ./itests -name '*_test.go'); do
if grep -q '//go:build integration .* parameters' $file; then
base_name=$(basename -- "$file")
test_name="${base_name%_test.go}"
parameters+=$'\n'"\"itest-$test_name\","
fi
done
parameters="[${parameters%?}]"
# Create a list of integration test groups
itests="$(
find ./itests -name "*_test.go" | \
jq -R '{
"name": "itest-\(. | split("/") | .[2] | sub("_test.go$";""))",
"packages": [.]
}' | jq -s
)"
# Create a list of packages that are covered by the integration and unit tests
packages="$(jq -n --argjson utests "$utests" '$utests | map(.packages) | flatten | . + ["./itests/..."]')"
# Create a new group for the unit tests that are not yet covered
rest="$(
find . -name "*_test.go" | cut -d/ -f2 | sort | uniq | \
jq -R '"./\(.)/..."' | \
jq -s --argjson p "$packages" '{"name": "unit-rest", "packages": (. - $p)}'
)"
# Combine the groups for integration tests, unit tests, the new unit-rest group, and the other tests
groups="$(jq -n --argjson i "$itests" --argjson u "$utests" --argjson r "$rest" --argjson o "$otests" '$i + $u + [$r] + $o')"
# Apply custom runner labels to the groups
groups="$(jq -n --argjson g "$groups" --argjson r "$runners" '$g | map(. + {"runner": (.name as $n | $r | .[$n]) })')"
# Apply the needs_yugabytedb flag to the groups
groups="$(jq -n --argjson g "$groups" --argjson y "$yugabytedb" '$g | map(. + {"needs_yugabytedb": ([.name] | inside($y)) })')"
# Apply the needs_parameters flag to the groups
groups="$(jq -n --argjson g "$groups" --argjson p "$parameters" '$g | map(. + {"needs_parameters": ([.name] | inside($p)) })')"
# Output the groups
echo "groups=$groups"
echo "groups=$(jq -nc --argjson g "$groups" '$g')" >> $GITHUB_OUTPUT
fetch:
name: Fetch Dependencies
runs-on: ubuntu-latest
outputs:
parameters_key: ${{ steps.parameters.outputs.key }}
parameters_path: ${{ steps.parameters.outputs.path }}
filcrypto_key: ${{ steps.filcrypto.outputs.key }}
filcrypto_path: ${{ steps.filcrypto.outputs.path }}
steps:
- uses: actions/checkout@v4
with:
submodules: 'recursive'
- id: parameters
env:
CACHE_KEY: filecoin-proof-parameters-${{ hashFiles('./extern/filecoin-ffi/parameters.json') }}
CACHE_PATH: |
/var/tmp/filecoin-proof-parameters/
run: |
echo -e "key=$CACHE_KEY" | tee -a $GITHUB_OUTPUT
echo -e "path<<EOF\n$CACHE_PATH\nEOF" | tee -a $GITHUB_OUTPUT
- id: filcrypto
env:
CACHE_KEY: ${{ runner.os }}-${{ runner.arch }}-filcrypto-${{ hashFiles('./extern/filecoin-ffi/install-filcrypto') }}-${{ hashFiles('./extern/filecoin-ffi/rust/rustc-target-features-optimized.json') }}
CACHE_PATH: |
./extern/filecoin-ffi/filcrypto.h
./extern/filecoin-ffi/libfilcrypto.a
./extern/filecoin-ffi/filcrypto.pc
run: |
echo -e "key=$CACHE_KEY" | tee -a $GITHUB_OUTPUT
echo -e "path<<EOF\n$CACHE_PATH\nEOF" | tee -a $GITHUB_OUTPUT
- id: restore_parameters
uses: actions/cache/restore@v4
with:
key: ${{ steps.parameters.outputs.key }}
path: ${{ steps.parameters.outputs.path }}
lookup-only: true
- id: restore_filcrypto
uses: actions/cache/restore@v4
with:
key: ${{ steps.filcrypto.outputs.key }}
path: ${{ steps.filcrypto.outputs.path }}
lookup-only: true
- if: steps.restore_parameters.outputs.cache-hit != 'true'
uses: ./.github/actions/install-ubuntu-deps
- if: steps.restore_parameters.outputs.cache-hit != 'true'
uses: ./.github/actions/install-go
- if: steps.restore_parameters.outputs.cache-hit != 'true' || steps.restore_filcrypto.outputs.cache-hit != 'true'
env:
GITHUB_TOKEN: ${{ github.token }}
run: make deps
- if: steps.restore_parameters.outputs.cache-hit != 'true'
run: make lotus
- if: steps.restore_parameters.outputs.cache-hit != 'true'
run: ./lotus fetch-params 2048
- if: steps.restore_parameters.outputs.cache-hit != 'true'
uses: actions/cache/save@v4
with:
key: ${{ steps.parameters.outputs.key }}
path: ${{ steps.parameters.outputs.path }}
- if: steps.restore_filcrypto.outputs.cache-hit != 'true'
uses: actions/cache/save@v4
with:
key: ${{ steps.filcrypto.outputs.key }}
path: ${{ steps.filcrypto.outputs.path }}
test:
needs: [discover, fetch]
name: Test (${{ matrix.name }})
runs-on: ${{ github.repository == 'filecoin-project/lotus' && matrix.runner || 'ubuntu-latest' }}
strategy:
fail-fast: false
matrix:
include: ${{ fromJson(needs.discover.outputs.groups) }}
steps:
- uses: actions/checkout@v4
with:
submodules: 'recursive'
- uses: ./.github/actions/install-ubuntu-deps
- uses: ./.github/actions/install-go
- run: go install gotest.tools/gotestsum@latest
- name: Install filcrypto
uses: actions/cache/restore@v4
with:
key: ${{ needs.fetch.outputs.filcrypto_key }}
path: ${{ needs.fetch.outputs.filcrypto_path }}
fail-on-cache-miss: true
- if: ${{ matrix.needs_parameters }}
name: Fetch Proof Parameters
uses: actions/cache/restore@v4
with:
key: ${{ needs.fetch.outputs.parameters_key }}
path: ${{ needs.fetch.outputs.parameters_path }}
fail-on-cache-miss: true
- if: ${{ matrix.needs_yugabytedb }}
uses: ./.github/actions/start-yugabytedb
timeout-minutes: 3
# TODO: Install statediff (used to be used for conformance)
- id: reports
run: mktemp -d | xargs -0 -I{} echo "path={}" | tee -a $GITHUB_OUTPUT
# TODO: Track coverage (used to be tracked for conformance)
- env:
NAME: ${{ matrix.name }}
LOTUS_SRC_DIR: ${{ github.workspace }}
LOTUS_HARMONYDB_HOSTS: 127.0.0.1
REPORTS_PATH: ${{ steps.reports.outputs.path }}
SKIP_CONFORMANCE: ${{ matrix.skip_conformance || '1' }}
TEST_RUSTPROOFS_LOGS: ${{ matrix.test_rustproofs_logs || '0' }}
FORMAT: ${{ matrix.format || 'standard-verbose' }}
PACKAGES: ${{ join(matrix.packages, ' ') }}
run: |
gotestsum \
--format "$FORMAT" \
--junitfile "$REPORTS_PATH/$NAME.xml" \
--jsonfile "$REPORTS_PATH/$NAME.json" \
--packages="$PACKAGES" \
-- ${{ matrix.go_test_flags || '' }}
- if: success() || failure()
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.name }}
path: |
${{ steps.reports.outputs.path }}/${{ matrix.name }}.xml
${{ steps.reports.outputs.path }}/${{ matrix.name }}.json
continue-on-error: true