1ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu/* 2ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu * Copyright (C) 2012 The Android Open Source Project 3ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu * 4ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu * Licensed under the Apache License, Version 2.0 (the "License"); 5ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu * you may not use this file except in compliance with the License. 6ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu * You may obtain a copy of the License at 7ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu * 8ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu * http://www.apache.org/licenses/LICENSE-2.0 9ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu * 10ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu * Unless required by applicable law or agreed to in writing, software 11ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu * distributed under the License is distributed on an "AS IS" BASIS, 12ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu * See the License for the specific language governing permissions and 14ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu * limitations under the License. 15ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu */ 16ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hupackage android.test; 17ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu 18ca4aab9cd724708af30abb4bfcb2f9b45087f449David Huimport android.net.NetworkStats; 19ca4aab9cd724708af30abb4bfcb2f9b45087f449David Huimport android.net.TrafficStats; 20ca4aab9cd724708af30abb4bfcb2f9b45087f449David Huimport android.os.Bundle; 2171a0d06fd8f0cae4d3f38f1f34ceebbfd6d61db6David Huimport android.util.Log; 22ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu 23ca4aab9cd724708af30abb4bfcb2f9b45087f449David Huimport java.lang.reflect.InvocationTargetException; 24ca4aab9cd724708af30abb4bfcb2f9b45087f449David Huimport java.lang.reflect.Method; 25ca4aab9cd724708af30abb4bfcb2f9b45087f449David Huimport java.lang.reflect.Modifier; 26ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu 27ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu/** 28ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu * A bandwidth test case that collects bandwidth statistics for tests that are 29ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu * annotated with {@link BandwidthTest} otherwise the test is executed 30ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu * as an {@link InstrumentationTestCase} 31ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu */ 32ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hupublic class BandwidthTestCase extends InstrumentationTestCase { 3371a0d06fd8f0cae4d3f38f1f34ceebbfd6d61db6David Hu private static final String TAG = "BandwidthTestCase"; 34ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu private static final String REPORT_KEY_PACKETS_SENT = "txPackets"; 35ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu private static final String REPORT_KEY_PACKETS_RECEIVED = "rxPackets"; 36ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu private static final String REPORT_KEY_BYTES_SENT = "txBytes"; 37ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu private static final String REPORT_KEY_BYTES_RECEIVED = "rxBytes"; 38ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu private static final String REPORT_KEY_OPERATIONS = "operations"; 39ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu 40ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu @Override 41ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu protected void runTest() throws Throwable { 42ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu //This is a copy of {@link InstrumentationTestCase#runTest} with 43ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu //added logic to handle bandwidth measurements 44ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu String fName = getName(); 45ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu assertNotNull(fName); 46ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu Method method = null; 47ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu Class testClass = null; 48ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu try { 49ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu // use getMethod to get all public inherited 50ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu // methods. getDeclaredMethods returns all 51ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu // methods of this class but excludes the 52ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu // inherited ones. 53ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu testClass = getClass(); 54ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu method = testClass.getMethod(fName, (Class[]) null); 55ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu } catch (NoSuchMethodException e) { 56ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu fail("Method \""+fName+"\" not found"); 57ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu } 58ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu 59ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu if (!Modifier.isPublic(method.getModifiers())) { 60ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu fail("Method \""+fName+"\" should be public"); 61ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu } 62ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu 63ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu int runCount = 1; 64ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu boolean isRepetitive = false; 65ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu if (method.isAnnotationPresent(FlakyTest.class)) { 66ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu runCount = method.getAnnotation(FlakyTest.class).tolerance(); 67ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu } else if (method.isAnnotationPresent(RepetitiveTest.class)) { 68ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu runCount = method.getAnnotation(RepetitiveTest.class).numIterations(); 69ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu isRepetitive = true; 70ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu } 71ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu 72ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu if (method.isAnnotationPresent(UiThreadTest.class)) { 73ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu final int tolerance = runCount; 74ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu final boolean repetitive = isRepetitive; 75ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu final Method testMethod = method; 76ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu final Throwable[] exceptions = new Throwable[1]; 77ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu getInstrumentation().runOnMainSync(new Runnable() { 78ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu public void run() { 79ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu try { 80ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu runMethod(testMethod, tolerance, repetitive); 81ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu } catch (Throwable throwable) { 82ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu exceptions[0] = throwable; 83ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu } 84ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu } 85ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu }); 86ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu if (exceptions[0] != null) { 87ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu throw exceptions[0]; 88ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu } 89ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu } else if (method.isAnnotationPresent(BandwidthTest.class) || 90ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu testClass.isAnnotationPresent(BandwidthTest.class)) { 9171a0d06fd8f0cae4d3f38f1f34ceebbfd6d61db6David Hu /** 9271a0d06fd8f0cae4d3f38f1f34ceebbfd6d61db6David Hu * If bandwidth profiling fails for whatever reason the test 9371a0d06fd8f0cae4d3f38f1f34ceebbfd6d61db6David Hu * should be allow to execute to its completion. 9471a0d06fd8f0cae4d3f38f1f34ceebbfd6d61db6David Hu * Typically bandwidth profiling would fail when a lower level 9571a0d06fd8f0cae4d3f38f1f34ceebbfd6d61db6David Hu * component is missing, such as the kernel module, for a newly 9671a0d06fd8f0cae4d3f38f1f34ceebbfd6d61db6David Hu * introduced hardware. 9771a0d06fd8f0cae4d3f38f1f34ceebbfd6d61db6David Hu */ 9871a0d06fd8f0cae4d3f38f1f34ceebbfd6d61db6David Hu try{ 9971a0d06fd8f0cae4d3f38f1f34ceebbfd6d61db6David Hu TrafficStats.startDataProfiling(null); 10071a0d06fd8f0cae4d3f38f1f34ceebbfd6d61db6David Hu } catch(IllegalStateException isx){ 10171a0d06fd8f0cae4d3f38f1f34ceebbfd6d61db6David Hu Log.w(TAG, "Failed to start bandwidth profiling"); 10271a0d06fd8f0cae4d3f38f1f34ceebbfd6d61db6David Hu } 103ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu runMethod(method, 1, false); 10471a0d06fd8f0cae4d3f38f1f34ceebbfd6d61db6David Hu try{ 10571a0d06fd8f0cae4d3f38f1f34ceebbfd6d61db6David Hu NetworkStats stats = TrafficStats.stopDataProfiling(null); 10671a0d06fd8f0cae4d3f38f1f34ceebbfd6d61db6David Hu NetworkStats.Entry entry = stats.getTotal(null); 10771a0d06fd8f0cae4d3f38f1f34ceebbfd6d61db6David Hu getInstrumentation().sendStatus(2, getBandwidthStats(entry)); 10871a0d06fd8f0cae4d3f38f1f34ceebbfd6d61db6David Hu } catch (IllegalStateException isx){ 10971a0d06fd8f0cae4d3f38f1f34ceebbfd6d61db6David Hu Log.w(TAG, "Failed to collect bandwidth stats"); 11071a0d06fd8f0cae4d3f38f1f34ceebbfd6d61db6David Hu } 111ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu } else { 112ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu runMethod(method, runCount, isRepetitive); 113ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu } 114ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu } 115ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu 116ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu private void runMethod(Method runMethod, int tolerance, boolean isRepetitive) throws Throwable { 117ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu //This is a copy of {@link InstrumentationTestCase#runMethod} 118ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu Throwable exception = null; 119ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu 120ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu int runCount = 0; 121ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu do { 122ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu try { 123ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu runMethod.invoke(this, (Object[]) null); 124ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu exception = null; 125ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu } catch (InvocationTargetException e) { 126ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu e.fillInStackTrace(); 127ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu exception = e.getTargetException(); 128ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu } catch (IllegalAccessException e) { 129ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu e.fillInStackTrace(); 130ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu exception = e; 131ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu } finally { 132ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu runCount++; 133ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu // Report current iteration number, if test is repetitive 134ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu if (isRepetitive) { 135ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu Bundle iterations = new Bundle(); 136ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu iterations.putInt("currentiterations", runCount); 137ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu getInstrumentation().sendStatus(2, iterations); 138ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu } 139ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu } 140ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu } while ((runCount < tolerance) && (isRepetitive || exception != null)); 141ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu 142ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu if (exception != null) { 143ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu throw exception; 144ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu } 145ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu } 146ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu 147ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu private Bundle getBandwidthStats(NetworkStats.Entry entry){ 148ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu Bundle bundle = new Bundle(); 149ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu bundle.putLong(REPORT_KEY_BYTES_RECEIVED, entry.rxBytes); 150ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu bundle.putLong(REPORT_KEY_BYTES_SENT, entry.txBytes); 151ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu bundle.putLong(REPORT_KEY_PACKETS_RECEIVED, entry.rxPackets); 152ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu bundle.putLong(REPORT_KEY_PACKETS_SENT, entry.txPackets); 153ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu bundle.putLong(REPORT_KEY_OPERATIONS, entry.operations); 154ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu return bundle; 155ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu } 156ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu} 157ca4aab9cd724708af30abb4bfcb2f9b45087f449David Hu 158