@Test @Repeat(10) public void createSpecificExperiments () { Container container1 = mock(Container.class); Container container2 = mock(Container.class); Container container3 = mock(Container.class); Experiment experiment1 = mock(Experiment.class); Experiment experiment2 = mock(Experiment.class); Experiment experiment3 = mock(Experiment.class); doReturn(experiment1).when(container1).createExperiment(anyString()); doReturn(experiment2).when(container2).createExperiment(anyString()); doReturn(experiment3).when(container3).createExperiment(anyString()); doReturn(Set.of(container1, container2, container3)).when(firstPlatform).getRosterByAggregationId("aggregate"); Set<Experiment> experiments = experimentManager.createSpecificExperiments(firstPlatform, new ExperimentSuite.ExperimentCriteria("aggregate", List .of("method1", "method2"), Collections.emptyList()), 1).collect(Collectors.toUnmodifiableSet()); assertThat(experiments, Matchers.anyOf(containsInAnyOrder(experiment1, experiment2), containsInAnyOrder(experiment2, experiment3), containsInAnyOrder(experiment1, experiment3))); }
Stream<Experiment> createSpecificExperiments (Platform platform, ExperimentSuite.ExperimentCriteria experimentCriteria, int minimumNumberOfSurvivors) { String containerAggregationIdentifier = experimentCriteria.getContainerIdentifier(); List<String> experimentMethods = experimentCriteria.getExperimentMethods(); List<String> specificContainerTargets = experimentCriteria.getSpecificContainerTargets(); log.debug("Creating experiments of type {} against {} with identifier {}", experimentMethods, platform, containerAggregationIdentifier); List<Container> potentialContainers = new ArrayList<>(platform.getRosterByAggregationId(containerAggregationIdentifier)); if (potentialContainers.size() - minimumNumberOfSurvivors < experimentMethods.size()) { throw new ChaosException(NOT_ENOUGH_CONTAINERS_FOR_PLANNED_EXPERIMENT); } Stream<Experiment> experimentStream1 = IntStream.range(0, specificContainerTargets.size()).mapToObj(i -> { String experimentMethod = experimentMethods.get(i); Experiment experiment = createSingleExperiment(platform, specificContainerTargets.get(i), experimentMethod); Optional.ofNullable(experiment).map(Experiment::getContainer).ifPresent(potentialContainers::remove); return experiment; }); List<String> leftoverExperimentMethods = experimentMethods.subList(specificContainerTargets.size(), experimentMethods .size()); Collections.shuffle(potentialContainers); Stream<Experiment> experimentStream2 = IntStream.range(0, leftoverExperimentMethods.size()).mapToObj(i -> { Container container = potentialContainers.get(i); String experimentMethod = leftoverExperimentMethods.get(i); return container.createExperiment(experimentMethod); }); return Stream.concat(experimentStream1, experimentStream2); }
ExperimentManager { Stream<Experiment> createSpecificExperiments (Platform platform, ExperimentSuite.ExperimentCriteria experimentCriteria, int minimumNumberOfSurvivors) { String containerAggregationIdentifier = experimentCriteria.getContainerIdentifier(); List<String> experimentMethods = experimentCriteria.getExperimentMethods(); List<String> specificContainerTargets = experimentCriteria.getSpecificContainerTargets(); log.debug("Creating experiments of type {} against {} with identifier {}", experimentMethods, platform, containerAggregationIdentifier); List<Container> potentialContainers = new ArrayList<>(platform.getRosterByAggregationId(containerAggregationIdentifier)); if (potentialContainers.size() - minimumNumberOfSurvivors < experimentMethods.size()) { throw new ChaosException(NOT_ENOUGH_CONTAINERS_FOR_PLANNED_EXPERIMENT); } Stream<Experiment> experimentStream1 = IntStream.range(0, specificContainerTargets.size()).mapToObj(i -> { String experimentMethod = experimentMethods.get(i); Experiment experiment = createSingleExperiment(platform, specificContainerTargets.get(i), experimentMethod); Optional.ofNullable(experiment).map(Experiment::getContainer).ifPresent(potentialContainers::remove); return experiment; }); List<String> leftoverExperimentMethods = experimentMethods.subList(specificContainerTargets.size(), experimentMethods .size()); Collections.shuffle(potentialContainers); Stream<Experiment> experimentStream2 = IntStream.range(0, leftoverExperimentMethods.size()).mapToObj(i -> { Container container = potentialContainers.get(i); String experimentMethod = leftoverExperimentMethods.get(i); return container.createExperiment(experimentMethod); }); return Stream.concat(experimentStream1, experimentStream2); } }
ExperimentManager { Stream<Experiment> createSpecificExperiments (Platform platform, ExperimentSuite.ExperimentCriteria experimentCriteria, int minimumNumberOfSurvivors) { String containerAggregationIdentifier = experimentCriteria.getContainerIdentifier(); List<String> experimentMethods = experimentCriteria.getExperimentMethods(); List<String> specificContainerTargets = experimentCriteria.getSpecificContainerTargets(); log.debug("Creating experiments of type {} against {} with identifier {}", experimentMethods, platform, containerAggregationIdentifier); List<Container> potentialContainers = new ArrayList<>(platform.getRosterByAggregationId(containerAggregationIdentifier)); if (potentialContainers.size() - minimumNumberOfSurvivors < experimentMethods.size()) { throw new ChaosException(NOT_ENOUGH_CONTAINERS_FOR_PLANNED_EXPERIMENT); } Stream<Experiment> experimentStream1 = IntStream.range(0, specificContainerTargets.size()).mapToObj(i -> { String experimentMethod = experimentMethods.get(i); Experiment experiment = createSingleExperiment(platform, specificContainerTargets.get(i), experimentMethod); Optional.ofNullable(experiment).map(Experiment::getContainer).ifPresent(potentialContainers::remove); return experiment; }); List<String> leftoverExperimentMethods = experimentMethods.subList(specificContainerTargets.size(), experimentMethods .size()); Collections.shuffle(potentialContainers); Stream<Experiment> experimentStream2 = IntStream.range(0, leftoverExperimentMethods.size()).mapToObj(i -> { Container container = potentialContainers.get(i); String experimentMethod = leftoverExperimentMethods.get(i); return container.createExperiment(experimentMethod); }); return Stream.concat(experimentStream1, experimentStream2); }  }
ExperimentManager { Stream<Experiment> createSpecificExperiments (Platform platform, ExperimentSuite.ExperimentCriteria experimentCriteria, int minimumNumberOfSurvivors) { String containerAggregationIdentifier = experimentCriteria.getContainerIdentifier(); List<String> experimentMethods = experimentCriteria.getExperimentMethods(); List<String> specificContainerTargets = experimentCriteria.getSpecificContainerTargets(); log.debug("Creating experiments of type {} against {} with identifier {}", experimentMethods, platform, containerAggregationIdentifier); List<Container> potentialContainers = new ArrayList<>(platform.getRosterByAggregationId(containerAggregationIdentifier)); if (potentialContainers.size() - minimumNumberOfSurvivors < experimentMethods.size()) { throw new ChaosException(NOT_ENOUGH_CONTAINERS_FOR_PLANNED_EXPERIMENT); } Stream<Experiment> experimentStream1 = IntStream.range(0, specificContainerTargets.size()).mapToObj(i -> { String experimentMethod = experimentMethods.get(i); Experiment experiment = createSingleExperiment(platform, specificContainerTargets.get(i), experimentMethod); Optional.ofNullable(experiment).map(Experiment::getContainer).ifPresent(potentialContainers::remove); return experiment; }); List<String> leftoverExperimentMethods = experimentMethods.subList(specificContainerTargets.size(), experimentMethods .size()); Collections.shuffle(potentialContainers); Stream<Experiment> experimentStream2 = IntStream.range(0, leftoverExperimentMethods.size()).mapToObj(i -> { Container container = potentialContainers.get(i); String experimentMethod = leftoverExperimentMethods.get(i); return container.createExperiment(experimentMethod); }); return Stream.concat(experimentStream1, experimentStream2); }  void setExperimentBackoffPeriod(Duration experimentBackoffPeriod); boolean areExperimentsInProgress(); }
ExperimentManager { Stream<Experiment> createSpecificExperiments (Platform platform, ExperimentSuite.ExperimentCriteria experimentCriteria, int minimumNumberOfSurvivors) { String containerAggregationIdentifier = experimentCriteria.getContainerIdentifier(); List<String> experimentMethods = experimentCriteria.getExperimentMethods(); List<String> specificContainerTargets = experimentCriteria.getSpecificContainerTargets(); log.debug("Creating experiments of type {} against {} with identifier {}", experimentMethods, platform, containerAggregationIdentifier); List<Container> potentialContainers = new ArrayList<>(platform.getRosterByAggregationId(containerAggregationIdentifier)); if (potentialContainers.size() - minimumNumberOfSurvivors < experimentMethods.size()) { throw new ChaosException(NOT_ENOUGH_CONTAINERS_FOR_PLANNED_EXPERIMENT); } Stream<Experiment> experimentStream1 = IntStream.range(0, specificContainerTargets.size()).mapToObj(i -> { String experimentMethod = experimentMethods.get(i); Experiment experiment = createSingleExperiment(platform, specificContainerTargets.get(i), experimentMethod); Optional.ofNullable(experiment).map(Experiment::getContainer).ifPresent(potentialContainers::remove); return experiment; }); List<String> leftoverExperimentMethods = experimentMethods.subList(specificContainerTargets.size(), experimentMethods .size()); Collections.shuffle(potentialContainers); Stream<Experiment> experimentStream2 = IntStream.range(0, leftoverExperimentMethods.size()).mapToObj(i -> { Container container = potentialContainers.get(i); String experimentMethod = leftoverExperimentMethods.get(i); return container.createExperiment(experimentMethod); }); return Stream.concat(experimentStream1, experimentStream2); }  void setExperimentBackoffPeriod(Duration experimentBackoffPeriod); boolean areExperimentsInProgress();  }