gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/pkg/tcpip/link/waitable/waitable_test.go (about) 1 // Copyright 2018 The gVisor 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 waitable 16 17 import ( 18 "os" 19 "testing" 20 21 "gvisor.dev/gvisor/pkg/refs" 22 "gvisor.dev/gvisor/pkg/tcpip" 23 "gvisor.dev/gvisor/pkg/tcpip/header" 24 "gvisor.dev/gvisor/pkg/tcpip/stack" 25 ) 26 27 var _ stack.LinkEndpoint = (*countedEndpoint)(nil) 28 29 type countedEndpoint struct { 30 dispatchCount int 31 writeCount int 32 attachCount int 33 34 mtu uint32 35 capabilities stack.LinkEndpointCapabilities 36 hdrLen uint16 37 linkAddr tcpip.LinkAddress 38 39 dispatcher stack.NetworkDispatcher 40 } 41 42 func (e *countedEndpoint) DeliverNetworkPacket(protocol tcpip.NetworkProtocolNumber, pkt *stack.PacketBuffer) { 43 e.dispatchCount++ 44 } 45 46 func (*countedEndpoint) DeliverLinkPacket(tcpip.NetworkProtocolNumber, *stack.PacketBuffer) { 47 panic("not implemented") 48 } 49 50 func (e *countedEndpoint) Attach(dispatcher stack.NetworkDispatcher) { 51 e.attachCount++ 52 e.dispatcher = dispatcher 53 } 54 55 // IsAttached implements stack.LinkEndpoint.IsAttached. 56 func (e *countedEndpoint) IsAttached() bool { 57 return e.dispatcher != nil 58 } 59 60 func (e *countedEndpoint) MTU() uint32 { 61 return e.mtu 62 } 63 64 func (e *countedEndpoint) Capabilities() stack.LinkEndpointCapabilities { 65 return e.capabilities 66 } 67 68 func (e *countedEndpoint) MaxHeaderLength() uint16 { 69 return e.hdrLen 70 } 71 72 func (e *countedEndpoint) LinkAddress() tcpip.LinkAddress { 73 return e.linkAddr 74 } 75 76 // WritePackets implements stack.LinkEndpoint.WritePackets. 77 func (e *countedEndpoint) WritePackets(pkts stack.PacketBufferList) (int, tcpip.Error) { 78 e.writeCount += pkts.Len() 79 return pkts.Len(), nil 80 } 81 82 // ARPHardwareType implements stack.LinkEndpoint.ARPHardwareType. 83 func (*countedEndpoint) ARPHardwareType() header.ARPHardwareType { 84 panic("unimplemented") 85 } 86 87 // Wait implements stack.LinkEndpoint.Wait. 88 func (*countedEndpoint) Wait() {} 89 90 // AddHeader implements stack.LinkEndpoint.AddHeader. 91 func (*countedEndpoint) AddHeader(*stack.PacketBuffer) { 92 panic("unimplemented") 93 } 94 95 // ParseHeader implements stack.LinkEndpoint.ParseHeader. 96 func (*countedEndpoint) ParseHeader(*stack.PacketBuffer) bool { 97 panic("unimplemented") 98 } 99 100 func TestWaitWrite(t *testing.T) { 101 ep := &countedEndpoint{} 102 wep := New(ep) 103 { 104 var pkts stack.PacketBufferList 105 pkts.PushBack(stack.NewPacketBuffer(stack.PacketBufferOptions{})) 106 // Write and check that it goes through. 107 if n, err := wep.WritePackets(pkts); err != nil { 108 t.Fatalf("WritePackets(_): %s", err) 109 } else if n != 1 { 110 t.Fatalf("got WritePackets(_) = %d, want = 1", n) 111 } 112 if want := 1; ep.writeCount != want { 113 t.Fatalf("Unexpected writeCount: got=%v, want=%v", ep.writeCount, want) 114 } 115 pkts.DecRef() 116 } 117 { 118 var pkts stack.PacketBufferList 119 pkts.PushBack(stack.NewPacketBuffer(stack.PacketBufferOptions{})) 120 // Wait on dispatches, then try to write. It must go through. 121 wep.WaitDispatch() 122 if n, err := wep.WritePackets(pkts); err != nil { 123 t.Fatalf("WritePackets(_): %s", err) 124 } else if n != 1 { 125 t.Fatalf("got WritePackets(_) = %d, want = 1", n) 126 } 127 if want := 2; ep.writeCount != want { 128 t.Fatalf("Unexpected writeCount: got=%v, want=%v", ep.writeCount, want) 129 } 130 pkts.DecRef() 131 } 132 133 { 134 var pkts stack.PacketBufferList 135 pkts.PushBack(stack.NewPacketBuffer(stack.PacketBufferOptions{})) 136 // Wait on writes, then try to write. It must not go through. 137 wep.WaitWrite() 138 if n, err := wep.WritePackets(pkts); err != nil { 139 t.Fatalf("WritePackets(_): %s", err) 140 } else if n != 1 { 141 t.Fatalf("got WritePackets(_) = %d, want = 1", n) 142 } 143 if want := 2; ep.writeCount != want { 144 t.Fatalf("Unexpected writeCount: got=%v, want=%v", ep.writeCount, want) 145 } 146 pkts.DecRef() 147 } 148 } 149 150 func TestWaitDispatch(t *testing.T) { 151 ep := &countedEndpoint{} 152 wep := New(ep) 153 154 // Check that attach happens. 155 wep.Attach(ep) 156 if want := 1; ep.attachCount != want { 157 t.Fatalf("Unexpected attachCount: got=%v, want=%v", ep.attachCount, want) 158 } 159 160 // Dispatch and check that it goes through. 161 { 162 p := stack.NewPacketBuffer(stack.PacketBufferOptions{}) 163 ep.dispatcher.DeliverNetworkPacket(0, p) 164 if want := 1; ep.dispatchCount != want { 165 t.Fatalf("Unexpected dispatchCount: got=%v, want=%v", ep.dispatchCount, want) 166 } 167 p.DecRef() 168 } 169 170 // Wait on writes, then try to dispatch. It must go through. 171 { 172 wep.WaitWrite() 173 p := stack.NewPacketBuffer(stack.PacketBufferOptions{}) 174 ep.dispatcher.DeliverNetworkPacket(0, p) 175 if want := 2; ep.dispatchCount != want { 176 t.Fatalf("Unexpected dispatchCount: got=%v, want=%v", ep.dispatchCount, want) 177 } 178 p.DecRef() 179 } 180 181 // Wait on dispatches, then try to dispatch. It must not go through. 182 { 183 wep.WaitDispatch() 184 p := stack.NewPacketBuffer(stack.PacketBufferOptions{}) 185 ep.dispatcher.DeliverNetworkPacket(0, p) 186 if want := 2; ep.dispatchCount != want { 187 t.Fatalf("Unexpected dispatchCount: got=%v, want=%v", ep.dispatchCount, want) 188 } 189 p.DecRef() 190 } 191 } 192 193 func TestOtherMethods(t *testing.T) { 194 const ( 195 mtu = 0xdead 196 capabilities = 0xbeef 197 hdrLen = 0x1234 198 linkAddr = "test address" 199 ) 200 ep := &countedEndpoint{ 201 mtu: mtu, 202 capabilities: capabilities, 203 hdrLen: hdrLen, 204 linkAddr: linkAddr, 205 } 206 wep := New(ep) 207 208 if v := wep.MTU(); v != mtu { 209 t.Fatalf("Unexpected mtu: got=%v, want=%v", v, mtu) 210 } 211 212 if v := wep.Capabilities(); v != capabilities { 213 t.Fatalf("Unexpected capabilities: got=%v, want=%v", v, capabilities) 214 } 215 216 if v := wep.MaxHeaderLength(); v != hdrLen { 217 t.Fatalf("Unexpected MaxHeaderLength: got=%v, want=%v", v, hdrLen) 218 } 219 220 if v := wep.LinkAddress(); v != linkAddr { 221 t.Fatalf("Unexpected LinkAddress: got=%q, want=%q", v, linkAddr) 222 } 223 } 224 225 func TestMain(m *testing.M) { 226 refs.SetLeakMode(refs.LeaksPanic) 227 code := m.Run() 228 refs.DoLeakCheck() 229 os.Exit(code) 230 }