xds: slightly refactor and improve tests for cluster_manager LB policy (#7773)

This commit is contained in:
Chengyuan Zhang 2021-01-11 10:49:39 -08:00 committed by GitHub
parent 32173975e0
commit ca7f1e4cee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 31 additions and 46 deletions

View File

@ -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);
} }