Home | History | Annotate | Download | only in util
      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  */
     16 
     17 package com.android.gallery3d.util;
     18 
     19 import com.android.gallery3d.util.Profile;
     20 
     21 import android.os.Environment;
     22 import android.test.suitebuilder.annotation.SmallTest;
     23 import android.util.Log;
     24 
     25 import java.io.DataInputStream;
     26 import java.io.File;
     27 import java.io.FileInputStream;
     28 import java.io.IOException;
     29 import java.util.ArrayList;
     30 import java.util.HashMap;
     31 import junit.framework.Assert;
     32 import junit.framework.TestCase;
     33 
     34 @SmallTest
     35 public class ProfileTest extends TestCase {
     36     private static final String TAG = "ProfileTest";
     37     private static final String TEST_FILE =
     38             Environment.getExternalStorageDirectory().getPath() + "/test.dat";
     39 
     40 
     41     public void testProfile() throws IOException {
     42         ProfileData p = new ProfileData();
     43         ParsedProfile q;
     44         String[] A = {"A"};
     45         String[] B = {"B"};
     46         String[] AC = {"A", "C"};
     47         String[] AD = {"A", "D"};
     48 
     49         // Empty profile
     50         p.dumpToFile(TEST_FILE);
     51         q = new ParsedProfile(TEST_FILE);
     52         assertTrue(q.mEntries.isEmpty());
     53         assertTrue(q.mSymbols.isEmpty());
     54 
     55         // Only one sample
     56         p.addSample(A);
     57         p.dumpToFile(TEST_FILE);
     58         q = new ParsedProfile(TEST_FILE);
     59         assertEquals(1, q.mEntries.size());
     60         assertEquals(1, q.mSymbols.size());
     61         assertEquals(1, q.mEntries.get(0).sampleCount);
     62 
     63         // Two samples at the same place
     64         p.addSample(A);
     65         p.dumpToFile(TEST_FILE);
     66         q = new ParsedProfile(TEST_FILE);
     67         assertEquals(1, q.mEntries.size());
     68         assertEquals(1, q.mSymbols.size());
     69         assertEquals(2, q.mEntries.get(0).sampleCount);
     70 
     71         // Two samples at the different places
     72         p.reset();
     73         p.addSample(A);
     74         p.addSample(B);
     75         p.dumpToFile(TEST_FILE);
     76         q = new ParsedProfile(TEST_FILE);
     77         assertEquals(2, q.mEntries.size());
     78         assertEquals(2, q.mSymbols.size());
     79         assertEquals(1, q.mEntries.get(0).sampleCount);
     80         assertEquals(1, q.mEntries.get(1).sampleCount);
     81 
     82         // depth > 1
     83         p.reset();
     84         p.addSample(AC);
     85         p.dumpToFile(TEST_FILE);
     86         q = new ParsedProfile(TEST_FILE);
     87         assertEquals(1, q.mEntries.size());
     88         assertEquals(2, q.mSymbols.size());
     89         assertEquals(1, q.mEntries.get(0).sampleCount);
     90 
     91         // two samples (AC and AD)
     92         p.addSample(AD);
     93         p.dumpToFile(TEST_FILE);
     94         q = new ParsedProfile(TEST_FILE);
     95         assertEquals(2, q.mEntries.size());
     96         assertEquals(3, q.mSymbols.size());  // three symbols: A, C, D
     97         assertEquals(1, q.mEntries.get(0).sampleCount);
     98         assertEquals(1, q.mEntries.get(0).sampleCount);
     99 
    100         // Remove the test file
    101         new File(TEST_FILE).delete();
    102     }
    103 }
    104 
    105 class ParsedProfile {
    106     public class Entry {
    107         int sampleCount;
    108         int stackId[];
    109     }
    110 
    111     ArrayList<Entry> mEntries = new ArrayList<Entry>();
    112     HashMap<Integer, String> mSymbols = new HashMap<Integer, String>();
    113     private DataInputStream mIn;
    114     private byte[] mScratch = new byte[4];  // scratch buffer for readInt
    115 
    116     public ParsedProfile(String filename) throws IOException {
    117         mIn = new DataInputStream(new FileInputStream(filename));
    118 
    119         Entry entry = parseOneEntry();
    120         checkIsFirstEntry(entry);
    121 
    122         while (true) {
    123             entry = parseOneEntry();
    124             if (entry.sampleCount == 0) {
    125                 checkIsLastEntry(entry);
    126                 break;
    127             }
    128             mEntries.add(entry);
    129         }
    130 
    131         // Read symbol table
    132         while (true) {
    133             String line = mIn.readLine();
    134             if (line == null) break;
    135             String[] fields = line.split(" +");
    136             checkIsValidSymbolLine(fields);
    137             mSymbols.put(Integer.decode(fields[0]), fields[1]);
    138         }
    139     }
    140 
    141     private void checkIsFirstEntry(Entry entry) {
    142         Assert.assertEquals(0, entry.sampleCount);
    143         Assert.assertEquals(3, entry.stackId.length);
    144         Assert.assertEquals(1, entry.stackId[0]);
    145         Assert.assertTrue(entry.stackId[1] > 0);  // sampling period
    146         Assert.assertEquals(0, entry.stackId[2]);  // padding
    147     }
    148 
    149     private void checkIsLastEntry(Entry entry) {
    150         Assert.assertEquals(0, entry.sampleCount);
    151         Assert.assertEquals(1, entry.stackId.length);
    152         Assert.assertEquals(0, entry.stackId[0]);
    153     }
    154 
    155     private void checkIsValidSymbolLine(String[] fields) {
    156         Assert.assertEquals(2, fields.length);
    157         Assert.assertTrue(fields[0].startsWith("0x"));
    158     }
    159 
    160     private Entry parseOneEntry() throws IOException {
    161         int sampleCount = readInt();
    162         int depth = readInt();
    163         Entry e = new Entry();
    164         e.sampleCount = sampleCount;
    165         e.stackId = new int[depth];
    166         for (int i = 0; i < depth; i++) {
    167             e.stackId[i] = readInt();
    168         }
    169         return e;
    170     }
    171 
    172     private int readInt() throws IOException {
    173         mIn.read(mScratch, 0, 4);
    174         return (mScratch[0] & 0xff) |
    175                 ((mScratch[1] & 0xff) << 8) |
    176                 ((mScratch[2] & 0xff) << 16) |
    177                 ((mScratch[3] & 0xff) << 24);
    178     }
    179 }
    180