@Test
    public void retire_proxy() {
        MockDeployer deployer = new MockDeployer(tester.provisioner(),
                                                 tester.clock(),
                                                 List.of(new MockDeployer.ApplicationContext(proxyApp, Version.fromString("6.42"))));
        RetiredExpirer retiredExpirer =  new RetiredExpirer(tester.nodeRepository(),
                                                            deployer,
                                                            new TestMetric(),
                                                            Duration.ofDays(30),
                                                            Duration.ofMinutes(10));

        { // Deploy
            tester.prepareAndActivateInfraApplication(proxyApp);
            NodeList nodes = tester.nodeRepository().nodes().list(Node.State.active).nodeType(NodeType.proxy);
            assertEquals("Activated all proxies", 11, nodes.size());
        }

        Node nodeToRetire = tester.nodeRepository().nodes().list(Node.State.active).nodeType(NodeType.proxy).asList().get(5);
        { // Pick out a node and retire it
            tester.nodeRepository().nodes().write(nodeToRetire.withWantToRetire(true, Agent.system, tester.clock().instant()), () -> {});

            tester.prepareAndActivateInfraApplication(proxyApp);
            NodeList nodes = tester.nodeRepository().nodes().list(Node.State.active).nodeType(NodeType.proxy);
            assertEquals(11, nodes.size());

            // Verify that wantToRetire has been propagated
            assertTrue(tester.nodeRepository().nodes().node(nodeToRetire.hostname())
                    .flatMap(Node::allocation)
                    .map(allocation -> allocation.membership().retired())
                    .orElseThrow(RuntimeException::new));
        }

        { // Redeploying while the node is still retiring has no effect
            tester.prepareAndActivateInfraApplication(proxyApp);
            NodeList nodes = tester.nodeRepository().nodes().list(Node.State.active).nodeType(NodeType.proxy);
            assertEquals(11, nodes.size());

            // Verify that the node is still marked as retired
            assertTrue(tester.nodeRepository().nodes().node(nodeToRetire.hostname())
                    .flatMap(Node::allocation)
                    .map(allocation -> allocation.membership().retired())
                    .orElseThrow(RuntimeException::new));
        }

        {
            tester.advanceTime(Duration.ofMinutes(11));
            retiredExpirer.run();

            tester.prepareAndActivateInfraApplication(proxyApp);
            NodeList nodes = tester.nodeRepository().nodes().list(Node.State.active).nodeType(NodeType.proxy);
            assertEquals(10, nodes.size());

            // Verify that the node is now inactive
            assertEquals(Node.State.dirty, tester.nodeRepository().nodes().node(nodeToRetire.hostname())
                    .orElseThrow(RuntimeException::new).state());
        }
    }
Tests provisioning by node type instead of by count and flavor

@author bratseth
node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/NodeTypeProvisioningTest.java