istio.io/istio@v0.0.0-20240520182934-d79c90f27776/cni/pkg/plugin/cnieventclient_test.go (about) 1 // Copyright Istio Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package plugin 16 17 import ( 18 "encoding/json" 19 "fmt" 20 "io" 21 "net" 22 "net/http" 23 "net/http/httptest" 24 "strings" 25 "testing" 26 27 "github.com/containernetworking/cni/pkg/skel" 28 cniv1 "github.com/containernetworking/cni/pkg/types/100" 29 30 "istio.io/istio/cni/pkg/constants" 31 "istio.io/istio/cni/pkg/nodeagent" 32 "istio.io/istio/pkg/test/util/assert" 33 ) 34 35 func fakeCNIEventClient(address string) CNIEventClient { 36 c := http.DefaultClient 37 38 eventC := CNIEventClient{ 39 client: c, 40 url: address + constants.CNIAddEventPath, 41 } 42 return eventC 43 } 44 45 var fakeCmdArgs = &skel.CmdArgs{ 46 Netns: "someNetNS", 47 IfName: "ethBro", 48 ContainerID: "bbb-eee-www", 49 } 50 51 var ( 52 fakeIP = net.ParseIP("99.9.9.9") 53 fakeGW = net.ParseIP("88.9.9.9") 54 fakeIDX = 0 55 fakePrevResultIPConfig = cniv1.IPConfig{ 56 Interface: &fakeIDX, 57 Address: net.IPNet{ 58 IP: fakeIP, 59 }, 60 Gateway: fakeGW, 61 } 62 ) 63 64 func TestPushCNIAddEventSucceed(t *testing.T) { 65 // Fake out a test HTTP server and use that instead of a real HTTP server over gRPC to validate req/resp flows 66 testServer := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) { 67 res.WriteHeader(http.StatusOK) 68 res.Write([]byte("server happy")) 69 })) 70 defer func() { testServer.Close() }() 71 72 cniC := fakeCNIEventClient(testServer.URL) 73 74 err := PushCNIEvent(cniC, fakeCmdArgs, []*cniv1.IPConfig{&fakePrevResultIPConfig}, "testpod", "testns") 75 76 assert.NoError(t, err) 77 } 78 79 func TestPushCNIAddEventNotOK(t *testing.T) { 80 // Fake out a test HTTP server and use that instead of a real HTTP server over gRPC to validate req/resp flows 81 testServer := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) { 82 res.WriteHeader(http.StatusInternalServerError) 83 res.Write([]byte("server pooped itself")) 84 })) 85 defer func() { testServer.Close() }() 86 87 cniC := fakeCNIEventClient(testServer.URL) 88 89 err := PushCNIEvent(cniC, fakeCmdArgs, []*cniv1.IPConfig{&fakePrevResultIPConfig}, "testpod", "testns") 90 91 assert.Error(t, err) 92 assert.Equal(t, strings.Contains(err.Error(), fmt.Sprintf("unable to push CNI event, error was %d", http.StatusInternalServerError)), true) 93 } 94 95 func TestPushCNIAddEventGoodPayload(t *testing.T) { 96 testPod := "testpod" 97 testNS := "testns" 98 // Fake out a test HTTP server and use that instead of a real HTTP server over gRPC to validate req/resp flows 99 testServer := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) { 100 defer req.Body.Close() 101 data, err := io.ReadAll(req.Body) 102 assert.NoError(t, err) 103 104 var msg nodeagent.CNIPluginAddEvent 105 err = json.Unmarshal(data, &msg) 106 assert.NoError(t, err) 107 assert.Equal(t, msg.PodName, testPod) 108 assert.Equal(t, msg.PodNamespace, testNS) 109 assert.Equal(t, msg.Netns, fakeCmdArgs.Netns) 110 res.WriteHeader(http.StatusOK) 111 res.Write([]byte("server happy")) 112 })) 113 defer func() { testServer.Close() }() 114 115 cniC := fakeCNIEventClient(testServer.URL) 116 117 err := PushCNIEvent(cniC, fakeCmdArgs, []*cniv1.IPConfig{&fakePrevResultIPConfig}, testPod, testNS) 118 119 assert.NoError(t, err) 120 } 121 122 func TestPushCNIAddEventBadPayload(t *testing.T) { 123 testPod := "testpod" 124 testNS := "testns" 125 // Fake out a test HTTP server and use that instead of a real HTTP server over gRPC to validate req/resp flows 126 testServer := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) { 127 assert.Equal(t, true, false) // if we get here, it's an autofail 128 })) 129 defer func() { testServer.Close() }() 130 131 cniC := fakeCNIEventClient(testServer.URL) 132 133 err := PushCNIEvent(cniC, nil, nil, testPod, testNS) 134 135 assert.Error(t, err) 136 assert.Equal(t, strings.Contains(err.Error(), "CmdArgs event was nil"), true) 137 }