.github/workflows: split long TestAutoApproveMultiNetwork into multiple jobs

Signed-off-by: Kristoffer Dalby <kristoffer@dalby.cc>
This commit is contained in:
Kristoffer Dalby
2025-12-16 11:54:43 +00:00
parent a50bd13930
commit 2c3c943acf
3 changed files with 69 additions and 5 deletions

View File

@@ -10,6 +10,55 @@ import (
"strings" "strings"
) )
// testsToSplit defines tests that should be split into multiple CI jobs.
// Key is the test function name, value is a list of subtest prefixes.
// Each prefix becomes a separate CI job as "TestName/prefix".
//
// Example: TestAutoApproveMultiNetwork has subtests like:
// - TestAutoApproveMultiNetwork/authkey-tag-advertiseduringup-false-pol-database
// - TestAutoApproveMultiNetwork/webauth-user-advertiseduringup-true-pol-file
//
// Splitting by approver type (tag, user, group) creates 6 CI jobs with 4 tests each:
// - TestAutoApproveMultiNetwork/authkey-tag.* (4 tests)
// - TestAutoApproveMultiNetwork/authkey-user.* (4 tests)
// - TestAutoApproveMultiNetwork/authkey-group.* (4 tests)
// - TestAutoApproveMultiNetwork/webauth-tag.* (4 tests)
// - TestAutoApproveMultiNetwork/webauth-user.* (4 tests)
// - TestAutoApproveMultiNetwork/webauth-group.* (4 tests)
//
// This reduces load per CI job (4 tests instead of 12) to avoid infrastructure
// flakiness when running many sequential Docker-based integration tests.
var testsToSplit = map[string][]string{
"TestAutoApproveMultiNetwork": {
"authkey-tag",
"authkey-user",
"authkey-group",
"webauth-tag",
"webauth-user",
"webauth-group",
},
}
// expandTests takes a list of test names and expands any that need splitting
// into multiple subtest patterns.
func expandTests(tests []string) []string {
var expanded []string
for _, test := range tests {
if prefixes, ok := testsToSplit[test]; ok {
// This test should be split into multiple jobs.
// We append ".*" to each prefix because the CI runner wraps patterns
// with ^...$ anchors. Without ".*", a pattern like "authkey$" wouldn't
// match "authkey-tag-advertiseduringup-false-pol-database".
for _, prefix := range prefixes {
expanded = append(expanded, fmt.Sprintf("%s/%s.*", test, prefix))
}
} else {
expanded = append(expanded, test)
}
}
return expanded
}
func findTests() []string { func findTests() []string {
rgBin, err := exec.LookPath("rg") rgBin, err := exec.LookPath("rg")
if err != nil { if err != nil {
@@ -66,8 +115,11 @@ func updateYAML(tests []string, jobName string, testPath string) {
func main() { func main() {
tests := findTests() tests := findTests()
quotedTests := make([]string, len(tests)) // Expand tests that should be split into multiple jobs
for i, test := range tests { expandedTests := expandTests(tests)
quotedTests := make([]string, len(expandedTests))
for i, test := range expandedTests {
quotedTests[i] = fmt.Sprintf("\"%s\"", test) quotedTests[i] = fmt.Sprintf("\"%s\"", test)
} }

View File

@@ -90,15 +90,22 @@ jobs:
run: /tmp/artifacts/hi run --stats --ts-memory-limit=300 --hs-memory-limit=1500 "^${{ inputs.test }}$" \ run: /tmp/artifacts/hi run --stats --ts-memory-limit=300 --hs-memory-limit=1500 "^${{ inputs.test }}$" \
--timeout=120m \ --timeout=120m \
${{ inputs.postgres_flag }} ${{ inputs.postgres_flag }}
# Sanitize test name for artifact upload (replace invalid characters: " : < > | * ? \ / with -)
- name: Sanitize test name for artifacts
if: always()
id: sanitize
run: echo "name=${TEST_NAME//[\":<>|*?\\\/]/-}" >> $GITHUB_OUTPUT
env:
TEST_NAME: ${{ inputs.test }}
- uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
if: always() if: always()
with: with:
name: ${{ inputs.database_name }}-${{ inputs.test }}-logs name: ${{ inputs.database_name }}-${{ steps.sanitize.outputs.name }}-logs
path: "control_logs/*/*.log" path: "control_logs/*/*.log"
- uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
if: always() if: always()
with: with:
name: ${{ inputs.database_name }}-${{ inputs.test }}-artifacts name: ${{ inputs.database_name }}-${{ steps.sanitize.outputs.name }}-artifacts
path: control_logs/ path: control_logs/
- name: Setup a blocking tmux session - name: Setup a blocking tmux session
if: ${{ env.HAS_TAILSCALE_SECRET }} if: ${{ env.HAS_TAILSCALE_SECRET }}

View File

@@ -195,7 +195,12 @@ jobs:
- TestEnablingExitRoutes - TestEnablingExitRoutes
- TestSubnetRouterMultiNetwork - TestSubnetRouterMultiNetwork
- TestSubnetRouterMultiNetworkExitNode - TestSubnetRouterMultiNetworkExitNode
- TestAutoApproveMultiNetwork - TestAutoApproveMultiNetwork/authkey-tag.*
- TestAutoApproveMultiNetwork/authkey-user.*
- TestAutoApproveMultiNetwork/authkey-group.*
- TestAutoApproveMultiNetwork/webauth-tag.*
- TestAutoApproveMultiNetwork/webauth-user.*
- TestAutoApproveMultiNetwork/webauth-group.*
- TestSubnetRouteACLFiltering - TestSubnetRouteACLFiltering
- TestHeadscale - TestHeadscale
- TestTailscaleNodesJoiningHeadcale - TestTailscaleNodesJoiningHeadcale