public Optional<HostFailurePath> worstCaseHostLossLeadingToFailure() {
        Map<Node, Integer> timesNodeCanBeRemoved = computeMaximalRepeatedRemovals();
        return greedyHeuristicFindFailurePath(timesNodeCanBeRemoved);
    }
@Test
    public void testNodeResourceFailurePaths() {
        {
            CapacityCheckerTester tester = new CapacityCheckerTester();
            tester.createNodes(1, 10,
                               10, new NodeResources(1, 100, 1000, 1), 100,
                               10, new NodeResources(0, 100, 1000, 1), 100);
            var failurePath = tester.capacityChecker.worstCaseHostLossLeadingToFailure();
            assertTrue(failurePath.isPresent());
            if (failurePath.get().failureReason.tenant.isPresent()) {
                var failureReasons = failurePath.get().failureReason.allocationFailures;
                assertEquals("All failures should be due to hosts lacking cpu cores.",
                             failureReasons.singularReasonFailures().insufficientVcpu(), failureReasons.size());
            } else {
                fail();
            }
        }

        {
            CapacityCheckerTester tester = new CapacityCheckerTester();
            tester.createNodes(1, 10,
                               10, new NodeResources(10, 1, 1000, 1), 100,
                               10, new NodeResources(10, 0, 1000, 1), 100);
            var failurePath = tester.capacityChecker.worstCaseHostLossLeadingToFailure();
            assertTrue(failurePath.isPresent());
            if (failurePath.get().failureReason.tenant.isPresent()) {
                var failureReasons = failurePath.get().failureReason.allocationFailures;
                assertEquals("All failures should be due to hosts lacking memory.",
                             failureReasons.singularReasonFailures().insufficientMemoryGb(), failureReasons.size());
            }
            else {
                fail();
            }
        }

        {
            CapacityCheckerTester tester = new CapacityCheckerTester();
            tester.createNodes(1, 10,
                               10, new NodeResources(10, 100, 10, 1), 100,
                               10, new NodeResources(10, 100, 0, 1), 100);
            var failurePath = tester.capacityChecker.worstCaseHostLossLeadingToFailure();
            assertTrue(failurePath.isPresent());
            if (failurePath.get().failureReason.tenant.isPresent()) {
                var failureReasons = failurePath.get().failureReason.allocationFailures;
                assertEquals("All failures should be due to hosts lacking disk space.",
                             failureReasons.singularReasonFailures().insufficientDiskGb(), failureReasons.size());
            } else {
                fail();
            }
        }

        {
            CapacityCheckerTester tester = new CapacityCheckerTester();
            int emptyHostsWithSlowDisk = 10;
            tester.createNodes(1, 10, List.of(new NodeResources(1, 10, 100, 1)),
                               10, new NodeResources(0, 0, 0, 0), 100,
                               10, new NodeResources(10, 1000, 10000, 1, NodeResources.DiskSpeed.slow), 100);
            var failurePath = tester.capacityChecker.worstCaseHostLossLeadingToFailure();
            assertTrue(failurePath.isPresent());
            if (failurePath.get().failureReason.tenant.isPresent()) {
                var failureReasons = failurePath.get().failureReason.allocationFailures;
                assertEquals("All empty hosts should be invalid due to having incompatible disk speed.",
                             failureReasons.singularReasonFailures().incompatibleDiskSpeed(), emptyHostsWithSlowDisk);
            } else {
                fail();
            }
        }
    }