@Override
    protected double maintain() {
        if (!nodeRepository().nodes().isWorking()) return 0.0;
        if (!nodeRepository().zone().environment().isProduction()) return 1.0;
        NodeList allNodes = nodeRepository().nodes().list(); // Lockless as strong consistency is not needed
        if (!zoneIsStable(allNodes)) return 1.0;

        Move bestMove = findBestMove(allNodes);
        if (!bestMove.isEmpty()) {
            LOG.info("Trying " + bestMove + " (" + bestMove.fromHost().switchHostname().orElse("<none>") +
                     " -> " + bestMove.toHost().switchHostname().orElse("<none>") + ")");
        }
        bestMove.execute(false, Agent.SwitchRebalancer, deployer, metric, nodeRepository());
        return 1.0;
    }
@Test
    public void rebalance_does_not_move_node_already_on_exclusive_switch() {
        ProvisioningTester tester = new ProvisioningTester.Builder().zone(new Zone(Environment.prod, RegionName.from("us-east"))).build();
        ClusterSpec spec = ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("c1")).vespaVersion("1").build();
        Capacity capacity = Capacity.from(new ClusterResources(4, 1, new NodeResources(4, 8, 50, 1)));
        MockDeployer deployer = deployer(tester, capacity, spec);
        SwitchRebalancer rebalancer = new SwitchRebalancer(tester.nodeRepository(), Duration.ofDays(1), new TestMetric(), deployer);

        // Provision initial hosts on two switches
        NodeResources hostResources = new NodeResources(8, 16, 500, 10);
        String switch0 = "switch0";
        String switch1 = "switch1";
        provisionHost(switch0, hostResources, tester);
        provisionHosts(3, switch1, hostResources, tester);

        // Deploy application
        deployer.deployFromLocalActive(app).get().activate();
        tester.assertSwitches(Set.of(switch0, switch1), app, spec.id());
        List<Node> nodesOnExclusiveSwitch = tester.activeNodesOn(switch0, app, spec.id());
        assertEquals(1, nodesOnExclusiveSwitch.size());
        assertEquals(3, tester.activeNodesOn(switch1, app, spec.id()).size());

        // Another host becomes available on a new host
        String switch2 = "switch2";
        provisionHost(switch2, hostResources, tester);

        // Rebalance
        tester.clock().advance(SwitchRebalancer.waitTimeAfterPreviousDeployment);
        rebalancer.maintain();
        NodeList activeNodes = nodesIn(spec.id(), tester).state(Node.State.active);
        NodeList retired = activeNodes.retired();
        assertEquals("Node is retired", 1, retired.size());
        assertFalse("Retired node was not on exclusive switch", nodesOnExclusiveSwitch.contains(retired.first().get()));
        tester.assertSwitches(Set.of(switch0, switch1, switch2), app, spec.id());
        // Retired node becomes inactive and makes zone stable
        deactivate(tester, retired);

        // Next iteration does nothing
        tester.clock().advance(SwitchRebalancer.waitTimeAfterPreviousDeployment);
        assertNoMoves(rebalancer, tester);
    }