• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2022 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 java.util.ArrayList;
23 import java.util.Arrays;
24 import java.util.Collections;
25 import java.util.List;
26 import java.util.regex.Pattern;
27 import org.junit.Test;
28 import org.junit.runner.RunWith;
29 import org.junit.runners.JUnit4;
30 
31 @RunWith(JUnit4.class)
32 public class GlobalInterceptorsTest {
33 
34   private final StaticTestingClassLoader classLoader =
35       new StaticTestingClassLoader(
36           getClass().getClassLoader(), Pattern.compile("io\\.grpc\\.[^.]+"));
37 
38   @Test
setInterceptorsTracers()39   public void setInterceptorsTracers() throws Exception {
40     Class<?> runnable = classLoader.loadClass(StaticTestingClassLoaderSet.class.getName());
41     ((Runnable) runnable.getDeclaredConstructor().newInstance()).run();
42   }
43 
44   @Test
setGlobalInterceptorsTracers_twice()45   public void setGlobalInterceptorsTracers_twice() throws Exception {
46     Class<?> runnable = classLoader.loadClass(StaticTestingClassLoaderSetTwice.class.getName());
47     ((Runnable) runnable.getDeclaredConstructor().newInstance()).run();
48   }
49 
50   @Test
getBeforeSet_clientInterceptors()51   public void getBeforeSet_clientInterceptors() throws Exception {
52     Class<?> runnable =
53         classLoader.loadClass(
54             StaticTestingClassLoaderGetBeforeSetClientInterceptor.class.getName());
55     ((Runnable) runnable.getDeclaredConstructor().newInstance()).run();
56   }
57 
58   @Test
getBeforeSet_serverInterceptors()59   public void getBeforeSet_serverInterceptors() throws Exception {
60     Class<?> runnable =
61         classLoader.loadClass(
62             StaticTestingClassLoaderGetBeforeSetServerInterceptor.class.getName());
63     ((Runnable) runnable.getDeclaredConstructor().newInstance()).run();
64   }
65 
66   @Test
getBeforeSet_serverStreamTracerFactories()67   public void getBeforeSet_serverStreamTracerFactories() throws Exception {
68     Class<?> runnable =
69         classLoader.loadClass(
70             StaticTestingClassLoaderGetBeforeSetServerStreamTracerFactory.class.getName());
71     ((Runnable) runnable.getDeclaredConstructor().newInstance()).run();
72   }
73 
74   // UsedReflectively
75   public static final class StaticTestingClassLoaderSet implements Runnable {
76     @Override
run()77     public void run() {
78       List<ClientInterceptor> clientInterceptorList =
79           new ArrayList<>(Arrays.asList(new NoopClientInterceptor()));
80       List<ServerInterceptor> serverInterceptorList =
81           new ArrayList<>(Arrays.asList(new NoopServerInterceptor()));
82       List<ServerStreamTracer.Factory> serverStreamTracerFactoryList =
83           new ArrayList<>(
84               Arrays.asList(
85                   new NoopServerStreamTracerFactory(), new NoopServerStreamTracerFactory()));
86 
87       GlobalInterceptors.setInterceptorsTracers(
88           clientInterceptorList, serverInterceptorList, serverStreamTracerFactoryList);
89 
90       assertThat(GlobalInterceptors.getClientInterceptors()).isEqualTo(clientInterceptorList);
91       assertThat(GlobalInterceptors.getServerInterceptors()).isEqualTo(serverInterceptorList);
92       assertThat(GlobalInterceptors.getServerStreamTracerFactories())
93           .isEqualTo(serverStreamTracerFactoryList);
94     }
95   }
96 
97   public static final class StaticTestingClassLoaderSetTwice implements Runnable {
98     @Override
run()99     public void run() {
100       GlobalInterceptors.setInterceptorsTracers(
101           new ArrayList<>(Arrays.asList(new NoopClientInterceptor())),
102               Collections.emptyList(),
103           new ArrayList<>(Arrays.asList(new NoopServerStreamTracerFactory())));
104       try {
105         GlobalInterceptors.setInterceptorsTracers(
106             null, new ArrayList<>(Arrays.asList(new NoopServerInterceptor())), null);
107         fail("should have failed for calling setGlobalInterceptorsTracers() again");
108       } catch (IllegalStateException e) {
109         assertThat(e).hasMessageThat().isEqualTo("Global interceptors and tracers are already set");
110       }
111     }
112   }
113 
114   public static final class StaticTestingClassLoaderGetBeforeSetClientInterceptor
115       implements Runnable {
116     @Override
run()117     public void run() {
118       List<ClientInterceptor> clientInterceptors = GlobalInterceptors.getClientInterceptors();
119       assertThat(clientInterceptors).isNull();
120 
121       try {
122         GlobalInterceptors.setInterceptorsTracers(
123             new ArrayList<>(Arrays.asList(new NoopClientInterceptor())), null, null);
124         fail("should have failed for invoking set call after get is already called");
125       } catch (IllegalStateException e) {
126         assertThat(e).hasMessageThat().isEqualTo("Set cannot be called after any get call");
127       }
128     }
129   }
130 
131   public static final class StaticTestingClassLoaderGetBeforeSetServerInterceptor
132       implements Runnable {
133     @Override
run()134     public void run() {
135       List<ServerInterceptor> serverInterceptors = GlobalInterceptors.getServerInterceptors();
136       assertThat(serverInterceptors).isNull();
137 
138       try {
139         GlobalInterceptors.setInterceptorsTracers(
140             null, new ArrayList<>(Arrays.asList(new NoopServerInterceptor())), null);
141         fail("should have failed for invoking set call after get is already called");
142       } catch (IllegalStateException e) {
143         assertThat(e).hasMessageThat().isEqualTo("Set cannot be called after any get call");
144       }
145     }
146   }
147 
148   public static final class StaticTestingClassLoaderGetBeforeSetServerStreamTracerFactory
149       implements Runnable {
150     @Override
run()151     public void run() {
152       List<ServerStreamTracer.Factory> serverStreamTracerFactories =
153           GlobalInterceptors.getServerStreamTracerFactories();
154       assertThat(serverStreamTracerFactories).isNull();
155 
156       try {
157         GlobalInterceptors.setInterceptorsTracers(
158             null, null, new ArrayList<>(Arrays.asList(new NoopServerStreamTracerFactory())));
159         fail("should have failed for invoking set call after get is already called");
160       } catch (IllegalStateException e) {
161         assertThat(e).hasMessageThat().isEqualTo("Set cannot be called after any get call");
162       }
163     }
164   }
165 
166   private static class NoopClientInterceptor implements ClientInterceptor {
167     @Override
interceptCall( MethodDescriptor<ReqT, RespT> method, CallOptions callOptions, Channel next)168     public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(
169         MethodDescriptor<ReqT, RespT> method, CallOptions callOptions, Channel next) {
170       return next.newCall(method, callOptions);
171     }
172   }
173 
174   private static class NoopServerInterceptor implements ServerInterceptor {
175     @Override
interceptCall( ServerCall<ReqT, RespT> call, Metadata headers, ServerCallHandler<ReqT, RespT> next)176     public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(
177         ServerCall<ReqT, RespT> call, Metadata headers, ServerCallHandler<ReqT, RespT> next) {
178       return next.startCall(call, headers);
179     }
180   }
181 
182   private static class NoopServerStreamTracerFactory extends ServerStreamTracer.Factory {
183     @Override
newServerStreamTracer(String fullMethodName, Metadata headers)184     public ServerStreamTracer newServerStreamTracer(String fullMethodName, Metadata headers) {
185       throw new UnsupportedOperationException();
186     }
187   }
188 }
189