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