1/* 2 * 3 * Copyright 2018 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19// Package testutil include useful test utilities for the handshaker. 20package testutil 21 22import ( 23 "bytes" 24 "encoding/binary" 25 "io" 26 "net" 27 "sync" 28 29 "google.golang.org/grpc/credentials/alts/internal/conn" 30) 31 32// Stats is used to collect statistics about concurrent handshake calls. 33type Stats struct { 34 mu sync.Mutex 35 calls int 36 MaxConcurrentCalls int 37} 38 39// Update updates the statistics by adding one call. 40func (s *Stats) Update() func() { 41 s.mu.Lock() 42 s.calls++ 43 if s.calls > s.MaxConcurrentCalls { 44 s.MaxConcurrentCalls = s.calls 45 } 46 s.mu.Unlock() 47 48 return func() { 49 s.mu.Lock() 50 s.calls-- 51 s.mu.Unlock() 52 } 53} 54 55// Reset resets the statistics. 56func (s *Stats) Reset() { 57 s.mu.Lock() 58 defer s.mu.Unlock() 59 s.calls = 0 60 s.MaxConcurrentCalls = 0 61} 62 63// testConn mimics a net.Conn to the peer. 64type testConn struct { 65 net.Conn 66 in *bytes.Buffer 67 out *bytes.Buffer 68} 69 70// NewTestConn creates a new instance of testConn object. 71func NewTestConn(in *bytes.Buffer, out *bytes.Buffer) net.Conn { 72 return &testConn{ 73 in: in, 74 out: out, 75 } 76} 77 78// Read reads from the in buffer. 79func (c *testConn) Read(b []byte) (n int, err error) { 80 return c.in.Read(b) 81} 82 83// Write writes to the out buffer. 84func (c *testConn) Write(b []byte) (n int, err error) { 85 return c.out.Write(b) 86} 87 88// Close closes the testConn object. 89func (c *testConn) Close() error { 90 return nil 91} 92 93// unresponsiveTestConn mimics a net.Conn for an unresponsive peer. It is used 94// for testing the PeerNotResponding case. 95type unresponsiveTestConn struct { 96 net.Conn 97} 98 99// NewUnresponsiveTestConn creates a new instance of unresponsiveTestConn object. 100func NewUnresponsiveTestConn() net.Conn { 101 return &unresponsiveTestConn{} 102} 103 104// Read reads from the in buffer. 105func (c *unresponsiveTestConn) Read(b []byte) (n int, err error) { 106 return 0, io.EOF 107} 108 109// Write writes to the out buffer. 110func (c *unresponsiveTestConn) Write(b []byte) (n int, err error) { 111 return 0, nil 112} 113 114// Close closes the TestConn object. 115func (c *unresponsiveTestConn) Close() error { 116 return nil 117} 118 119// MakeFrame creates a handshake frame. 120func MakeFrame(pl string) []byte { 121 f := make([]byte, len(pl)+conn.MsgLenFieldSize) 122 binary.LittleEndian.PutUint32(f, uint32(len(pl))) 123 copy(f[conn.MsgLenFieldSize:], []byte(pl)) 124 return f 125} 126