github.com/imran-kn/cilium-fork@v1.6.9/pkg/envoy/xds/stream.go (about) 1 // Copyright 2018 Authors of Cilium 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 xds 16 17 import ( 18 "context" 19 "io" 20 "time" 21 22 envoy_api_v2 "github.com/cilium/proxy/go/envoy/api/v2" 23 ) 24 25 // Stream is the subset of the gRPC bi-directional stream types which is used 26 // by Server. 27 type Stream interface { 28 // Send sends a xDS response back to the client. 29 Send(*envoy_api_v2.DiscoveryResponse) error 30 31 // Recv receives a xDS request from the client. 32 Recv() (*envoy_api_v2.DiscoveryRequest, error) 33 } 34 35 // MockStream is a mock implementation of Stream used for testing. 36 type MockStream struct { 37 ctx context.Context 38 recv chan *envoy_api_v2.DiscoveryRequest 39 sent chan *envoy_api_v2.DiscoveryResponse 40 recvTimeout time.Duration 41 sentTimeout time.Duration 42 } 43 44 // NewMockStream creates a new mock Stream for testing. 45 func NewMockStream(ctx context.Context, recvSize, sentSize int, recvTimeout, sentTimeout time.Duration) *MockStream { 46 return &MockStream{ 47 ctx: ctx, 48 recv: make(chan *envoy_api_v2.DiscoveryRequest, recvSize), 49 sent: make(chan *envoy_api_v2.DiscoveryResponse, sentSize), 50 recvTimeout: recvTimeout, 51 sentTimeout: sentTimeout, 52 } 53 } 54 55 func (s *MockStream) Send(resp *envoy_api_v2.DiscoveryResponse) error { 56 subCtx, cancel := context.WithTimeout(s.ctx, s.sentTimeout) 57 58 select { 59 case <-subCtx.Done(): 60 cancel() 61 if subCtx.Err() == context.Canceled { 62 return io.EOF 63 } 64 return subCtx.Err() 65 case s.sent <- resp: 66 cancel() 67 return nil 68 } 69 } 70 71 func (s *MockStream) Recv() (*envoy_api_v2.DiscoveryRequest, error) { 72 subCtx, cancel := context.WithTimeout(s.ctx, s.recvTimeout) 73 74 select { 75 case <-subCtx.Done(): 76 cancel() 77 if subCtx.Err() == context.Canceled { 78 return nil, io.EOF 79 } 80 return nil, subCtx.Err() 81 case req := <-s.recv: 82 cancel() 83 return req, nil 84 } 85 } 86 87 // SendRequest queues a request to be received by calling Recv. 88 func (s *MockStream) SendRequest(req *envoy_api_v2.DiscoveryRequest) error { 89 subCtx, cancel := context.WithTimeout(s.ctx, s.recvTimeout) 90 91 select { 92 case <-subCtx.Done(): 93 cancel() 94 if subCtx.Err() == context.Canceled { 95 return io.EOF 96 } 97 return subCtx.Err() 98 case s.recv <- req: 99 cancel() 100 return nil 101 } 102 } 103 104 // RecvResponse receives a response that was queued by calling Send. 105 func (s *MockStream) RecvResponse() (*envoy_api_v2.DiscoveryResponse, error) { 106 subCtx, cancel := context.WithTimeout(s.ctx, s.sentTimeout) 107 108 select { 109 case <-subCtx.Done(): 110 cancel() 111 if subCtx.Err() == context.Canceled { 112 return nil, io.EOF 113 } 114 return nil, subCtx.Err() 115 case resp := <-s.sent: 116 cancel() 117 return resp, nil 118 } 119 } 120 121 // Close closes the resources used by this MockStream. 122 func (s *MockStream) Close() { 123 close(s.recv) 124 close(s.sent) 125 }