mirror of https://github.com/grpc/grpc-java.git
xds: slightly refactor and improve tests for cluster_manager LB policy (#7773)
This commit is contained in:
parent
32173975e0
commit
ca7f1e4cee
|
|
@ -28,7 +28,6 @@ import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.Iterables;
|
|
||||||
import io.grpc.CallOptions;
|
import io.grpc.CallOptions;
|
||||||
import io.grpc.ConnectivityState;
|
import io.grpc.ConnectivityState;
|
||||||
import io.grpc.EquivalentAddressGroup;
|
import io.grpc.EquivalentAddressGroup;
|
||||||
|
|
@ -147,6 +146,7 @@ public class ClusterManagerLoadBalancerTest {
|
||||||
assertThat(childBalancer3.name).isEqualTo("policy_c");
|
assertThat(childBalancer3.name).isEqualTo("policy_c");
|
||||||
assertThat(childBalancer3.config).isEqualTo(lbConfigInventory.get("childC"));
|
assertThat(childBalancer3.config).isEqualTo(lbConfigInventory.get("childC"));
|
||||||
|
|
||||||
|
// delayed policy_b deletion
|
||||||
fakeClock.forwardTime(
|
fakeClock.forwardTime(
|
||||||
ClusterManagerLoadBalancer.DELAYED_CHILD_DELETION_TIME_MINUTES, TimeUnit.MINUTES);
|
ClusterManagerLoadBalancer.DELAYED_CHILD_DELETION_TIME_MINUTES, TimeUnit.MINUTES);
|
||||||
assertThat(childBalancer2.shutdown).isTrue();
|
assertThat(childBalancer2.shutdown).isTrue();
|
||||||
|
|
@ -176,36 +176,41 @@ public class ClusterManagerLoadBalancerTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void updateBalancingStateFromDeactivatedChildBalancer() {
|
public void ignoreBalancingStateUpdateForDeactivatedChildLbs() {
|
||||||
FakeLoadBalancer balancer = deliverAddressesAndUpdateToRemoveChildPolicy("childA", "policy_a");
|
deliverResolvedAddresses(ImmutableMap.of("childA", "policy_a", "childB", "policy_b"));
|
||||||
|
deliverResolvedAddresses(ImmutableMap.of("childB", "policy_b"));
|
||||||
|
FakeLoadBalancer childBalancer1 = childBalancers.get(0); // policy_a (deactivated)
|
||||||
Subchannel subchannel = mock(Subchannel.class);
|
Subchannel subchannel = mock(Subchannel.class);
|
||||||
balancer.deliverSubchannelState(subchannel, ConnectivityState.READY);
|
childBalancer1.deliverSubchannelState(subchannel, ConnectivityState.READY);
|
||||||
verify(helper, never()).updateBalancingState(
|
verify(helper, never()).updateBalancingState(
|
||||||
eq(ConnectivityState.READY), any(SubchannelPicker.class));
|
eq(ConnectivityState.READY), any(SubchannelPicker.class));
|
||||||
|
|
||||||
deliverResolvedAddresses(ImmutableMap.of("childA", "policy_a"));
|
// reactivate policy_a
|
||||||
|
deliverResolvedAddresses(ImmutableMap.of("childA", "policy_a", "childB", "policy_b"));
|
||||||
verify(helper).updateBalancingState(eq(ConnectivityState.READY), pickerCaptor.capture());
|
verify(helper).updateBalancingState(eq(ConnectivityState.READY), pickerCaptor.capture());
|
||||||
assertThat(pickSubchannel(pickerCaptor.getValue(), "childA").getSubchannel())
|
assertThat(pickSubchannel(pickerCaptor.getValue(), "childA").getSubchannel())
|
||||||
.isEqualTo(subchannel);
|
.isEqualTo(subchannel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void errorPropagation() {
|
public void handleNameResolutionError_beforeChildLbsInstantiated_returnErrorPicker() {
|
||||||
Status error = Status.UNAVAILABLE.withDescription("resolver error");
|
clusterManagerLoadBalancer.handleNameResolutionError(
|
||||||
clusterManagerLoadBalancer.handleNameResolutionError(error);
|
Status.UNAVAILABLE.withDescription("resolver error"));
|
||||||
verify(helper).updateBalancingState(
|
verify(helper).updateBalancingState(
|
||||||
eq(ConnectivityState.TRANSIENT_FAILURE), pickerCaptor.capture());
|
eq(ConnectivityState.TRANSIENT_FAILURE), pickerCaptor.capture());
|
||||||
PickResult result = pickerCaptor.getValue().pickSubchannel(mock(PickSubchannelArgs.class));
|
PickResult result = pickerCaptor.getValue().pickSubchannel(mock(PickSubchannelArgs.class));
|
||||||
assertThat(result.getStatus().getCode()).isEqualTo(Code.UNAVAILABLE);
|
assertThat(result.getStatus().getCode()).isEqualTo(Code.UNAVAILABLE);
|
||||||
assertThat(result.getStatus().getDescription()).isEqualTo("resolver error");
|
assertThat(result.getStatus().getDescription()).isEqualTo("resolver error");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void handleNameResolutionError_afterChildLbsInstantiated_propagateToChildLbs() {
|
||||||
deliverResolvedAddresses(ImmutableMap.of("childA", "policy_a", "childB", "policy_b"));
|
deliverResolvedAddresses(ImmutableMap.of("childA", "policy_a", "childB", "policy_b"));
|
||||||
|
|
||||||
assertThat(childBalancers).hasSize(2);
|
assertThat(childBalancers).hasSize(2);
|
||||||
FakeLoadBalancer childBalancer1 = childBalancers.get(0);
|
FakeLoadBalancer childBalancer1 = childBalancers.get(0);
|
||||||
FakeLoadBalancer childBalancer2 = childBalancers.get(1);
|
FakeLoadBalancer childBalancer2 = childBalancers.get(1);
|
||||||
|
clusterManagerLoadBalancer.handleNameResolutionError(
|
||||||
clusterManagerLoadBalancer.handleNameResolutionError(error);
|
Status.UNAVAILABLE.withDescription("resolver error"));
|
||||||
assertThat(childBalancer1.upstreamError.getCode()).isEqualTo(Code.UNAVAILABLE);
|
assertThat(childBalancer1.upstreamError.getCode()).isEqualTo(Code.UNAVAILABLE);
|
||||||
assertThat(childBalancer1.upstreamError.getDescription()).isEqualTo("resolver error");
|
assertThat(childBalancer1.upstreamError.getDescription()).isEqualTo("resolver error");
|
||||||
assertThat(childBalancer2.upstreamError.getCode()).isEqualTo(Code.UNAVAILABLE);
|
assertThat(childBalancer2.upstreamError.getCode()).isEqualTo(Code.UNAVAILABLE);
|
||||||
|
|
@ -213,44 +218,24 @@ public class ClusterManagerLoadBalancerTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void errorPropagationToDeactivatedChildBalancer() {
|
public void handleNameResolutionError_notPropagateToDeactivatedChildLbs() {
|
||||||
FakeLoadBalancer balancer = deliverAddressesAndUpdateToRemoveChildPolicy("childA", "policy_a");
|
deliverResolvedAddresses(ImmutableMap.of("childA", "policy_a", "childB", "policy_b"));
|
||||||
|
deliverResolvedAddresses(ImmutableMap.of("childB", "policy_b"));
|
||||||
|
FakeLoadBalancer childBalancer1 = childBalancers.get(0); // policy_a (deactivated)
|
||||||
|
FakeLoadBalancer childBalancer2 = childBalancers.get(1); // policy_b
|
||||||
clusterManagerLoadBalancer.handleNameResolutionError(
|
clusterManagerLoadBalancer.handleNameResolutionError(
|
||||||
Status.UNKNOWN.withDescription("unknown error"));
|
Status.UNKNOWN.withDescription("unknown error"));
|
||||||
assertThat(balancer.upstreamError).isNull();
|
assertThat(childBalancer1.upstreamError).isNull();
|
||||||
}
|
assertThat(childBalancer2.upstreamError.getCode()).isEqualTo(Code.UNKNOWN);
|
||||||
|
assertThat(childBalancer2.upstreamError.getDescription()).isEqualTo("unknown error");
|
||||||
private FakeLoadBalancer deliverAddressesAndUpdateToRemoveChildPolicy(
|
|
||||||
String childName, String childPolicyName) {
|
|
||||||
lbConfigInventory.put("childFoo", null);
|
|
||||||
deliverResolvedAddresses(
|
|
||||||
ImmutableMap.of(childName, childPolicyName, "childFoo", "policy_foo"));
|
|
||||||
|
|
||||||
verify(helper, atLeastOnce()).updateBalancingState(
|
|
||||||
eq(ConnectivityState.CONNECTING), any(SubchannelPicker.class));
|
|
||||||
assertThat(childBalancers).hasSize(2);
|
|
||||||
FakeLoadBalancer balancer = childBalancers.get(0);
|
|
||||||
|
|
||||||
deliverResolvedAddresses(ImmutableMap.of("childFoo", "policy_foo"));
|
|
||||||
verify(helper, atLeast(2)).updateBalancingState(
|
|
||||||
eq(ConnectivityState.CONNECTING), any(SubchannelPicker.class));
|
|
||||||
assertThat(Iterables.getOnlyElement(fakeClock.getPendingTasks()).getDelay(TimeUnit.MINUTES))
|
|
||||||
.isEqualTo(ClusterManagerLoadBalancer.DELAYED_CHILD_DELETION_TIME_MINUTES);
|
|
||||||
return balancer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void deliverResolvedAddresses(final Map<String, String> childPolicies) {
|
private void deliverResolvedAddresses(final Map<String, String> childPolicies) {
|
||||||
syncContext.execute(new Runnable() {
|
clusterManagerLoadBalancer.handleResolvedAddresses(
|
||||||
@Override
|
ResolvedAddresses.newBuilder()
|
||||||
public void run() {
|
.setAddresses(Collections.<EquivalentAddressGroup>emptyList())
|
||||||
clusterManagerLoadBalancer
|
.setLoadBalancingPolicyConfig(buildConfig(childPolicies))
|
||||||
.handleResolvedAddresses(
|
.build());
|
||||||
ResolvedAddresses.newBuilder()
|
|
||||||
.setAddresses(Collections.<EquivalentAddressGroup>emptyList())
|
|
||||||
.setLoadBalancingPolicyConfig(buildConfig(childPolicies))
|
|
||||||
.build());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ClusterManagerConfig buildConfig(Map<String, String> childPolicies) {
|
private ClusterManagerConfig buildConfig(Map<String, String> childPolicies) {
|
||||||
|
|
@ -265,7 +250,7 @@ public class ClusterManagerLoadBalancerTest {
|
||||||
return new ClusterManagerConfig(childPolicySelections);
|
return new ClusterManagerConfig(childPolicySelections);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static PickResult pickSubchannel(SubchannelPicker picker, String name) {
|
private static PickResult pickSubchannel(SubchannelPicker picker, String clusterName) {
|
||||||
PickSubchannelArgs args =
|
PickSubchannelArgs args =
|
||||||
new PickSubchannelArgsImpl(
|
new PickSubchannelArgsImpl(
|
||||||
MethodDescriptor.<Void, Void>newBuilder()
|
MethodDescriptor.<Void, Void>newBuilder()
|
||||||
|
|
@ -276,7 +261,7 @@ public class ClusterManagerLoadBalancerTest {
|
||||||
.build(),
|
.build(),
|
||||||
new Metadata(),
|
new Metadata(),
|
||||||
CallOptions.DEFAULT.withOption(
|
CallOptions.DEFAULT.withOption(
|
||||||
XdsNameResolver.CLUSTER_SELECTION_KEY, name));
|
XdsNameResolver.CLUSTER_SELECTION_KEY, clusterName));
|
||||||
return picker.pickSubchannel(args);
|
return picker.pickSubchannel(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue