Home | History | Annotate | Download | only in internal
      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