diff options
author | David Hu <hud@google.com> | 2012-03-14 15:43:46 -0700 |
---|---|---|
committer | David Hu <hud@google.com> | 2012-03-19 18:33:58 -0700 |
commit | ca4aab9cd724708af30abb4bfcb2f9b45087f449 (patch) | |
tree | b39154026ba138251e979556f83810965e0f17c9 /core/tests | |
parent | bf02b984738f6be5cc2e2d66b12aff7af99eb79e (diff) | |
download | frameworks_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.java | 30 | ||||
-rw-r--r-- | core/tests/utillib/src/android/test/BandwidthTestCase.java | 140 |
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; + } +} + |