1 /* 2 * Copyright 2015 The gRPC Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package io.grpc.internal; 18 19 import static org.mockito.Matchers.any; 20 import static org.mockito.Mockito.doAnswer; 21 import static org.mockito.Mockito.mock; 22 import static org.mockito.Mockito.when; 23 24 import io.grpc.CallOptions; 25 import io.grpc.InternalLogId; 26 import io.grpc.Metadata; 27 import io.grpc.MethodDescriptor; 28 import java.net.SocketAddress; 29 import java.util.concurrent.BlockingQueue; 30 import java.util.concurrent.LinkedBlockingQueue; 31 import javax.annotation.Nullable; 32 import org.mockito.invocation.InvocationOnMock; 33 import org.mockito.stubbing.Answer; 34 35 /** 36 * Common utility methods for tests. 37 */ 38 final class TestUtils { 39 40 static class MockClientTransportInfo { 41 /** 42 * A mock transport created by the mock transport factory. 43 */ 44 final ConnectionClientTransport transport; 45 46 /** 47 * The listener passed to the start() of the mock transport. 48 */ 49 final ManagedClientTransport.Listener listener; 50 51 MockClientTransportInfo(ConnectionClientTransport transport, 52 ManagedClientTransport.Listener listener) { 53 this.transport = transport; 54 this.listener = listener; 55 } 56 } 57 58 /** 59 * Stub the given mock {@link ClientTransportFactory} by returning mock 60 * {@link ManagedClientTransport}s which saves their listeners along with them. This method 61 * returns a list of {@link MockClientTransportInfo}, each of which is a started mock transport 62 * and its listener. 63 */ 64 static BlockingQueue<MockClientTransportInfo> captureTransports( 65 ClientTransportFactory mockTransportFactory) { 66 return captureTransports(mockTransportFactory, null); 67 } 68 69 static BlockingQueue<MockClientTransportInfo> captureTransports( 70 ClientTransportFactory mockTransportFactory, @Nullable final Runnable startRunnable) { 71 final BlockingQueue<MockClientTransportInfo> captor = 72 new LinkedBlockingQueue<MockClientTransportInfo>(); 73 74 doAnswer(new Answer<ConnectionClientTransport>() { 75 @Override 76 public ConnectionClientTransport answer(InvocationOnMock invocation) throws Throwable { 77 final ConnectionClientTransport mockTransport = mock(ConnectionClientTransport.class); 78 when(mockTransport.getLogId()).thenReturn(InternalLogId.allocate("mocktransport")); 79 when(mockTransport.newStream( 80 any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class))) 81 .thenReturn(mock(ClientStream.class)); 82 // Save the listener 83 doAnswer(new Answer<Runnable>() { 84 @Override 85 public Runnable answer(InvocationOnMock invocation) throws Throwable { 86 captor.add(new MockClientTransportInfo( 87 mockTransport, (ManagedClientTransport.Listener) invocation.getArguments()[0])); 88 return startRunnable; 89 } 90 }).when(mockTransport).start(any(ManagedClientTransport.Listener.class)); 91 return mockTransport; 92 } 93 }).when(mockTransportFactory) 94 .newClientTransport( 95 any(SocketAddress.class), 96 any(ClientTransportFactory.ClientTransportOptions.class)); 97 98 return captor; 99 } 100 101 private TestUtils() { 102 } 103 } 104