1 /* 2 * Copyright (C) 2016 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 17 package android.perftests.utils; 18 19 import static junit.framework.Assert.assertFalse; 20 import static junit.framework.Assert.assertTrue; 21 22 import android.util.Log; 23 24 import androidx.test.InstrumentationRegistry; 25 26 import org.junit.rules.TestRule; 27 import org.junit.runner.Description; 28 import org.junit.runners.model.Statement; 29 30 /** 31 * Use this rule to make sure we report the status after the test success. 32 * 33 * <code> 34 * 35 * @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter(); 36 * @Test public void functionName() { 37 * ... 38 * BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); 39 * while (state.keepRunning()) { 40 * // DO YOUR TEST HERE! 41 * } 42 * ... 43 * } 44 * </code> 45 * 46 * When test succeeded, the status report will use the key as 47 * "functionName[optional subTestName]_*" 48 * 49 * Notice that optional subTestName can't be just numbers, that means each sub test needs to have a 50 * name when using parameterization. 51 */ 52 53 public class PerfStatusReporter implements TestRule { 54 private static final String TAG = "PerfStatusReporter"; 55 private final BenchmarkState mState = new BenchmarkState(); 56 getBenchmarkState()57 public BenchmarkState getBenchmarkState() { 58 return mState; 59 } 60 61 @Override apply(Statement base, Description description)62 public Statement apply(Statement base, Description description) { 63 return new Statement() { 64 @Override 65 public void evaluate() throws Throwable { 66 String invokeMethodName = description.getMethodName(); 67 Log.i(TAG, "Running " + description.getClassName() + "#" + invokeMethodName); 68 69 // validate and simplify the function name. 70 // First, remove the "test" prefix which normally comes from CTS test. 71 // Then make sure the [subTestName] is valid, not just numbers like [0]. 72 if (invokeMethodName.startsWith("test")) { 73 assertTrue("The test name " + invokeMethodName + " is too short", 74 invokeMethodName.length() > 5); 75 invokeMethodName = invokeMethodName.substring(4, 5).toLowerCase() 76 + invokeMethodName.substring(5); 77 } 78 79 int index = invokeMethodName.lastIndexOf('['); 80 if (index > 0) { 81 boolean allDigits = true; 82 for (int i = index + 1; i < invokeMethodName.length() - 1; i++) { 83 if (!Character.isDigit(invokeMethodName.charAt(i))) { 84 allDigits = false; 85 break; 86 } 87 } 88 assertFalse("The name in [] can't contain only digits for " + invokeMethodName, 89 allDigits); 90 } 91 92 base.evaluate(); 93 94 mState.sendFullStatusReport(InstrumentationRegistry.getInstrumentation(), 95 invokeMethodName); 96 } 97 }; 98 } 99 } 100