Home | History | Annotate | Download | only in cts
      1 /*
      2  * Copyright (C) 2009 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  */
     16 package android.os.cts;
     17 
     18 import android.content.Context;
     19 import android.os.Debug;
     20 import android.platform.test.annotations.AppModeFull;
     21 import android.test.AndroidTestCase;
     22 
     23 import com.android.compatibility.common.util.TestThread;
     24 
     25 import java.io.File;
     26 import java.io.FileOutputStream;
     27 import java.io.IOException;
     28 import java.util.ArrayList;
     29 import java.util.List;
     30 import java.util.Map;
     31 import java.util.logging.Level;
     32 import java.util.logging.Logger;
     33 
     34 public class DebugTest extends AndroidTestCase {
     35     private static final Logger Log = Logger.getLogger(DebugTest.class.getName());
     36 
     37     // Static list here to avoid R8 optimizations in #testGetAndReset causing wrong alloc counts
     38     private static final List<int[]> TEST_ALLOC = new ArrayList<>();
     39 
     40     @Override
     41     public void tearDown() throws Exception {
     42         super.tearDown();
     43         Debug.stopAllocCounting();
     44         Debug.resetAllCounts();
     45     }
     46 
     47     public void testPrintLoadedClasses() {
     48         Debug.printLoadedClasses(Debug.SHOW_FULL_DETAIL);
     49         Debug.printLoadedClasses(Debug.SHOW_CLASSLOADER);
     50         Debug.printLoadedClasses(Debug.SHOW_INITIALIZED);
     51     }
     52 
     53     public void testStartMethodTracing() throws InterruptedException {
     54         final long debugTime = 3000;
     55         final String traceName = getFileName();
     56 
     57         final int bufSize = 1024 * 1024 * 2;
     58         final int debug_flag = Debug.TRACE_COUNT_ALLOCS;
     59 
     60         Debug.startMethodTracing(traceName);
     61         Thread.sleep(debugTime);
     62         Debug.stopMethodTracing();
     63 
     64         Debug.startMethodTracing(traceName, bufSize);
     65         Thread.sleep(debugTime);
     66         Debug.stopMethodTracing();
     67 
     68         Debug.startMethodTracing(traceName, bufSize, debug_flag);
     69         Thread.sleep(debugTime);
     70         Debug.stopMethodTracing();
     71     }
     72 
     73     @AppModeFull(
     74             reason = "Default trace in Context#getExternalFilesDir not accessible by instant apps"
     75     )
     76     public void testStartMethodTracingDefaultExternalStorage() throws InterruptedException {
     77         final long debugTime = 3000;
     78 
     79         Debug.startMethodTracing();
     80         Thread.sleep(debugTime);
     81         Debug.stopMethodTracing();
     82     }
     83 
     84     private String getFileName() {
     85         File dir = getContext().getFilesDir();
     86         File file = new File(dir, "debug.trace");
     87         return file.getAbsolutePath();
     88     }
     89 
     90     public void testStartNativeTracing() {
     91         Debug.startNativeTracing();
     92 
     93         Debug.stopNativeTracing();
     94     }
     95 
     96     public void testThreadCpuTimeNanos() throws Exception {
     97         if (Debug.threadCpuTimeNanos() == -1) {
     98             // Indicates the system does not support this operation, so we can't test it.
     99             Log.log(Level.WARNING, "Skipping testThreadCpuTimeNanos() on unsupported system");
    100             return;
    101         }
    102 
    103         TestThread t = new TestThread(new Runnable() {
    104                 @Override
    105                 public void run() {
    106                     long startDebugTime = Debug.threadCpuTimeNanos();
    107 
    108                     // Do some work for a second to increment CPU time
    109                     long startSystemTime = System.currentTimeMillis();
    110                     while (System.currentTimeMillis() - startSystemTime < 1000) {
    111                         Math.random();
    112                     }
    113 
    114                     // Verify that threadCpuTimeNanos reports that some work was done.
    115                     // We can't do more than this because the specification for this API call makes
    116                     // clear that this is only an estimate.
    117                     assertTrue(Debug.threadCpuTimeNanos() > startDebugTime);
    118                 }
    119             });
    120         t.start();
    121         t.join();
    122     }
    123 
    124     public void testWaitingForDebugger() {
    125         assertFalse(Debug.waitingForDebugger());
    126     }
    127 
    128     public void testGetAndReset() throws IOException {
    129         final String dumpFile = getFileName();
    130         Debug.startAllocCounting();
    131 
    132         final int MIN_GLOBAL_ALLOC_COUNT = 100;
    133         final int ARRAY_SIZE = 100;
    134         final int MIN_GLOBAL_ALLOC_SIZE = MIN_GLOBAL_ALLOC_COUNT * ARRAY_SIZE;
    135         for(int i = 0; i < MIN_GLOBAL_ALLOC_COUNT; i++){
    136             // for test alloc huge memory
    137             TEST_ALLOC.add(new int[ARRAY_SIZE]);
    138             TEST_ALLOC.clear();
    139         }
    140 
    141         assertTrue(Debug.getGlobalAllocCount() >= MIN_GLOBAL_ALLOC_COUNT);
    142         assertTrue(Debug.getGlobalAllocSize() >= MIN_GLOBAL_ALLOC_SIZE);
    143         assertTrue(Debug.getGlobalFreedCount() >= 0);
    144         assertTrue(Debug.getGlobalFreedSize() >= 0);
    145         assertTrue(Debug.getNativeHeapSize() >= 0);
    146         assertTrue(Debug.getGlobalExternalAllocCount() >= 0);
    147         assertTrue(Debug.getGlobalExternalAllocSize() >= 0);
    148         assertTrue(Debug.getGlobalExternalFreedCount() >= 0);
    149         assertTrue(Debug.getGlobalExternalFreedSize() >= 0);
    150         assertTrue(Debug.getLoadedClassCount() >= 0);
    151         assertTrue(Debug.getNativeHeapAllocatedSize() >= 0);
    152         assertTrue(Debug.getNativeHeapFreeSize() >= 0);
    153         assertTrue(Debug.getNativeHeapSize() >= 0);
    154         assertTrue(Debug.getThreadAllocCount() >= 0);
    155         assertTrue(Debug.getThreadAllocSize() >= 0);
    156         assertTrue(Debug.getThreadExternalAllocCount() >=0);
    157         assertTrue(Debug.getThreadExternalAllocSize() >= 0);
    158         assertTrue(Debug.getThreadGcInvocationCount() >= 0);
    159         assertTrue(Debug.getBinderDeathObjectCount() >= 0);
    160         assertTrue(Debug.getBinderLocalObjectCount() >= 0);
    161         assertTrue(Debug.getBinderProxyObjectCount() >= 0);
    162         Debug.getBinderReceivedTransactions();
    163         Debug.getBinderSentTransactions();
    164 
    165         Debug.stopAllocCounting();
    166 
    167         Debug.MemoryInfo memoryInfo = new Debug.MemoryInfo();
    168         Debug.getMemoryInfo(memoryInfo);
    169 
    170         Debug.resetGlobalAllocCount();
    171         assertEquals(0, Debug.getGlobalAllocCount());
    172 
    173         Debug.resetGlobalAllocSize();
    174         assertEquals(0, Debug.getGlobalAllocSize());
    175 
    176         Debug.resetGlobalExternalAllocCount();
    177         assertEquals(0, Debug.getGlobalExternalAllocCount());
    178 
    179         Debug.resetGlobalExternalAllocSize();
    180         assertEquals(0, Debug.getGlobalExternalAllocSize());
    181 
    182         Debug.resetGlobalExternalFreedCount();
    183         assertEquals(0, Debug.getGlobalExternalFreedCount());
    184 
    185         Debug.resetGlobalExternalFreedSize();
    186         assertEquals(0, Debug.getGlobalExternalFreedSize());
    187 
    188         Debug.resetGlobalFreedCount();
    189         assertEquals(0, Debug.getGlobalFreedCount());
    190 
    191         Debug.resetGlobalFreedSize();
    192         assertEquals(0, Debug.getGlobalFreedSize());
    193 
    194         Debug.resetGlobalGcInvocationCount();
    195         assertEquals(0, Debug.getGlobalGcInvocationCount());
    196 
    197         Debug.resetThreadAllocCount();
    198         assertEquals(0, Debug.getThreadAllocCount());
    199 
    200         Debug.resetThreadAllocSize();
    201         assertEquals(0, Debug.getThreadAllocSize());
    202 
    203         Debug.resetThreadExternalAllocCount();
    204         assertEquals(0, Debug.getThreadExternalAllocCount());
    205 
    206         Debug.resetThreadExternalAllocSize();
    207         assertEquals(0, Debug.getThreadExternalAllocSize());
    208 
    209         Debug.resetThreadGcInvocationCount();
    210         assertEquals(0, Debug.getThreadGcInvocationCount());
    211 
    212         Debug.resetAllCounts();
    213         Debug.dumpHprofData(dumpFile);
    214     }
    215 
    216     public void testDumpService() throws Exception {
    217         File file = getContext().getFileStreamPath("dump.out");
    218         file.delete();
    219         assertFalse(file.exists());
    220 
    221         FileOutputStream out = getContext().openFileOutput("dump.out", Context.MODE_PRIVATE);
    222         assertFalse(Debug.dumpService("xyzzy -- not a valid service name", out.getFD(), null));
    223         out.close();
    224 
    225         // File was opened, but nothing was written
    226         assertTrue(file.exists());
    227         assertEquals(0, file.length());
    228 
    229         out = getContext().openFileOutput("dump.out", Context.MODE_PRIVATE);
    230         assertTrue(Debug.dumpService(Context.POWER_SERVICE, out.getFD(), null));
    231         out.close();
    232 
    233         // Don't require any specific content, just that something was written
    234         assertTrue(file.exists());
    235         assertTrue(file.length() > 0);
    236     }
    237 
    238     private static void checkNumber(String s) throws Exception {
    239         assertTrue(s != null);
    240         long n = Long.valueOf(s);
    241         assertTrue(n >= 0);
    242     }
    243 
    244     private static void checkHistogram(String s) throws Exception {
    245         assertTrue(s != null);
    246         assertTrue(s.length() > 0);
    247         String[] buckets = s.split(",");
    248         long last_key = 0;
    249         for (int i = 0; i < buckets.length; ++i) {
    250             String bucket = buckets[i];
    251             assertTrue(bucket.length() > 0);
    252             String[] kv = bucket.split(":");
    253             assertTrue(kv.length == 2);
    254             assertTrue(kv[0].length() > 0);
    255             assertTrue(kv[1].length() > 0);
    256             long key = Long.valueOf(kv[0]);
    257             long value = Long.valueOf(kv[1]);
    258             assertTrue(key >= 0);
    259             assertTrue(value >= 0);
    260             assertTrue(key >= last_key);
    261             last_key = key;
    262         }
    263     }
    264 
    265     public void testGetRuntimeStat() throws Exception {
    266         // Invoke at least one GC and wait for 20 seconds or so so we get at
    267         // least one bucket in the histograms.
    268         for (int i = 0; i < 20; ++i) {
    269             Runtime.getRuntime().gc();
    270             Thread.sleep(1000L);
    271         }
    272         String gc_count = Debug.getRuntimeStat("art.gc.gc-count");
    273         String gc_time = Debug.getRuntimeStat("art.gc.gc-time");
    274         String bytes_allocated = Debug.getRuntimeStat("art.gc.bytes-allocated");
    275         String bytes_freed = Debug.getRuntimeStat("art.gc.bytes-freed");
    276         String blocking_gc_count = Debug.getRuntimeStat("art.gc.blocking-gc-count");
    277         String blocking_gc_time = Debug.getRuntimeStat("art.gc.blocking-gc-time");
    278         String gc_count_rate_histogram = Debug.getRuntimeStat("art.gc.gc-count-rate-histogram");
    279         String blocking_gc_count_rate_histogram =
    280             Debug.getRuntimeStat("art.gc.blocking-gc-count-rate-histogram");
    281         checkNumber(gc_count);
    282         checkNumber(gc_time);
    283         checkNumber(bytes_allocated);
    284         checkNumber(bytes_freed);
    285         checkNumber(blocking_gc_count);
    286         checkNumber(blocking_gc_time);
    287         checkHistogram(gc_count_rate_histogram);
    288         checkHistogram(blocking_gc_count_rate_histogram);
    289     }
    290 
    291     public void testGetRuntimeStats() throws Exception {
    292         // Invoke at least one GC and wait for 20 seconds or so so we get at
    293         // least one bucket in the histograms.
    294         for (int i = 0; i < 20; ++i) {
    295             Runtime.getRuntime().gc();
    296             Thread.sleep(1000L);
    297         }
    298         Map<String, String> map = Debug.getRuntimeStats();
    299         String gc_count = map.get("art.gc.gc-count");
    300         String gc_time = map.get("art.gc.gc-time");
    301         String bytes_allocated = map.get("art.gc.bytes-allocated");
    302         String bytes_freed = map.get("art.gc.bytes-freed");
    303         String blocking_gc_count = map.get("art.gc.blocking-gc-count");
    304         String blocking_gc_time = map.get("art.gc.blocking-gc-time");
    305         String gc_count_rate_histogram = map.get("art.gc.gc-count-rate-histogram");
    306         String blocking_gc_count_rate_histogram =
    307             map.get("art.gc.blocking-gc-count-rate-histogram");
    308         checkNumber(gc_count);
    309         checkNumber(gc_time);
    310         checkNumber(bytes_allocated);
    311         checkNumber(bytes_freed);
    312         checkNumber(blocking_gc_count);
    313         checkNumber(blocking_gc_time);
    314         checkHistogram(gc_count_rate_histogram);
    315         checkHistogram(blocking_gc_count_rate_histogram);
    316     }
    317 
    318     public void testGetMemoryStat() throws Exception {
    319         Debug.MemoryInfo memoryInfo = new Debug.MemoryInfo();
    320         Debug.getMemoryInfo(memoryInfo);
    321 
    322         String summary_java_heap = memoryInfo.getMemoryStat("summary.java-heap");
    323         String summary_native_heap = memoryInfo.getMemoryStat("summary.native-heap");
    324         String summary_code = memoryInfo.getMemoryStat("summary.code");
    325         String summary_stack = memoryInfo.getMemoryStat("summary.stack");
    326         String summary_graphics = memoryInfo.getMemoryStat("summary.graphics");
    327         String summary_private_other = memoryInfo.getMemoryStat("summary.private-other");
    328         String summary_system = memoryInfo.getMemoryStat("summary.system");
    329         String summary_total_pss = memoryInfo.getMemoryStat("summary.total-pss");
    330         String summary_total_swap = memoryInfo.getMemoryStat("summary.total-swap");
    331         checkNumber(summary_java_heap);
    332         checkNumber(summary_native_heap);
    333         checkNumber(summary_code);
    334         checkNumber(summary_stack);
    335         checkNumber(summary_graphics);
    336         checkNumber(summary_private_other);
    337         checkNumber(summary_system);
    338         checkNumber(summary_total_pss);
    339         checkNumber(summary_total_swap);
    340     }
    341 
    342     public void testGetMemoryStats() throws Exception {
    343         Debug.MemoryInfo memoryInfo = new Debug.MemoryInfo();
    344         Debug.getMemoryInfo(memoryInfo);
    345 
    346         Map<String, String> map = memoryInfo.getMemoryStats();
    347         String summary_java_heap = map.get("summary.java-heap");
    348         String summary_native_heap = map.get("summary.native-heap");
    349         String summary_code = map.get("summary.code");
    350         String summary_stack = map.get("summary.stack");
    351         String summary_graphics = map.get("summary.graphics");
    352         String summary_private_other = map.get("summary.private-other");
    353         String summary_system = map.get("summary.system");
    354         String summary_total_pss = map.get("summary.total-pss");
    355         String summary_total_swap = map.get("summary.total-swap");
    356         checkNumber(summary_java_heap);
    357         checkNumber(summary_native_heap);
    358         checkNumber(summary_code);
    359         checkNumber(summary_stack);
    360         checkNumber(summary_graphics);
    361         checkNumber(summary_private_other);
    362         checkNumber(summary_system);
    363         checkNumber(summary_total_pss);
    364         checkNumber(summary_total_swap);
    365     }
    366 }
    367