Search in sources :

Example 1 with UpstreamLocalityStats

use of io.envoyproxy.envoy.api.v2.endpoint.UpstreamLocalityStats in project grpc-java by grpc.

the class LoadReportClientTest method periodicLoadReporting.

@Test
public void periodicLoadReporting() {
    verify(mockLoadReportingService).streamLoadStats(lrsResponseObserverCaptor.capture());
    StreamObserver<LoadStatsResponse> responseObserver = lrsResponseObserverCaptor.getValue();
    StreamObserver<LoadStatsRequest> requestObserver = Iterables.getOnlyElement(lrsRequestObservers);
    verify(requestObserver).onNext(eq(buildInitialRequest()));
    // Management server asks to report loads for cluster1.
    responseObserver.onNext(LoadStatsResponse.newBuilder().addClusters(CLUSTER1).setLoadReportingInterval(Durations.fromSeconds(10L)).build());
    fakeClock.forwardTime(10L, TimeUnit.SECONDS);
    verify(requestObserver, times(2)).onNext(requestCaptor.capture());
    LoadStatsRequest request = requestCaptor.getValue();
    ClusterStats clusterStats = Iterables.getOnlyElement(request.getClusterStatsList());
    assertThat(clusterStats.getClusterName()).isEqualTo(CLUSTER1);
    assertThat(clusterStats.getClusterServiceName()).isEqualTo(EDS_SERVICE_NAME1);
    assertThat(Durations.toSeconds(clusterStats.getLoadReportInterval())).isEqualTo(10L);
    assertThat(Iterables.getOnlyElement(clusterStats.getDroppedRequestsList()).getCategory()).isEqualTo("lb");
    assertThat(Iterables.getOnlyElement(clusterStats.getDroppedRequestsList()).getDroppedCount()).isEqualTo(52L);
    assertThat(clusterStats.getTotalDroppedRequests()).isEqualTo(52L);
    UpstreamLocalityStats localityStats = Iterables.getOnlyElement(clusterStats.getUpstreamLocalityStatsList());
    assertThat(localityStats.getLocality().getRegion()).isEqualTo("region1");
    assertThat(localityStats.getLocality().getZone()).isEqualTo("zone1");
    assertThat(localityStats.getLocality().getSubZone()).isEqualTo("subZone1");
    assertThat(localityStats.getTotalIssuedRequests()).isEqualTo(31L);
    assertThat(localityStats.getTotalSuccessfulRequests()).isEqualTo(0L);
    assertThat(localityStats.getTotalErrorRequests()).isEqualTo(0L);
    assertThat(localityStats.getTotalRequestsInProgress()).isEqualTo(31L);
    fakeClock.forwardTime(10L, TimeUnit.SECONDS);
    verify(requestObserver, times(3)).onNext(requestCaptor.capture());
    request = requestCaptor.getValue();
    clusterStats = Iterables.getOnlyElement(request.getClusterStatsList());
    assertThat(clusterStats.getClusterName()).isEqualTo(CLUSTER1);
    assertThat(clusterStats.getClusterServiceName()).isEqualTo(EDS_SERVICE_NAME1);
    assertThat(Durations.toSeconds(clusterStats.getLoadReportInterval())).isEqualTo(10L);
    assertThat(clusterStats.getDroppedRequestsCount()).isEqualTo(0L);
    assertThat(clusterStats.getTotalDroppedRequests()).isEqualTo(0L);
    localityStats = Iterables.getOnlyElement(clusterStats.getUpstreamLocalityStatsList());
    assertThat(localityStats.getLocality().getRegion()).isEqualTo("region1");
    assertThat(localityStats.getLocality().getZone()).isEqualTo("zone1");
    assertThat(localityStats.getLocality().getSubZone()).isEqualTo("subZone1");
    assertThat(localityStats.getTotalIssuedRequests()).isEqualTo(0L);
    assertThat(localityStats.getTotalSuccessfulRequests()).isEqualTo(0L);
    assertThat(localityStats.getTotalErrorRequests()).isEqualTo(0L);
    assertThat(localityStats.getTotalRequestsInProgress()).isEqualTo(31L);
    // Management server updates the interval of sending load reports, while still asking for
    // loads to cluster1 only.
    responseObserver.onNext(LoadStatsResponse.newBuilder().addClusters(CLUSTER1).setLoadReportingInterval(Durations.fromSeconds(20L)).build());
    fakeClock.forwardTime(10L, TimeUnit.SECONDS);
    verifyNoMoreInteractions(requestObserver);
    fakeClock.forwardTime(10L, TimeUnit.SECONDS);
    verify(requestObserver, times(4)).onNext(requestCaptor.capture());
    request = requestCaptor.getValue();
    clusterStats = Iterables.getOnlyElement(request.getClusterStatsList());
    assertThat(clusterStats.getClusterName()).isEqualTo(CLUSTER1);
    assertThat(clusterStats.getClusterServiceName()).isEqualTo(EDS_SERVICE_NAME1);
    assertThat(Durations.toSeconds(clusterStats.getLoadReportInterval())).isEqualTo(20L);
    assertThat(clusterStats.getDroppedRequestsCount()).isEqualTo(0);
    localityStats = Iterables.getOnlyElement(clusterStats.getUpstreamLocalityStatsList());
    assertThat(localityStats.getLocality().getRegion()).isEqualTo("region1");
    assertThat(localityStats.getLocality().getZone()).isEqualTo("zone1");
    assertThat(localityStats.getLocality().getSubZone()).isEqualTo("subZone1");
    assertThat(localityStats.getTotalIssuedRequests()).isEqualTo(0L);
    assertThat(localityStats.getTotalSuccessfulRequests()).isEqualTo(0L);
    assertThat(localityStats.getTotalErrorRequests()).isEqualTo(0L);
    assertThat(localityStats.getTotalRequestsInProgress()).isEqualTo(31L);
    // Management server asks to report loads for all clusters.
    responseObserver.onNext(LoadStatsResponse.newBuilder().setSendAllClusters(true).setLoadReportingInterval(Durations.fromSeconds(20L)).build());
    fakeClock.forwardTime(20L, TimeUnit.SECONDS);
    verify(requestObserver, times(5)).onNext(requestCaptor.capture());
    request = requestCaptor.getValue();
    assertThat(request.getClusterStatsCount()).isEqualTo(2);
    ClusterStats clusterStats1 = findClusterStats(request.getClusterStatsList(), CLUSTER1);
    assertThat(Durations.toSeconds(clusterStats1.getLoadReportInterval())).isEqualTo(20L);
    assertThat(clusterStats1.getDroppedRequestsCount()).isEqualTo(0L);
    assertThat(clusterStats1.getTotalDroppedRequests()).isEqualTo(0L);
    UpstreamLocalityStats localityStats1 = Iterables.getOnlyElement(clusterStats1.getUpstreamLocalityStatsList());
    assertThat(localityStats1.getLocality().getRegion()).isEqualTo("region1");
    assertThat(localityStats1.getLocality().getZone()).isEqualTo("zone1");
    assertThat(localityStats1.getLocality().getSubZone()).isEqualTo("subZone1");
    assertThat(localityStats1.getTotalIssuedRequests()).isEqualTo(0L);
    assertThat(localityStats1.getTotalSuccessfulRequests()).isEqualTo(0L);
    assertThat(localityStats1.getTotalErrorRequests()).isEqualTo(0L);
    assertThat(localityStats1.getTotalRequestsInProgress()).isEqualTo(31L);
    ClusterStats clusterStats2 = findClusterStats(request.getClusterStatsList(), CLUSTER2);
    assertThat(Durations.toSeconds(clusterStats2.getLoadReportInterval())).isEqualTo(10L + 10L + 20L + 20L);
    assertThat(Iterables.getOnlyElement(clusterStats2.getDroppedRequestsList()).getCategory()).isEqualTo("throttle");
    assertThat(Iterables.getOnlyElement(clusterStats2.getDroppedRequestsList()).getDroppedCount()).isEqualTo(23L);
    assertThat(clusterStats2.getTotalDroppedRequests()).isEqualTo(23L);
    UpstreamLocalityStats localityStats2 = Iterables.getOnlyElement(clusterStats2.getUpstreamLocalityStatsList());
    assertThat(localityStats2.getLocality().getRegion()).isEqualTo("region2");
    assertThat(localityStats2.getLocality().getZone()).isEqualTo("zone2");
    assertThat(localityStats2.getLocality().getSubZone()).isEqualTo("subZone2");
    assertThat(localityStats2.getTotalIssuedRequests()).isEqualTo(45L);
    assertThat(localityStats2.getTotalSuccessfulRequests()).isEqualTo(1L);
    assertThat(localityStats2.getTotalErrorRequests()).isEqualTo(0L);
    assertThat(localityStats2.getTotalRequestsInProgress()).isEqualTo(45L - 1L);
    // Load reports for cluster1 is no longer wanted.
    responseObserver.onNext(LoadStatsResponse.newBuilder().addClusters(CLUSTER2).setLoadReportingInterval(Durations.fromSeconds(10L)).build());
    fakeClock.forwardTime(10L, TimeUnit.SECONDS);
    verify(requestObserver, times(6)).onNext(requestCaptor.capture());
    request = requestCaptor.getValue();
    clusterStats = Iterables.getOnlyElement(request.getClusterStatsList());
    assertThat(clusterStats.getClusterName()).isEqualTo(CLUSTER2);
    assertThat(clusterStats.getClusterServiceName()).isEqualTo(EDS_SERVICE_NAME2);
    assertThat(Durations.toSeconds(clusterStats.getLoadReportInterval())).isEqualTo(10L);
    assertThat(clusterStats.getDroppedRequestsCount()).isEqualTo(0L);
    assertThat(clusterStats.getTotalDroppedRequests()).isEqualTo(0L);
    localityStats = Iterables.getOnlyElement(clusterStats.getUpstreamLocalityStatsList());
    assertThat(localityStats.getLocality().getRegion()).isEqualTo("region2");
    assertThat(localityStats.getLocality().getZone()).isEqualTo("zone2");
    assertThat(localityStats.getLocality().getSubZone()).isEqualTo("subZone2");
    assertThat(localityStats.getTotalIssuedRequests()).isEqualTo(0L);
    assertThat(localityStats.getTotalSuccessfulRequests()).isEqualTo(0L);
    assertThat(localityStats.getTotalErrorRequests()).isEqualTo(0L);
    assertThat(localityStats.getTotalRequestsInProgress()).isEqualTo(44L);
    fakeClock.forwardTime(10L, TimeUnit.SECONDS);
    verify(requestObserver, times(7)).onNext(requestCaptor.capture());
    request = requestCaptor.getValue();
    clusterStats = Iterables.getOnlyElement(request.getClusterStatsList());
    assertThat(clusterStats.getClusterName()).isEqualTo(CLUSTER2);
    assertThat(clusterStats.getClusterServiceName()).isEqualTo(EDS_SERVICE_NAME2);
    assertThat(Durations.toSeconds(clusterStats.getLoadReportInterval())).isEqualTo(10L);
    assertThat(clusterStats.getDroppedRequestsCount()).isEqualTo(0L);
    assertThat(clusterStats.getTotalDroppedRequests()).isEqualTo(0L);
    localityStats = Iterables.getOnlyElement(clusterStats.getUpstreamLocalityStatsList());
    assertThat(localityStats.getLocality().getRegion()).isEqualTo("region2");
    assertThat(localityStats.getLocality().getZone()).isEqualTo("zone2");
    assertThat(localityStats.getLocality().getSubZone()).isEqualTo("subZone2");
    assertThat(localityStats.getTotalIssuedRequests()).isEqualTo(0L);
    assertThat(localityStats.getTotalSuccessfulRequests()).isEqualTo(0L);
    assertThat(localityStats.getTotalErrorRequests()).isEqualTo(0L);
    assertThat(localityStats.getTotalRequestsInProgress()).isEqualTo(44L);
    // Management server asks loads for a cluster that client has no load data.
    responseObserver.onNext(LoadStatsResponse.newBuilder().addClusters("unknown.googleapis.com").setLoadReportingInterval(Durations.fromSeconds(20L)).build());
    fakeClock.forwardTime(20L, TimeUnit.SECONDS);
    verify(requestObserver, times(8)).onNext(requestCaptor.capture());
    assertThat(requestCaptor.getValue().getClusterStatsCount()).isEqualTo(0);
}
Also used : LoadStatsResponse(io.envoyproxy.envoy.service.load_stats.v2.LoadStatsResponse) LoadStatsRequest(io.envoyproxy.envoy.service.load_stats.v2.LoadStatsRequest) UpstreamLocalityStats(io.envoyproxy.envoy.api.v2.endpoint.UpstreamLocalityStats) ClusterStats(io.envoyproxy.envoy.api.v2.endpoint.ClusterStats) Test(org.junit.Test)

Example 2 with UpstreamLocalityStats

use of io.envoyproxy.envoy.api.v2.endpoint.UpstreamLocalityStats in project grpc-java by grpc.

the class LoadReportClientTest method lrsStreamClosedAndRetried.

@Test
public void lrsStreamClosedAndRetried() {
    InOrder inOrder = inOrder(mockLoadReportingService, backoffPolicyProvider, backoffPolicy1, backoffPolicy2);
    inOrder.verify(mockLoadReportingService).streamLoadStats(lrsResponseObserverCaptor.capture());
    StreamObserver<LoadStatsResponse> responseObserver = lrsResponseObserverCaptor.getValue();
    assertThat(lrsRequestObservers).hasSize(1);
    StreamObserver<LoadStatsRequest> requestObserver = lrsRequestObservers.poll();
    // First balancer RPC
    verify(requestObserver).onNext(eq(buildInitialRequest()));
    assertEquals(0, fakeClock.numPendingTasks(LRS_RPC_RETRY_TASK_FILTER));
    // Balancer closes it immediately (erroneously)
    responseObserver.onCompleted();
    // Will start backoff sequence 1 (1s)
    inOrder.verify(backoffPolicyProvider).get();
    inOrder.verify(backoffPolicy1).nextBackoffNanos();
    assertEquals(1, fakeClock.numPendingTasks(LRS_RPC_RETRY_TASK_FILTER));
    // Fast-forward to a moment before the retry
    fakeClock.forwardNanos(TimeUnit.SECONDS.toNanos(1) - 1);
    verifyNoMoreInteractions(mockLoadReportingService);
    // Then time for retry
    fakeClock.forwardNanos(1);
    inOrder.verify(mockLoadReportingService).streamLoadStats(lrsResponseObserverCaptor.capture());
    responseObserver = lrsResponseObserverCaptor.getValue();
    assertThat(lrsRequestObservers).hasSize(1);
    requestObserver = lrsRequestObservers.poll();
    verify(requestObserver).onNext(eq(buildInitialRequest()));
    assertEquals(0, fakeClock.numPendingTasks(LRS_RPC_RETRY_TASK_FILTER));
    // Balancer closes it with an error.
    responseObserver.onError(Status.UNAVAILABLE.asException());
    // Will continue the backoff sequence 1 (10s)
    verifyNoMoreInteractions(backoffPolicyProvider);
    inOrder.verify(backoffPolicy1).nextBackoffNanos();
    assertEquals(1, fakeClock.numPendingTasks(LRS_RPC_RETRY_TASK_FILTER));
    // Fast-forward to a moment before the retry
    fakeClock.forwardNanos(TimeUnit.SECONDS.toNanos(10) - 1);
    verifyNoMoreInteractions(mockLoadReportingService);
    // Then time for retry
    fakeClock.forwardNanos(1);
    inOrder.verify(mockLoadReportingService).streamLoadStats(lrsResponseObserverCaptor.capture());
    responseObserver = lrsResponseObserverCaptor.getValue();
    assertThat(lrsRequestObservers).hasSize(1);
    requestObserver = lrsRequestObservers.poll();
    verify(requestObserver).onNext(eq(buildInitialRequest()));
    assertEquals(0, fakeClock.numPendingTasks(LRS_RPC_RETRY_TASK_FILTER));
    // Balancer sends a response asking for loads of the cluster.
    responseObserver.onNext(LoadStatsResponse.newBuilder().addClusters(CLUSTER1).setLoadReportingInterval(Durations.fromNanos(5L)).build());
    // Then breaks the RPC
    responseObserver.onError(Status.UNAVAILABLE.asException());
    // Will reset the retry sequence and retry immediately, because balancer has responded.
    inOrder.verify(backoffPolicyProvider).get();
    inOrder.verify(mockLoadReportingService).streamLoadStats(lrsResponseObserverCaptor.capture());
    responseObserver = lrsResponseObserverCaptor.getValue();
    assertThat(lrsRequestObservers).hasSize(1);
    requestObserver = lrsRequestObservers.poll();
    verify(requestObserver).onNext(eq(buildInitialRequest()));
    // Fail the retry after spending 4ns
    fakeClock.forwardNanos(4);
    responseObserver.onError(Status.UNAVAILABLE.asException());
    // Will be on the first retry (2s) of backoff sequence 2.
    inOrder.verify(backoffPolicy2).nextBackoffNanos();
    assertEquals(1, fakeClock.numPendingTasks(LRS_RPC_RETRY_TASK_FILTER));
    // Fast-forward to a moment before the retry, the time spent in the last try is deducted.
    fakeClock.forwardNanos(TimeUnit.SECONDS.toNanos(2) - 4 - 1);
    verifyNoMoreInteractions(mockLoadReportingService);
    // Then time for retry
    fakeClock.forwardNanos(1);
    inOrder.verify(mockLoadReportingService).streamLoadStats(lrsResponseObserverCaptor.capture());
    assertThat(lrsRequestObservers).hasSize(1);
    requestObserver = lrsRequestObservers.poll();
    verify(requestObserver).onNext(eq(buildInitialRequest()));
    assertEquals(0, fakeClock.numPendingTasks(LRS_RPC_RETRY_TASK_FILTER));
    // Load reporting back to normal.
    responseObserver = lrsResponseObserverCaptor.getValue();
    responseObserver.onNext(LoadStatsResponse.newBuilder().addClusters(CLUSTER1).setLoadReportingInterval(Durations.fromNanos(10L)).build());
    fakeClock.forwardNanos(10);
    verify(requestObserver, times(2)).onNext(requestCaptor.capture());
    LoadStatsRequest request = requestCaptor.getValue();
    ClusterStats clusterStats = Iterables.getOnlyElement(request.getClusterStatsList());
    assertThat(clusterStats.getClusterName()).isEqualTo(CLUSTER1);
    assertThat(clusterStats.getClusterServiceName()).isEqualTo(EDS_SERVICE_NAME1);
    assertThat(Durations.toSeconds(clusterStats.getLoadReportInterval())).isEqualTo(1L + 10L + 2L);
    assertThat(Iterables.getOnlyElement(clusterStats.getDroppedRequestsList()).getCategory()).isEqualTo("lb");
    assertThat(Iterables.getOnlyElement(clusterStats.getDroppedRequestsList()).getDroppedCount()).isEqualTo(52L);
    assertThat(clusterStats.getTotalDroppedRequests()).isEqualTo(52L);
    UpstreamLocalityStats localityStats = Iterables.getOnlyElement(clusterStats.getUpstreamLocalityStatsList());
    assertThat(localityStats.getLocality().getRegion()).isEqualTo("region1");
    assertThat(localityStats.getLocality().getZone()).isEqualTo("zone1");
    assertThat(localityStats.getLocality().getSubZone()).isEqualTo("subZone1");
    assertThat(localityStats.getTotalIssuedRequests()).isEqualTo(31L);
    assertThat(localityStats.getTotalSuccessfulRequests()).isEqualTo(0L);
    assertThat(localityStats.getTotalErrorRequests()).isEqualTo(0L);
    assertThat(localityStats.getTotalRequestsInProgress()).isEqualTo(31L);
    // Wrapping up
    verify(backoffPolicyProvider, times(2)).get();
    verify(backoffPolicy1, times(2)).nextBackoffNanos();
    verify(backoffPolicy2, times(1)).nextBackoffNanos();
}
Also used : LoadStatsResponse(io.envoyproxy.envoy.service.load_stats.v2.LoadStatsResponse) LoadStatsRequest(io.envoyproxy.envoy.service.load_stats.v2.LoadStatsRequest) UpstreamLocalityStats(io.envoyproxy.envoy.api.v2.endpoint.UpstreamLocalityStats) InOrder(org.mockito.InOrder) ClusterStats(io.envoyproxy.envoy.api.v2.endpoint.ClusterStats) Test(org.junit.Test)

Aggregations

ClusterStats (io.envoyproxy.envoy.api.v2.endpoint.ClusterStats)2 UpstreamLocalityStats (io.envoyproxy.envoy.api.v2.endpoint.UpstreamLocalityStats)2 LoadStatsRequest (io.envoyproxy.envoy.service.load_stats.v2.LoadStatsRequest)2 LoadStatsResponse (io.envoyproxy.envoy.service.load_stats.v2.LoadStatsResponse)2 Test (org.junit.Test)2 InOrder (org.mockito.InOrder)1