### Question:
RouteGuideClient { public void recordRoute(List<Feature> features, int numPoints) throws InterruptedException { info("*** RecordRoute"); final CountDownLatch finishLatch = new CountDownLatch(1); StreamObserver<RouteSummary> responseObserver = new StreamObserver<RouteSummary>() { @Override public void onNext(RouteSummary summary) { info("Finished trip with {0} points. Passed {1} features. " + "Travelled {2} meters. It took {3} seconds.", summary.getPointCount(), summary.getFeatureCount(), summary.getDistance(), summary.getElapsedTime()); if (testHelper != null) { testHelper.onMessage(summary); } } @Override public void onError(Throwable t) { warning("RecordRoute Failed: {0}", Status.fromThrowable(t)); if (testHelper != null) { testHelper.onRpcError(t); } finishLatch.countDown(); } @Override public void onCompleted() { info("Finished RecordRoute"); finishLatch.countDown(); } }; StreamObserver<Point> requestObserver = asyncStub.recordRoute(responseObserver); try { for (int i = 0; i < numPoints; ++i) { int index = random.nextInt(features.size()); Point point = features.get(index).getLocation(); info("Visiting point {0}, {1}", RouteGuideUtil.getLatitude(point), RouteGuideUtil.getLongitude(point)); requestObserver.onNext(point); Thread.sleep(random.nextInt(1000) + 500); if (finishLatch.getCount() == 0) { return; } } } catch (RuntimeException e) { requestObserver.onError(e); throw e; } requestObserver.onCompleted(); if (!finishLatch.await(1, TimeUnit.MINUTES)) { warning("recordRoute can not finish within 1 minutes"); } } RouteGuideClient(String host, int port);  RouteGuideClient(ManagedChannelBuilder<?> channelBuilder); void shutdown(); void getFeature(int lat, int lon); void listFeatures(int lowLat, int lowLon, int hiLat, int hiLon); void recordRoute(List<Feature> features, int numPoints); CountDownLatch routeChat(); static void main(String[] args);  }### Answer:
@Test public void recordRoute() throws Exception { client.setRandom(noRandomness); Point point1 = Point.newBuilder().setLatitude(1).setLongitude(1).build(); Point point2 = Point.newBuilder().setLatitude(2).setLongitude(2).build(); Point point3 = Point.newBuilder().setLatitude(3).setLongitude(3).build(); Feature requestFeature1 = Feature.newBuilder().setLocation(point1).build(); Feature requestFeature2 = Feature.newBuilder().setLocation(point2).build(); Feature requestFeature3 = Feature.newBuilder().setLocation(point3).build(); final List<Feature> features = Arrays.asList( requestFeature1, requestFeature2, requestFeature3); final List<Point> pointsDelivered = new ArrayList<>(); final RouteSummary fakeResponse = RouteSummary .newBuilder() .setPointCount(7) .setFeatureCount(8) .setDistance(9) .setElapsedTime(10) .build(); RouteGuideImplBase recordRouteImpl = new RouteGuideImplBase() { @Override public StreamObserver<Point> recordRoute( final StreamObserver<RouteSummary> responseObserver) { StreamObserver<Point> requestObserver = new StreamObserver<Point>() { @Override public void onNext(Point value) { pointsDelivered.add(value); } @Override public void onError(Throwable t) { } @Override public void onCompleted() { responseObserver.onNext(fakeResponse); responseObserver.onCompleted(); } }; return requestObserver; } }; serviceRegistry.addService(recordRouteImpl); client.recordRoute(features, 4); assertEquals( Arrays.asList( requestFeature1.getLocation(), requestFeature2.getLocation(), requestFeature3.getLocation(), requestFeature1.getLocation()), pointsDelivered); verify(testHelper).onMessage(fakeResponse); verify(testHelper, never()).onRpcError(any(Throwable.class)); }