1 /* 2 * Copyright 2016 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 junit.framework.TestCase.assertSame; 20 import static org.junit.Assert.assertEquals; 21 import static org.junit.Assert.assertFalse; 22 import static org.junit.Assert.assertNotEquals; 23 import static org.junit.Assert.assertNull; 24 import static org.junit.Assert.assertTrue; 25 26 import io.grpc.MethodDescriptor.Marshaller; 27 import io.grpc.MethodDescriptor.MethodType; 28 import io.grpc.testing.TestMethodDescriptors; 29 import org.junit.Rule; 30 import org.junit.Test; 31 import org.junit.rules.ExpectedException; 32 import org.junit.runner.RunWith; 33 import org.junit.runners.JUnit4; 34 35 /** 36 * Tests for {@link MethodDescriptor}. 37 */ 38 @RunWith(JUnit4.class) 39 public class MethodDescriptorTest { 40 @SuppressWarnings("deprecation") // https://github.com/grpc/grpc-java/issues/7467 41 @Rule 42 public final ExpectedException thrown = ExpectedException.none(); 43 44 @Test createMethodDescriptor()45 public void createMethodDescriptor() { 46 MethodDescriptor<String, String> descriptor = MethodDescriptor.<String, String>newBuilder() 47 .setType(MethodType.CLIENT_STREAMING) 48 .setFullMethodName("package.service/method") 49 .setRequestMarshaller(new StringMarshaller()) 50 .setResponseMarshaller(new StringMarshaller()) 51 .build(); 52 53 assertEquals(MethodType.CLIENT_STREAMING, descriptor.getType()); 54 assertEquals("package.service/method", descriptor.getFullMethodName()); 55 assertFalse(descriptor.isIdempotent()); 56 assertFalse(descriptor.isSafe()); 57 } 58 59 @Test idempotent()60 public void idempotent() { 61 MethodDescriptor<String, String> descriptor = MethodDescriptor.<String, String>newBuilder() 62 .setType(MethodType.SERVER_STREAMING) 63 .setFullMethodName("package.service/method") 64 .setRequestMarshaller(new StringMarshaller()) 65 .setResponseMarshaller(new StringMarshaller()) 66 .build(); 67 68 assertFalse(descriptor.isIdempotent()); 69 70 // Create a new desriptor by setting idempotent to true 71 MethodDescriptor<String, String> newDescriptor = 72 descriptor.toBuilder().setIdempotent(true).build(); 73 assertTrue(newDescriptor.isIdempotent()); 74 // All other fields should staty the same 75 assertEquals(MethodType.SERVER_STREAMING, newDescriptor.getType()); 76 assertEquals("package.service/method", newDescriptor.getFullMethodName()); 77 } 78 79 @Test safe()80 public void safe() { 81 MethodDescriptor<String, String> descriptor = MethodDescriptor.<String, String>newBuilder() 82 .setType(MethodType.UNARY) 83 .setFullMethodName("package.service/method") 84 .setRequestMarshaller(new StringMarshaller()) 85 .setResponseMarshaller(new StringMarshaller()) 86 .build(); 87 assertFalse(descriptor.isSafe()); 88 89 // Create a new desriptor by setting safe to true 90 MethodDescriptor<String, String> newDescriptor = descriptor.toBuilder().setSafe(true).build(); 91 assertTrue(newDescriptor.isSafe()); 92 // All other fields should staty the same 93 assertEquals(MethodType.UNARY, newDescriptor.getType()); 94 assertEquals("package.service/method", newDescriptor.getFullMethodName()); 95 } 96 97 @Test safeImpliesIdempotent()98 public void safeImpliesIdempotent() { 99 MethodDescriptor<String, String> descriptor = MethodDescriptor.<String, String>newBuilder() 100 .setType(MethodType.UNARY) 101 .setFullMethodName("package.service/method") 102 .setRequestMarshaller(new StringMarshaller()) 103 .setResponseMarshaller(new StringMarshaller()) 104 .setSafe(true) 105 .build(); 106 assertTrue(descriptor.isSafe()); 107 assertTrue(descriptor.isIdempotent()); 108 descriptor = descriptor.toBuilder().setIdempotent(false).build(); 109 assertFalse(descriptor.isSafe()); 110 assertFalse(descriptor.isIdempotent()); 111 } 112 113 @Test safeAndNonUnary()114 public void safeAndNonUnary() { 115 MethodDescriptor<String, String> descriptor = MethodDescriptor.<String, String>newBuilder() 116 .setType(MethodType.SERVER_STREAMING) 117 .setFullMethodName("package.service/method") 118 .setRequestMarshaller(new StringMarshaller()) 119 .setResponseMarshaller(new StringMarshaller()) 120 .build(); 121 122 // Verify it does not throw 123 MethodDescriptor<String, String> newDescriptor = descriptor.toBuilder().setSafe(true).build(); 124 assertTrue(newDescriptor.isSafe()); 125 } 126 127 @Test sampledToLocalTracing()128 public void sampledToLocalTracing() { 129 MethodDescriptor<String, String> md1 = MethodDescriptor.<String, String>newBuilder() 130 .setType(MethodType.SERVER_STREAMING) 131 .setFullMethodName("package.service/method") 132 .setRequestMarshaller(new StringMarshaller()) 133 .setResponseMarshaller(new StringMarshaller()) 134 .setSampledToLocalTracing(true) 135 .build(); 136 assertTrue(md1.isSampledToLocalTracing()); 137 138 MethodDescriptor<String, String> md2 = md1.toBuilder() 139 .setFullMethodName("package.service/method2") 140 .build(); 141 assertTrue(md2.isSampledToLocalTracing()); 142 143 // Same method name as md1, but not setting sampledToLocalTracing 144 MethodDescriptor<String, String> md3 = MethodDescriptor.<String, String>newBuilder() 145 .setType(MethodType.SERVER_STREAMING) 146 .setFullMethodName("package.service/method") 147 .setRequestMarshaller(new StringMarshaller()) 148 .setResponseMarshaller(new StringMarshaller()) 149 .build(); 150 assertFalse(md3.isSampledToLocalTracing()); 151 152 MethodDescriptor<String, String> md4 = md3.toBuilder() 153 .setFullMethodName("package.service/method2") 154 .setSampledToLocalTracing(true) 155 .build(); 156 assertTrue(md4.isSampledToLocalTracing()); 157 } 158 159 @Test getServiceName_extractsService()160 public void getServiceName_extractsService() { 161 Marshaller<Void> marshaller = TestMethodDescriptors.voidMarshaller(); 162 MethodDescriptor<?, ?> md = MethodDescriptor.newBuilder(marshaller, marshaller) 163 .setType(MethodType.UNARY) 164 .setFullMethodName("foo/bar") 165 .build(); 166 167 assertEquals("foo", md.getServiceName()); 168 } 169 170 @Test getServiceName_returnsNull()171 public void getServiceName_returnsNull() { 172 Marshaller<Void> marshaller = TestMethodDescriptors.voidMarshaller(); 173 MethodDescriptor<?, ?> md = MethodDescriptor.newBuilder(marshaller, marshaller) 174 .setType(MethodType.UNARY) 175 .setFullMethodName("foo-bar") 176 .build(); 177 178 assertNull(md.getServiceName()); 179 } 180 181 @Test getBareMethodName_extractsMethod()182 public void getBareMethodName_extractsMethod() { 183 Marshaller<Void> marshaller = TestMethodDescriptors.voidMarshaller(); 184 MethodDescriptor<?, ?> md = MethodDescriptor.newBuilder(marshaller, marshaller) 185 .setType(MethodType.UNARY) 186 .setFullMethodName("foo/bar") 187 .build(); 188 189 assertEquals("bar", md.getBareMethodName()); 190 } 191 192 @Test getBareMethodName_returnsNull()193 public void getBareMethodName_returnsNull() { 194 Marshaller<Void> marshaller = TestMethodDescriptors.voidMarshaller(); 195 MethodDescriptor<?, ?> md = MethodDescriptor.newBuilder(marshaller, marshaller) 196 .setType(MethodType.UNARY) 197 .setFullMethodName("foo-bar") 198 .build(); 199 200 assertNull(md.getBareMethodName()); 201 } 202 203 @Test getBareMethodName_returnsEmptyStringWithMethodMissing()204 public void getBareMethodName_returnsEmptyStringWithMethodMissing() { 205 Marshaller<Void> marshaller = TestMethodDescriptors.voidMarshaller(); 206 MethodDescriptor<?, ?> md = MethodDescriptor.newBuilder(marshaller, marshaller) 207 .setType(MethodType.UNARY) 208 .setFullMethodName("foo/") 209 .build(); 210 211 assertTrue(md.getBareMethodName().isEmpty()); 212 } 213 214 @Test toBuilderTest()215 public void toBuilderTest() { 216 MethodDescriptor<String, String> md1 = MethodDescriptor.<String, String>newBuilder() 217 .setType(MethodType.UNARY) 218 .setFullMethodName("package.service/method") 219 .setRequestMarshaller(StringMarshaller.INSTANCE) 220 .setResponseMarshaller(StringMarshaller.INSTANCE) 221 .setSampledToLocalTracing(true) 222 .setIdempotent(true) 223 .setSafe(true) 224 .setSchemaDescriptor(new Object()) 225 .build(); 226 // Verify that we are not using any default builder values, so if md1 and md2 matches, 227 // it's because toBuilder explicitly copied it. 228 MethodDescriptor<String, String> defaults = MethodDescriptor.<String, String>newBuilder() 229 .setType(MethodType.UNARY) 230 .setFullMethodName("package.service/method") 231 .setRequestMarshaller(StringMarshaller.INSTANCE) 232 .setResponseMarshaller(StringMarshaller.INSTANCE) 233 .build(); 234 assertNotEquals(md1.isSampledToLocalTracing(), defaults.isSampledToLocalTracing()); 235 assertNotEquals(md1.isIdempotent(), defaults.isIdempotent()); 236 assertNotEquals(md1.isSafe(), defaults.isSafe()); 237 assertNotEquals(md1.getSchemaDescriptor(), defaults.getSchemaDescriptor()); 238 239 // Verify that the builder correctly copied over the values 240 MethodDescriptor<Integer, Integer> md2 = md1.toBuilder( 241 IntegerMarshaller.INSTANCE, 242 IntegerMarshaller.INSTANCE).build(); 243 assertSame(md1.getType(), md2.getType()); 244 assertSame(md1.getFullMethodName(), md2.getFullMethodName()); 245 assertSame(IntegerMarshaller.INSTANCE, md2.getRequestMarshaller()); 246 assertSame(IntegerMarshaller.INSTANCE, md2.getResponseMarshaller()); 247 assertEquals(md1.isSampledToLocalTracing(), md2.isSampledToLocalTracing()); 248 assertEquals(md1.isIdempotent(), md2.isIdempotent()); 249 assertEquals(md1.isSafe(), md2.isSafe()); 250 assertSame(md1.getSchemaDescriptor(), md2.getSchemaDescriptor()); 251 } 252 253 @Test toStringTest()254 public void toStringTest() { 255 MethodDescriptor<String, String> descriptor = MethodDescriptor.<String, String>newBuilder() 256 .setType(MethodType.UNARY) 257 .setFullMethodName("package.service/method") 258 .setRequestMarshaller(StringMarshaller.INSTANCE) 259 .setResponseMarshaller(StringMarshaller.INSTANCE) 260 .setSampledToLocalTracing(true) 261 .setIdempotent(true) 262 .setSafe(true) 263 .setSchemaDescriptor(new Object()) 264 .build(); 265 266 String toString = descriptor.toString(); 267 assertTrue(toString.contains("MethodDescriptor")); 268 assertTrue(toString.contains("fullMethodName=package.service/method")); 269 assertTrue(toString.contains("type=UNARY")); 270 assertTrue(toString.contains("idempotent=true")); 271 assertTrue(toString.contains("safe=true")); 272 assertTrue(toString.contains("sampledToLocalTracing=true")); 273 assertTrue(toString.contains("requestMarshaller=io.grpc.StringMarshaller")); 274 assertTrue(toString.contains("responseMarshaller=io.grpc.StringMarshaller")); 275 assertTrue(toString.contains("schemaDescriptor=java.lang.Object")); 276 } 277 } 278