1 /* 2 * Copyright (C) 2016 The Dagger 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 dagger.grpc.functional.server; 18 19 import static com.google.common.truth.Truth.assertThat; 20 import static com.google.common.util.concurrent.Futures.getUnchecked; 21 import static com.google.protos.test.CoffeeService.CoffeeType.AMERICANO; 22 import static com.google.protos.test.CoffeeService.CoffeeType.DRIP; 23 import static com.google.protos.test.CoffeeService.CoffeeType.ESPRESSO; 24 import static com.google.protos.test.CoffeeService.CoffeeType.LATTE; 25 import static com.google.protos.test.CoffeeService.CoffeeType.POUR_OVER; 26 import static java.util.Arrays.asList; 27 28 import com.google.common.collect.ImmutableList; 29 import com.google.common.util.concurrent.SettableFuture; 30 import com.google.protos.test.BaristaGrpc; 31 import com.google.protos.test.BaristaGrpc.BaristaStub; 32 import com.google.protos.test.CoffeeService.CoffeeRequest; 33 import com.google.protos.test.CoffeeService.CoffeeResponse; 34 import com.google.protos.test.CoffeeService.CoffeeType; 35 import io.grpc.inprocess.InProcessChannelBuilder; 36 import io.grpc.stub.StreamObserver; 37 import java.util.ArrayList; 38 import java.util.List; 39 import org.junit.Before; 40 import org.junit.ClassRule; 41 import org.junit.Rule; 42 import org.junit.Test; 43 import org.junit.runner.RunWith; 44 import org.junit.runners.Parameterized; 45 import org.junit.runners.Parameterized.Parameters; 46 47 @RunWith(Parameterized.class) 48 public class BaristaTest { 49 50 private static final class CoffeeResponseObserver implements StreamObserver<CoffeeResponse> { 51 private final SettableFuture<Void> completion = SettableFuture.create(); 52 private final List<CoffeeResponse> responses = new ArrayList<>(); 53 responses()54 List<CoffeeResponse> responses() { 55 getUnchecked(completion); 56 return responses; 57 } 58 59 @Override onNext(CoffeeResponse value)60 public void onNext(CoffeeResponse value) { 61 responses.add(value); 62 } 63 64 @Override onError(Throwable t)65 public void onError(Throwable t) { 66 completion.setException(t); 67 } 68 69 @Override onCompleted()70 public void onCompleted() { 71 completion.set(null); 72 } 73 } 74 75 @ClassRule 76 public static CoffeeServerResource coffeeServerWithCallScope = 77 new CoffeeServerResource("CallScope", DaggerCoffeeServerWithCallScopeService.builder()); 78 79 @ClassRule 80 public static CoffeeServerResource coffeeServerWithSingletonScope = 81 new CoffeeServerResource("Unscoped", DaggerCoffeeServerWithUnscopedService.builder()); 82 83 @Parameters(name = "{0}") coffeeServers()84 public static Iterable<Object[]> coffeeServers() { 85 return ImmutableList.copyOf( 86 new Object[][] {{coffeeServerWithCallScope}, {coffeeServerWithSingletonScope}}); 87 } 88 89 @Rule public final VerifyInterceptor verifyCount; 90 private final CoffeeServerResource coffeeServer; 91 private final CoffeeResponseObserver responseObserver = new CoffeeResponseObserver(); 92 93 private BaristaStub barista; 94 BaristaTest(CoffeeServerResource coffeeServer)95 public BaristaTest(CoffeeServerResource coffeeServer) { 96 this.coffeeServer = coffeeServer; 97 this.verifyCount = new VerifyInterceptor(coffeeServer); 98 } 99 100 @Before setUp()101 public void setUp() { 102 barista = BaristaGrpc.newStub(InProcessChannelBuilder.forName(coffeeServer.name()).build()); 103 } 104 105 @Test testUnaryGetCoffee()106 public void testUnaryGetCoffee() { 107 barista.unaryGetCoffee(request(POUR_OVER, LATTE), responseObserver); 108 assertThat(responseObserver.responses()) 109 .containsExactly(response("Here you go!", POUR_OVER, LATTE)); 110 } 111 112 @Test testClientStreamingGetCoffee()113 public void testClientStreamingGetCoffee() { 114 StreamObserver<CoffeeRequest> requestObserver = 115 barista.clientStreamingGetCoffee(responseObserver); 116 requestObserver.onNext(request(POUR_OVER, LATTE)); 117 requestObserver.onNext(request(AMERICANO)); 118 requestObserver.onNext(request(DRIP, ESPRESSO)); 119 requestObserver.onCompleted(); 120 assertThat(responseObserver.responses()) 121 .containsExactly(response("All yours!", POUR_OVER, LATTE, AMERICANO, DRIP, ESPRESSO)); 122 } 123 124 @Test testServerStreamingGetCoffee()125 public void testServerStreamingGetCoffee() { 126 barista.serverStreamingGetCoffee(request(DRIP, AMERICANO), responseObserver); 127 assertThat(responseObserver.responses()) 128 .containsExactly( 129 response("Here's a DRIP", DRIP), response("Here's a AMERICANO", AMERICANO)); 130 } 131 132 @Test testBidiStreamingGetCoffee()133 public void testBidiStreamingGetCoffee() { 134 StreamObserver<CoffeeRequest> requestObserver = 135 barista.bidiStreamingGetCoffee(responseObserver); 136 requestObserver.onNext(request(POUR_OVER, LATTE)); 137 requestObserver.onNext(request(AMERICANO)); 138 requestObserver.onNext(request(DRIP, ESPRESSO)); 139 requestObserver.onCompleted(); 140 assertThat(responseObserver.responses()) 141 .containsExactly( 142 response("Enjoy!", POUR_OVER, LATTE), 143 response("Enjoy!", AMERICANO), 144 response("Enjoy!", DRIP, ESPRESSO)); 145 } 146 request(CoffeeType... types)147 private CoffeeRequest request(CoffeeType... types) { 148 return CoffeeRequest.newBuilder().addAllType(asList(types)).build(); 149 } 150 response(String message, CoffeeType... types)151 private CoffeeResponse response(String message, CoffeeType... types) { 152 return CoffeeResponse.newBuilder().setMessage(message).addAllCup(asList(types)).build(); 153 } 154 } 155