• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2017 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.testing.protobuf;
18 
19 import static io.grpc.MethodDescriptor.MethodType.BIDI_STREAMING;
20 import static io.grpc.MethodDescriptor.MethodType.CLIENT_STREAMING;
21 import static io.grpc.MethodDescriptor.MethodType.SERVER_STREAMING;
22 import static io.grpc.MethodDescriptor.MethodType.UNARY;
23 import static org.junit.Assert.assertEquals;
24 import static org.junit.Assert.assertTrue;
25 
26 import io.grpc.MethodDescriptor;
27 import io.grpc.stub.annotations.RpcMethod;
28 import java.io.File;
29 import java.util.Collections;
30 import java.util.HashMap;
31 import java.util.Map;
32 import java.util.Set;
33 import javax.annotation.processing.AbstractProcessor;
34 import javax.annotation.processing.RoundEnvironment;
35 import javax.lang.model.SourceVersion;
36 import javax.lang.model.element.Element;
37 import javax.lang.model.element.TypeElement;
38 import javax.lang.model.type.MirroredTypeException;
39 import javax.tools.JavaCompiler;
40 import javax.tools.JavaCompiler.CompilationTask;
41 import javax.tools.JavaFileObject;
42 import javax.tools.StandardJavaFileManager;
43 import javax.tools.ToolProvider;
44 import org.junit.Assume;
45 import org.junit.Test;
46 import org.junit.runner.RunWith;
47 import org.junit.runners.JUnit4;
48 
49 /** Test to verify that the proto file simpleservice.proto generates the expected service. */
50 @RunWith(JUnit4.class)
51 public class SimpleServiceTest {
52   @Test
serviceDescriptor()53   public void serviceDescriptor() {
54     assertEquals("grpc.testing.SimpleService", SimpleServiceGrpc.getServiceDescriptor().getName());
55   }
56 
57   @Test
serviceMethodDescriotrs()58   public void serviceMethodDescriotrs() {
59     MethodDescriptor<SimpleRequest, SimpleResponse> genericTypeShouldMatchWhenAssigned;
60 
61     genericTypeShouldMatchWhenAssigned = SimpleServiceGrpc.getUnaryRpcMethod();
62     assertEquals(UNARY, genericTypeShouldMatchWhenAssigned.getType());
63 
64     genericTypeShouldMatchWhenAssigned = SimpleServiceGrpc.getClientStreamingRpcMethod();
65     assertEquals(CLIENT_STREAMING, genericTypeShouldMatchWhenAssigned.getType());
66 
67     genericTypeShouldMatchWhenAssigned = SimpleServiceGrpc.getServerStreamingRpcMethod();
68     assertEquals(SERVER_STREAMING, genericTypeShouldMatchWhenAssigned.getType());
69 
70     genericTypeShouldMatchWhenAssigned = SimpleServiceGrpc.getBidiStreamingRpcMethod();
71     assertEquals(BIDI_STREAMING, genericTypeShouldMatchWhenAssigned.getType());
72   }
73 
74   @Test
generatedMethodsAreSampledToLocalTracing()75   public void generatedMethodsAreSampledToLocalTracing() throws Exception {
76     assertTrue(SimpleServiceGrpc.getUnaryRpcMethod().isSampledToLocalTracing());
77   }
78 
79   public static class AnnotationProcessor extends AbstractProcessor {
80 
81     private boolean processedClass = false;
82 
83     @Override
getSupportedSourceVersion()84     public SourceVersion getSupportedSourceVersion() {
85       return SourceVersion.latestSupported();
86     }
87 
88     @Override
getSupportedAnnotationTypes()89     public Set<String> getSupportedAnnotationTypes() {
90       return Collections.singleton(RpcMethod.class.getCanonicalName());
91     }
92 
verifyRpcMethodAnnotation( MethodDescriptor<SimpleRequest, SimpleResponse> descriptor, RpcMethod annotation)93     private void verifyRpcMethodAnnotation(
94         MethodDescriptor<SimpleRequest, SimpleResponse> descriptor, RpcMethod annotation) {
95       assertEquals(descriptor.getFullMethodName(), annotation.fullMethodName());
96       assertEquals(descriptor.getType(), annotation.methodType());
97 
98       // Class objects may not be available at runtime, handle MirroredTypeException if it occurs
99       try {
100         assertEquals(SimpleRequest.class, annotation.requestType());
101       } catch (MirroredTypeException e) {
102         assertEquals(SimpleRequest.class.getCanonicalName(), e.getTypeMirror().toString());
103       }
104 
105       try {
106         assertEquals(SimpleResponse.class, annotation.responseType());
107       } catch (MirroredTypeException e) {
108         assertEquals(SimpleResponse.class.getCanonicalName(), e.getTypeMirror().toString());
109       }
110     }
111 
112     @Override
process( Set<? extends TypeElement> annotations, RoundEnvironment roundEnv)113     public synchronized boolean process(
114         Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
115       for (Element rootElement : roundEnv.getRootElements()) {
116         if (!rootElement.asType().toString().equals(SimpleServiceGrpc.class.getCanonicalName())) {
117           continue;
118         }
119 
120         Map<String, RpcMethod> methodToAnnotation = new HashMap<>();
121         for (Element enclosedElement : rootElement.getEnclosedElements()) {
122           RpcMethod annotation = enclosedElement.getAnnotation(RpcMethod.class);
123           if (annotation != null) {
124             methodToAnnotation.put(enclosedElement.getSimpleName().toString(), annotation);
125           }
126         }
127 
128         verifyRpcMethodAnnotation(
129             SimpleServiceGrpc.getUnaryRpcMethod(), methodToAnnotation.get("getUnaryRpcMethod"));
130         verifyRpcMethodAnnotation(
131             SimpleServiceGrpc.getServerStreamingRpcMethod(),
132             methodToAnnotation.get("getServerStreamingRpcMethod"));
133         verifyRpcMethodAnnotation(
134             SimpleServiceGrpc.getClientStreamingRpcMethod(),
135             methodToAnnotation.get("getClientStreamingRpcMethod"));
136         verifyRpcMethodAnnotation(
137             SimpleServiceGrpc.getBidiStreamingRpcMethod(),
138             methodToAnnotation.get("getBidiStreamingRpcMethod"));
139 
140         processedClass = true;
141       }
142       return false;
143     }
144   }
145 
146   @Test
testRpcMethodAnnotations()147   public void testRpcMethodAnnotations() throws Exception {
148     File grpcJavaFile =
149         new File("./src/generated/main/grpc/io/grpc/testing/protobuf/SimpleServiceGrpc.java");
150     Assume.assumeTrue(grpcJavaFile.exists());
151 
152     JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
153     StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
154     AnnotationProcessor processor = new AnnotationProcessor();
155     Iterable<? extends JavaFileObject> obs = fileManager.getJavaFileObjects(grpcJavaFile);
156 
157     CompilationTask task =
158         compiler.getTask(
159             null,
160             fileManager,
161             null,
162             Collections.singleton("-proc:only"),
163             Collections.singleton(SimpleServiceGrpc.class.getCanonicalName()),
164             obs);
165     task.setProcessors(Collections.singleton(processor));
166     assertTrue(task.call());
167     assertTrue(processor.processedClass);
168     fileManager.close();
169   }
170 }
171