• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package android.platform.test.microbenchmark;
17 
18 import static com.google.common.truth.Truth.assertThat;
19 
20 import android.os.Bundle;
21 import android.platform.test.rule.TracePointRule;
22 
23 import org.junit.After;
24 import org.junit.Before;
25 import org.junit.Test;
26 import org.junit.rules.TestRule;
27 import org.junit.runner.Description;
28 import org.junit.runner.JUnitCore;
29 import org.junit.runner.Result;
30 import org.junit.runner.RunWith;
31 import org.junit.runners.JUnit4;
32 import org.junit.runners.model.InitializationError;
33 import org.junit.runners.model.Statement;
34 
35 import java.util.ArrayList;
36 import java.util.List;
37 
38 /**
39  * Unit tests for the {@link Microbenchmark} runner.
40  */
41 @RunWith(JUnit4.class)
42 public final class MicrobenchmarkTest {
43     /**
44      * Tests that iterations are respected for microbenchmark tests.
45      */
46     @Test
testIterationCount()47     public void testIterationCount() throws InitializationError {
48         Bundle args = new Bundle();
49         args.putString("iterations", "10");
50         Microbenchmark microbench = new Microbenchmark(BasicTest.class, args);
51         assertThat(microbench.testCount()).isEqualTo(10);
52     }
53 
54     public static class BasicTest {
55         @Test
doNothingTest()56         public void doNothingTest() { }
57     }
58 
59     /**
60      * Tests that {@link TracePointRule} and {@link TightMethodRule}s are properly ordered.
61      *
62      * Before --> TightBefore --> Trace (begin) --> Test --> Trace(end) --> TightAfter --> After
63      */
64     @Test
testFeatureExecutionOrder()65     public void testFeatureExecutionOrder() throws InitializationError {
66         LoggingMicrobenchmark loggingRunner = new LoggingMicrobenchmark(LoggingTest.class);
67         loggingRunner.setOperationLog(new ArrayList<String>());
68         Result result = new JUnitCore().run(loggingRunner);
69         assertThat(result.wasSuccessful()).isTrue();
70         assertThat(loggingRunner.getOperationLog()).containsExactly(
71                 "before",
72                 "tight before",
73                 "begin: testMethod("
74                     + "android.platform.test.microbenchmark.MicrobenchmarkTest$LoggingTest)",
75                 "test",
76                 "end",
77                 "tight after",
78                 "after")
79             .inOrder();
80     }
81 
82     /**
83      * An extensions of the {@link Microbenchmark} runner that logs the start and end of collecting
84      * traces. It also passes the operation log to the provided test {@code Class}, if it is a
85      * {@link LoggingTest}. This is used for ensuring the proper order for evaluating test {@link
86      * Statement}s.
87      */
88     public static class LoggingMicrobenchmark extends Microbenchmark {
89         private List<String> mOperationLog;
90 
LoggingMicrobenchmark(Class<?> klass)91         public LoggingMicrobenchmark(Class<?> klass) throws InitializationError {
92             super(klass);
93         }
94 
LoggingMicrobenchmark(Class<?> klass, Bundle arguments)95         LoggingMicrobenchmark(Class<?> klass, Bundle arguments) throws InitializationError {
96             super(klass, arguments);
97         }
98 
createTest()99         protected Object createTest() throws Exception {
100             Object test = super.createTest();
101             if (test instanceof LoggingTest) {
102                 ((LoggingTest)test).setOperationLog(mOperationLog);
103             }
104             return test;
105         }
106 
setOperationLog(List<String> log)107         void setOperationLog(List<String> log) {
108             mOperationLog = log;
109         }
110 
getOperationLog()111         List<String> getOperationLog() {
112             return mOperationLog;
113         }
114 
115         @Override
getTracePointRule()116         protected TracePointRule getTracePointRule() {
117             return new LoggingTracePointRule();
118         }
119 
120         class LoggingTracePointRule extends TracePointRule {
121             @Override
beginSection(String sectionTag)122             protected void beginSection(String sectionTag) {
123                 mOperationLog.add(String.format("begin: %s", sectionTag));
124             }
125 
126             @Override
endSection()127             protected void endSection() {
128                 mOperationLog.add("end");
129             }
130         }
131     }
132 
133     /**
134      * A test that logs {@link Before}, {@link After}, {@link Test}, and the logging {@link
135      * TightMethodRule} included, used in conjunction with {@link LoggingMicrobenchmark} to
136      * determine all {@link Statement}s are evaluated in the proper order.
137      */
138     public static class LoggingTest {
139         @Microbenchmark.TightMethodRule
140         public TightRule orderRule = new TightRule();
141 
142         private List<String> mOperationLog;
143 
setOperationLog(List<String> log)144         void setOperationLog(List<String> log) {
145             mOperationLog = log;
146         }
147 
148         @Before
beforeMethod()149         public void beforeMethod() {
150             mOperationLog.add("before");
151         }
152 
153         @Test
testMethod()154         public void testMethod() {
155             mOperationLog.add("test");
156         }
157 
158         @After
afterMethod()159         public void afterMethod() {
160             mOperationLog.add("after");
161         }
162 
163         class TightRule implements TestRule {
164             @Override
apply(Statement base, Description description)165             public Statement apply(Statement base, Description description) {
166                 return new Statement() {
167                     @Override
168                     public void evaluate() throws Throwable {
169                         mOperationLog.add("tight before");
170                         base.evaluate();
171                         mOperationLog.add("tight after");
172                     }
173                 };
174             }
175         }
176     }
177 }
178