github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/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 "testing" 19 20 "github.com/SagerNet/gvisor/pkg/tcpip" 21 "github.com/SagerNet/gvisor/pkg/tcpip/header" 22 "github.com/SagerNet/gvisor/pkg/tcpip/stack" 23 ) 24 25 type countedEndpoint struct { 26 dispatchCount int 27 writeCount int 28 attachCount int 29 30 mtu uint32 31 capabilities stack.LinkEndpointCapabilities 32 hdrLen uint16 33 linkAddr tcpip.LinkAddress 34 35 dispatcher stack.NetworkDispatcher 36 } 37 38 func (e *countedEndpoint) DeliverNetworkPacket(remote, local tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, pkt *stack.PacketBuffer) { 39 e.dispatchCount++ 40 } 41 42 func (e *countedEndpoint) DeliverOutboundPacket(remote, local tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, pkt *stack.PacketBuffer) { 43 panic("unimplemented") 44 } 45 46 func (e *countedEndpoint) Attach(dispatcher stack.NetworkDispatcher) { 47 e.attachCount++ 48 e.dispatcher = dispatcher 49 } 50 51 // IsAttached implements stack.LinkEndpoint.IsAttached. 52 func (e *countedEndpoint) IsAttached() bool { 53 return e.dispatcher != nil 54 } 55 56 func (e *countedEndpoint) MTU() uint32 { 57 return e.mtu 58 } 59 60 func (e *countedEndpoint) Capabilities() stack.LinkEndpointCapabilities { 61 return e.capabilities 62 } 63 64 func (e *countedEndpoint) MaxHeaderLength() uint16 { 65 return e.hdrLen 66 } 67 68 func (e *countedEndpoint) LinkAddress() tcpip.LinkAddress { 69 return e.linkAddr 70 } 71 72 func (e *countedEndpoint) WritePacket(stack.RouteInfo, tcpip.NetworkProtocolNumber, *stack.PacketBuffer) tcpip.Error { 73 e.writeCount++ 74 return nil 75 } 76 77 // WritePackets implements stack.LinkEndpoint.WritePackets. 78 func (e *countedEndpoint) WritePackets(_ stack.RouteInfo, pkts stack.PacketBufferList, _ tcpip.NetworkProtocolNumber) (int, tcpip.Error) { 79 e.writeCount += pkts.Len() 80 return pkts.Len(), nil 81 } 82 83 // ARPHardwareType implements stack.LinkEndpoint.ARPHardwareType. 84 func (*countedEndpoint) ARPHardwareType() header.ARPHardwareType { 85 panic("unimplemented") 86 } 87 88 // Wait implements stack.LinkEndpoint.Wait. 89 func (*countedEndpoint) Wait() {} 90 91 // AddHeader implements stack.LinkEndpoint.AddHeader. 92 func (e *countedEndpoint) AddHeader(local, remote tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, pkt *stack.PacketBuffer) { 93 panic("unimplemented") 94 } 95 96 func TestWaitWrite(t *testing.T) { 97 ep := &countedEndpoint{} 98 wep := New(ep) 99 100 // Write and check that it goes through. 101 wep.WritePacket(stack.RouteInfo{}, 0, stack.NewPacketBuffer(stack.PacketBufferOptions{})) 102 if want := 1; ep.writeCount != want { 103 t.Fatalf("Unexpected writeCount: got=%v, want=%v", ep.writeCount, want) 104 } 105 106 // Wait on dispatches, then try to write. It must go through. 107 wep.WaitDispatch() 108 wep.WritePacket(stack.RouteInfo{}, 0, stack.NewPacketBuffer(stack.PacketBufferOptions{})) 109 if want := 2; ep.writeCount != want { 110 t.Fatalf("Unexpected writeCount: got=%v, want=%v", ep.writeCount, want) 111 } 112 113 // Wait on writes, then try to write. It must not go through. 114 wep.WaitWrite() 115 wep.WritePacket(stack.RouteInfo{}, 0, stack.NewPacketBuffer(stack.PacketBufferOptions{})) 116 if want := 2; ep.writeCount != want { 117 t.Fatalf("Unexpected writeCount: got=%v, want=%v", ep.writeCount, want) 118 } 119 } 120 121 func TestWaitDispatch(t *testing.T) { 122 ep := &countedEndpoint{} 123 wep := New(ep) 124 125 // Check that attach happens. 126 wep.Attach(ep) 127 if want := 1; ep.attachCount != want { 128 t.Fatalf("Unexpected attachCount: got=%v, want=%v", ep.attachCount, want) 129 } 130 131 // Dispatch and check that it goes through. 132 ep.dispatcher.DeliverNetworkPacket("", "", 0, stack.NewPacketBuffer(stack.PacketBufferOptions{})) 133 if want := 1; ep.dispatchCount != want { 134 t.Fatalf("Unexpected dispatchCount: got=%v, want=%v", ep.dispatchCount, want) 135 } 136 137 // Wait on writes, then try to dispatch. It must go through. 138 wep.WaitWrite() 139 ep.dispatcher.DeliverNetworkPacket("", "", 0, stack.NewPacketBuffer(stack.PacketBufferOptions{})) 140 if want := 2; ep.dispatchCount != want { 141 t.Fatalf("Unexpected dispatchCount: got=%v, want=%v", ep.dispatchCount, want) 142 } 143 144 // Wait on dispatches, then try to dispatch. It must not go through. 145 wep.WaitDispatch() 146 ep.dispatcher.DeliverNetworkPacket("", "", 0, stack.NewPacketBuffer(stack.PacketBufferOptions{})) 147 if want := 2; ep.dispatchCount != want { 148 t.Fatalf("Unexpected dispatchCount: got=%v, want=%v", ep.dispatchCount, want) 149 } 150 } 151 152 func TestOtherMethods(t *testing.T) { 153 const ( 154 mtu = 0xdead 155 capabilities = 0xbeef 156 hdrLen = 0x1234 157 linkAddr = "test address" 158 ) 159 ep := &countedEndpoint{ 160 mtu: mtu, 161 capabilities: capabilities, 162 hdrLen: hdrLen, 163 linkAddr: linkAddr, 164 } 165 wep := New(ep) 166 167 if v := wep.MTU(); v != mtu { 168 t.Fatalf("Unexpected mtu: got=%v, want=%v", v, mtu) 169 } 170 171 if v := wep.Capabilities(); v != capabilities { 172 t.Fatalf("Unexpected capabilities: got=%v, want=%v", v, capabilities) 173 } 174 175 if v := wep.MaxHeaderLength(); v != hdrLen { 176 t.Fatalf("Unexpected MaxHeaderLength: got=%v, want=%v", v, hdrLen) 177 } 178 179 if v := wep.LinkAddress(); v != linkAddr { 180 t.Fatalf("Unexpected LinkAddress: got=%q, want=%q", v, linkAddr) 181 } 182 }