Skip to content

Commit e89f21a

Browse files
committed
test(ipset): add unit tests for ipset regression testing
1 parent e068f30 commit e89f21a

File tree

7 files changed

+967
-8
lines changed

7 files changed

+967
-8
lines changed
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
package netpol
2+
3+
import (
4+
"context"
5+
"path/filepath"
6+
"sync"
7+
"testing"
8+
9+
"github.com/cloudnativelabs/kube-router/v2/pkg/controllers/testhelpers"
10+
"github.com/cloudnativelabs/kube-router/v2/pkg/options"
11+
"github.com/cloudnativelabs/kube-router/v2/pkg/utils"
12+
13+
"github.com/stretchr/testify/require"
14+
15+
v1 "k8s.io/api/core/v1"
16+
networkingv1 "k8s.io/api/networking/v1"
17+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
18+
"k8s.io/apimachinery/pkg/util/intstr"
19+
"k8s.io/client-go/informers"
20+
"k8s.io/client-go/kubernetes/fake"
21+
"k8s.io/client-go/tools/cache"
22+
)
23+
24+
func TestNetworkPolicyFixtureIPSets(t *testing.T) {
25+
fixtureDir := filepath.Join("..", "..", "..", "testdata", "ipset_test_1")
26+
27+
pods := testhelpers.LoadPodList(t, filepath.Join(fixtureDir, "pods.yaml"))
28+
networkPolicies := testhelpers.LoadNetworkPolicyList(t, filepath.Join(fixtureDir, "networkpolicy.yaml"))
29+
nodes := testhelpers.LoadNodeList(t, filepath.Join(fixtureDir, "nodes.yaml"))
30+
namespaces := deriveNamespaces(pods, networkPolicies)
31+
32+
client := fake.NewSimpleClientset()
33+
for i := range nodes.Items {
34+
_, err := client.CoreV1().Nodes().Create(context.Background(), nodes.Items[i].DeepCopy(), metav1.CreateOptions{})
35+
require.NoError(t, err)
36+
}
37+
38+
config := &options.KubeRouterConfig{
39+
EnableIPv4: true,
40+
EnableIPv6: true,
41+
ClusterIPCIDRs: []string{"10.96.0.0/16", "2001:db8:42:1::/112"},
42+
HostnameOverride: nodes.Items[0].Name,
43+
NodePortRange: "30000-32767",
44+
}
45+
46+
informerFactory := informers.NewSharedInformerFactory(client, 0)
47+
podInformer := informerFactory.Core().V1().Pods().Informer()
48+
npInformer := informerFactory.Networking().V1().NetworkPolicies().Informer()
49+
nsInformer := informerFactory.Core().V1().Namespaces().Informer()
50+
51+
ipv4Handler := testhelpers.NewFakeIPSetHandler(false)
52+
ipv6Handler := testhelpers.NewFakeIPSetHandler(true)
53+
t.Cleanup(func() {
54+
if t.Failed() {
55+
t.Logf("ipv4 restore script:\n%s", ipv4Handler.Restored())
56+
t.Logf("ipv6 restore script:\n%s", ipv6Handler.Restored())
57+
}
58+
})
59+
60+
linkQ := utils.NewFakeLocalLinkQuerier(collectNodeIPs(nodes), nil)
61+
62+
controller, err := NewNetworkPolicyController(
63+
client,
64+
config,
65+
podInformer,
66+
npInformer,
67+
nsInformer,
68+
&sync.Mutex{},
69+
linkQ,
70+
map[v1.IPFamily]utils.IPTablesHandler{
71+
v1.IPv4Protocol: &fakeIPTables{},
72+
v1.IPv6Protocol: &fakeIPTables{},
73+
},
74+
map[v1.IPFamily]utils.IPSetHandler{
75+
v1.IPv4Protocol: ipv4Handler,
76+
v1.IPv6Protocol: ipv6Handler,
77+
},
78+
)
79+
require.NoError(t, err)
80+
81+
addPodsToInformer(t, podInformer.GetStore(), pods)
82+
addNetworkPoliciesToInformer(t, npInformer.GetStore(), networkPolicies)
83+
addNamespacesToInformer(nsInformer.GetStore(), namespaces)
84+
85+
netpolInfo, err := controller.buildNetworkPoliciesInfo()
86+
require.NoError(t, err)
87+
88+
_, _, err = controller.syncNetworkPolicyChains(netpolInfo, "fixture")
89+
require.NoError(t, err)
90+
91+
actual := testhelpers.MergeExpectations(
92+
testhelpers.ParseRestoreScript(ipv4Handler.Restored()),
93+
testhelpers.ParseRestoreScript(ipv6Handler.Restored()),
94+
)
95+
expected := testhelpers.ParseSnapshot(t, filepath.Join(fixtureDir, "ipset_save.txt"))
96+
97+
require.NotEmpty(t, expected, "expected snapshot should not be empty")
98+
require.Equal(t, testhelpers.ExpectedKeys(expected), testhelpers.ExpectedKeys(actual))
99+
100+
for name, exp := range expected {
101+
act := actual[name]
102+
require.Equal(t, exp.SetType, act.SetType, "set type mismatch for %s", name)
103+
require.Equal(t, exp.Entries, act.Entries, "entries mismatch for %s", name)
104+
}
105+
}
106+
107+
func addPodsToInformer(t *testing.T, store cache.Store, pods *v1.PodList) {
108+
for i := range pods.Items {
109+
pod := pods.Items[i].DeepCopy()
110+
pod.SetResourceVersion("1")
111+
if len(pod.Status.PodIPs) > 0 {
112+
pod.Status.PodIP = pod.Status.PodIPs[0].IP
113+
}
114+
require.NoError(t, store.Add(pod))
115+
}
116+
}
117+
118+
func addNetworkPoliciesToInformer(t *testing.T, store cache.Store, policies *networkingv1.NetworkPolicyList) {
119+
for i := range policies.Items {
120+
pol := policies.Items[i].DeepCopy()
121+
pol.SetResourceVersion("1")
122+
for j := range pol.Spec.Ingress {
123+
for k := range pol.Spec.Ingress[j].Ports {
124+
if pol.Spec.Ingress[j].Ports[k].Protocol == nil {
125+
proto := v1.ProtocolTCP
126+
pol.Spec.Ingress[j].Ports[k].Protocol = &proto
127+
}
128+
if pol.Spec.Ingress[j].Ports[k].Port == nil {
129+
port := intstr.FromInt(0)
130+
pol.Spec.Ingress[j].Ports[k].Port = &port
131+
}
132+
}
133+
}
134+
require.NoError(t, store.Add(pol))
135+
}
136+
}
137+
138+
func addNamespacesToInformer(store cache.Store, namespaces *v1.NamespaceList) {
139+
for i := range namespaces.Items {
140+
_ = store.Add(namespaces.Items[i].DeepCopy())
141+
}
142+
}
143+
144+
func deriveNamespaces(pods *v1.PodList, policies *networkingv1.NetworkPolicyList) *v1.NamespaceList {
145+
nsSet := map[string]struct{}{}
146+
for _, pod := range pods.Items {
147+
nsSet[pod.Namespace] = struct{}{}
148+
}
149+
for _, pol := range policies.Items {
150+
nsSet[pol.Namespace] = struct{}{}
151+
}
152+
list := &v1.NamespaceList{}
153+
for ns := range nsSet {
154+
list.Items = append(list.Items, v1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: ns}})
155+
}
156+
return list
157+
}
158+
159+
func collectNodeIPs(nodes *v1.NodeList) []string {
160+
ipSet := map[string]struct{}{}
161+
for _, node := range nodes.Items {
162+
for _, addr := range node.Status.Addresses {
163+
ipSet[addr.Address] = struct{}{}
164+
}
165+
}
166+
ips := make([]string, 0, len(ipSet))
167+
for ip := range ipSet {
168+
ips = append(ips, ip)
169+
}
170+
return ips
171+
}

0 commit comments

Comments
 (0)