Skip to content

Commit 394517d

Browse files
Copilotjpayne3506rbtr
authored
ci: Convert unit tests from Azure Pipelines to GitHub Actions (#4298)
* Initial plan * Add GitHub Actions workflow for unit tests (convert from AZP) Agent-Logs-Url: https://github.com/Azure/azure-container-networking/sessions/65c859ae-cffd-4891-a71d-15c17aa8a992 Co-authored-by: jpayne3506 <89417863+jpayne3506@users.noreply.github.com> * chore: manual updates for go version + security * wrap fd-redirect/tee block with set +e/+o pipefail to preserve exit-code propagation Agent-Logs-Url: https://github.com/Azure/azure-container-networking/sessions/22d6fdb8-35a0-4791-a1bc-8ea11a3b1464 Co-authored-by: jpayne3506 <89417863+jpayne3506@users.noreply.github.com> * test: linux runner * test: use window cmd shell * test: 22.04 * ci: add required npm pkgs * fix: CNS UT ordering issue * ci: add merge group and concurrency group * chore: address comments * Initial plan Co-authored-by: rbtr <2940321+rbtr@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jpayne3506 <89417863+jpayne3506@users.noreply.github.com> Co-authored-by: jpayne3506 <payne.3506@gmail.com> Co-authored-by: rbtr <2940321+rbtr@users.noreply.github.com>
1 parent 656d38d commit 394517d

2 files changed

Lines changed: 181 additions & 4 deletions

File tree

.github/workflows/unit-tests.yml

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
name: Unit Tests
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
- release/*
8+
pull_request:
9+
branches:
10+
- master
11+
- release/*
12+
merge_group:
13+
branches:
14+
- master
15+
- release/*
16+
workflow_dispatch:
17+
schedule:
18+
- cron: "0 6 * * *" # daily at 06:00 UTC
19+
20+
permissions:
21+
contents: read
22+
23+
concurrency:
24+
group: ${{ github.workflow }}-${{ github.event.merge_group.head_sha || github.event.pull_request.number || github.ref }}
25+
cancel-in-progress: ${{ github.event_name != 'merge_group' }}
26+
27+
jobs:
28+
setup:
29+
name: Setup
30+
runs-on: ubuntu-latest
31+
outputs:
32+
go-version: ${{ steps.goversion.outputs.version }}
33+
steps:
34+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
35+
36+
- name: Determine Go version
37+
id: goversion
38+
run: |
39+
version=$(find . -name go.mod -exec grep -h '^go ' {} \; | awk '{print $2}' | sort -V | tail -1)
40+
if ! [[ "$version" =~ ^[0-9]+\.[0-9]+(\.[0-9]+)?$ ]]; then
41+
echo "Invalid Go version: $version"
42+
exit 1
43+
fi
44+
echo "version=$version" >> $GITHUB_OUTPUT
45+
46+
test-linux:
47+
name: Test Linux (${{ matrix.os }})
48+
runs-on: ${{ matrix.os }}
49+
needs: setup
50+
strategy:
51+
matrix:
52+
os: [ubuntu-22.04, ubuntu-24.04]
53+
steps:
54+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
55+
56+
- name: Set up Go
57+
uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6
58+
with:
59+
go-version: ${{ needs.setup.outputs.go-version }}
60+
61+
- name: Install system dependencies
62+
run: sudo apt-get update -y && sudo apt-get install -y iptables ipset iproute2
63+
64+
- name: Build BPF lib
65+
run: make bpf-lib
66+
67+
- name: Go generate
68+
run: go generate ./...
69+
70+
- name: Install go-junit-report
71+
run: make go-junit-report
72+
73+
- name: Run Tests
74+
run: |
75+
# TODO: Refactor this fd-redirect/tee pipeline to work natively under
76+
# bash strict mode (-e/-o pipefail). Strict mode is temporarily disabled
77+
# here to preserve the original exit-code propagation behavior intact.
78+
set +e +o pipefail
79+
{ { { {
80+
sudo -E env "PATH=$PATH" make test-all;
81+
echo $? >&3;
82+
} | tee >($(go env GOPATH)/bin/go-junit-report > report.xml) >&4;
83+
} 3>&1;
84+
} | { read xs; exit $xs; }
85+
} 4>&1
86+
test_exit=$?
87+
set -eo pipefail
88+
89+
# combine coverage from multiple modules
90+
(echo "mode: atomic"; tail -q -n +2 coverage-*.out) > coverage.cover
91+
mv coverage.cover linux-coverage.out
92+
93+
(exit "$test_exit")
94+
95+
- name: Upload Linux Coverage
96+
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
97+
with:
98+
name: linux-coverage-${{ matrix.os }}
99+
path: linux-coverage.out
100+
101+
test-windows:
102+
name: Test Windows
103+
runs-on: windows-latest
104+
needs: setup
105+
steps:
106+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
107+
108+
- name: Set up Go
109+
uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6
110+
with:
111+
go-version: ${{ needs.setup.outputs.go-version }}
112+
113+
- name: Run Windows Tests
114+
shell: cmd
115+
run: |
116+
go test -timeout 30m -covermode atomic -coverprofile=windows-coverage.out ./cns/... ./npm/... ./cni/... ./platform/...
117+
go tool cover -func=windows-coverage.out
118+
119+
- name: Upload Windows Coverage
120+
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
121+
with:
122+
name: windows-coverage
123+
path: windows-coverage.out
124+
125+
code-coverage:
126+
name: Code Coverage
127+
runs-on: ubuntu-latest
128+
needs: [setup, test-linux]
129+
if: always()
130+
steps:
131+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
132+
133+
- name: Set up Go
134+
uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6
135+
with:
136+
go-version: ${{ needs.setup.outputs.go-version }}
137+
138+
- name: Download Linux Coverage Artifact
139+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
140+
with:
141+
name: linux-coverage-ubuntu-24.04
142+
path: ./
143+
144+
- name: Generate Coverage Report
145+
run: |
146+
# use go work to include multiple modules or gocov will omit results from those modules
147+
make workspace
148+
149+
make tools
150+
sudo ln -s $(go env GOPATH)/bin/gocov /usr/local/bin/gocov
151+
sudo ln -s $(go env GOPATH)/bin/gocov-xml /usr/local/bin/gocov-xml
152+
153+
GOOS=linux gocov convert linux-coverage.out > linux-coverage.json
154+
GOOS=linux gocov-xml < linux-coverage.json > linux-coverage.xml
155+
156+
mkdir coverage
157+
mv linux-coverage.xml coverage/
158+
159+
- name: Upload Coverage Report
160+
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
161+
with:
162+
name: linux-coverage-report
163+
path: coverage/linux-coverage.xml
164+
165+
- name: Publish Code Coverage Summary
166+
uses: irongut/CodeCoverageSummary@51cc3a756ddcd398d447c044c02cb6aa83fdae95 # v1.3.0
167+
with:
168+
filename: coverage/linux-coverage.xml
169+
format: markdown
170+
output: both

cns/restserver/api_test.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2095,10 +2095,17 @@ func TestPostNetworkContainersWithIPv6(t *testing.T) {
20952095
ncResponses, err := getAllNetworkContainers(t, ncParamsWithIPv6)
20962096
require.NoError(t, err)
20972097

2098-
// Verify each NC has IPv6Configuration
2099-
for i, nc := range ncResponses.NetworkContainers {
2100-
assert.Equal(t, ncParamsWithIPv6[i].ipv6Config.IPSubnet.IPAddress, nc.IPv6Configuration.IPSubnet.IPAddress, "NC %d: IPv6 address mismatch", i)
2101-
assert.Equal(t, ncParamsWithIPv6[i].ipv6Config.GatewayIPAddress, nc.IPv6Configuration.GatewayIPAddress, "NC %d: IPv6 gateway mismatch", i)
2098+
// Verify each NC has IPv6Configuration (index by NC ID to avoid ordering assumptions)
2099+
ncByID := make(map[string]cns.GetNetworkContainerResponse, len(ncResponses.NetworkContainers))
2100+
for _, nc := range ncResponses.NetworkContainers {
2101+
ncByID[nc.NetworkContainerID] = nc
2102+
}
2103+
for i, params := range ncParamsWithIPv6 {
2104+
ncID := "Swift_" + params.ncID
2105+
nc, ok := ncByID[ncID]
2106+
require.True(t, ok, "NC %d (%s) not found in response", i, ncID)
2107+
assert.Equal(t, params.ipv6Config.IPSubnet.IPAddress, nc.IPv6Configuration.IPSubnet.IPAddress, "NC %d: IPv6 address mismatch", i)
2108+
assert.Equal(t, params.ipv6Config.GatewayIPAddress, nc.IPv6Configuration.GatewayIPAddress, "NC %d: IPv6 gateway mismatch", i)
21022109
}
21032110

21042111
// Cleanup

0 commit comments

Comments
 (0)