Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion .github/workflows/stlc-generate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,15 @@ jobs:
--targets all \
"${commit_args[@]}"
stlc exec --targets "$SDK_TARGETS" -- ./scripts/bootstrap
stlc lint --targets "$SDK_TARGETS"
for attempt in 1 2 3; do
if stlc lint --targets "$SDK_TARGETS"; then
break
fi
if [ "$attempt" -eq 3 ]; then
exit 1
fi
sleep 5
done
stlc test --targets "$SDK_TARGETS"
stlc exec --targets "$SDK_TARGETS" -- sh -c \
'status=$(git status --porcelain --untracked-files=all) && [ -z "$status" ] || { printf "%s\n" "$status" >&2; exit 1; }'
Expand Down
32 changes: 32 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,17 @@ jobs:
runs-on: [self-hosted, linux, x64, kvm]
steps:
- uses: actions/checkout@v4
id: checkout
continue-on-error: true
with:
clean: false
repository: ${{ env.TEST_SOURCE_REPO }}
ref: ${{ env.TEST_SOURCE_REF }}
persist-credentials: false

- name: Retry checkout
if: steps.checkout.outcome == 'failure'
uses: actions/checkout@v4
with:
clean: false
repository: ${{ env.TEST_SOURCE_REPO }}
Expand Down Expand Up @@ -97,6 +108,27 @@ jobs:
sudo env "PATH=$TEST_PATH" bash -lc "command -v '$bin'"
done

- name: Stage Windows test fixtures
run: |
fixture_dir=/mnt/data/ci-fixtures/windows
image_source=$(sudo find /mnt/data/home -path '*/windows-vm-exp/build/*-agent.qcow2' -print -quit)
base_source=$(sudo find /mnt/data/home -path '*/windows-vm-exp/build/*-golden.raw' -print -quit)
sudo mkdir -p "$fixture_dir" /ci/windows
if ! test -r "$fixture_dir/image-agent.qcow2" && test -n "$image_source"; then
sudo cp --reflink=auto --sparse=always "$image_source" "$fixture_dir/image-agent.qcow2"
sudo chmod 0444 "$fixture_dir/image-agent.qcow2"
fi
if ! test -r "$fixture_dir/base.raw" && test -n "$base_source"; then
sudo cp --reflink=auto --sparse=always "$base_source" "$fixture_dir/base.raw"
sudo chmod 0444 "$fixture_dir/base.raw"
fi
if test -r "$fixture_dir/image-agent.qcow2"; then
sudo ln -sfn "$fixture_dir/image-agent.qcow2" /ci/windows/image-agent.qcow2
fi

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Recovery find can abort CI

Medium Severity

The Windows fixture staging path is best-effort: missing source only skips the symlink. The new sudo find runs in that same path under Actions’ default bash -e, so a missing /mnt/data/home or any find error fails the whole step and blocks later tests that do not need the fixture.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 44df562. Configure here.

if test -r "$fixture_dir/base.raw"; then
sudo ln -sfn "$fixture_dir/base.raw" /ci/windows/base.raw
fi

# Slash-command runs are maintainer-approved and need authenticated pulls
# for images that are not covered by the prewarm cache.
- name: Login to Docker Hub
Expand Down
33 changes: 32 additions & 1 deletion lib/instances/test_network_config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,10 @@ func allocateTestNetworkLease(testName string, seq uint32) (*testNetworkLease, e
return err
}

bridgeName = fmt.Sprintf("hm%04x%03x", testNetworkRunSeed&0xffff, seq%0xfff)
bridgeName, err = testBridgeNameForSubnet(subnet)
if err != nil {
return err
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Orphan bridges can block subnets

Medium Severity

Bridge names are now a fixed function of the leased subnet, but subnet selection only skips leases and overlapping routes. An orphan hm* bridge with no lease and no route still maps to the same name on the next lease of that subnet, so createBridge can fail when the interface already exists without the expected address. The old seed-based names avoided reusing that interface name.

Additional Locations (2)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 7e3924e. Configure here.

allocatedSubnet = subnet
leases[subnet] = subnetLease{
TestName: testName,
Expand Down Expand Up @@ -443,6 +446,34 @@ func pruneStaleLeases(leases map[string]subnetLease, routes []hostRoute) {
}
}

func testBridgeNameForSubnet(subnet string) (string, error) {
ip, _, err := net.ParseCIDR(subnet)
if err != nil {
return "", fmt.Errorf("parse test subnet %q: %w", subnet, err)
}
ip = ip.To4()
if ip == nil {
return "", fmt.Errorf("test subnet %q is not IPv4", subnet)
}
return fmt.Sprintf("hm%02x%02x", ip[1], ip[2]), nil
}

func TestBridgeNameForTestSubnet(t *testing.T) {
t.Parallel()

first, err := testBridgeNameForSubnet("10.200.1.0/24")
if err != nil {
t.Fatal(err)
}
second, err := testBridgeNameForSubnet("10.200.2.0/24")
if err != nil {
t.Fatal(err)
}
if first != "hmc801" || second != "hmc802" || first == second {
Comment on lines +461 to +472

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this looks like it's just trying two options but that would only decrease but not resolve the issue

t.Fatalf("unexpected bridge names: %q %q", first, second)
}
}

func bridgeExists(name string) bool {
if name == "" {
return false
Expand Down
Loading