BandwidthTestCase.java revision ca4aab9cd724708af30abb4bfcb2f9b45087f449
1/* 2 * Copyright (C) 2012 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 */ 16package android.test; 17 18import android.net.NetworkStats; 19import android.net.TrafficStats; 20import android.os.Bundle; 21 22import java.lang.reflect.InvocationTargetException; 23import java.lang.reflect.Method; 24import java.lang.reflect.Modifier; 25 26/** 27 * A bandwidth test case that collects bandwidth statistics for tests that are 28 * annotated with {@link BandwidthTest} otherwise the test is executed 29 * as an {@link InstrumentationTestCase} 30 */ 31public class BandwidthTestCase extends InstrumentationTestCase { 32 private static final String REPORT_KEY_PACKETS_SENT = "txPackets"; 33 private static final String REPORT_KEY_PACKETS_RECEIVED = "rxPackets"; 34 private static final String REPORT_KEY_BYTES_SENT = "txBytes"; 35 private static final String REPORT_KEY_BYTES_RECEIVED = "rxBytes"; 36 private static final String REPORT_KEY_OPERATIONS = "operations"; 37 38 @Override 39 protected void runTest() throws Throwable { 40 //This is a copy of {@link InstrumentationTestCase#runTest} with 41 //added logic to handle bandwidth measurements 42 String fName = getName(); 43 assertNotNull(fName); 44 Method method = null; 45 Class testClass = null; 46 try { 47 // use getMethod to get all public inherited 48 // methods. getDeclaredMethods returns all 49 // methods of this class but excludes the 50 // inherited ones. 51 testClass = getClass(); 52 method = testClass.getMethod(fName, (Class[]) null); 53 } catch (NoSuchMethodException e) { 54 fail("Method \""+fName+"\" not found"); 55 } 56 57 if (!Modifier.isPublic(method.getModifiers())) { 58 fail("Method \""+fName+"\" should be public"); 59 } 60 61 int runCount = 1; 62 boolean isRepetitive = false; 63 if (method.isAnnotationPresent(FlakyTest.class)) { 64 runCount = method.getAnnotation(FlakyTest.class).tolerance(); 65 } else if (method.isAnnotationPresent(RepetitiveTest.class)) { 66 runCount = method.getAnnotation(RepetitiveTest.class).numIterations(); 67 isRepetitive = true; 68 } 69 70 if (method.isAnnotationPresent(UiThreadTest.class)) { 71 final int tolerance = runCount; 72 final boolean repetitive = isRepetitive; 73 final Method testMethod = method; 74 final Throwable[] exceptions = new Throwable[1]; 75 getInstrumentation().runOnMainSync(new Runnable() { 76 public void run() { 77 try { 78 runMethod(testMethod, tolerance, repetitive); 79 } catch (Throwable throwable) { 80 exceptions[0] = throwable; 81 } 82 } 83 }); 84 if (exceptions[0] != null) { 85 throw exceptions[0]; 86 } 87 } else if (method.isAnnotationPresent(BandwidthTest.class) || 88 testClass.isAnnotationPresent(BandwidthTest.class)) { 89 TrafficStats.startDataProfiling(null); 90 runMethod(method, 1, false); 91 NetworkStats stats = TrafficStats.stopDataProfiling(null); 92 NetworkStats.Entry entry = stats.getTotal(null); 93 getInstrumentation().sendStatus(2, getBandwidthStats(entry)); 94 } else { 95 runMethod(method, runCount, isRepetitive); 96 } 97 } 98 99 private void runMethod(Method runMethod, int tolerance, boolean isRepetitive) throws Throwable { 100 //This is a copy of {@link InstrumentationTestCase#runMethod} 101 Throwable exception = null; 102 103 int runCount = 0; 104 do { 105 try { 106 runMethod.invoke(this, (Object[]) null); 107 exception = null; 108 } catch (InvocationTargetException e) { 109 e.fillInStackTrace(); 110 exception = e.getTargetException(); 111 } catch (IllegalAccessException e) { 112 e.fillInStackTrace(); 113 exception = e; 114 } finally { 115 runCount++; 116 // Report current iteration number, if test is repetitive 117 if (isRepetitive) { 118 Bundle iterations = new Bundle(); 119 iterations.putInt("currentiterations", runCount); 120 getInstrumentation().sendStatus(2, iterations); 121 } 122 } 123 } while ((runCount < tolerance) && (isRepetitive || exception != null)); 124 125 if (exception != null) { 126 throw exception; 127 } 128 } 129 130 private Bundle getBandwidthStats(NetworkStats.Entry entry){ 131 Bundle bundle = new Bundle(); 132 bundle.putLong(REPORT_KEY_BYTES_RECEIVED, entry.rxBytes); 133 bundle.putLong(REPORT_KEY_BYTES_SENT, entry.txBytes); 134 bundle.putLong(REPORT_KEY_PACKETS_RECEIVED, entry.rxPackets); 135 bundle.putLong(REPORT_KEY_PACKETS_SENT, entry.txPackets); 136 bundle.putLong(REPORT_KEY_OPERATIONS, entry.operations); 137 return bundle; 138 } 139} 140 141