|
16 | 16 | import io.envoyproxy.controlplane.cache.TestResources;
|
17 | 17 | import io.envoyproxy.controlplane.cache.Watch;
|
18 | 18 | import io.envoyproxy.controlplane.cache.WatchCancelledException;
|
| 19 | +import io.envoyproxy.controlplane.server.exception.RequestException; |
19 | 20 | import io.envoyproxy.envoy.api.v2.Cluster;
|
20 | 21 | import io.envoyproxy.envoy.api.v2.ClusterDiscoveryServiceGrpc;
|
21 | 22 | import io.envoyproxy.envoy.api.v2.ClusterDiscoveryServiceGrpc.ClusterDiscoveryServiceStub;
|
|
56 | 57 | import java.util.concurrent.atomic.AtomicReference;
|
57 | 58 | import java.util.function.Consumer;
|
58 | 59 | import java.util.stream.Collectors;
|
| 60 | + |
59 | 61 | import org.assertj.core.api.Condition;
|
60 | 62 | import org.junit.Rule;
|
61 | 63 | import org.junit.Test;
|
@@ -864,6 +866,90 @@ public Watch createWatch(boolean ads, DiscoveryRequest request, Set<String> know
|
864 | 866 | assertThat(callbacks.streamResponseCount).hasValue(1);
|
865 | 867 | }
|
866 | 868 |
|
| 869 | + @Test |
| 870 | + public void testCallbacksRequestException() throws InterruptedException { |
| 871 | + MockDiscoveryServerCallbacks callbacks = new MockDiscoveryServerCallbacks() { |
| 872 | + @Override |
| 873 | + public void onStreamRequest(long streamId, DiscoveryRequest request) { |
| 874 | + super.onStreamRequest(streamId, request); |
| 875 | + throw new RequestException(Status.INVALID_ARGUMENT.withDescription("request not valid")); |
| 876 | + } |
| 877 | + }; |
| 878 | + |
| 879 | + MockConfigWatcher configWatcher = new MockConfigWatcher(false, createResponses()); |
| 880 | + DiscoveryServer server = new DiscoveryServer(callbacks, configWatcher); |
| 881 | + |
| 882 | + grpcServer.getServiceRegistry().addService(server.getAggregatedDiscoveryServiceImpl()); |
| 883 | + AggregatedDiscoveryServiceStub stub = AggregatedDiscoveryServiceGrpc.newStub(grpcServer.getChannel()); |
| 884 | + |
| 885 | + MockDiscoveryResponseObserver responseObserver = new MockDiscoveryResponseObserver(); |
| 886 | + StreamObserver<DiscoveryRequest> requestObserver = stub.streamAggregatedResources(responseObserver); |
| 887 | + |
| 888 | + requestObserver.onNext(DiscoveryRequest.newBuilder() |
| 889 | + .setNode(NODE) |
| 890 | + .setTypeUrl(Resources.LISTENER_TYPE_URL) |
| 891 | + .build()); |
| 892 | + |
| 893 | + if (!responseObserver.errorLatch.await(1, TimeUnit.SECONDS) || responseObserver.completed.get()) { |
| 894 | + fail(format("failed to error before timeout, completed = %b", responseObserver.completed.get())); |
| 895 | + } |
| 896 | + |
| 897 | + callbacks.assertThatNoErrors(); |
| 898 | + |
| 899 | + assertThat(responseObserver.errorException).isInstanceOfSatisfying(StatusRuntimeException.class, ex -> { |
| 900 | + assertThat(ex.getStatus().getCode()).isEqualTo(Status.Code.INVALID_ARGUMENT); |
| 901 | + assertThat(ex.getStatus().getDescription()).isEqualTo("request not valid"); |
| 902 | + }); |
| 903 | + |
| 904 | + assertThat(callbacks.streamCloseCount).hasValue(0); |
| 905 | + assertThat(callbacks.streamCloseWithErrorCount).hasValue(0); |
| 906 | + assertThat(callbacks.streamOpenCount).hasValue(1); |
| 907 | + assertThat(callbacks.streamRequestCount).hasValue(1); |
| 908 | + assertThat(callbacks.streamResponseCount).hasValue(0); |
| 909 | + } |
| 910 | + |
| 911 | + @Test |
| 912 | + public void testCallbacksOtherStatusException() throws InterruptedException { |
| 913 | + MockDiscoveryServerCallbacks callbacks = new MockDiscoveryServerCallbacks() { |
| 914 | + @Override |
| 915 | + public void onStreamRequest(long streamId, DiscoveryRequest request) { |
| 916 | + super.onStreamRequest(streamId, request); |
| 917 | + throw new StatusRuntimeException(Status.INVALID_ARGUMENT.withDescription("request not valid")); |
| 918 | + } |
| 919 | + }; |
| 920 | + |
| 921 | + MockConfigWatcher configWatcher = new MockConfigWatcher(false, createResponses()); |
| 922 | + DiscoveryServer server = new DiscoveryServer(callbacks, configWatcher); |
| 923 | + |
| 924 | + grpcServer.getServiceRegistry().addService(server.getAggregatedDiscoveryServiceImpl()); |
| 925 | + AggregatedDiscoveryServiceStub stub = AggregatedDiscoveryServiceGrpc.newStub(grpcServer.getChannel()); |
| 926 | + |
| 927 | + MockDiscoveryResponseObserver responseObserver = new MockDiscoveryResponseObserver(); |
| 928 | + StreamObserver<DiscoveryRequest> requestObserver = stub.streamAggregatedResources(responseObserver); |
| 929 | + |
| 930 | + requestObserver.onNext(DiscoveryRequest.newBuilder() |
| 931 | + .setNode(NODE) |
| 932 | + .setTypeUrl(Resources.LISTENER_TYPE_URL) |
| 933 | + .build()); |
| 934 | + |
| 935 | + if (!responseObserver.errorLatch.await(1, TimeUnit.SECONDS) || responseObserver.completed.get()) { |
| 936 | + fail(format("failed to error before timeout, completed = %b", responseObserver.completed.get())); |
| 937 | + } |
| 938 | + |
| 939 | + callbacks.assertThatNoErrors(); |
| 940 | + |
| 941 | + assertThat(responseObserver.errorException).isInstanceOfSatisfying(StatusRuntimeException.class, ex -> { |
| 942 | + assertThat(ex.getStatus().getCode()).isEqualTo(Status.Code.UNKNOWN); |
| 943 | + assertThat(ex.getStatus().getDescription()).isNull(); |
| 944 | + }); |
| 945 | + |
| 946 | + assertThat(callbacks.streamCloseCount).hasValue(0); |
| 947 | + assertThat(callbacks.streamCloseWithErrorCount).hasValue(0); |
| 948 | + assertThat(callbacks.streamOpenCount).hasValue(1); |
| 949 | + assertThat(callbacks.streamRequestCount).hasValue(1); |
| 950 | + assertThat(callbacks.streamResponseCount).hasValue(0); |
| 951 | + } |
| 952 | + |
867 | 953 | private static Table<String, String, Collection<? extends Message>> createResponses() {
|
868 | 954 | return ImmutableTable.<String, String, Collection<? extends Message>>builder()
|
869 | 955 | .put(Resources.CLUSTER_TYPE_URL, VERSION, ImmutableList.of(CLUSTER))
|
@@ -1005,6 +1091,7 @@ private static class MockDiscoveryResponseObserver implements StreamObserver<Dis
|
1005 | 1091 | private final AtomicInteger nonce = new AtomicInteger();
|
1006 | 1092 | private final Collection<DiscoveryResponse> responses = new LinkedList<>();
|
1007 | 1093 |
|
| 1094 | + private Throwable errorException; |
1008 | 1095 | private boolean sendError = false;
|
1009 | 1096 |
|
1010 | 1097 | void assertThatNoErrors() {
|
@@ -1054,6 +1141,7 @@ public void onNext(DiscoveryResponse value) {
|
1054 | 1141 | @Override
|
1055 | 1142 | public void onError(Throwable t) {
|
1056 | 1143 | error.set(true);
|
| 1144 | + errorException = t; |
1057 | 1145 | errorLatch.countDown();
|
1058 | 1146 | }
|
1059 | 1147 |
|
|
0 commit comments