@Test
    public void hw_fail_only_if_whole_host_is_suspended() {
        NodeFailTester tester = NodeFailTester.withTwoApplications(6);
        String hostWithFailureReports = selectFirstParentHostWithNActiveNodesExcept(tester.nodeRepository, 2);
        assertEquals(Node.State.active, tester.nodeRepository.nodes().node(hostWithFailureReports).get().state());

        // The host has 2 nodes in active
        Map<Node.State, List<String>> hostnamesByState = tester.nodeRepository.nodes().list().childrenOf(hostWithFailureReports).asList().stream()
                .collect(Collectors.groupingBy(Node::state, Collectors.mapping(Node::hostname, Collectors.toList())));
        assertEquals(2, hostnamesByState.get(Node.State.active).size());
        String activeChild1 = hostnamesByState.get(Node.State.active).get(0);
        String activeChild2 = hostnamesByState.get(Node.State.active).get(1);

        // Set failure report to the parent and all its children.
        Report badTotalMemorySizeReport = Report.basicReport("badTotalMemorySize", HARD_FAIL, Instant.now(), "too low");
        tester.nodeRepository.nodes().list().stream()
                .filter(node -> node.hostname().equals(hostWithFailureReports))
                .forEach(node -> {
                    Node updatedNode = node.with(node.reports().withReport(badTotalMemorySizeReport));
                    tester.nodeRepository.nodes().write(updatedNode, () -> {});
                });

        // Neither the host nor the 2 active nodes are failed out because they have not been suspended
        tester.runMaintainers();
        assertEquals(Node.State.active, tester.nodeRepository.nodes().node(hostWithFailureReports).get().state());
        assertEquals(Node.State.active, tester.nodeRepository.nodes().node(activeChild1).get().state());
        assertEquals(Node.State.active, tester.nodeRepository.nodes().node(activeChild2).get().state());

        // Suspending the host will not fail any more since none of the children are suspended
        tester.suspend(hostWithFailureReports);
        tester.clock.advance(Duration.ofHours(25));
        tester.runMaintainers();
        assertEquals(Node.State.active, tester.nodeRepository.nodes().node(hostWithFailureReports).get().state());
        assertEquals(Node.State.active, tester.nodeRepository.nodes().node(activeChild1).get().state());
        assertEquals(Node.State.active, tester.nodeRepository.nodes().node(activeChild2).get().state());

        // Suspending one child node will fail that out.
        tester.suspend(activeChild1);
        tester.clock.advance(Duration.ofHours(25));
        tester.runMaintainers();
        assertEquals(Node.State.active, tester.nodeRepository.nodes().node(hostWithFailureReports).get().state());
        assertEquals(Node.State.failed, tester.nodeRepository.nodes().node(activeChild1).get().state());
        assertEquals(Node.State.active, tester.nodeRepository.nodes().node(activeChild2).get().state());

        // Suspending the second child node will fail that out and the host.
        tester.suspend(activeChild2);
        tester.clock.advance(Duration.ofHours(25));
        tester.runMaintainers();
        tester.runMaintainers(); // hosts are typically failed in the 2. maintain()
        assertEquals(Node.State.failed, tester.nodeRepository.nodes().node(hostWithFailureReports).get().state());
        assertEquals(Node.State.failed, tester.nodeRepository.nodes().node(activeChild1).get().state());
        assertEquals(Node.State.failed, tester.nodeRepository.nodes().node(activeChild2).get().state());
    }
Tests automatic failing of nodes.

@author bratseth
@author mpolden
node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/NodeFailerTest.java