• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2016 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.cronet;
18 
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertTrue;
21 import static org.mockito.Mockito.any;
22 import static org.mockito.Mockito.mock;
23 import static org.mockito.Mockito.times;
24 import static org.mockito.Mockito.verify;
25 import static org.mockito.Mockito.when;
26 
27 import io.grpc.Attributes;
28 import io.grpc.CallCredentials;
29 import io.grpc.CallOptions;
30 import io.grpc.Metadata;
31 import io.grpc.MethodDescriptor;
32 import io.grpc.SecurityLevel;
33 import io.grpc.Status;
34 import io.grpc.cronet.CronetChannelBuilder.StreamBuilderFactory;
35 import io.grpc.internal.ClientStreamListener;
36 import io.grpc.internal.ManagedClientTransport;
37 import io.grpc.internal.TransportTracer;
38 import io.grpc.testing.TestMethodDescriptors;
39 import java.net.InetSocketAddress;
40 import java.util.concurrent.Executor;
41 import org.chromium.net.BidirectionalStream;
42 import org.junit.Before;
43 import org.junit.Test;
44 import org.junit.runner.RunWith;
45 import org.mockito.ArgumentCaptor;
46 import org.mockito.Mock;
47 import org.mockito.MockitoAnnotations;
48 import org.robolectric.RobolectricTestRunner;
49 
50 @RunWith(RobolectricTestRunner.class)
51 public final class CronetClientTransportTest {
52 
53   private static final String AUTHORITY = "test.example.com";
54 
55   private CronetClientTransport transport;
56   @Mock private StreamBuilderFactory streamFactory;
57   @Mock private Executor executor;
58   private MethodDescriptor<Void, Void> descriptor = TestMethodDescriptors.voidMethod();
59   @Mock private ManagedClientTransport.Listener clientTransportListener;
60   @Mock private BidirectionalStream.Builder builder;
61 
62   @Before
setUp()63   public void setUp() {
64     MockitoAnnotations.initMocks(this);
65 
66     transport =
67         new CronetClientTransport(
68             streamFactory,
69             new InetSocketAddress("localhost", 443),
70             AUTHORITY,
71             null,
72             executor,
73             5000,
74             false,
75             TransportTracer.getDefaultFactory().create());
76     Runnable callback = transport.start(clientTransportListener);
77     assertTrue(callback != null);
78     callback.run();
79     verify(clientTransportListener).transportReady();
80   }
81 
82   @Test
transportAttributes()83   public void transportAttributes() {
84     Attributes attrs = transport.getAttributes();
85     assertEquals(AUTHORITY, attrs.get(CallCredentials.ATTR_AUTHORITY));
86     assertEquals(
87         SecurityLevel.PRIVACY_AND_INTEGRITY, attrs.get(CallCredentials.ATTR_SECURITY_LEVEL));
88   }
89 
90   @Test
shutdownTransport()91   public void shutdownTransport() throws Exception {
92     CronetClientStream stream1 =
93         transport.newStream(descriptor, new Metadata(), CallOptions.DEFAULT);
94     CronetClientStream stream2 =
95         transport.newStream(descriptor, new Metadata(), CallOptions.DEFAULT);
96 
97     // Create a transport and start two streams on it.
98     ArgumentCaptor<BidirectionalStream.Callback> callbackCaptor =
99         ArgumentCaptor.forClass(BidirectionalStream.Callback.class);
100     when(streamFactory.newBidirectionalStreamBuilder(
101             any(String.class), callbackCaptor.capture(), any(Executor.class)))
102         .thenReturn(builder);
103     BidirectionalStream cronetStream1 = mock(BidirectionalStream.class);
104     when(builder.build()).thenReturn(cronetStream1);
105     stream1.start(mock(ClientStreamListener.class));
106     BidirectionalStream.Callback callback1 = callbackCaptor.getValue();
107 
108     BidirectionalStream cronetStream2 = mock(BidirectionalStream.class);
109     when(builder.build()).thenReturn(cronetStream2);
110     stream2.start(mock(ClientStreamListener.class));
111     BidirectionalStream.Callback callback2 = callbackCaptor.getValue();
112     // Shut down the transport. transportShutdown should be called immediately.
113     transport.shutdown();
114     verify(clientTransportListener).transportShutdown(any(Status.class));
115     // Have two live streams. Transport has not been terminated.
116     verify(clientTransportListener, times(0)).transportTerminated();
117 
118     callback1.onCanceled(cronetStream1, null);
119     // Still has one live stream
120     verify(clientTransportListener, times(0)).transportTerminated();
121     callback2.onCanceled(cronetStream1, null);
122     // All streams are gone now.
123     verify(clientTransportListener, times(1)).transportTerminated();
124   }
125 }
126