summaryrefslogtreecommitdiffstats
path: root/core/tests
diff options
context:
space:
mode:
authorDavid Hu <hud@google.com>2012-03-14 15:43:46 -0700
committerDavid Hu <hud@google.com>2012-03-19 18:33:58 -0700
commitca4aab9cd724708af30abb4bfcb2f9b45087f449 (patch)
treeb39154026ba138251e979556f83810965e0f17c9 /core/tests
parentbf02b984738f6be5cc2e2d66b12aff7af99eb79e (diff)
downloadframeworks_base-ca4aab9cd724708af30abb4bfcb2f9b45087f449.zip
frameworks_base-ca4aab9cd724708af30abb4bfcb2f9b45087f449.tar.gz
frameworks_base-ca4aab9cd724708af30abb4bfcb2f9b45087f449.tar.bz2
BandwidthTestCase
A test case that measures bandwidth metrics when annotated with android.test.BandwidthTest and adds the metrics to the status bundle Change-Id: I085110c66c7fcf651aefeeac3d4cdf5bd438ff67
Diffstat (limited to 'core/tests')
-rw-r--r--core/tests/utillib/src/android/test/BandwidthTest.java30
-rw-r--r--core/tests/utillib/src/android/test/BandwidthTestCase.java140
2 files changed, 170 insertions, 0 deletions
diff --git a/core/tests/utillib/src/android/test/BandwidthTest.java b/core/tests/utillib/src/android/test/BandwidthTest.java
new file mode 100644
index 0000000..6cff0ff
--- /dev/null
+++ b/core/tests/utillib/src/android/test/BandwidthTest.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2012 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.test;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * This annotation can be used on an {@link junit.framework.TestCase}'s test methods. When the
+ * annotation is present, the test method is profiled for bandwidth metrics and the results
+ * written through instrumentation output. It can also be used on the class itself,
+ * which is equivalent to tagging all test methods with this annotation.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+public @interface BandwidthTest {
+}
diff --git a/core/tests/utillib/src/android/test/BandwidthTestCase.java b/core/tests/utillib/src/android/test/BandwidthTestCase.java
new file mode 100644
index 0000000..4f95f77
--- /dev/null
+++ b/core/tests/utillib/src/android/test/BandwidthTestCase.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2012 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.test;
+
+import android.net.NetworkStats;
+import android.net.TrafficStats;
+import android.os.Bundle;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+/**
+ * A bandwidth test case that collects bandwidth statistics for tests that are
+ * annotated with {@link BandwidthTest} otherwise the test is executed
+ * as an {@link InstrumentationTestCase}
+ */
+public class BandwidthTestCase extends InstrumentationTestCase {
+ private static final String REPORT_KEY_PACKETS_SENT = "txPackets";
+ private static final String REPORT_KEY_PACKETS_RECEIVED = "rxPackets";
+ private static final String REPORT_KEY_BYTES_SENT = "txBytes";
+ private static final String REPORT_KEY_BYTES_RECEIVED = "rxBytes";
+ private static final String REPORT_KEY_OPERATIONS = "operations";
+
+ @Override
+ protected void runTest() throws Throwable {
+ //This is a copy of {@link InstrumentationTestCase#runTest} with
+ //added logic to handle bandwidth measurements
+ String fName = getName();
+ assertNotNull(fName);
+ Method method = null;
+ Class testClass = null;
+ try {
+ // use getMethod to get all public inherited
+ // methods. getDeclaredMethods returns all
+ // methods of this class but excludes the
+ // inherited ones.
+ testClass = getClass();
+ method = testClass.getMethod(fName, (Class[]) null);
+ } catch (NoSuchMethodException e) {
+ fail("Method \""+fName+"\" not found");
+ }
+
+ if (!Modifier.isPublic(method.getModifiers())) {
+ fail("Method \""+fName+"\" should be public");
+ }
+
+ int runCount = 1;
+ boolean isRepetitive = false;
+ if (method.isAnnotationPresent(FlakyTest.class)) {
+ runCount = method.getAnnotation(FlakyTest.class).tolerance();
+ } else if (method.isAnnotationPresent(RepetitiveTest.class)) {
+ runCount = method.getAnnotation(RepetitiveTest.class).numIterations();
+ isRepetitive = true;
+ }
+
+ if (method.isAnnotationPresent(UiThreadTest.class)) {
+ final int tolerance = runCount;
+ final boolean repetitive = isRepetitive;
+ final Method testMethod = method;
+ final Throwable[] exceptions = new Throwable[1];
+ getInstrumentation().runOnMainSync(new Runnable() {
+ public void run() {
+ try {
+ runMethod(testMethod, tolerance, repetitive);
+ } catch (Throwable throwable) {
+ exceptions[0] = throwable;
+ }
+ }
+ });
+ if (exceptions[0] != null) {
+ throw exceptions[0];
+ }
+ } else if (method.isAnnotationPresent(BandwidthTest.class) ||
+ testClass.isAnnotationPresent(BandwidthTest.class)) {
+ TrafficStats.startDataProfiling(null);
+ runMethod(method, 1, false);
+ NetworkStats stats = TrafficStats.stopDataProfiling(null);
+ NetworkStats.Entry entry = stats.getTotal(null);
+ getInstrumentation().sendStatus(2, getBandwidthStats(entry));
+ } else {
+ runMethod(method, runCount, isRepetitive);
+ }
+ }
+
+ private void runMethod(Method runMethod, int tolerance, boolean isRepetitive) throws Throwable {
+ //This is a copy of {@link InstrumentationTestCase#runMethod}
+ Throwable exception = null;
+
+ int runCount = 0;
+ do {
+ try {
+ runMethod.invoke(this, (Object[]) null);
+ exception = null;
+ } catch (InvocationTargetException e) {
+ e.fillInStackTrace();
+ exception = e.getTargetException();
+ } catch (IllegalAccessException e) {
+ e.fillInStackTrace();
+ exception = e;
+ } finally {
+ runCount++;
+ // Report current iteration number, if test is repetitive
+ if (isRepetitive) {
+ Bundle iterations = new Bundle();
+ iterations.putInt("currentiterations", runCount);
+ getInstrumentation().sendStatus(2, iterations);
+ }
+ }
+ } while ((runCount < tolerance) && (isRepetitive || exception != null));
+
+ if (exception != null) {
+ throw exception;
+ }
+ }
+
+ private Bundle getBandwidthStats(NetworkStats.Entry entry){
+ Bundle bundle = new Bundle();
+ bundle.putLong(REPORT_KEY_BYTES_RECEIVED, entry.rxBytes);
+ bundle.putLong(REPORT_KEY_BYTES_SENT, entry.txBytes);
+ bundle.putLong(REPORT_KEY_PACKETS_RECEIVED, entry.rxPackets);
+ bundle.putLong(REPORT_KEY_PACKETS_SENT, entry.txPackets);
+ bundle.putLong(REPORT_KEY_OPERATIONS, entry.operations);
+ return bundle;
+ }
+}
+