use of io.grpc.LoadBalancer.SubchannelPicker in project grpc-java by grpc.
the class LbPolicyConfigurationTest method updateBalancingState_triggersListener.
@Test
public void updateBalancingState_triggersListener() {
ChildPolicyWrapper childPolicyWrapper = factory.createOrGet("foo.google.com");
ChildPolicyReportingHelper childPolicyReportingHelper = childPolicyWrapper.getHelper();
SubchannelPicker childPicker = mock(SubchannelPicker.class);
childPolicyReportingHelper.updateBalancingState(ConnectivityState.READY, childPicker);
verify(childLbStatusListener).onStatusChanged(ConnectivityState.READY);
assertThat(childPolicyWrapper.getPicker()).isEqualTo(childPicker);
// picker governs childPickers will be reported to parent LB
verify(helper).updateBalancingState(ConnectivityState.READY, picker);
}
use of io.grpc.LoadBalancer.SubchannelPicker in project grpc-java by grpc.
the class RlsLoadBalancerTest method lb_working_withoutDefaultTarget.
@Test
public void lb_working_withoutDefaultTarget() throws Exception {
defaultTarget = "";
deliverResolvedAddresses();
InOrder inOrder = inOrder(helper);
inOrder.verify(helper).updateBalancingState(eq(ConnectivityState.CONNECTING), pickerCaptor.capture());
SubchannelPicker picker = pickerCaptor.getValue();
Metadata headers = new Metadata();
PickResult res = picker.pickSubchannel(new PickSubchannelArgsImpl(fakeSearchMethod, headers, CallOptions.DEFAULT));
inOrder.verify(helper).createSubchannel(any(CreateSubchannelArgs.class));
inOrder.verify(helper).updateBalancingState(eq(ConnectivityState.CONNECTING), any(SubchannelPicker.class));
inOrder.verifyNoMoreInteractions();
assertThat(res.getStatus().isOk()).isTrue();
assertThat(subchannels).hasSize(1);
FakeSubchannel searchSubchannel = subchannels.getLast();
searchSubchannel.updateState(ConnectivityStateInfo.forNonError(ConnectivityState.READY));
inOrder.verify(helper).updateBalancingState(eq(ConnectivityState.READY), pickerCaptor.capture());
inOrder.verifyNoMoreInteractions();
assertThat(subchannelIsReady(res.getSubchannel())).isTrue();
assertThat(res.getSubchannel().getAddresses()).isEqualTo(searchSubchannel.getAddresses());
assertThat(res.getSubchannel().getAttributes()).isEqualTo(searchSubchannel.getAttributes());
// rescue should be pending status although the overall channel state is READY
picker = pickerCaptor.getValue();
res = picker.pickSubchannel(new PickSubchannelArgsImpl(fakeRescueMethod, headers, CallOptions.DEFAULT));
inOrder.verify(helper).createSubchannel(any(CreateSubchannelArgs.class));
// other rls picker itself is ready due to first channel.
inOrder.verify(helper).updateBalancingState(eq(ConnectivityState.READY), pickerCaptor.capture());
inOrder.verifyNoMoreInteractions();
assertThat(res.getStatus().isOk()).isTrue();
assertThat(subchannelIsReady(res.getSubchannel())).isFalse();
assertThat(subchannels).hasSize(2);
FakeSubchannel rescueSubchannel = subchannels.getLast();
// search subchannel is down, rescue subchannel is still connecting
searchSubchannel.updateState(ConnectivityStateInfo.forTransientFailure(Status.NOT_FOUND));
inOrder.verify(helper).updateBalancingState(eq(ConnectivityState.CONNECTING), pickerCaptor.capture());
rescueSubchannel.updateState(ConnectivityStateInfo.forNonError(ConnectivityState.READY));
inOrder.verify(helper).updateBalancingState(eq(ConnectivityState.READY), pickerCaptor.capture());
// search method will fail because there is no fallback target.
picker = pickerCaptor.getValue();
res = picker.pickSubchannel(new PickSubchannelArgsImpl(fakeSearchMethod, headers, CallOptions.DEFAULT));
assertThat(res.getStatus().isOk()).isFalse();
assertThat(subchannelIsReady(res.getSubchannel())).isFalse();
res = picker.pickSubchannel(new PickSubchannelArgsImpl(fakeRescueMethod, headers, CallOptions.DEFAULT));
assertThat(subchannelIsReady(res.getSubchannel())).isTrue();
assertThat(res.getSubchannel().getAddresses()).isEqualTo(rescueSubchannel.getAddresses());
assertThat(res.getSubchannel().getAttributes()).isEqualTo(rescueSubchannel.getAttributes());
// all channels are failed
rescueSubchannel.updateState(ConnectivityStateInfo.forTransientFailure(Status.NOT_FOUND));
inOrder.verify(helper).updateBalancingState(eq(ConnectivityState.TRANSIENT_FAILURE), pickerCaptor.capture());
inOrder.verifyNoMoreInteractions();
}
use of io.grpc.LoadBalancer.SubchannelPicker in project grpc-java by grpc.
the class WeightedTargetLoadBalancerTest method balancingStateUpdatedFromChildBalancers.
@Test
public void balancingStateUpdatedFromChildBalancers() {
Map<String, WeightedPolicySelection> targets = ImmutableMap.of(// {foo, 10, config0}
"target0", weightedLbConfig0, // {bar, 20, config1}
"target1", weightedLbConfig1, // {bar, 30, config2}
"target2", weightedLbConfig2, // {foo, 40, config3}
"target3", weightedLbConfig3);
weightedTargetLb.handleResolvedAddresses(ResolvedAddresses.newBuilder().setAddresses(ImmutableList.<EquivalentAddressGroup>of()).setLoadBalancingPolicyConfig(new WeightedTargetConfig(targets)).build());
verify(helper).updateBalancingState(eq(CONNECTING), eq(BUFFER_PICKER));
// Subchannels to be created for each child balancer.
final SubchannelPicker[] subchannelPickers = new SubchannelPicker[] { mock(SubchannelPicker.class), mock(SubchannelPicker.class), mock(SubchannelPicker.class), mock(SubchannelPicker.class) };
final SubchannelPicker[] failurePickers = new SubchannelPicker[] { new ErrorPicker(Status.CANCELLED), new ErrorPicker(Status.ABORTED), new ErrorPicker(Status.DATA_LOSS), new ErrorPicker(Status.DATA_LOSS) };
ArgumentCaptor<SubchannelPicker> pickerCaptor = ArgumentCaptor.forClass(null);
// One child balancer goes to TRANSIENT_FAILURE.
childHelpers.get(1).updateBalancingState(TRANSIENT_FAILURE, failurePickers[1]);
verify(helper, never()).updateBalancingState(eq(TRANSIENT_FAILURE), any(SubchannelPicker.class));
verify(helper, times(2)).updateBalancingState(eq(CONNECTING), eq(BUFFER_PICKER));
// Another child balancer goes to READY.
childHelpers.get(2).updateBalancingState(READY, subchannelPickers[2]);
verify(helper).updateBalancingState(eq(READY), pickerCaptor.capture());
assertThat(pickerCaptor.getValue()).isInstanceOf(WeightedRandomPicker.class);
WeightedRandomPicker overallPicker = (WeightedRandomPicker) pickerCaptor.getValue();
assertThat(overallPicker.weightedChildPickers).containsExactly(new WeightedChildPicker(weights[2], subchannelPickers[2]));
// Another child balancer goes to READY.
childHelpers.get(3).updateBalancingState(READY, subchannelPickers[3]);
verify(helper, times(2)).updateBalancingState(eq(READY), pickerCaptor.capture());
overallPicker = (WeightedRandomPicker) pickerCaptor.getValue();
assertThat(overallPicker.weightedChildPickers).containsExactly(new WeightedChildPicker(weights[2], subchannelPickers[2]), new WeightedChildPicker(weights[3], subchannelPickers[3]));
// Another child balancer goes to READY.
childHelpers.get(0).updateBalancingState(READY, subchannelPickers[0]);
verify(helper, times(3)).updateBalancingState(eq(READY), pickerCaptor.capture());
overallPicker = (WeightedRandomPicker) pickerCaptor.getValue();
assertThat(overallPicker.weightedChildPickers).containsExactly(new WeightedChildPicker(weights[0], subchannelPickers[0]), new WeightedChildPicker(weights[2], subchannelPickers[2]), new WeightedChildPicker(weights[3], subchannelPickers[3]));
// One of READY child balancers goes to TRANSIENT_FAILURE.
childHelpers.get(2).updateBalancingState(TRANSIENT_FAILURE, failurePickers[2]);
verify(helper, times(4)).updateBalancingState(eq(READY), pickerCaptor.capture());
overallPicker = (WeightedRandomPicker) pickerCaptor.getValue();
assertThat(overallPicker.weightedChildPickers).containsExactly(new WeightedChildPicker(weights[0], subchannelPickers[0]), new WeightedChildPicker(weights[3], subchannelPickers[3]));
// All child balancers go to TRANSIENT_FAILURE.
childHelpers.get(3).updateBalancingState(TRANSIENT_FAILURE, failurePickers[3]);
childHelpers.get(0).updateBalancingState(TRANSIENT_FAILURE, failurePickers[0]);
verify(helper).updateBalancingState(eq(TRANSIENT_FAILURE), pickerCaptor.capture());
overallPicker = (WeightedRandomPicker) pickerCaptor.getValue();
assertThat(overallPicker.weightedChildPickers).containsExactly(new WeightedChildPicker(weights[0], failurePickers[0]), new WeightedChildPicker(weights[1], failurePickers[1]), new WeightedChildPicker(weights[2], failurePickers[2]), new WeightedChildPicker(weights[3], failurePickers[3]));
}
use of io.grpc.LoadBalancer.SubchannelPicker in project grpc-java by grpc.
the class WeightedTargetLoadBalancerTest method handleNameResolutionError.
@Test
public void handleNameResolutionError() {
ArgumentCaptor<SubchannelPicker> pickerCaptor = ArgumentCaptor.forClass(null);
ArgumentCaptor<Status> statusCaptor = ArgumentCaptor.forClass(null);
// Error before any child balancer created.
weightedTargetLb.handleNameResolutionError(Status.DATA_LOSS);
verify(helper).updateBalancingState(eq(TRANSIENT_FAILURE), pickerCaptor.capture());
PickResult pickResult = pickerCaptor.getValue().pickSubchannel(mock(PickSubchannelArgs.class));
assertThat(pickResult.getStatus().getCode()).isEqualTo(Status.Code.DATA_LOSS);
// Child configs updated.
Map<String, WeightedPolicySelection> targets = ImmutableMap.of(// {foo, 10, config0}
"target0", weightedLbConfig0, // {bar, 20, config1}
"target1", weightedLbConfig1, // {bar, 30, config2}
"target2", weightedLbConfig2, // {foo, 40, config3}
"target3", weightedLbConfig3);
weightedTargetLb.handleResolvedAddresses(ResolvedAddresses.newBuilder().setAddresses(ImmutableList.<EquivalentAddressGroup>of()).setLoadBalancingPolicyConfig(new WeightedTargetConfig(targets)).build());
verify(helper).updateBalancingState(eq(CONNECTING), eq(BUFFER_PICKER));
// Error after child balancers created.
weightedTargetLb.handleNameResolutionError(Status.ABORTED);
for (LoadBalancer childBalancer : childBalancers) {
verify(childBalancer).handleNameResolutionError(statusCaptor.capture());
assertThat(statusCaptor.getValue().getCode()).isEqualTo(Status.Code.ABORTED);
}
}
use of io.grpc.LoadBalancer.SubchannelPicker in project grpc-java by grpc.
the class ManagedChannelImplTest method subtestFailRpcFromBalancer.
private void subtestFailRpcFromBalancer(boolean waitForReady, boolean drop, boolean shouldFail) {
createChannel();
// This call will be buffered by the channel, thus involve delayed transport
CallOptions callOptions = CallOptions.DEFAULT;
if (waitForReady) {
callOptions = callOptions.withWaitForReady();
} else {
callOptions = callOptions.withoutWaitForReady();
}
ClientCall<String, Integer> call1 = channel.newCall(method, callOptions);
call1.start(mockCallListener, new Metadata());
SubchannelPicker picker = mock(SubchannelPicker.class);
Status status = Status.UNAVAILABLE.withDescription("for test");
when(picker.pickSubchannel(any(PickSubchannelArgs.class))).thenReturn(drop ? PickResult.withDrop(status) : PickResult.withError(status));
updateBalancingStateSafely(helper, READY, picker);
executor.runDueTasks();
if (shouldFail) {
verify(mockCallListener).onClose(same(status), any(Metadata.class));
} else {
verifyNoInteractions(mockCallListener);
}
// This call doesn't involve delayed transport
ClientCall<String, Integer> call2 = channel.newCall(method, callOptions);
call2.start(mockCallListener2, new Metadata());
executor.runDueTasks();
if (shouldFail) {
verify(mockCallListener2).onClose(same(status), any(Metadata.class));
} else {
verifyNoInteractions(mockCallListener2);
}
}
Aggregations