package io.jenkins.plugins.analysis.core.charts; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import io.jenkins.plugins.analysis.core.model.AnalysisResult; import io.jenkins.plugins.analysis.core.util.HealthDescriptor; import static java.util.Arrays.*; import static org.assertj.core.api.Assertions.*; import static org.mockito.Mockito.*; /** * Tests class {@link HealthSeriesBuilder}. * * @author Florian Pirchmoser */ class HealthSeriesBuilderTest { private static final int HEALTH_THRESHOLD = 2; private static final int UNHEALTHY_THRESHOLD = 5; @SuppressFBWarnings("UPM") @SuppressWarnings("PMD.UnusedPrivateMethod") private static Iterable<Object> testData() { return asList( new TestArgumentsBuilder() .setTestName("all healthy when descriptor disabled") .setDescriptor(createDisabledDescriptor()) .setRun(createRunWithSize(4)) .setExpectedSeries(4) .build(), new TestArgumentsBuilder() .setTestName("no issues") .setDescriptor(createEnabledDescriptor(HEALTH_THRESHOLD, UNHEALTHY_THRESHOLD)) .setRun(createRunWithSize(0)) .setExpectedSeries(0, 0, 0) .build(), new TestArgumentsBuilder() .setTestName("all healthy when below health threshold") .setDescriptor(createEnabledDescriptor(HEALTH_THRESHOLD, UNHEALTHY_THRESHOLD)) .setRun(createRunWithSize(1)) .setExpectedSeries(HEALTH_THRESHOLD - 1, 0, 0) .build(), new TestArgumentsBuilder() .setTestName("all healthy when at health threshold") .setDescriptor(createEnabledDescriptor(HEALTH_THRESHOLD, UNHEALTHY_THRESHOLD)) .setRun(createRunWithSize(HEALTH_THRESHOLD)) .setExpectedSeries(HEALTH_THRESHOLD, 0, 0) .build(), new TestArgumentsBuilder() .setTestName("one medium when above health, below unhealth threshold") .setDescriptor(createEnabledDescriptor(HEALTH_THRESHOLD, UNHEALTHY_THRESHOLD)) .setRun(createRunWithSize(HEALTH_THRESHOLD + 1)) .setExpectedSeries(HEALTH_THRESHOLD, 1, 0) .build(), new TestArgumentsBuilder() .setTestName("none unhealthy when below unhealth threshold") .setDescriptor(createEnabledDescriptor(HEALTH_THRESHOLD, UNHEALTHY_THRESHOLD)) .setRun(createRunWithSize(UNHEALTHY_THRESHOLD - 1)) .setExpectedSeries(HEALTH_THRESHOLD, 2, 0) .build(), new TestArgumentsBuilder() .setTestName("none unhealthy when at unhealth threshold") .setDescriptor(createEnabledDescriptor(HEALTH_THRESHOLD, UNHEALTHY_THRESHOLD)) .setRun(createRunWithSize(UNHEALTHY_THRESHOLD)) .setExpectedSeries(HEALTH_THRESHOLD, 3, 0) .build(), new TestArgumentsBuilder() .setTestName("one unhealthy when above unhealth threshold") .setDescriptor(createEnabledDescriptor(HEALTH_THRESHOLD, UNHEALTHY_THRESHOLD)) .setRun(createRunWithSize(UNHEALTHY_THRESHOLD + 1)) .setExpectedSeries(HEALTH_THRESHOLD, 3, 1) .build() ); } @ParameterizedTest(name = "{0}") @MethodSource("testData") void testComputeSeries( final String name, final HealthDescriptor descriptor, final AnalysisResult run, final List<Integer> expectedSeries) { HealthSeriesBuilder sut = new HealthSeriesBuilder(descriptor); Map<String, Integer> series = sut.computeSeries(run); List<Integer> values = new ArrayList<>(); if (expectedSeries.size() == 1) { values.add(series.get(HealthSeriesBuilder.TOTAL)); } else { values.add(series.get(HealthSeriesBuilder.HEALTHY)); values.add(series.get(HealthSeriesBuilder.BETWEEN)); values.add(series.get(HealthSeriesBuilder.UNHEALTHY)); } expectedSeries.forEach(value -> assertThat(values).contains(value)); } private static AnalysisResult createRunWithSize(final int totalSize) { AnalysisResult run = mock(AnalysisResult.class); when(run.getTotalSize()).thenReturn(totalSize); return run; } private static HealthDescriptor createDisabledDescriptor() { return createDescriptor(false); } private static HealthDescriptor createEnabledDescriptor(final int healthThreshold, final int unhealthThreshhold) { HealthDescriptor healthDescriptor = createDescriptor(true); when(healthDescriptor.getHealthy()).thenReturn(healthThreshold); when(healthDescriptor.getUnhealthy()).thenReturn(unhealthThreshhold); return healthDescriptor; } private static HealthDescriptor createDescriptor(final boolean isEnabled) { HealthDescriptor descriptor = mock(HealthDescriptor.class); if (isEnabled) { when(descriptor.isEnabled()).thenReturn(true); } return descriptor; } /** * Builds arg for the parameterized test. */ private static class TestArgumentsBuilder { private String name; private AnalysisResult run; private HealthDescriptor descriptor; private Iterable<Integer> series; /** * Set the tests name. * * @param testName * name of the test. * * @return this */ TestArgumentsBuilder setTestName(final String testName) { name = testName; return this; } /** * Set the health descriptor used in test. * * @param descriptor * used in test * * @return this */ TestArgumentsBuilder setDescriptor(final HealthDescriptor descriptor) { this.descriptor = descriptor; return this; } /** * Set the analysis run used in test. * * @param run * used in test * * @return this */ TestArgumentsBuilder setRun(final AnalysisResult run) { this.run = run; return this; } /** * Set test expectation. * * @param expectedSeries * expected as result. * * @return this */ TestArgumentsBuilder setExpectedSeries(final Integer... expectedSeries) { series = asList(expectedSeries); return this; } /** * Build the tests argument. * * @return test arg */ Object build() { return Arguments.of( name, descriptor, run, series ); } } }