@Test
    void testGetNodeStateWithConfigurationChangeToRetired() throws Exception {
        { // Configuration: 5 nodes, all normal
            List<ConfiguredNode> configuredNodes = new ArrayList<>();
            for (int i = 0; i < 5; i++)
                configuredNodes.add(new ConfiguredNode(i, false));
            FleetControllerOptions.Builder builder = defaultOptions(configuredNodes)
                    .setMaxInitProgressTime(30000)
                    .setStableStateTimePeriod(60000);
            options = builder.build();
            setUpFleetController(timer, builder);
            setUpVdsNodes(timer, false, configuredNodes);
            waitForState("version:\\d+ distributor:5 storage:5");
        }

        { // Reconfigure with the same state
            Set<ConfiguredNode> configuredNodes = new TreeSet<>();
            for (int i = 0; i < 5; i++)
                configuredNodes.add(new ConfiguredNode(i, false));
            var builder = FleetControllerOptions.Builder.copy(fleetController().getOptions())
                    .setNodes(configuredNodes);
            fleetController().updateOptions(builder.build());
            waitForState("version:\\d+ distributor:5 storage:5");
        }

        { // Configuration change: Add 2 new nodes and retire the 5 existing ones
            setUpVdsNodes(timer, false, 2);
            Set<ConfiguredNode> configuredNodes = new TreeSet<>();
            for (int i = 0; i < 5; i++)
                configuredNodes.add(new ConfiguredNode(i, true));
            configuredNodes.add(new ConfiguredNode(5, false));
            configuredNodes.add(new ConfiguredNode(6, false));
            var builder = FleetControllerOptions.Builder.copy(fleetController().getOptions())
                    .setNodes(configuredNodes);
            fleetController().updateOptions(builder.build());
            waitForState("version:\\d+ distributor:7 storage:7 .0.s:r .1.s:r .2.s:r .3.s:r .4.s:r");
        }

        { // Reconfigure with the same state
            Set<ConfiguredNode> configuredNodes = new TreeSet<>();
            for (int i = 0; i < 5; i++)
                configuredNodes.add(new ConfiguredNode(i, true));
            configuredNodes.add(new ConfiguredNode(5, false));
            configuredNodes.add(new ConfiguredNode(6, false));
            var builder = FleetControllerOptions.Builder.copy(fleetController().getOptions())
                    .setNodes(configuredNodes);
            fleetController().updateOptions(builder.build());
            waitForState("version:\\d+ distributor:7 storage:7 .0.s:r .1.s:r .2.s:r .3.s:r .4.s:r");
        }

        { // Configuration change: Remove the previously retired nodes
            /*
        TODO: Verify current result: version:23 distributor:7 .0.s:d .1.s:d .2.s:d .3.s:d .4.s:d storage:7 .0.s:m .1.s:m .2.s:m .3.s:m .4.s:m
        TODO: Make this work without stopping/disconnecting (see StateChangeHandler.setNodes
        Set<ConfiguredNode> configuredNodes = new TreeSet<>();
        configuredNodes.add(new ConfiguredNode(5, false));
        configuredNodes.add(new ConfiguredNode(6, false));
        FleetControllerOptions.Builder builder = new FleetControllerOptions.Builder("mycluster", configuredNodes)
        .setSlobrokConnectionSpecs(options.slobrokConnectionSpecs())
        .setMaxInitProgressTimeMs(30000)
        .setStableStateTimePeriod(60000);
        fleetController.updateOptions(options, 0);
        for (int i = 0; i < 5*2; i++) {
            nodes.get(i).disconnectSlobrok();
            nodes.get(i).disconnect();
        }
        waitForState("version:\\d+ distributor:7 storage:7 .0.s:d .1.s:d .2.s:d .3.s:d .4.s:d");
        */
        }
    }
Note: RpcServer is only used in unit tests

@author humbe
clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/RpcServerTest.java