1// Copyright 2020 Google LLC 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// https://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 14package wire 15 16import ( 17 "fmt" 18 "testing" 19 "time" 20) 21 22func testReceiveSettings() ReceiveSettings { 23 settings := DefaultReceiveSettings 24 settings.Timeout = 5 * time.Second 25 return settings 26} 27 28const serviceTestWaitTimeout = 30 * time.Second 29 30// serviceTestProxy wraps a `service` and provides some convenience methods for 31// testing. 32type serviceTestProxy struct { 33 t *testing.T 34 service service 35 name string 36 clients apiClients 37 started chan struct{} 38 terminated chan struct{} 39} 40 41func (sp *serviceTestProxy) initAndStart(t *testing.T, s service, name string, clients ...apiClient) { 42 sp.t = t 43 sp.service = s 44 sp.name = name 45 sp.clients = clients 46 sp.started = make(chan struct{}) 47 sp.terminated = make(chan struct{}) 48 s.AddStatusChangeReceiver(nil, sp.onStatusChange) 49 s.Start() 50} 51 52func (sp *serviceTestProxy) onStatusChange(_ serviceHandle, status serviceStatus, _ error) { 53 if status == serviceActive { 54 close(sp.started) 55 } 56 if status == serviceTerminated { 57 close(sp.terminated) 58 } 59} 60 61func (sp *serviceTestProxy) Start() { sp.service.Start() } 62func (sp *serviceTestProxy) Stop() { sp.service.Stop() } 63 64// StartError waits for the service to start and returns the error. 65func (sp *serviceTestProxy) StartError() error { 66 select { 67 case <-time.After(serviceTestWaitTimeout): 68 return fmt.Errorf("%s did not start within %v", sp.name, serviceTestWaitTimeout) 69 case <-sp.terminated: 70 sp.clients.Close() 71 return sp.service.Error() 72 case <-sp.started: 73 return sp.service.Error() 74 } 75} 76 77// FinalError waits for the service to terminate and returns the error. 78func (sp *serviceTestProxy) FinalError() error { 79 select { 80 case <-time.After(serviceTestWaitTimeout): 81 return fmt.Errorf("%s did not terminate within %v", sp.name, serviceTestWaitTimeout) 82 case <-sp.terminated: 83 sp.clients.Close() 84 return sp.service.Error() 85 } 86} 87 88// StopVerifyNoError stops the service, waits for it to terminate and verifies 89// that there is no error. 90func (sp *serviceTestProxy) StopVerifyNoError() { 91 sp.service.Stop() 92 if gotErr := sp.FinalError(); gotErr != nil { 93 sp.t.Errorf("%s final err: (%v), want: <nil>", sp.name, gotErr) 94 } 95} 96