gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/pkg/p9/client_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 p9 16 17 import ( 18 "testing" 19 20 "golang.org/x/sys/unix" 21 "gvisor.dev/gvisor/pkg/unet" 22 ) 23 24 // TestVersion tests the version negotiation. 25 func TestVersion(t *testing.T) { 26 // First, create a new server and connection. 27 serverSocket, clientSocket, err := unet.SocketPair(false) 28 if err != nil { 29 t.Fatalf("socketpair got err %v expected nil", err) 30 } 31 defer clientSocket.Close() 32 33 // Create a new server and client. 34 s := NewServer(nil) 35 go s.Handle(serverSocket) 36 37 // NewClient does a Tversion exchange, so this is our test for success. 38 c, err := NewClient(clientSocket, DefaultMessageSize, HighestVersionString()) 39 if err != nil { 40 t.Fatalf("got %v, expected nil", err) 41 } 42 43 // Check a bogus version string. 44 if err := c.sendRecv(&Tversion{Version: "notokay", MSize: DefaultMessageSize}, &Rversion{}); err != unix.EINVAL { 45 t.Errorf("got %v expected %v", err, unix.EINVAL) 46 } 47 48 // Check a bogus version number. 49 if err := c.sendRecv(&Tversion{Version: "9P1000.L", MSize: DefaultMessageSize}, &Rversion{}); err != unix.EINVAL { 50 t.Errorf("got %v expected %v", err, unix.EINVAL) 51 } 52 53 // Check a too high version number. 54 if err := c.sendRecv(&Tversion{Version: versionString(highestSupportedVersion + 1), MSize: DefaultMessageSize}, &Rversion{}); err != unix.EAGAIN { 55 t.Errorf("got %v expected %v", err, unix.EAGAIN) 56 } 57 58 // Check an invalid MSize. 59 if err := c.sendRecv(&Tversion{Version: versionString(highestSupportedVersion), MSize: 0}, &Rversion{}); err != unix.EINVAL { 60 t.Errorf("got %v expected %v", err, unix.EINVAL) 61 } 62 } 63 64 func benchmarkSendRecv(b *testing.B, fn func(c *Client) func(message, message) error) { 65 b.ReportAllocs() 66 67 // See above. 68 serverSocket, clientSocket, err := unet.SocketPair(false) 69 if err != nil { 70 b.Fatalf("socketpair got err %v expected nil", err) 71 } 72 defer clientSocket.Close() 73 74 // See above. 75 s := NewServer(nil) 76 go s.Handle(serverSocket) 77 78 // See above. 79 c, err := NewClient(clientSocket, DefaultMessageSize, HighestVersionString()) 80 if err != nil { 81 b.Fatalf("got %v, expected nil", err) 82 } 83 84 // Initialize messages. 85 sendRecv := fn(c) 86 tversion := &Tversion{ 87 Version: versionString(highestSupportedVersion), 88 MSize: DefaultMessageSize, 89 } 90 rversion := new(Rversion) 91 92 // Run in a loop. 93 for i := 0; i < b.N; i++ { 94 if err := sendRecv(tversion, rversion); err != nil { 95 b.Fatalf("got unexpected err: %v", err) 96 } 97 } 98 } 99 100 func BenchmarkSendRecvLegacy(b *testing.B) { 101 benchmarkSendRecv(b, func(c *Client) func(message, message) error { 102 return func(t message, r message) error { 103 _, err := c.sendRecvLegacy(t, r) 104 return err 105 } 106 }) 107 } 108 109 func BenchmarkSendRecvChannel(b *testing.B) { 110 benchmarkSendRecv(b, func(c *Client) func(message, message) error { return c.sendRecvChannel }) 111 }