blob: 0434969b3503f66efd448ade1cc967fd9a029615 [file] [log] [blame]
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.regression.tests;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import com.android.regression.tests.DetectRegression.TableRow;
import com.android.tradefed.result.TestDescription;
import com.android.tradefed.util.MultiMap;
import com.google.common.primitives.Doubles;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.mockito.ArgumentCaptor;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/** Unit tests for {@link DetectRegression}. */
@RunWith(JUnit4.class)
public class DetectRegressionTest {
private static final double EPS = 0.0001;
@Test
public void testCalcMean() {
Map<Double, double[]> data = new HashMap<>();
data.put(2.5, new double[] {1, 2, 3, 4});
data.put(
4.5,
new double[] {
-11, 22, 5, 4, 2.5,
});
data.forEach(
(k, v) -> {
assertTrue(equal(k, DetectRegression.calcMean(Doubles.asList(v))));
});
}
@Test
public void testCalcStdDev() {
Map<Double, double[]> data = new HashMap<>();
data.put(36.331000536732, new double[] {12.3, 56.7, 45.6, 124, 56});
data.put(119.99906922093, new double[] {123.4, 22.5, 5.67, 4.56, 2.5, 333});
data.forEach(
(k, v) -> {
assertTrue(equal(k, DetectRegression.calcStdDev(Doubles.asList(v))));
});
}
@Test
public void testDetectRegression() {
List<List<Double>> befores =
Arrays.stream(
new double[][] {
{3, 3, 3, 3, 3},
{3, 5, 3, 5, 4},
{3, 4, 3, 4, 3},
{1, 2, 3, 2, 1},
{-1, -2, -3, 0, 1, 2, 3},
{5, 6, 5, 6, 6, 5, 7},
})
.map(Doubles::asList)
.collect(Collectors.toList());
List<List<Double>> afters =
Arrays.stream(
new double[][] {
{3, 3, 3, 3, 3},
{2, 3, 4, 5, 6},
{2, 5, 2, 5, 2},
{10, 11, 12, 13, 14},
{-10, -20, -30, 0, 10, 20, 30},
{5, 6, 5, 6, 6, 5, 700},
})
.map(Doubles::asList)
.collect(Collectors.toList());
boolean[] result = {false, false, true, true, true, false};
for (int i = 0; i < result.length; i++) {
assertEquals(
result[i], DetectRegression.computeRegression(befores.get(i), afters.get(i)));
}
}
@SuppressWarnings("unchecked")
@Test
public void testRunRegressionDetection() {
DetectRegression detector = spy(DetectRegression.class);
doNothing().when(detector).logResult(any(), any(), any(), any());
TestDescription id1 = new TestDescription("class", "test1");
TestDescription id2 = new TestDescription("class", "test2");
Metrics before = new Metrics(false);
Arrays.asList("3.0", "3.0", "3.0", "3.0", "3.0")
.forEach(e -> before.addRunMetric("metric-1", e));
Arrays.asList("3.1", "3.3", "3.1", "3.2", "3.3")
.forEach(e -> before.addRunMetric("metric-2", e));
Arrays.asList("5.1", "5.2", "5.1", "5.2", "5.1")
.forEach(e -> before.addRunMetric("metric-3", e));
Arrays.asList("3.0", "3.0", "3.0", "3.0", "3.0")
.forEach(e -> before.addTestMetric(id1, "metric-4", e));
Arrays.asList("3.1", "3.3", "3.1", "3.2", "3.3")
.forEach(e -> before.addTestMetric(id2, "metric-5", e));
Arrays.asList("5.1", "5.2", "5.1", "5.2", "5.1")
.forEach(e -> before.addTestMetric(id2, "metric-6", e));
Metrics after = new Metrics(false);
Arrays.asList("3.0", "3.0", "3.0", "3.0", "3.0")
.forEach(e -> after.addRunMetric("metric-1", e));
Arrays.asList("3.2", "3.2", "3.2", "3.2", "3.2")
.forEach(e -> after.addRunMetric("metric-2", e));
Arrays.asList("8.1", "8.2", "8.1", "8.2", "8.1")
.forEach(e -> after.addRunMetric("metric-3", e));
Arrays.asList("3.0", "3.0", "3.0", "3.0", "3.0")
.forEach(e -> after.addTestMetric(id1, "metric-4", e));
Arrays.asList("3.2", "3.2", "3.2", "3.2", "3.2")
.forEach(e -> after.addTestMetric(id2, "metric-5", e));
Arrays.asList("8.1", "8.2", "8.1", "8.2", "8.1")
.forEach(e -> after.addTestMetric(id2, "metric-6", e));
ArgumentCaptor<List<TableRow>> runResultCaptor = ArgumentCaptor.forClass(List.class);
ArgumentCaptor<MultiMap<String, TableRow>> testResultCaptor =
ArgumentCaptor.forClass(MultiMap.class);
detector.runRegressionDetection(before, after);
verify(detector, times(1))
.logResult(
eq(before),
eq(after),
runResultCaptor.capture(),
testResultCaptor.capture());
List<TableRow> runResults = runResultCaptor.getValue();
assertEquals(1, runResults.size());
assertEquals("metric-3", runResults.get(0).name);
MultiMap<String, TableRow> testResults = testResultCaptor.getValue();
assertEquals(1, testResults.size());
assertEquals(1, testResults.get(id2.toString()).size());
assertEquals("metric-6", testResults.get(id2.toString()).get(0).name);
}
private boolean equal(double d1, double d2) {
return Math.abs(d1 - d2) < EPS;
}
}