Skip to content

Commit 20a2e03

Browse files
Aprazoraauren
authored andcommitted
test(NSC): reorganize test files per reviewer feedback
Move tests from hardening_test.go into the files requested by aauren: - TestShuffleDoesNotPanicOnEmptySlice → network_services_controller_test.go - TestSetupMangleTableRuleRejectsInvalidIP → network_services_controller_test.go - TestNodePortHealthCheckConcurrentAccess → new nodeport_healthcheck_test.go Delete hardening_test.go (now empty).
1 parent 59c5ec6 commit 20a2e03

File tree

3 files changed

+99
-102
lines changed

3 files changed

+99
-102
lines changed

pkg/controllers/proxy/hardening_test.go

Lines changed: 0 additions & 102 deletions
This file was deleted.

pkg/controllers/proxy/network_services_controller_test.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2088,3 +2088,56 @@ func TestBuildServicesInfoWithStrictValidation(t *testing.T) {
20882088
})
20892089
}
20902090
}
2091+
2092+
func TestShuffleDoesNotPanicOnEmptySlice(t *testing.T) {
2093+
// shuffle should handle empty and single-element slices safely
2094+
tests := []struct {
2095+
name string
2096+
input []endpointSliceInfo
2097+
}{
2098+
{
2099+
name: "empty slice",
2100+
input: []endpointSliceInfo{},
2101+
},
2102+
{
2103+
name: "single element",
2104+
input: []endpointSliceInfo{{ip: "10.0.0.1", port: 80}},
2105+
},
2106+
{
2107+
name: "multiple elements",
2108+
input: []endpointSliceInfo{
2109+
{ip: "10.0.0.1", port: 80},
2110+
{ip: "10.0.0.2", port: 80},
2111+
{ip: "10.0.0.3", port: 80},
2112+
},
2113+
},
2114+
}
2115+
2116+
for _, tt := range tests {
2117+
t.Run(tt.name, func(t *testing.T) {
2118+
// Should not panic
2119+
result := shuffle(tt.input)
2120+
assert.Equal(t, len(tt.input), len(result), "shuffle should preserve slice length")
2121+
})
2122+
}
2123+
}
2124+
2125+
func TestSetupMangleTableRuleRejectsInvalidIP(t *testing.T) {
2126+
// Verify that net.ParseIP returning nil is handled gracefully
2127+
// rather than causing a nil pointer dereference on .To4()
2128+
tests := []struct {
2129+
name string
2130+
ip string
2131+
}{
2132+
{name: "empty string", ip: ""},
2133+
{name: "garbage", ip: "not-an-ip"},
2134+
{name: "incomplete", ip: "192.168.1"},
2135+
}
2136+
2137+
for _, tt := range tests {
2138+
t.Run(tt.name, func(t *testing.T) {
2139+
parsedIP := net.ParseIP(tt.ip)
2140+
assert.Nil(t, parsedIP, "net.ParseIP should return nil for invalid IP %q", tt.ip)
2141+
})
2142+
}
2143+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package proxy
2+
3+
import (
4+
"sync"
5+
"testing"
6+
)
7+
8+
func TestNodePortHealthCheckConcurrentAccess(t *testing.T) {
9+
// Verify that concurrent reads and writes to the healthcheck controller
10+
// do not cause a data race (this test is meaningful with -race flag)
11+
nphc := NewNodePortHealthCheck()
12+
13+
svcMap := serviceInfoMap{
14+
"test-svc": &serviceInfo{
15+
healthCheckNodePort: 0, // no actual listener needed
16+
},
17+
}
18+
epMap := endpointSliceInfoMap{
19+
"test-svc": {
20+
{ip: "10.0.0.1", port: 80, isLocal: true},
21+
},
22+
}
23+
24+
var wg sync.WaitGroup
25+
// Concurrent writes
26+
wg.Add(1)
27+
go func() {
28+
defer wg.Done()
29+
for i := 0; i < 100; i++ {
30+
_ = nphc.UpdateServicesInfo(svcMap, epMap)
31+
}
32+
}()
33+
34+
// Concurrent reads (simulating what the HTTP handler does)
35+
wg.Add(1)
36+
go func() {
37+
defer wg.Done()
38+
for i := 0; i < 100; i++ {
39+
nphc.mu.RLock()
40+
_ = nphc.endpointsInfoMap["test-svc"]
41+
nphc.mu.RUnlock()
42+
}
43+
}()
44+
45+
wg.Wait()
46+
}

0 commit comments

Comments
 (0)