summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuang Zhu <guangzhu@google.com>2015-05-12 10:37:41 -0700
committerGuang Zhu <guangzhu@google.com>2015-05-12 10:45:18 -0700
commit392b02203de525e2b14d869031974a23fc8428a2 (patch)
tree3511abbda723898b5e09973a9b4a434aa118c9f6
parentb8046de3d836019895807ea4e28504a297d5e844 (diff)
downloadjanktesthelper-392b02203de525e2b14d869031974a23fc8428a2.tar.gz
support specifying process name at runtime
If the annoated process name with GfxMonitor starts with '#', we treat it as a method that returns a String to indicate process name. Such method will be called between beforeTest and test iteration starts, in case that test class needs to setup test iteration before it can determine the process name. Also added monitor class name in the assertion message when not enough frames are received. Change-Id: I462f7c10a600372e137eb3d314cbf6703aa14ff5
-rw-r--r--src/main/java/android/support/test/jank/GfxMonitor.java5
-rw-r--r--src/main/java/android/support/test/jank/JankTestBase.java15
-rw-r--r--src/main/java/android/support/test/jank/internal/JankMonitorFactory.java36
3 files changed, 47 insertions, 9 deletions
diff --git a/src/main/java/android/support/test/jank/GfxMonitor.java b/src/main/java/android/support/test/jank/GfxMonitor.java
index 71ede73..18f283a 100644
--- a/src/main/java/android/support/test/jank/GfxMonitor.java
+++ b/src/main/java/android/support/test/jank/GfxMonitor.java
@@ -25,7 +25,10 @@ import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface GfxMonitor {
- /** The name of the process to monitor */
+ /**
+ * The name of the process to monitor. Alternatively, if the name begins with '#', it specifies
+ * a method that takes no parameters and returns string as the process name to monitor.
+ * */
String processName();
public static final String KEY_AVG_NUM_JANKY = "gfx-avg-jank";
diff --git a/src/main/java/android/support/test/jank/JankTestBase.java b/src/main/java/android/support/test/jank/JankTestBase.java
index bb2605d..a2398c7 100644
--- a/src/main/java/android/support/test/jank/JankTestBase.java
+++ b/src/main/java/android/support/test/jank/JankTestBase.java
@@ -20,8 +20,8 @@ import android.app.Activity;
import android.app.Instrumentation;
import android.os.Bundle;
import android.support.test.InstrumentationRegistry;
-import android.support.test.jank.internal.JankMonitorFactory;
import android.support.test.jank.internal.JankMonitor;
+import android.support.test.jank.internal.JankMonitorFactory;
import android.support.test.runner.AndroidJUnitRunner;
import android.test.InstrumentationTestCase;
import android.test.InstrumentationTestRunner;
@@ -89,14 +89,14 @@ public class JankTestBase extends InstrumentationTestCase {
Method afterLoop = resolveMethod(annotation.afterLoop());
Method afterTest = resolveAfterTest(annotation.afterTest());
+ // Test setup
+ beforeTest.invoke(this, (Object[])null);
+
// Get the appropriate JankMonitors for the test type
JankMonitorFactory factory = new JankMonitorFactory(getInstrumentation().getUiAutomation());
- List<JankMonitor> monitors = factory.getJankMonitors(testMethod);
+ List<JankMonitor> monitors = factory.getJankMonitors(testMethod, this);
assertTrue("No monitors configured for this test", monitors.size() > 0);
- // Test setup
- beforeTest.invoke(this, (Object[])null);
-
// Execute the test several times according to the "iteration" parameter
int iterations = Integer.valueOf(getArguments().getString("iterations",
Integer.toString(annotation.defaultIterationCount())));
@@ -117,8 +117,9 @@ public class JankTestBase extends InstrumentationTestCase {
int numFrames = monitor.stopIteration();
// Fail the test if we didn't get enough frames
- assertTrue(String.format("Too few frames received. Expected: %d, Received: %d.",
- annotation.expectedFrames(), numFrames),
+ assertTrue(String.format(
+ "Too few frames received. Monitor: %s, Expected: %d, Received: %d.",
+ monitor.getClass().getSimpleName(), annotation.expectedFrames(), numFrames),
numFrames >= annotation.expectedFrames());
}
diff --git a/src/main/java/android/support/test/jank/internal/JankMonitorFactory.java b/src/main/java/android/support/test/jank/internal/JankMonitorFactory.java
index 55f940d..d3b1cb7 100644
--- a/src/main/java/android/support/test/jank/internal/JankMonitorFactory.java
+++ b/src/main/java/android/support/test/jank/internal/JankMonitorFactory.java
@@ -18,12 +18,17 @@ package android.support.test.jank.internal;
import android.app.UiAutomation;
import android.os.Build;
+import android.support.test.jank.JankTestBase;
import android.support.test.jank.WindowAnimationFrameStatsMonitor;
import android.support.test.jank.WindowContentFrameStatsMonitor;
import android.support.test.jank.GfxMonitor;
import android.util.Log;
+import junit.framework.Assert;
+
+import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
@@ -40,7 +45,7 @@ public class JankMonitorFactory {
mUiAutomation = automation;
}
- public List<JankMonitor> getJankMonitors(Method testMethod) {
+ public List<JankMonitor> getJankMonitors(Method testMethod, JankTestBase testInstance) {
List<JankMonitor> monitors = new ArrayList<JankMonitor>();
if (testMethod.getAnnotation(GfxMonitor.class) != null) {
// GfxMonitor only works on M+. NB: Hard coding value since SDK 22 isn't in prebuilts.
@@ -48,6 +53,35 @@ public class JankMonitorFactory {
Log.w(TAG, "Skipping GfxMonitor. Not supported by current platform.");
} else {
String process = testMethod.getAnnotation(GfxMonitor.class).processName();
+ // if process name starts with "#", treat it as a method that returns process name
+ if (process.startsWith("#")) {
+ process = process.substring(1);
+ Method method = null;
+ try {
+ method = testMethod.getDeclaringClass().getMethod(process, (Class[]) null);
+ } catch (NoSuchMethodException e) {
+ Assert.fail(String.format("Method \"%s\" not found", process));
+ }
+
+ if (!Modifier.isPublic(method.getModifiers())) {
+ Assert.fail(String.format("Method \"%s\" should be public", process));
+ }
+
+ Object o = null;
+ try {
+ o = method.invoke(testInstance, (Object[])null);
+ } catch (IllegalAccessException | IllegalArgumentException
+ | InvocationTargetException e) {
+ Assert.fail(String.format(
+ "Exception %s(%s) while invoking \"%s\" for monitored process name",
+ e.getClass().getName(), e.getMessage(), process));
+ }
+ if (o == null || !(o instanceof String)) {
+ Assert.fail(String.format("Method \"%s\" should return String", process));
+ }
+ process = (String)o;
+ Log.d(TAG, "Using process name from annotated method: " + process);
+ }
monitors.add(new GfxMonitorImpl(mUiAutomation, process));
}
}