• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2020 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;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 import static org.junit.Assert.fail;
21 
22 import com.google.common.collect.ImmutableSet;
23 import java.net.InetSocketAddress;
24 import java.net.SocketAddress;
25 import java.net.URI;
26 import java.util.Collection;
27 import java.util.Collections;
28 import org.junit.Test;
29 import org.junit.runner.RunWith;
30 import org.junit.runners.JUnit4;
31 
32 /** Unit tests for {@link ManagedChannelRegistry}. */
33 @RunWith(JUnit4.class)
34 public class ManagedChannelRegistryTest {
35   private String target = "testing123";
36   private ChannelCredentials creds = new ChannelCredentials() {
37     @Override
38     public ChannelCredentials withoutBearerTokens() {
39       throw new UnsupportedOperationException();
40     }
41   };
42 
43   @Test
register_unavailableProviderThrows()44   public void register_unavailableProviderThrows() {
45     ManagedChannelRegistry reg = new ManagedChannelRegistry();
46     try {
47       reg.register(new BaseProvider(false, 5));
48       fail("Should throw");
49     } catch (IllegalArgumentException e) {
50       assertThat(e).hasMessageThat().contains("isAvailable() returned false");
51     }
52     assertThat(reg.providers()).isEmpty();
53   }
54 
55   @Test
deregister()56   public void deregister() {
57     ManagedChannelRegistry reg = new ManagedChannelRegistry();
58     ManagedChannelProvider p1 = new BaseProvider(true, 5);
59     ManagedChannelProvider p2 = new BaseProvider(true, 5);
60     ManagedChannelProvider p3 = new BaseProvider(true, 5);
61     reg.register(p1);
62     reg.register(p2);
63     reg.register(p3);
64     assertThat(reg.providers()).containsExactly(p1, p2, p3).inOrder();
65     reg.deregister(p2);
66     assertThat(reg.providers()).containsExactly(p1, p3).inOrder();
67   }
68 
69   @Test
provider_sorted()70   public void provider_sorted() {
71     ManagedChannelRegistry reg = new ManagedChannelRegistry();
72     ManagedChannelProvider p1 = new BaseProvider(true, 5);
73     ManagedChannelProvider p2 = new BaseProvider(true, 3);
74     ManagedChannelProvider p3 = new BaseProvider(true, 8);
75     ManagedChannelProvider p4 = new BaseProvider(true, 3);
76     ManagedChannelProvider p5 = new BaseProvider(true, 8);
77     reg.register(p1);
78     reg.register(p2);
79     reg.register(p3);
80     reg.register(p4);
81     reg.register(p5);
82     assertThat(reg.providers()).containsExactly(p3, p5, p1, p2, p4).inOrder();
83   }
84 
85   @Test
getProvider_noProvider()86   public void getProvider_noProvider() {
87     assertThat(new ManagedChannelRegistry().provider()).isNull();
88   }
89 
90   @Test
newChannelBuilder_providerReturnsError()91   public void newChannelBuilder_providerReturnsError() {
92     final String errorString = "brisking";
93     class ErrorProvider extends BaseProvider {
94       ErrorProvider() {
95         super(true, 5);
96       }
97 
98       @Override
99       public NewChannelBuilderResult newChannelBuilder(
100           String passedTarget, ChannelCredentials passedCreds) {
101         assertThat(passedTarget).isSameInstanceAs(target);
102         assertThat(passedCreds).isSameInstanceAs(creds);
103         return NewChannelBuilderResult.error(errorString);
104       }
105     }
106 
107     ManagedChannelRegistry registry = new ManagedChannelRegistry();
108     registry.register(new ErrorProvider());
109     try {
110       registry.newChannelBuilder(target, creds);
111       fail("expected exception");
112     } catch (ManagedChannelRegistry.ProviderNotFoundException ex) {
113       assertThat(ex).hasMessageThat().contains(errorString);
114       assertThat(ex).hasMessageThat().contains(ErrorProvider.class.getName());
115     }
116   }
117 
118   @Test
newChannelBuilder_providerReturnsNonNull()119   public void newChannelBuilder_providerReturnsNonNull() {
120     ManagedChannelRegistry registry = new ManagedChannelRegistry();
121     registry.register(new BaseProvider(true, 5) {
122       @Override
123       public NewChannelBuilderResult newChannelBuilder(
124           String passedTarget, ChannelCredentials passedCreds) {
125         return NewChannelBuilderResult.error("dodging");
126       }
127     });
128     class MockChannelBuilder extends ForwardingChannelBuilder<MockChannelBuilder> {
129       @Override public ManagedChannelBuilder<?> delegate() {
130         throw new UnsupportedOperationException();
131       }
132     }
133 
134     final ManagedChannelBuilder<?> mcb = new MockChannelBuilder();
135     registry.register(new BaseProvider(true, 4) {
136       @Override
137       public NewChannelBuilderResult newChannelBuilder(
138           String passedTarget, ChannelCredentials passedCreds) {
139         return NewChannelBuilderResult.channelBuilder(mcb);
140       }
141     });
142     registry.register(new BaseProvider(true, 3) {
143       @Override
144       public NewChannelBuilderResult newChannelBuilder(
145           String passedTarget, ChannelCredentials passedCreds) {
146         fail("Should not be called");
147         throw new AssertionError();
148       }
149     });
150     assertThat(registry.newChannelBuilder(target, creds)).isSameInstanceAs(mcb);
151   }
152 
153   @Test
newChannelBuilder_noProvider()154   public void newChannelBuilder_noProvider() {
155     ManagedChannelRegistry registry = new ManagedChannelRegistry();
156     try {
157       registry.newChannelBuilder(target, creds);
158       fail("expected exception");
159     } catch (ManagedChannelRegistry.ProviderNotFoundException ex) {
160       assertThat(ex).hasMessageThat().contains("No functional channel service provider found");
161       assertThat(ex).hasMessageThat().contains("grpc-netty");
162     }
163   }
164 
165   @Test
newChannelBuilder_usesScheme()166   public void newChannelBuilder_usesScheme() {
167     NameResolverRegistry nameResolverRegistry = new NameResolverRegistry();
168     class SocketAddress1 extends SocketAddress {
169     }
170 
171     class SocketAddress2 extends SocketAddress {
172     }
173 
174     nameResolverRegistry.register(new BaseNameResolverProvider(true, 5, "sc1") {
175       @Override
176       protected Collection<Class<? extends SocketAddress>> getProducedSocketAddressTypes() {
177         return Collections.singleton(SocketAddress1.class);
178       }
179     });
180     nameResolverRegistry.register(new BaseNameResolverProvider(true, 6, "sc2") {
181       @Override
182       protected Collection<Class<? extends SocketAddress>> getProducedSocketAddressTypes() {
183         fail("Should not be called");
184         throw new AssertionError();
185       }
186     });
187 
188     ManagedChannelRegistry registry = new ManagedChannelRegistry();
189     registry.register(new BaseProvider(true, 5) {
190       @Override
191       protected Collection<Class<? extends SocketAddress>> getSupportedSocketAddressTypes() {
192         return Collections.singleton(SocketAddress2.class);
193       }
194 
195       @Override
196       public NewChannelBuilderResult newChannelBuilder(
197               String passedTarget, ChannelCredentials passedCreds) {
198         fail("Should not be called");
199         throw new AssertionError();
200       }
201     });
202     class MockChannelBuilder extends ForwardingChannelBuilder<MockChannelBuilder> {
203       @Override public ManagedChannelBuilder<?> delegate() {
204         throw new UnsupportedOperationException();
205       }
206     }
207 
208     final ManagedChannelBuilder<?> mcb = new MockChannelBuilder();
209     registry.register(new BaseProvider(true, 4) {
210       @Override
211       protected Collection<Class<? extends SocketAddress>> getSupportedSocketAddressTypes() {
212         return Collections.singleton(SocketAddress1.class);
213       }
214 
215       @Override
216       public NewChannelBuilderResult newChannelBuilder(
217               String passedTarget, ChannelCredentials passedCreds) {
218         return NewChannelBuilderResult.channelBuilder(mcb);
219       }
220     });
221     assertThat(
222         registry.newChannelBuilder(nameResolverRegistry, "sc1:" + target, creds)).isSameInstanceAs(
223         mcb);
224   }
225 
226   @Test
newChannelBuilder_unsupportedSocketAddressTypes()227   public void newChannelBuilder_unsupportedSocketAddressTypes() {
228     NameResolverRegistry nameResolverRegistry = new NameResolverRegistry();
229     class SocketAddress1 extends SocketAddress {
230     }
231 
232     class SocketAddress2 extends SocketAddress {
233     }
234 
235     nameResolverRegistry.register(new BaseNameResolverProvider(true, 5, "sc1") {
236       @Override
237       protected Collection<Class<? extends SocketAddress>> getProducedSocketAddressTypes() {
238         return ImmutableSet.of(SocketAddress1.class, SocketAddress2.class);
239       }
240     });
241 
242     ManagedChannelRegistry registry = new ManagedChannelRegistry();
243     registry.register(new BaseProvider(true, 5) {
244       @Override
245       protected Collection<Class<? extends SocketAddress>> getSupportedSocketAddressTypes() {
246         return Collections.singleton(SocketAddress2.class);
247       }
248 
249       @Override
250       public NewChannelBuilderResult newChannelBuilder(
251               String passedTarget, ChannelCredentials passedCreds) {
252         fail("Should not be called");
253         throw new AssertionError();
254       }
255     });
256 
257     registry.register(new BaseProvider(true, 4) {
258       @Override
259       protected Collection<Class<? extends SocketAddress>> getSupportedSocketAddressTypes() {
260         return Collections.singleton(SocketAddress1.class);
261       }
262 
263       @Override
264       public NewChannelBuilderResult newChannelBuilder(
265               String passedTarget, ChannelCredentials passedCreds) {
266         fail("Should not be called");
267         throw new AssertionError();
268       }
269     });
270     try {
271       registry.newChannelBuilder(nameResolverRegistry, "sc1:" + target, creds);
272       fail("expected exception");
273     } catch (ManagedChannelRegistry.ProviderNotFoundException ex) {
274       assertThat(ex).hasMessageThat().contains("does not support 1 or more of");
275       assertThat(ex).hasMessageThat().contains("SocketAddress1");
276       assertThat(ex).hasMessageThat().contains("SocketAddress2");
277     }
278   }
279 
280   @Test
newChannelBuilder_emptySet_asDefault()281   public void newChannelBuilder_emptySet_asDefault() {
282     NameResolverRegistry nameResolverRegistry = new NameResolverRegistry();
283 
284     ManagedChannelRegistry registry = new ManagedChannelRegistry();
285     class MockChannelBuilder extends ForwardingChannelBuilder<MockChannelBuilder> {
286       @Override public ManagedChannelBuilder<?> delegate() {
287         throw new UnsupportedOperationException();
288       }
289     }
290 
291     final ManagedChannelBuilder<?> mcb = new MockChannelBuilder();
292     registry.register(new BaseProvider(true, 4) {
293       @Override
294       protected Collection<Class<? extends SocketAddress>> getSupportedSocketAddressTypes() {
295         return Collections.emptySet();
296       }
297 
298       @Override
299       public NewChannelBuilderResult newChannelBuilder(
300               String passedTarget, ChannelCredentials passedCreds) {
301         return NewChannelBuilderResult.channelBuilder(mcb);
302       }
303     });
304     assertThat(
305         registry.newChannelBuilder(nameResolverRegistry, "sc1:" + target, creds)).isSameInstanceAs(
306         mcb);
307   }
308 
309   @Test
newChannelBuilder_noSchemeUsesDefaultScheme()310   public void newChannelBuilder_noSchemeUsesDefaultScheme() {
311     NameResolverRegistry nameResolverRegistry = new NameResolverRegistry();
312     class SocketAddress1 extends SocketAddress {
313     }
314 
315     nameResolverRegistry.register(new BaseNameResolverProvider(true, 5, "sc1") {
316       @Override
317       protected Collection<Class<? extends SocketAddress>> getProducedSocketAddressTypes() {
318         return Collections.singleton(SocketAddress1.class);
319       }
320     });
321 
322     ManagedChannelRegistry registry = new ManagedChannelRegistry();
323     class MockChannelBuilder extends ForwardingChannelBuilder<MockChannelBuilder> {
324       @Override public ManagedChannelBuilder<?> delegate() {
325         throw new UnsupportedOperationException();
326       }
327     }
328 
329     final ManagedChannelBuilder<?> mcb = new MockChannelBuilder();
330     registry.register(new BaseProvider(true, 4) {
331       @Override
332       protected Collection<Class<? extends SocketAddress>> getSupportedSocketAddressTypes() {
333         return Collections.singleton(SocketAddress1.class);
334       }
335 
336       @Override
337       public NewChannelBuilderResult newChannelBuilder(
338               String passedTarget, ChannelCredentials passedCreds) {
339         return NewChannelBuilderResult.channelBuilder(mcb);
340       }
341     });
342     assertThat(registry.newChannelBuilder(nameResolverRegistry, target, creds)).isSameInstanceAs(
343         mcb);
344   }
345 
346   @Test
newChannelBuilder_badUri()347   public void newChannelBuilder_badUri() {
348     NameResolverRegistry nameResolverRegistry = new NameResolverRegistry();
349     class SocketAddress1 extends SocketAddress {
350     }
351 
352     ManagedChannelRegistry registry = new ManagedChannelRegistry();
353 
354     class MockChannelBuilder extends ForwardingChannelBuilder<MockChannelBuilder> {
355       @Override public ManagedChannelBuilder<?> delegate() {
356         throw new UnsupportedOperationException();
357       }
358     }
359 
360     final ManagedChannelBuilder<?> mcb = new MockChannelBuilder();
361     registry.register(new BaseProvider(true, 4) {
362       @Override
363       protected Collection<Class<? extends SocketAddress>> getSupportedSocketAddressTypes() {
364         return Collections.singleton(SocketAddress1.class);
365       }
366 
367       @Override
368       public NewChannelBuilderResult newChannelBuilder(
369           String passedTarget, ChannelCredentials passedCreds) {
370         return NewChannelBuilderResult.channelBuilder(mcb);
371       }
372     });
373     assertThat(
374         registry.newChannelBuilder(nameResolverRegistry, ":testing123", creds)).isSameInstanceAs(
375         mcb);
376   }
377 
378   private static class BaseNameResolverProvider extends NameResolverProvider {
379     private final boolean isAvailable;
380     private final int priority;
381     private final String defaultScheme;
382 
BaseNameResolverProvider(boolean isAvailable, int priority, String defaultScheme)383     public BaseNameResolverProvider(boolean isAvailable, int priority, String defaultScheme) {
384       this.isAvailable = isAvailable;
385       this.priority = priority;
386       this.defaultScheme = defaultScheme;
387     }
388 
389     @Override
newNameResolver(URI targetUri, NameResolver.Args args)390     public NameResolver newNameResolver(URI targetUri, NameResolver.Args args) {
391       return null;
392     }
393 
394     @Override
getDefaultScheme()395     public String getDefaultScheme() {
396       return defaultScheme;
397     }
398 
399     @Override
isAvailable()400     protected boolean isAvailable() {
401       return isAvailable;
402     }
403 
404     @Override
priority()405     protected int priority() {
406       return priority;
407     }
408   }
409 
410   private static class BaseProvider extends ManagedChannelProvider {
411     private final boolean isAvailable;
412     private final int priority;
413 
BaseProvider(boolean isAvailable, int priority)414     public BaseProvider(boolean isAvailable, int priority) {
415       this.isAvailable = isAvailable;
416       this.priority = priority;
417     }
418 
419     @Override
isAvailable()420     protected boolean isAvailable() {
421       return isAvailable;
422     }
423 
424     @Override
priority()425     protected int priority() {
426       return priority;
427     }
428 
429     @Override
builderForAddress(String name, int port)430     protected ManagedChannelBuilder<?> builderForAddress(String name, int port) {
431       throw new UnsupportedOperationException();
432     }
433 
434     @Override
builderForTarget(String target)435     protected ManagedChannelBuilder<?> builderForTarget(String target) {
436       throw new UnsupportedOperationException();
437     }
438 
439     @Override
getSupportedSocketAddressTypes()440     protected Collection<Class<? extends SocketAddress>> getSupportedSocketAddressTypes() {
441       return Collections.singleton(InetSocketAddress.class);
442     }
443   }
444 }
445