SimpleCapacityGuaranteeStrategy implements CapacityGuaranteeStrategy { @Override public CapacityAllocations compute(CapacityRequirements capacityRequirements) { Map<AgentInstanceGroup, Integer> instanceAllocations = new HashMap<>(); Map<Tier, ResourceDimension> resourceShortage = new HashMap<>(); for (Tier tier : capacityRequirements.getTiers()) { boolean hasEnoughApps = (tier == Tier.Flex && capacityRequirements.getTierRequirements(tier).size() > 1) || (tier != Tier.Flex && capacityRequirements.getTierRequirements(tier).size() > 0); if (hasEnoughApps) { Optional<ResourceDimension> left = allocate(tier, capacityRequirements, instanceAllocations); left.ifPresent(resourceDimension -> resourceShortage.put(tier, resourceDimension)); } } return new CapacityAllocations(instanceAllocations, resourceShortage); } @Inject  SimpleCapacityGuaranteeStrategy(CapacityManagementConfiguration configuration,
                                           AgentManagementService agentManagementService,
                                           ServerInfoResolver serverInfoResolver); @Override CapacityAllocations compute(CapacityRequirements capacityRequirements);  }
@Test public void testOnlyFenzoPartitionIsIncluded() { List<AgentInstanceGroup> instanceGroups = asList( getInstanceGroup(Tier.Critical, R4_8XLARGE_ID, 0, 1).toBuilder().withId("fenzo").build(), getInstanceGroup(Tier.Critical, R4_8XLARGE_ID, 0, 1).toBuilder().withId("kubeScheduler").build() ); when(agentManagementService.getInstanceGroups()).thenReturn(instanceGroups); when(agentManagementService.isOwnedByFenzo(any(AgentInstanceGroup.class))).thenAnswer(invocation -> { AgentInstanceGroup instanceGroup = invocation.getArgument(0); return instanceGroup.getId().equals("fenzo"); }); ApplicationSLA bigSLA = ApplicationSlaSample.CriticalLarge.builder().withInstanceCount(100).build(); CapacityRequirements requirements = new CapacityRequirements(singletonMap(Tier.Critical, singletonList(bigSLA))); CapacityAllocations allocations = strategy.compute(requirements); assertThat(allocations.getInstanceGroups()).hasSize(1); assertThat(CollectionsExt.first(allocations.getInstanceGroups()).getId()).isEqualTo("fenzo"); }
@Test public void testSingleInstanceFitsAll() { List<AgentInstanceGroup> instanceGroups = asList( getInstanceGroup(Tier.Critical, M4_XLARGE_ID, 0, 2), getInstanceGroup(Tier.Critical, M4_4XLARGE_ID, 0, 0), getInstanceGroup(Tier.Flex, R4_8XLARGE_ID, 0, 0), getInstanceGroup(Tier.Flex, P2_8XLARGE_ID, 0, 0) ); when(agentManagementService.getInstanceGroups()).thenReturn(instanceGroups); ApplicationSLA smallSLA = ApplicationSlaSample.CriticalSmall.builder().withInstanceCount(1).build(); CapacityRequirements requirements = new CapacityRequirements(singletonMap(Tier.Critical, singletonList(smallSLA))); CapacityAllocations allocations = strategy.compute(requirements); allocations.getInstanceGroups().forEach(instanceGroup -> { assertThat(instanceGroup.getTier()).isEqualTo(Tier.Critical); }); AgentInstanceGroup m4xlInstanceGroup = findInstanceGroupByInstanceType(allocations.getInstanceGroups(), M4_XLARGE_ID); assertThat(allocations.getExpectedMinSize(m4xlInstanceGroup)).isEqualTo(1); AgentInstanceGroup m44xlInstanceGroup = findInstanceGroupByInstanceType(allocations.getInstanceGroups(), M4_4XLARGE_ID); assertThat(allocations.getExpectedMinSize(m44xlInstanceGroup)).isEqualTo(0); }
@Test public void testLargeAllocation() { List<AgentInstanceGroup> instanceGroups = asList( getInstanceGroup(Tier.Critical, M4_XLARGE_ID, 0, 10), getInstanceGroup(Tier.Critical, M4_4XLARGE_ID, 0, 0), getInstanceGroup(Tier.Flex, R4_8XLARGE_ID, 0, 0), getInstanceGroup(Tier.Flex, P2_8XLARGE_ID, 0, 0) ); when(agentManagementService.getInstanceGroups()).thenReturn(instanceGroups); ApplicationSLA largeSLA = ApplicationSlaSample.CriticalLarge.builder().withInstanceCount(10).build(); CapacityRequirements requirements = new CapacityRequirements(singletonMap(Tier.Critical, singletonList(largeSLA))); CapacityAllocations allocations = strategy.compute(requirements); allocations.getInstanceGroups().forEach(instanceGroup -> { assertThat(instanceGroup.getTier()).isEqualTo(Tier.Critical); }); AgentInstanceGroup m4xlInstanceGroup = findInstanceGroupByInstanceType(allocations.getInstanceGroups(), M4_XLARGE_ID); assertThat(allocations.getExpectedMinSize(m4xlInstanceGroup)).isEqualTo(6); AgentInstanceGroup m44xlInstanceGroup = findInstanceGroupByInstanceType(allocations.getInstanceGroups(), M4_4XLARGE_ID); assertThat(allocations.getExpectedMinSize(m44xlInstanceGroup)).isEqualTo(0); }
@Test public void testFlexTierMultiInstanceAllocation() { List<AgentInstanceGroup> instanceGroups = asList( getInstanceGroup(Tier.Critical, M4_XLARGE_ID, 0, 0), getInstanceGroup(Tier.Critical, M4_4XLARGE_ID, 0, 0), getInstanceGroup(Tier.Flex, R4_8XLARGE_ID, 0, 5), getInstanceGroup(Tier.Flex, R4_4XLARGE_ID, 0, 5), getInstanceGroup(Tier.Flex, P2_8XLARGE_ID, 0, 5) ); when(agentManagementService.getInstanceGroups()).thenReturn(instanceGroups); ApplicationSLA defaultSLA = ApplicationSLA.newBuilder() .withAppName(ApplicationSlaManagementEndpoint.DEFAULT_APPLICATION) .withTier(Tier.Flex) .withResourceDimension(ResourceDimension .newBuilder().withCpus(4).withMemoryMB(512).withNetworkMbs(128).withDiskMB(512).build() ) .withInstanceCount(10) .build(); ApplicationSLA flexAppSLA = ApplicationSLA.newBuilder(defaultSLA).withInstanceCount(40).build(); CapacityRequirements requirements = new CapacityRequirements(singletonMap(Tier.Flex, asList(defaultSLA, flexAppSLA))); CapacityAllocations allocations = strategy.compute(requirements); allocations.getInstanceGroups().forEach(instanceGroup -> { assertThat(instanceGroup.getTier()).isEqualTo(Tier.Flex); }); AgentInstanceGroup r48xlInstanceGroup = findInstanceGroupByInstanceType(allocations.getInstanceGroups(), R4_8XLARGE_ID); assertThat(allocations.getExpectedMinSize(r48xlInstanceGroup)).isEqualTo(5); AgentInstanceGroup r44xlInstanceGroup = findInstanceGroupByInstanceType(allocations.getInstanceGroups(), R4_4XLARGE_ID); assertThat(allocations.getExpectedMinSize(r44xlInstanceGroup)).isEqualTo(4); AgentInstanceGroup p28xlInstanceGroup = findInstanceGroupByInstanceType(allocations.getInstanceGroups(), P2_8XLARGE_ID); assertThat(allocations.getExpectedMinSize(p28xlInstanceGroup)).isEqualTo(0); }
@Test public void testTierSharedInstanceAllocation() { List<AgentInstanceGroup> instanceGroups = asList( getInstanceGroup(Tier.Critical, M4_XLARGE_ID, 0, 0), getInstanceGroup(Tier.Critical, M4_4XLARGE_ID, 0, 0), getInstanceGroup(Tier.Flex, R4_4XLARGE_ID, 0, 0), getInstanceGroup(Tier.Flex, R4_8XLARGE_ID, 0, 0), getInstanceGroup(Tier.Flex, P2_8XLARGE_ID, 0, 3) ); when(agentManagementService.getInstanceGroups()).thenReturn(instanceGroups); ApplicationSLA criticalSLA = ApplicationSlaSample.CriticalSmall.builder().withInstanceCount(20).build(); ApplicationSLA flexSLA = ApplicationSlaSample.FlexSmall.builder().withInstanceCount(20).build(); ApplicationSLA defaultFlexSLA = ApplicationSlaSample.DefaultFlex.builder().withInstanceCount(1).build(); Map<Tier, List<ApplicationSLA>> tierSLAs = CollectionsExt.<Tier, List<ApplicationSLA>>newHashMap() .entry(Tier.Critical, singletonList(criticalSLA)) .entry(Tier.Flex, asList(defaultFlexSLA, flexSLA)) .toMap(); CapacityRequirements requirements = new CapacityRequirements(tierSLAs); CapacityAllocations allocations = strategy.compute(requirements); AgentInstanceGroup p28xlInstanceGroup = findInstanceGroupByInstanceType(allocations.getInstanceGroups(), P2_8XLARGE_ID); assertThat(allocations.getExpectedMinSize(p28xlInstanceGroup)).isEqualTo(1); }
@Test public void testBuffer() { List<AgentInstanceGroup> instanceGroups = singletonList( getInstanceGroup(Tier.Critical, M4_XLARGE_ID, 0, 2) ); when(agentManagementService.getInstanceGroups()).thenReturn(instanceGroups); ApplicationSLA smallSLA = ApplicationSlaSample.CriticalSmall.builder().withInstanceCount(4).build(); CapacityRequirements requirements = new CapacityRequirements(singletonMap(Tier.Critical, singletonList(smallSLA))); CapacityAllocations allocations = strategy.compute(requirements); allocations.getInstanceGroups().forEach(instanceGroup -> { assertThat(instanceGroup.getTier()).isEqualTo(Tier.Critical); }); AgentInstanceGroup r48xlInstanceGroup = findInstanceGroupByInstanceType(allocations.getInstanceGroups(), M4_XLARGE_ID); assertThat(allocations.getExpectedMinSize(r48xlInstanceGroup)).isEqualTo(2); }
@Test public void testAllocationNotChangedIfNoAppInTier() { List<AgentInstanceGroup> instanceGroups = singletonList( getInstanceGroup(Tier.Critical, M4_XLARGE_ID, 0, 1) ); when(agentManagementService.getInstanceGroups()).thenReturn(instanceGroups); CapacityRequirements requirements = new CapacityRequirements(Collections.emptyMap()); CapacityAllocations allocations = strategy.compute(requirements); assertThat(allocations.getInstanceGroups()).isEmpty(); }
@Test public void testAllocationNotChangedIfOnlyDefaultAppInFlexTier() { List<AgentInstanceGroup> instanceGroups = singletonList( getInstanceGroup(Tier.Flex, R4_8XLARGE_ID, 0, 1) ); when(agentManagementService.getInstanceGroups()).thenReturn(instanceGroups); CapacityRequirements requirements = new CapacityRequirements(singletonMap(Tier.Flex, singletonList(ApplicationSlaSample.DefaultFlex.build()))); CapacityAllocations allocations = strategy.compute(requirements); assertThat(allocations.getInstanceGroups()).isEmpty(); }
@Test public void testResourceShortageReporting() { List<AgentInstanceGroup> instanceGroups = singletonList( getInstanceGroup(Tier.Critical, M4_XLARGE_ID, 0, 2) ); when(agentManagementService.getInstanceGroups()).thenReturn(instanceGroups); ApplicationSLA veryBigSLA = ApplicationSlaSample.CriticalSmall.builder().withInstanceCount(100).build(); CapacityRequirements requirements = new CapacityRequirements(singletonMap(Tier.Critical, singletonList(veryBigSLA))); CapacityAllocations allocations = strategy.compute(requirements); assertThat(allocations.getTiersWithResourceShortage()).containsExactly(Tier.Critical); }