aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Polden <mpolden@mpolden.no>2024-02-28 16:31:11 +0100
committerGitHub <noreply@github.com>2024-02-28 16:31:11 +0100
commit180e79e309b9903304dc68f9ff560053ce039a36 (patch)
tree77f4248c0047e16ed3182c1ac8efd6b3ec0d37b1
parentd31bc234beb39489fc23c19eccd7dddc86aec03b (diff)
parentb0c73c71b3865786389d31fc0a59160ce5f0ed85 (diff)
Merge pull request #30430 from vespa-engine/hmusum/add-test-showing-failure-when-deprovisioning-load-balancer-when-using-combined-cluster
Add test showing that load balancer might be removed erroneously for …
-rw-r--r--node-repository/pom.xml5
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/LoadBalancerProvisionerTest.java142
2 files changed, 103 insertions, 44 deletions
diff --git a/node-repository/pom.xml b/node-repository/pom.xml
index c63ce62f7c1..c4eeaa1d2d0 100644
--- a/node-repository/pom.xml
+++ b/node-repository/pom.xml
@@ -125,6 +125,11 @@
<version>${project.version}</version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-params</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
<plugins>
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/LoadBalancerProvisionerTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/LoadBalancerProvisionerTest.java
index 7096ea3de46..e3b5f25f104 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/LoadBalancerProvisionerTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/LoadBalancerProvisionerTest.java
@@ -32,13 +32,14 @@ import com.yahoo.vespa.hosted.provision.Node;
import com.yahoo.vespa.hosted.provision.NodeList;
import com.yahoo.vespa.hosted.provision.lb.LoadBalancer;
import com.yahoo.vespa.hosted.provision.lb.LoadBalancerList;
-import com.yahoo.vespa.hosted.provision.lb.LoadBalancerSpec;
import com.yahoo.vespa.hosted.provision.lb.Real;
import com.yahoo.vespa.hosted.provision.maintenance.LoadBalancerExpirer;
import com.yahoo.vespa.hosted.provision.maintenance.TestMetric;
import com.yahoo.vespa.hosted.provision.node.Agent;
import com.yahoo.vespa.hosted.provision.node.IP;
import org.junit.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
import java.time.Duration;
import java.util.Collections;
@@ -50,6 +51,8 @@ import java.util.SortedSet;
import java.util.function.Supplier;
import java.util.stream.Collectors;
+import static com.yahoo.config.provision.ClusterSpec.Type.combined;
+import static com.yahoo.config.provision.ClusterSpec.Type.container;
import static com.yahoo.vespa.hosted.provision.lb.LoadBalancerSpec.preProvisionOwner;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
@@ -81,13 +84,13 @@ public class LoadBalancerProvisionerTest {
// Provision a load balancer for each application
var nodes = prepare(app1,
- clusterRequest(ClusterSpec.Type.container, containerCluster),
+ clusterRequest(container, containerCluster),
clusterRequest(ClusterSpec.Type.content, contentCluster));
assertEquals(1, lbApp1.get().size());
assertEquals("Prepare provisions load balancer without any nodes", 0, lbApp1.get().get(0).instance().get().reals().size());
tester.activate(app1, nodes);
assertEquals("Activate configures load balancer with reserved nodes", 2, lbApp1.get().get(0).instance().get().reals().size());
- tester.activate(app2, prepare(app2, clusterRequest(ClusterSpec.Type.container, containerCluster)));
+ tester.activate(app2, prepare(app2, clusterRequest(container, containerCluster)));
assertEquals(1, lbApp2.get().size());
assertReals(app1, containerCluster, Node.State.active);
assertReals(app2, containerCluster, Node.State.active);
@@ -108,7 +111,7 @@ public class LoadBalancerProvisionerTest {
// Redeploying replaces failed node and removes it from load balancer
tester.activate(app1, prepare(app1,
- clusterRequest(ClusterSpec.Type.container, containerCluster),
+ clusterRequest(container, containerCluster),
clusterRequest(ClusterSpec.Type.content, contentCluster)));
LoadBalancer loadBalancer = tester.nodeRepository().loadBalancers().list(app1).asList().get(0);
assertEquals(2, loadBalancer.instance().get().reals().size());
@@ -123,15 +126,15 @@ public class LoadBalancerProvisionerTest {
// Add another container cluster to first app
ClusterSpec.Id containerCluster2 = ClusterSpec.Id.from("qrs2");
tester.activate(app1, prepare(app1,
- clusterRequest(ClusterSpec.Type.container, containerCluster),
- clusterRequest(ClusterSpec.Type.container, containerCluster2),
+ clusterRequest(container, containerCluster),
+ clusterRequest(container, containerCluster2),
clusterRequest(ClusterSpec.Type.content, contentCluster)));
// Load balancer is provisioned for second container cluster
assertReals(app1, containerCluster2, Node.State.active);
// Cluster removal deactivates relevant load balancer
- tester.activate(app1, prepare(app1, clusterRequest(ClusterSpec.Type.container, containerCluster)));
+ tester.activate(app1, prepare(app1, clusterRequest(container, containerCluster)));
assertEquals(2, lbApp1.get().size());
assertEquals("Deactivated load balancer for cluster " + containerCluster2, LoadBalancer.State.inactive,
lbApp1.get().stream()
@@ -156,7 +159,7 @@ public class LoadBalancerProvisionerTest {
// Application is redeployed with one cluster and load balancer is re-activated
tester.activate(app1, prepare(app1,
- clusterRequest(ClusterSpec.Type.container, containerCluster),
+ clusterRequest(container, containerCluster),
clusterRequest(ClusterSpec.Type.content, contentCluster)));
assertSame("Re-activated load balancer for " + containerCluster, LoadBalancer.State.active,
lbApp1.get().stream()
@@ -168,14 +171,14 @@ public class LoadBalancerProvisionerTest {
// Next redeploy does not create a new load balancer instance because reals are unchanged
tester.loadBalancerService().throwOnCreate(true);
tester.activate(app1, prepare(app1,
- clusterRequest(ClusterSpec.Type.container, containerCluster),
+ clusterRequest(container, containerCluster),
clusterRequest(ClusterSpec.Type.content, contentCluster)));
// Routing is disabled through feature flag. Reals are removed on next deployment
tester.loadBalancerService().throwOnCreate(false);
flagSource.withBooleanFlag(PermanentFlags.DEACTIVATE_ROUTING.id(), true);
tester.activate(app1, prepare(app1,
- clusterRequest(ClusterSpec.Type.container, containerCluster),
+ clusterRequest(container, containerCluster),
clusterRequest(ClusterSpec.Type.content, contentCluster)));
List<LoadBalancer> activeLoadBalancers = lbApp1.get().stream()
.filter(lb -> lb.state() == LoadBalancer.State.active).toList();
@@ -190,12 +193,12 @@ public class LoadBalancerProvisionerTest {
LoadBalancerExpirer expirer = new LoadBalancerExpirer(tester.nodeRepository(), Duration.ofDays(1), tester.loadBalancerService(), new NullMetric());
provisioner.refreshPool();
expirer.run();
- assertEquals(2, tester.nodeRepository().loadBalancers().list().size());
+ assertEquals(2, loadBalancers().size());
assertEquals(2, tester.nodeRepository().loadBalancers().list(preProvisionOwner).size());
// Provision a load balancer when the pool has two entries.
ClusterSpec.Id containerCluster = ClusterSpec.Id.from("qrs");
- prepare(app1, clusterRequest(ClusterSpec.Type.container, containerCluster));
+ prepare(app1, clusterRequest(container, containerCluster));
List<LoadBalancer> loadBalancers = tester.nodeRepository().loadBalancers().list(app1).asList();
assertEquals(1, loadBalancers.size());
assertEquals(1, tester.nodeRepository().loadBalancers().list(preProvisionOwner).asList().size());
@@ -206,7 +209,7 @@ public class LoadBalancerProvisionerTest {
provisioner.refreshPool();
expirer.run();
assertEquals(loadBalancers.stream().map(LoadBalancer::id).toList(),
- tester.nodeRepository().loadBalancers().list().mapToList(LoadBalancer::id));
+ loadBalancers().mapToList(LoadBalancer::id));
// Increase pool to 1 entry again. Creating an LB fails; the slot and idSeed are reused on retry.
tester.loadBalancerService().throwOnCreate(true);
@@ -225,7 +228,7 @@ public class LoadBalancerProvisionerTest {
NodeResources resources = new NodeResources(1, 4, 10, 0.3);
tester.makeReadyHosts(2, resources);
tester.activateTenantHosts();
- var nodes = tester.prepare(app1, clusterRequest(ClusterSpec.Type.container, ClusterSpec.Id.from("qrs")), 2 , 1, resources);
+ var nodes = tester.prepare(app1, clusterRequest(container, ClusterSpec.Id.from("qrs")), 2 , 1, resources);
Supplier<LoadBalancer> lb = () -> tester.nodeRepository().loadBalancers().list(app1).asList().get(0);
assertEquals("Load balancer provisioned with empty reals", Set.of(), tester.loadBalancerService().instances().get(lb.get().id()).reals());
assignIps(tester.nodeRepository().nodes().list().owner(app1));
@@ -244,7 +247,7 @@ public class LoadBalancerProvisionerTest {
new LoadBalancerExpirer(tester.nodeRepository(), Duration.ofDays(1), tester.loadBalancerService(), new NullMetric()).run();
// Application is redeployed
- nodes = tester.prepare(app1, clusterRequest(ClusterSpec.Type.container, ClusterSpec.Id.from("qrs")), 2, 1, resources);
+ nodes = tester.prepare(app1, clusterRequest(container, ClusterSpec.Id.from("qrs")), 2, 1, resources);
assertEquals("Load balancer is reconfigured with empty reals", Set.of(), tester.loadBalancerService().instances().get(lb.get().id()).reals());
assignIps(tester.nodeRepository().nodes().list().owner(app1));
tester.activate(app1, nodes);
@@ -271,7 +274,7 @@ public class LoadBalancerProvisionerTest {
public void provision_load_balancer_combined_cluster() {
Supplier<List<LoadBalancer>> lbs = () -> tester.nodeRepository().loadBalancers().list(app1).asList();
var combinedId = ClusterSpec.Id.from("container1");
- var nodes = prepare(app1, clusterRequest(ClusterSpec.Type.combined, ClusterSpec.Id.from("content1"), Optional.of(combinedId), ZoneEndpoint.defaultEndpoint));
+ var nodes = prepare(app1, clusterRequest(combined, ClusterSpec.Id.from("content1"), Optional.of(combinedId), ZoneEndpoint.defaultEndpoint));
assertEquals(1, lbs.get().size());
assertEquals("Prepare provisions load balancer without reserved nodes", 0, lbs.get().get(0).instance().get().reals().size());
tester.activate(app1, nodes);
@@ -299,20 +302,20 @@ public class LoadBalancerProvisionerTest {
ClusterSpec.Id defaultCluster = ClusterSpec.Id.from("default");
// instance1 is deployed
- tester.activate(instance1, prepare(instance1, clusterRequest(ClusterSpec.Type.container, devCluster)));
+ tester.activate(instance1, prepare(instance1, clusterRequest(container, devCluster)));
// instance2 clashes because instance name matches instance1 cluster name
try {
- prepare(instance2, clusterRequest(ClusterSpec.Type.container, defaultCluster));
+ prepare(instance2, clusterRequest(container, defaultCluster));
fail("Expected exception");
} catch (IllegalArgumentException ignored) {
}
// instance2 changes cluster name and does not clash
- tester.activate(instance2, prepare(instance2, clusterRequest(ClusterSpec.Type.container, ClusterSpec.Id.from("qrs"))));
+ tester.activate(instance2, prepare(instance2, clusterRequest(container, ClusterSpec.Id.from("qrs"))));
// instance3 does not clash
- tester.activate(instance3, prepare(instance3, clusterRequest(ClusterSpec.Type.container, defaultCluster)));
+ tester.activate(instance3, prepare(instance3, clusterRequest(container, defaultCluster)));
}
@Test
@@ -323,7 +326,7 @@ public class LoadBalancerProvisionerTest {
// Provisioning load balancer fails on deployment
tester.loadBalancerService().throwOnCreate(true);
try {
- prepare(app1, clusterRequest(ClusterSpec.Type.container, cluster));
+ prepare(app1, clusterRequest(container, cluster));
fail("Expected exception");
} catch (LoadBalancerServiceException ignored) {}
List<LoadBalancer> loadBalancers = lbs.get();
@@ -333,7 +336,7 @@ public class LoadBalancerProvisionerTest {
// Next deployment succeeds
tester.loadBalancerService().throwOnCreate(false);
- Set<HostSpec> nodes = prepare(app1, clusterRequest(ClusterSpec.Type.container, cluster));
+ Set<HostSpec> nodes = prepare(app1, clusterRequest(container, cluster));
loadBalancers = lbs.get();
assertSame(LoadBalancer.State.reserved, loadBalancers.get(0).state());
assertTrue("Load balancer has instance", loadBalancers.get(0).instance().isPresent());
@@ -346,7 +349,7 @@ public class LoadBalancerProvisionerTest {
tester.loadBalancerService().throwOnCreate(true);
ZoneEndpoint settings = new ZoneEndpoint(true, true, List.of(new AllowedUrn(AccessType.awsPrivateLink, "alice"), new AllowedUrn(AccessType.gcpServiceConnect, "bob")));
try {
- prepare(app1, clusterRequest(ClusterSpec.Type.container, cluster, Optional.empty(), settings));
+ prepare(app1, clusterRequest(container, cluster, Optional.empty(), settings));
fail("Expected exception");
} catch (LoadBalancerServiceException ignored) {
}
@@ -357,7 +360,7 @@ public class LoadBalancerProvisionerTest {
@Test
public void provisioning_load_balancer_for_unsupported_cluster_fails_gracefully() {
tester.loadBalancerService().supportsProvisioning(false);
- tester.activate(app1, prepare(app1, clusterRequest(ClusterSpec.Type.container, ClusterSpec.Id.from("qrs"))));
+ tester.activate(app1, prepare(app1, clusterRequest(container, ClusterSpec.Id.from("qrs"))));
assertTrue("No load balancer provisioned", tester.nodeRepository().loadBalancers().list(app1).asList().isEmpty());
}
@@ -367,7 +370,7 @@ public class LoadBalancerProvisionerTest {
// Initial deployment
{
Capacity capacity1 = Capacity.from(new ClusterResources(3, 1, nodeResources));
- Set<HostSpec> preparedHosts = prepare(app1, capacity1, clusterRequest(ClusterSpec.Type.container, container1));
+ Set<HostSpec> preparedHosts = prepare(app1, capacity1, clusterRequest(container, container1));
tester.activate(app1, preparedHosts);
}
assertReals(app1, container1, Node.State.active);
@@ -375,7 +378,7 @@ public class LoadBalancerProvisionerTest {
// Next deployment removes a node
{
Capacity capacity1 = Capacity.from(new ClusterResources(2, 1, nodeResources));
- Set<HostSpec> preparedHosts = prepare(app1, capacity1, clusterRequest(ClusterSpec.Type.container, container1));
+ Set<HostSpec> preparedHosts = prepare(app1, capacity1, clusterRequest(container, container1));
tester.activate(app1, preparedHosts);
}
assertReals(app1, container1, Node.State.active);
@@ -385,15 +388,15 @@ public class LoadBalancerProvisionerTest {
public void load_balancer_with_custom_settings() {
ClusterResources resources = new ClusterResources(3, 1, nodeResources);
Capacity capacity = Capacity.from(resources, resources, IntRange.empty(), false, true, Optional.of(CloudAccount.empty), ClusterInfo.empty());
- tester.activate(app1, prepare(app1, capacity, clusterRequest(ClusterSpec.Type.container, ClusterSpec.Id.from("c1"))));
- LoadBalancerList loadBalancers = tester.nodeRepository().loadBalancers().list();
+ tester.activate(app1, prepare(app1, capacity, clusterRequest(container, ClusterSpec.Id.from("c1"))));
+ LoadBalancerList loadBalancers = loadBalancers();
assertEquals(1, loadBalancers.size());
assertEquals(ZoneEndpoint.defaultEndpoint, loadBalancers.first().get().instance().get().settings());
// Next deployment contains new settings
ZoneEndpoint settings = new ZoneEndpoint(true, true, List.of(new AllowedUrn(AccessType.awsPrivateLink, "alice"), new AllowedUrn(AccessType.gcpServiceConnect, "bob")));
- tester.activate(app1, prepare(app1, capacity, clusterRequest(ClusterSpec.Type.container, ClusterSpec.Id.from("c1"), Optional.empty(), settings)));
- loadBalancers = tester.nodeRepository().loadBalancers().list();
+ tester.activate(app1, prepare(app1, capacity, clusterRequest(container, ClusterSpec.Id.from("c1"), Optional.empty(), settings)));
+ loadBalancers = loadBalancers();
assertEquals(1, loadBalancers.size());
assertEquals(settings, loadBalancers.first().get().instance().get().settings());
}
@@ -402,8 +405,8 @@ public class LoadBalancerProvisionerTest {
public void load_balancer_with_changing_visibility() {
ClusterResources resources = new ClusterResources(3, 1, nodeResources);
Capacity capacity = Capacity.from(resources, resources, IntRange.empty(), false, true, Optional.of(CloudAccount.empty), ClusterInfo.empty());
- tester.activate(app1, prepare(app1, capacity, clusterRequest(ClusterSpec.Type.container, ClusterSpec.Id.from("c1"))));
- LoadBalancerList loadBalancers = tester.nodeRepository().loadBalancers().list();
+ tester.activate(app1, prepare(app1, capacity, clusterRequest(container, ClusterSpec.Id.from("c1"))));
+ LoadBalancerList loadBalancers = loadBalancers();
assertEquals(1, loadBalancers.size());
assertEquals(ZoneEndpoint.defaultEndpoint, loadBalancers.first().get().instance().get().settings());
@@ -411,11 +414,11 @@ public class LoadBalancerProvisionerTest {
ZoneEndpoint settings = new ZoneEndpoint(false, true, List.of(new AllowedUrn(AccessType.awsPrivateLink, "alice"), new AllowedUrn(AccessType.gcpServiceConnect, "bob")));
assertEquals("Could not (re)configure load balancer tenant1:application1:default:c1 due to change in load balancer visibility. The operation will be retried on next deployment",
assertThrows(LoadBalancerServiceException.class,
- () -> prepare(app1, capacity, clusterRequest(ClusterSpec.Type.container, ClusterSpec.Id.from("c1"), Optional.empty(), settings)))
+ () -> prepare(app1, capacity, clusterRequest(container, ClusterSpec.Id.from("c1"), Optional.empty(), settings)))
.getMessage());
// Existing LB is removed
- loadBalancers = tester.nodeRepository().loadBalancers().list();
+ loadBalancers = loadBalancers();
assertEquals(1, loadBalancers.size());
assertSame(LoadBalancer.State.removable, loadBalancers.first().get().state());
new LoadBalancerExpirer(tester.nodeRepository(),
@@ -423,11 +426,11 @@ public class LoadBalancerProvisionerTest {
tester.loadBalancerService(),
new TestMetric())
.run();
- assertEquals(0, tester.nodeRepository().loadBalancers().list().in(LoadBalancer.State.removable).size());
+ assertEquals(0, loadBalancers().in(LoadBalancer.State.removable).size());
// Next deployment provisions a new LB
- tester.activate(app1, prepare(app1, capacity, clusterRequest(ClusterSpec.Type.container, ClusterSpec.Id.from("c1"), Optional.empty(), settings)));
- loadBalancers = tester.nodeRepository().loadBalancers().list();
+ tester.activate(app1, prepare(app1, capacity, clusterRequest(container, ClusterSpec.Id.from("c1"), Optional.empty(), settings)));
+ loadBalancers = loadBalancers();
assertEquals(1, loadBalancers.size());
assertEquals(settings, loadBalancers.first().get().instance().get().settings());
}
@@ -438,9 +441,9 @@ public class LoadBalancerProvisionerTest {
CloudAccount cloudAccount0 = CloudAccount.empty;
{
Capacity capacity = Capacity.from(resources, resources, IntRange.empty(), false, true, Optional.of(cloudAccount0), ClusterInfo.empty());
- tester.activate(app1, prepare(app1, capacity, clusterRequest(ClusterSpec.Type.container, ClusterSpec.Id.from("c1"))));
+ tester.activate(app1, prepare(app1, capacity, clusterRequest(container, ClusterSpec.Id.from("c1"))));
}
- LoadBalancerList loadBalancers = tester.nodeRepository().loadBalancers().list();
+ LoadBalancerList loadBalancers = loadBalancers();
assertEquals(1, loadBalancers.size());
assertEquals(cloudAccount0, loadBalancers.first().get().instance().get().cloudAccount());
@@ -448,14 +451,14 @@ public class LoadBalancerProvisionerTest {
CloudAccount cloudAccount1 = CloudAccount.from("111111111111");
Capacity capacity = Capacity.from(resources, resources, IntRange.empty(), false, true, Optional.of(cloudAccount1), ClusterInfo.empty());
try {
- prepare(app1, capacity, clusterRequest(ClusterSpec.Type.container, ClusterSpec.Id.from("c1")));
+ prepare(app1, capacity, clusterRequest(container, ClusterSpec.Id.from("c1")));
fail("Expected exception");
} catch (LoadBalancerServiceException e) {
assertTrue(e.getMessage().contains("due to change in cloud account"));
}
// Existing LB and nodes are removed
- loadBalancers = tester.nodeRepository().loadBalancers().list();
+ loadBalancers = loadBalancers();
assertEquals(1, loadBalancers.size());
assertSame(LoadBalancer.State.removable, loadBalancers.first().get().state());
LoadBalancerExpirer expirer = new LoadBalancerExpirer(tester.nodeRepository(),
@@ -463,17 +466,64 @@ public class LoadBalancerProvisionerTest {
tester.loadBalancerService(),
new TestMetric());
expirer.run();
- assertEquals(0, tester.nodeRepository().loadBalancers().list().in(LoadBalancer.State.removable).size());
+ assertEquals(0, loadBalancers().in(LoadBalancer.State.removable).size());
tester.deactivate(app1);
tester.nodeRepository().nodes().list().forEach(node -> tester.nodeRepository().nodes().removeRecursively(node, true));
// Next deployment provisions a new LB
- tester.activate(app1, prepare(app1, capacity, clusterRequest(ClusterSpec.Type.container, ClusterSpec.Id.from("c1"))));
- loadBalancers = tester.nodeRepository().loadBalancers().list();
+ tester.activate(app1, prepare(app1, capacity, clusterRequest(container, ClusterSpec.Id.from("c1"))));
+ loadBalancers = loadBalancers();
assertEquals(1, loadBalancers.size());
assertEquals(cloudAccount1, loadBalancers.first().get().instance().get().cloudAccount());
}
+ // TODO: 'combined' does not work
+ public static Object[] data() {
+ return new Object[]{container /*, combined */};
+ }
+
+ @MethodSource("data")
+ @ParameterizedTest(name = "clusterType={0}")
+ public void load_balancer_with_existing_in_removable_state(ClusterSpec.Type clusterType) {
+ ClusterResources resources = new ClusterResources(3, 1, nodeResources);
+ Capacity capacity = Capacity.from(resources, resources, IntRange.empty(), false, true, Optional.of(CloudAccount.empty), ClusterInfo.empty());
+ ClusterSpec clusterSpec = clusterRequest(
+ clusterType,
+ ClusterSpec.Id.from("c1"),
+ clusterType == container ? Optional.empty() : Optional.of(ClusterSpec.Id.from("c2")),
+ ZoneEndpoint.defaultEndpoint);
+
+ tester.activate(app1, prepare(app1, capacity, clusterSpec));
+ assertEquals(1, loadBalancers().size());
+
+ // Remove app, existing LB should be inactive
+ tester.remove(app1);
+ assertEquals(1, loadBalancers().size());
+ assertSame(LoadBalancer.State.inactive, loadBalancers().first().get().state());
+ var expirer = new LoadBalancerExpirer(tester.nodeRepository(),
+ Duration.ofDays(1),
+ tester.loadBalancerService(),
+ new TestMetric());
+ // Expirer should not remove load balancer
+ expirer.run();
+ assertEquals(1, loadBalancers().in(LoadBalancer.State.inactive).size());
+
+ tester.clock().advance(Duration.ofHours(1));
+
+ // Prepare app, should reuse the LB, but it should still be inactive
+ var hosts = prepare(app1, capacity, clusterSpec);
+ assertEquals(1, loadBalancers().size());
+ assertEquals(1, loadBalancers().in(LoadBalancer.State.inactive).size());
+
+ // Run expirer, should not remove load balancer
+ expirer.run();
+ assertEquals(1, loadBalancers().size());
+ assertEquals(1, loadBalancers().in(LoadBalancer.State.inactive).size());
+
+ // Activate should work
+ tester.activate(app1, hosts);
+ }
+
private void assertReals(ApplicationId application, ClusterSpec.Id cluster, Node.State... states) {
List<LoadBalancer> loadBalancers = tester.nodeRepository().loadBalancers().list(application).cluster(cluster).asList();
assertEquals(1, loadBalancers.size());
@@ -536,6 +586,10 @@ public class LoadBalancerProvisionerTest {
}
}
+ private LoadBalancerList loadBalancers() {
+ return tester.nodeRepository().loadBalancers().list();
+ }
+
private static ClusterSpec clusterRequest(ClusterSpec.Type type, ClusterSpec.Id id) {
return clusterRequest(type, id, Optional.empty(), ZoneEndpoint.defaultEndpoint);
}