use of io.grpc.LoadBalancer.SubchannelPicker in project grpc-java by grpc.
the class CachingRlsLbClientTest method get_updatesLbState.
@Test
public void get_updatesLbState() throws Exception {
setUpRlsLbClient();
InOrder inOrder = inOrder(helper);
RouteLookupRequest routeLookupRequest = RouteLookupRequest.create(ImmutableMap.of("server", "bigtable.googleapis.com", "service-key", "service1", "method-key", "create"));
rlsServerImpl.setLookupTable(ImmutableMap.of(routeLookupRequest, RouteLookupResponse.create(ImmutableList.of("primary.cloudbigtable.googleapis.com"), "header-rls-data-value")));
// valid channel
CachedRouteLookupResponse resp = getInSyncContext(routeLookupRequest);
assertThat(resp.isPending()).isTrue();
fakeTimeProvider.forwardTime(SERVER_LATENCY_MILLIS, TimeUnit.MILLISECONDS);
resp = getInSyncContext(routeLookupRequest);
assertThat(resp.hasData()).isTrue();
ArgumentCaptor<SubchannelPicker> pickerCaptor = ArgumentCaptor.forClass(SubchannelPicker.class);
ArgumentCaptor<ConnectivityState> stateCaptor = ArgumentCaptor.forClass(ConnectivityState.class);
inOrder.verify(helper, times(2)).updateBalancingState(stateCaptor.capture(), pickerCaptor.capture());
assertThat(new HashSet<>(pickerCaptor.getAllValues())).hasSize(1);
assertThat(stateCaptor.getAllValues()).containsExactly(ConnectivityState.CONNECTING, ConnectivityState.READY);
Metadata headers = new Metadata();
PickResult pickResult = pickerCaptor.getValue().pickSubchannel(new PickSubchannelArgsImpl(TestMethodDescriptors.voidMethod().toBuilder().setFullMethodName("service1/create").build(), headers, CallOptions.DEFAULT));
assertThat(pickResult.getStatus().isOk()).isTrue();
assertThat(pickResult.getSubchannel()).isNotNull();
assertThat(headers.get(RLS_DATA_KEY)).isEqualTo("header-rls-data-value");
// move backoff further back to only test error behavior
fakeBackoffProvider.nextPolicy = createBackoffPolicy(100, TimeUnit.MILLISECONDS);
// try to get invalid
RouteLookupRequest invalidRouteLookupRequest = RouteLookupRequest.create(ImmutableMap.<String, String>of());
CachedRouteLookupResponse errorResp = getInSyncContext(invalidRouteLookupRequest);
assertThat(errorResp.isPending()).isTrue();
fakeTimeProvider.forwardTime(SERVER_LATENCY_MILLIS, TimeUnit.MILLISECONDS);
errorResp = getInSyncContext(invalidRouteLookupRequest);
assertThat(errorResp.hasError()).isTrue();
// Channel is still READY because the subchannel for method /service1/create is still READY.
// Method /doesn/exists will use fallback child balancer and fail immediately.
inOrder.verify(helper).updateBalancingState(eq(ConnectivityState.READY), pickerCaptor.capture());
pickResult = pickerCaptor.getValue().pickSubchannel(new PickSubchannelArgsImpl(TestMethodDescriptors.voidMethod().toBuilder().setFullMethodName("doesn/exists").build(), headers, CallOptions.DEFAULT));
assertThat(pickResult.getStatus().getCode()).isEqualTo(Code.UNAVAILABLE);
assertThat(pickResult.getStatus().getDescription()).isEqualTo("fallback not available");
}
use of io.grpc.LoadBalancer.SubchannelPicker in project grpc-java by grpc.
the class ClusterManagerLoadBalancerTest method handleResolvedAddressesUpdatesChannelPicker.
@Test
public void handleResolvedAddressesUpdatesChannelPicker() {
deliverResolvedAddresses(ImmutableMap.of("childA", "policy_a", "childB", "policy_b"));
verify(helper, atLeastOnce()).updateBalancingState(eq(ConnectivityState.CONNECTING), pickerCaptor.capture());
SubchannelPicker picker = pickerCaptor.getValue();
assertThat(pickSubchannel(picker, "childA")).isEqualTo(PickResult.withNoResult());
assertThat(pickSubchannel(picker, "childB")).isEqualTo(PickResult.withNoResult());
assertThat(childBalancers).hasSize(2);
FakeLoadBalancer childBalancer1 = childBalancers.get(0);
FakeLoadBalancer childBalancer2 = childBalancers.get(1);
assertThat(childBalancer1.name).isEqualTo("policy_a");
assertThat(childBalancer2.name).isEqualTo("policy_b");
assertThat(childBalancer1.config).isEqualTo(lbConfigInventory.get("childA"));
assertThat(childBalancer2.config).isEqualTo(lbConfigInventory.get("childB"));
// Receive an updated config.
deliverResolvedAddresses(ImmutableMap.of("childA", "policy_a", "childC", "policy_c"));
verify(helper, atLeast(2)).updateBalancingState(eq(ConnectivityState.CONNECTING), pickerCaptor.capture());
picker = pickerCaptor.getValue();
assertThat(pickSubchannel(picker, "childA")).isEqualTo(PickResult.withNoResult());
assertThat(pickSubchannel(picker, "childC")).isEqualTo(PickResult.withNoResult());
Status status = pickSubchannel(picker, "childB").getStatus();
assertThat(status.getCode()).isEqualTo(Code.UNAVAILABLE);
assertThat(status.getDescription()).isEqualTo("CDS encountered error: unable to find available subchannel for cluster childB");
assertThat(fakeClock.numPendingTasks()).isEqualTo(// (delayed) shutdown because "childB" is removed
1);
assertThat(childBalancer1.shutdown).isFalse();
assertThat(childBalancer2.shutdown).isFalse();
assertThat(childBalancers).hasSize(3);
FakeLoadBalancer childBalancer3 = childBalancers.get(2);
assertThat(childBalancer3.name).isEqualTo("policy_c");
assertThat(childBalancer3.config).isEqualTo(lbConfigInventory.get("childC"));
// delayed policy_b deletion
fakeClock.forwardTime(ClusterManagerLoadBalancer.DELAYED_CHILD_DELETION_TIME_MINUTES, TimeUnit.MINUTES);
assertThat(childBalancer2.shutdown).isTrue();
}
use of io.grpc.LoadBalancer.SubchannelPicker in project grpc-java by grpc.
the class LeastRequestLoadBalancerTest method subchannelStateIsolation.
@Test
public void subchannelStateIsolation() throws Exception {
Iterator<Subchannel> subchannelIterator = subchannels.values().iterator();
Subchannel sc1 = subchannelIterator.next();
Subchannel sc2 = subchannelIterator.next();
Subchannel sc3 = subchannelIterator.next();
loadBalancer.handleResolvedAddresses(ResolvedAddresses.newBuilder().setAddresses(servers).setAttributes(Attributes.EMPTY).build());
verify(sc1, times(1)).requestConnection();
verify(sc2, times(1)).requestConnection();
verify(sc3, times(1)).requestConnection();
deliverSubchannelState(sc1, ConnectivityStateInfo.forNonError(READY));
deliverSubchannelState(sc2, ConnectivityStateInfo.forNonError(READY));
deliverSubchannelState(sc3, ConnectivityStateInfo.forNonError(READY));
deliverSubchannelState(sc2, ConnectivityStateInfo.forNonError(IDLE));
deliverSubchannelState(sc3, ConnectivityStateInfo.forTransientFailure(Status.UNAVAILABLE));
verify(mockHelper, times(6)).updateBalancingState(stateCaptor.capture(), pickerCaptor.capture());
Iterator<ConnectivityState> stateIterator = stateCaptor.getAllValues().iterator();
Iterator<SubchannelPicker> pickers = pickerCaptor.getAllValues().iterator();
// The picker is incrementally updated as subchannels become READY
assertEquals(CONNECTING, stateIterator.next());
assertThat(pickers.next()).isInstanceOf(EmptyPicker.class);
assertEquals(READY, stateIterator.next());
assertThat(getList(pickers.next())).containsExactly(sc1);
assertEquals(READY, stateIterator.next());
assertThat(getList(pickers.next())).containsExactly(sc1, sc2);
assertEquals(READY, stateIterator.next());
assertThat(getList(pickers.next())).containsExactly(sc1, sc2, sc3);
// The IDLE subchannel is dropped from the picker, but a reconnection is requested
assertEquals(READY, stateIterator.next());
assertThat(getList(pickers.next())).containsExactly(sc1, sc3);
verify(sc2, times(2)).requestConnection();
// The failing subchannel is dropped from the picker, with no requested reconnect
assertEquals(READY, stateIterator.next());
assertThat(getList(pickers.next())).containsExactly(sc1);
verify(sc3, times(1)).requestConnection();
assertThat(stateIterator.hasNext()).isFalse();
assertThat(pickers.hasNext()).isFalse();
}
use of io.grpc.LoadBalancer.SubchannelPicker in project grpc-java by grpc.
the class LeastRequestLoadBalancerTest method pickAfterResolvedUpdatedHosts.
@Test
public void pickAfterResolvedUpdatedHosts() throws Exception {
Subchannel removedSubchannel = mock(Subchannel.class);
Subchannel oldSubchannel = mock(Subchannel.class);
Subchannel newSubchannel = mock(Subchannel.class);
Attributes.Key<String> key = Attributes.Key.create("check-that-it-is-propagated");
FakeSocketAddress removedAddr = new FakeSocketAddress("removed");
EquivalentAddressGroup removedEag = new EquivalentAddressGroup(removedAddr);
FakeSocketAddress oldAddr = new FakeSocketAddress("old");
EquivalentAddressGroup oldEag1 = new EquivalentAddressGroup(oldAddr);
EquivalentAddressGroup oldEag2 = new EquivalentAddressGroup(oldAddr, Attributes.newBuilder().set(key, "oldattr").build());
FakeSocketAddress newAddr = new FakeSocketAddress("new");
EquivalentAddressGroup newEag = new EquivalentAddressGroup(newAddr, Attributes.newBuilder().set(key, "newattr").build());
subchannels.put(Collections.singletonList(removedEag), removedSubchannel);
subchannels.put(Collections.singletonList(oldEag1), oldSubchannel);
subchannels.put(Collections.singletonList(newEag), newSubchannel);
List<EquivalentAddressGroup> currentServers = Lists.newArrayList(removedEag, oldEag1);
InOrder inOrder = inOrder(mockHelper);
loadBalancer.handleResolvedAddresses(ResolvedAddresses.newBuilder().setAddresses(currentServers).setAttributes(affinity).build());
inOrder.verify(mockHelper).updateBalancingState(eq(CONNECTING), pickerCaptor.capture());
deliverSubchannelState(removedSubchannel, ConnectivityStateInfo.forNonError(READY));
deliverSubchannelState(oldSubchannel, ConnectivityStateInfo.forNonError(READY));
inOrder.verify(mockHelper, times(2)).updateBalancingState(eq(READY), pickerCaptor.capture());
SubchannelPicker picker = pickerCaptor.getValue();
assertThat(getList(picker)).containsExactly(removedSubchannel, oldSubchannel);
verify(removedSubchannel, times(1)).requestConnection();
verify(oldSubchannel, times(1)).requestConnection();
assertThat(loadBalancer.getSubchannels()).containsExactly(removedSubchannel, oldSubchannel);
// This time with Attributes
List<EquivalentAddressGroup> latestServers = Lists.newArrayList(oldEag2, newEag);
loadBalancer.handleResolvedAddresses(ResolvedAddresses.newBuilder().setAddresses(latestServers).setAttributes(affinity).build());
verify(newSubchannel, times(1)).requestConnection();
verify(oldSubchannel, times(1)).updateAddresses(Arrays.asList(oldEag2));
verify(removedSubchannel, times(1)).shutdown();
deliverSubchannelState(removedSubchannel, ConnectivityStateInfo.forNonError(SHUTDOWN));
deliverSubchannelState(newSubchannel, ConnectivityStateInfo.forNonError(READY));
assertThat(loadBalancer.getSubchannels()).containsExactly(oldSubchannel, newSubchannel);
verify(mockHelper, times(3)).createSubchannel(any(CreateSubchannelArgs.class));
inOrder.verify(mockHelper, times(2)).updateBalancingState(eq(READY), pickerCaptor.capture());
picker = pickerCaptor.getValue();
assertThat(getList(picker)).containsExactly(oldSubchannel, newSubchannel);
// test going from non-empty to empty
loadBalancer.handleResolvedAddresses(ResolvedAddresses.newBuilder().setAddresses(Collections.<EquivalentAddressGroup>emptyList()).setAttributes(affinity).build());
inOrder.verify(mockHelper).updateBalancingState(eq(TRANSIENT_FAILURE), pickerCaptor.capture());
assertEquals(PickResult.withNoResult(), pickerCaptor.getValue().pickSubchannel(mockArgs));
verifyNoMoreInteractions(mockHelper);
}
use of io.grpc.LoadBalancer.SubchannelPicker in project grpc-java by grpc.
the class LeastRequestLoadBalancerTest method pickerEmptyList.
@Test
public void pickerEmptyList() throws Exception {
SubchannelPicker picker = new EmptyPicker(Status.UNKNOWN);
assertEquals(null, picker.pickSubchannel(mockArgs).getSubchannel());
assertEquals(Status.UNKNOWN, picker.pickSubchannel(mockArgs).getStatus());
}
Aggregations