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