blob: 0de79e33516b47b9fb2d1f2f264b81adda7ed7e0 [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 android.platform.test.microbenchmark;
import static com.google.common.truth.Truth.assertThat;
import android.os.Bundle;
import android.platform.test.rule.TracePointRule;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.junit.runners.model.InitializationError;
import org.junit.runners.model.Statement;
import java.util.ArrayList;
import java.util.List;
/**
* Unit tests for the {@link Microbenchmark} runner.
*/
@RunWith(JUnit4.class)
public final class MicrobenchmarkTest {
/**
* Tests that iterations are respected for microbenchmark tests.
*/
@Test
public void testIterationCount() throws InitializationError {
Bundle args = new Bundle();
args.putString("iterations", "10");
Microbenchmark microbench = new Microbenchmark(BasicTest.class, args);
assertThat(microbench.testCount()).isEqualTo(10);
}
public static class BasicTest {
@Test
public void doNothingTest() { }
}
/**
* Tests that {@link TracePointRule} and {@link TightMethodRule}s are properly ordered.
*
* Before --> TightBefore --> Trace (begin) --> Test --> Trace(end) --> TightAfter --> After
*/
@Test
public void testFeatureExecutionOrder() throws InitializationError {
LoggingMicrobenchmark loggingRunner = new LoggingMicrobenchmark(LoggingTest.class);
loggingRunner.setOperationLog(new ArrayList<String>());
Result result = new JUnitCore().run(loggingRunner);
assertThat(result.wasSuccessful()).isTrue();
assertThat(loggingRunner.getOperationLog()).containsExactly(
"before",
"tight before",
"begin: testMethod("
+ "android.platform.test.microbenchmark.MicrobenchmarkTest$LoggingTest)",
"test",
"end",
"tight after",
"after")
.inOrder();
}
/**
* An extensions of the {@link Microbenchmark} runner that logs the start and end of collecting
* traces. It also passes the operation log to the provided test {@code Class}, if it is a
* {@link LoggingTest}. This is used for ensuring the proper order for evaluating test {@link
* Statement}s.
*/
public static class LoggingMicrobenchmark extends Microbenchmark {
private List<String> mOperationLog;
public LoggingMicrobenchmark(Class<?> klass) throws InitializationError {
super(klass);
}
LoggingMicrobenchmark(Class<?> klass, Bundle arguments) throws InitializationError {
super(klass, arguments);
}
protected Object createTest() throws Exception {
Object test = super.createTest();
if (test instanceof LoggingTest) {
((LoggingTest)test).setOperationLog(mOperationLog);
}
return test;
}
void setOperationLog(List<String> log) {
mOperationLog = log;
}
List<String> getOperationLog() {
return mOperationLog;
}
@Override
protected TracePointRule getTracePointRule() {
return new LoggingTracePointRule();
}
class LoggingTracePointRule extends TracePointRule {
@Override
protected void beginSection(String sectionTag) {
mOperationLog.add(String.format("begin: %s", sectionTag));
}
@Override
protected void endSection() {
mOperationLog.add("end");
}
}
}
/**
* A test that logs {@link Before}, {@link After}, {@link Test}, and the logging {@link
* TightMethodRule} included, used in conjunction with {@link LoggingMicrobenchmark} to
* determine all {@link Statement}s are evaluated in the proper order.
*/
public static class LoggingTest {
@Microbenchmark.TightMethodRule
public TightRule orderRule = new TightRule();
private List<String> mOperationLog;
void setOperationLog(List<String> log) {
mOperationLog = log;
}
@Before
public void beforeMethod() {
mOperationLog.add("before");
}
@Test
public void testMethod() {
mOperationLog.add("test");
}
@After
public void afterMethod() {
mOperationLog.add("after");
}
class TightRule implements TestRule {
@Override
public Statement apply(Statement base, Description description) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
mOperationLog.add("tight before");
base.evaluate();
mOperationLog.add("tight after");
}
};
}
}
}
}