@Override
    protected double maintain() {
        expireReserved();
        return (deprovisionRemovable() + pruneReals()) / 2;
    }
@Test
    public void expire_reserved() {
        LoadBalancerExpirer expirer = new LoadBalancerExpirer(tester.nodeRepository(),
                                                              Duration.ofDays(1),
                                                              tester.loadBalancerService(),
                                                              new TestMetric());
        Supplier<Map<LoadBalancerId, LoadBalancer>> loadBalancers = () -> tester.nodeRepository().database().readLoadBalancers((ignored) -> true);


        // Prepare application
        ClusterSpec.Id cluster = ClusterSpec.Id.from("qrs");
        ApplicationId app = ProvisioningTester.applicationId();
        LoadBalancerId lb = new LoadBalancerId(app, cluster);
        deployApplication(app, false, cluster);

        // Provisions load balancer in reserved
        assertSame(LoadBalancer.State.reserved, loadBalancers.get().get(lb).state());

        // Expirer does nothing
        expirer.maintain();
        assertSame(LoadBalancer.State.reserved, loadBalancers.get().get(lb).state());

        // Application never activates and nodes are dirtied and readied. Expirer moves load balancer to inactive after timeout
        removeNodesOf(app, cluster);
        tester.clock().advance(Duration.ofHours(1).plus(Duration.ofSeconds(1)));
        expirer.maintain();
        assertSame(LoadBalancer.State.inactive, loadBalancers.get().get(lb).state());

        // Expirer does nothing as inactive expiration time has not yet passed
        expirer.maintain();
        assertSame(LoadBalancer.State.inactive, loadBalancers.get().get(lb).state());

        // Expirer removes inactive load balancer
        tester.clock().advance(Duration.ofHours(1).plus(Duration.ofSeconds(1)));
        expirer.maintain();
        assertFalse("Inactive load balancer removed", loadBalancers.get().containsKey(lb));
    }