github.com/inspektor-gadget/inspektor-gadget@v0.28.1/pkg/gadgets/snapshot/socket/tracer/tracer_test.go (about) 1 // Copyright 2022-2023 The Inspektor Gadget 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 //go:build linux 16 // +build linux 17 18 package tracer 19 20 import ( 21 "fmt" 22 "net" 23 "testing" 24 25 "github.com/stretchr/testify/require" 26 27 utilstest "github.com/inspektor-gadget/inspektor-gadget/internal/test" 28 "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/snapshot/socket/types" 29 eventtypes "github.com/inspektor-gadget/inspektor-gadget/pkg/types" 30 ) 31 32 func TestSocketTracerCreate(t *testing.T) { 33 t.Parallel() 34 35 utilstest.RequireRoot(t) 36 37 tracer, err := NewTracer(types.ALL) 38 require.Nil(t, err, "creating tracer: %v", err) 39 40 tracer.CloseIters() 41 } 42 43 type testCase struct { 44 name string 45 proto types.Proto 46 addr string 47 port int 48 expectedEvent func(info *utilstest.RunnerInfo, _ any) *types.Event 49 socketCreator func(addr string, port int) error 50 } 51 52 func TestSnapshotSocket(t *testing.T) { 53 t.Parallel() 54 55 utilstest.RequireRoot(t) 56 57 cases := []testCase{ 58 { 59 name: "listen_tcp_v4", 60 proto: types.TCP, 61 addr: "127.0.0.1", 62 port: 8082, 63 expectedEvent: func(info *utilstest.RunnerInfo, _ any) *types.Event { 64 return &types.Event{ 65 Event: eventtypes.Event{Type: eventtypes.NORMAL}, 66 WithNetNsID: eventtypes.WithNetNsID{NetNsID: info.NetworkNsID}, 67 Protocol: "TCP", 68 Status: "LISTEN", 69 SrcEndpoint: eventtypes.L4Endpoint{ 70 L3Endpoint: eventtypes.L3Endpoint{ 71 Addr: "127.0.0.1", 72 Version: 4, 73 }, 74 Port: 8082, 75 }, 76 DstEndpoint: eventtypes.L4Endpoint{ 77 L3Endpoint: eventtypes.L3Endpoint{ 78 // There is no connection in this test, so there remote address is null. 79 Addr: "0.0.0.0", 80 Version: 4, 81 }, 82 }, 83 } 84 }, 85 socketCreator: func(addr string, port int) error { 86 conn, err := net.Listen("tcp", fmt.Sprintf("%s:%d", addr, port)) 87 if err != nil { 88 return fmt.Errorf("listening to %s: %w", addr, err) 89 } 90 t.Cleanup(func() { conn.Close() }) 91 92 return nil 93 }, 94 }, 95 { 96 name: "listen_tcp_v6", 97 proto: types.TCP, 98 addr: "::1", 99 port: 8082, 100 expectedEvent: func(info *utilstest.RunnerInfo, _ any) *types.Event { 101 return &types.Event{ 102 Event: eventtypes.Event{Type: eventtypes.NORMAL}, 103 WithNetNsID: eventtypes.WithNetNsID{NetNsID: info.NetworkNsID}, 104 Protocol: "TCP", 105 Status: "LISTEN", 106 SrcEndpoint: eventtypes.L4Endpoint{ 107 L3Endpoint: eventtypes.L3Endpoint{ 108 Addr: "::1", 109 Version: 6, 110 }, 111 Port: 8082, 112 }, 113 DstEndpoint: eventtypes.L4Endpoint{ 114 L3Endpoint: eventtypes.L3Endpoint{ 115 // There is no connection in this test, so the remote address is null. 116 Addr: "::", 117 Version: 6, 118 }, 119 }, 120 } 121 }, 122 socketCreator: func(addr string, port int) error { 123 conn, err := net.Listen("tcp", fmt.Sprintf("[%s]:%d", addr, port)) 124 if err != nil { 125 return fmt.Errorf("listening to %s: %w", addr, err) 126 } 127 t.Cleanup(func() { conn.Close() }) 128 129 return nil 130 }, 131 }, 132 { 133 name: "listen_udp_v4", 134 proto: types.UDP, 135 addr: "127.0.0.1", 136 port: 8082, 137 expectedEvent: func(info *utilstest.RunnerInfo, _ any) *types.Event { 138 return &types.Event{ 139 Event: eventtypes.Event{Type: eventtypes.NORMAL}, 140 WithNetNsID: eventtypes.WithNetNsID{NetNsID: info.NetworkNsID}, 141 Protocol: "UDP", 142 Status: "INACTIVE", 143 SrcEndpoint: eventtypes.L4Endpoint{ 144 L3Endpoint: eventtypes.L3Endpoint{ 145 Addr: "127.0.0.1", 146 Version: 4, 147 }, 148 Port: 8082, 149 }, 150 DstEndpoint: eventtypes.L4Endpoint{ 151 L3Endpoint: eventtypes.L3Endpoint{ 152 // There is no connection in this test, so there remote address is null. 153 Addr: "0.0.0.0", 154 Version: 4, 155 }, 156 }, 157 } 158 }, 159 socketCreator: func(addr string, port int) error { 160 conn, err := net.ListenUDP("udp", &net.UDPAddr{ 161 Port: port, 162 IP: net.ParseIP(addr), 163 }) 164 if err != nil { 165 return fmt.Errorf("listening to %s: %w", addr, err) 166 } 167 t.Cleanup(func() { conn.Close() }) 168 169 return nil 170 }, 171 }, 172 { 173 name: "listen_udp_v6", 174 proto: types.UDP, 175 addr: "::1", 176 port: 8082, 177 expectedEvent: func(info *utilstest.RunnerInfo, _ any) *types.Event { 178 return &types.Event{ 179 Event: eventtypes.Event{Type: eventtypes.NORMAL}, 180 WithNetNsID: eventtypes.WithNetNsID{NetNsID: info.NetworkNsID}, 181 Protocol: "UDP", 182 Status: "INACTIVE", 183 SrcEndpoint: eventtypes.L4Endpoint{ 184 L3Endpoint: eventtypes.L3Endpoint{ 185 Addr: "::1", 186 Version: 6, 187 }, 188 Port: 8082, 189 }, 190 DstEndpoint: eventtypes.L4Endpoint{ 191 L3Endpoint: eventtypes.L3Endpoint{ 192 // There is no connection in this test, so there remote address is null. 193 Addr: "::", 194 Version: 6, 195 }, 196 }, 197 } 198 }, 199 socketCreator: func(addr string, port int) error { 200 conn, err := net.ListenUDP("udp6", &net.UDPAddr{ 201 Port: port, 202 IP: net.ParseIP(addr), 203 }) 204 if err != nil { 205 return fmt.Errorf("listening to %s: %w", addr, err) 206 } 207 t.Cleanup(func() { conn.Close() }) 208 209 return nil 210 }, 211 }, 212 } 213 214 for _, c := range cases { 215 c := c 216 t.Run(c.name, func(t *testing.T) { 217 t.Parallel() 218 219 runner := utilstest.NewRunnerWithTest(t, nil) 220 utilstest.RunWithRunner(t, runner, func() error { 221 return c.socketCreator(c.addr, c.port) 222 }) 223 224 tracer, err := NewTracer(c.proto) 225 require.NoError(t, err, "creating tracer: %v", err) 226 defer tracer.CloseIters() 227 228 evs, err := tracer.runCollector(uint32(runner.Info.Tid), runner.Info.NetworkNsID) 229 require.NoError(t, err, "running collector: %v", err) 230 231 events := make([]types.Event, len(evs)) 232 for i, ev := range evs { 233 events[i] = *ev 234 235 // This is hard to guess the inode number, let's normalize it for the 236 // moment. 237 events[i].InodeNumber = 0 238 } 239 240 utilstest.ExpectAtLeastOneEvent(c.expectedEvent)(t, runner.Info, nil, events) 241 }) 242 } 243 }