Home | History | Annotate | Download | only in storage
      1 /*
      2  * Copyright (C) 2016 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.server.storage;
     18 
     19 import android.content.pm.PackageStats;
     20 import android.test.AndroidTestCase;
     21 import android.util.ArraySet;
     22 import libcore.io.IoUtils;
     23 import org.json.JSONArray;
     24 import org.json.JSONObject;
     25 import org.junit.Before;
     26 import org.junit.Rule;
     27 import org.junit.Test;
     28 import org.junit.rules.TemporaryFolder;
     29 import org.junit.runner.RunWith;
     30 import org.junit.runners.JUnit4;
     31 
     32 import java.io.File;
     33 import java.util.ArrayList;
     34 
     35 import static com.google.common.truth.Truth.assertThat;
     36 
     37 @RunWith(JUnit4.class)
     38 public class DiskStatsFileLoggerTest extends AndroidTestCase {
     39     @Rule public TemporaryFolder temporaryFolder;
     40     public FileCollector.MeasurementResult mMainResult;
     41     public FileCollector.MeasurementResult mDownloadsResult;
     42     private ArrayList<PackageStats> mPackages;
     43     private File mOutputFile;
     44 
     45     @Before
     46     public void setUp() throws Exception {
     47         super.setUp();
     48         temporaryFolder = new TemporaryFolder();
     49         temporaryFolder.create();
     50         mOutputFile = temporaryFolder.newFile();
     51         mMainResult = new FileCollector.MeasurementResult();
     52         mDownloadsResult = new FileCollector.MeasurementResult();
     53         mPackages = new ArrayList<>();
     54     }
     55 
     56     @Test
     57     public void testEmptyStorage() throws Exception {
     58         DiskStatsFileLogger logger = new DiskStatsFileLogger(
     59                 mMainResult, mDownloadsResult,mPackages, 0L);
     60 
     61         logger.dumpToFile(mOutputFile);
     62 
     63         JSONObject output = getOutputFileAsJson();
     64         assertThat(output.getLong(DiskStatsFileLogger.PHOTOS_KEY)).isEqualTo(0L);
     65         assertThat(output.getLong(DiskStatsFileLogger.VIDEOS_KEY)).isEqualTo(0L);
     66         assertThat(output.getLong(DiskStatsFileLogger.AUDIO_KEY)).isEqualTo(0L);
     67         assertThat(output.getLong(DiskStatsFileLogger.DOWNLOADS_KEY)).isEqualTo(0L);
     68         assertThat(output.getLong(DiskStatsFileLogger.SYSTEM_KEY)).isEqualTo(0L);
     69         assertThat(output.getLong(DiskStatsFileLogger.MISC_KEY)).isEqualTo(0L);
     70         assertThat(output.getLong(DiskStatsFileLogger.APP_SIZE_AGG_KEY)).isEqualTo(0L);
     71         assertThat(output.getLong(DiskStatsFileLogger.APP_CACHE_AGG_KEY)).isEqualTo(0L);
     72         assertThat(
     73                 output.getJSONArray(DiskStatsFileLogger.PACKAGE_NAMES_KEY).length()).isEqualTo(0L);
     74         assertThat(output.getJSONArray(DiskStatsFileLogger.APP_SIZES_KEY).length()).isEqualTo(0L);
     75         assertThat(output.getJSONArray(DiskStatsFileLogger.APP_CACHES_KEY).length()).isEqualTo(0L);
     76     }
     77 
     78     @Test
     79     public void testMeasurementResultsReported() throws Exception {
     80         mMainResult.audioSize = 1;
     81         mMainResult.imagesSize = 10;
     82         mMainResult.miscSize = 100;
     83         mDownloadsResult.miscSize = 1000;
     84         DiskStatsFileLogger logger = new DiskStatsFileLogger(
     85                 mMainResult, mDownloadsResult,mPackages, 3L);
     86 
     87         logger.dumpToFile(mOutputFile);
     88 
     89         JSONObject output = getOutputFileAsJson();
     90         assertThat(output.getLong(DiskStatsFileLogger.AUDIO_KEY)).isEqualTo(1L);
     91         assertThat(output.getLong(DiskStatsFileLogger.PHOTOS_KEY)).isEqualTo(10L);
     92         assertThat(output.getLong(DiskStatsFileLogger.MISC_KEY)).isEqualTo(100L);
     93         assertThat(output.getLong(DiskStatsFileLogger.DOWNLOADS_KEY)).isEqualTo(1000L);
     94         assertThat(output.getLong(DiskStatsFileLogger.SYSTEM_KEY)).isEqualTo(3L);
     95     }
     96 
     97     @Test
     98     public void testAppsReported() throws Exception {
     99         PackageStats firstPackage = new PackageStats("com.test.app");
    100         firstPackage.codeSize = 100;
    101         firstPackage.dataSize = 1000;
    102         firstPackage.cacheSize = 20;
    103         mPackages.add(firstPackage);
    104 
    105         PackageStats secondPackage = new PackageStats("com.test.app2");
    106         secondPackage.codeSize = 10;
    107         secondPackage.dataSize = 1;
    108         secondPackage.cacheSize = 2;
    109         mPackages.add(secondPackage);
    110 
    111         DiskStatsFileLogger logger = new DiskStatsFileLogger(
    112                 mMainResult, mDownloadsResult, mPackages, 0L);
    113         logger.dumpToFile(mOutputFile);
    114 
    115         JSONObject output = getOutputFileAsJson();
    116         assertThat(output.getLong(DiskStatsFileLogger.APP_SIZE_AGG_KEY)).isEqualTo(1111);
    117         assertThat(output.getLong(DiskStatsFileLogger.APP_CACHE_AGG_KEY)).isEqualTo(22);
    118 
    119         JSONArray packageNames = output.getJSONArray(DiskStatsFileLogger.PACKAGE_NAMES_KEY);
    120         assertThat(packageNames.length()).isEqualTo(2);
    121         JSONArray appSizes = output.getJSONArray(DiskStatsFileLogger.APP_SIZES_KEY);
    122         assertThat(appSizes.length()).isEqualTo(2);
    123         JSONArray cacheSizes = output.getJSONArray(DiskStatsFileLogger.APP_CACHES_KEY);
    124         assertThat(cacheSizes.length()).isEqualTo(2);
    125 
    126         // We need to do this crazy Set over this because the DiskStatsFileLogger provides no
    127         // guarantee of the ordering of the apps in its output. By using a set, we avoid any order
    128         // problems.
    129         ArraySet<AppSizeGrouping> apps = new ArraySet<>();
    130         for (int i = 0; i < packageNames.length(); i++) {
    131             AppSizeGrouping app = new AppSizeGrouping(packageNames.getString(i),
    132                     appSizes.getLong(i), cacheSizes.getLong(i));
    133             apps.add(app);
    134         }
    135         assertThat(apps).containsAllOf(new AppSizeGrouping("com.test.app", 1100, 20),
    136                 new AppSizeGrouping("com.test.app2", 11, 2));
    137     }
    138 
    139     @Test
    140     public void testEmulatedExternalStorageCounted() throws Exception {
    141         PackageStats app = new PackageStats("com.test.app");
    142         app.dataSize = 1000;
    143         app.externalDataSize = 1000;
    144         app.cacheSize = 20;
    145         mPackages.add(app);
    146 
    147         DiskStatsFileLogger logger = new DiskStatsFileLogger(
    148                 mMainResult, mDownloadsResult, mPackages, 0L);
    149         logger.dumpToFile(mOutputFile);
    150 
    151         JSONObject output = getOutputFileAsJson();
    152         JSONArray appSizes = output.getJSONArray(DiskStatsFileLogger.APP_SIZES_KEY);
    153         assertThat(appSizes.length()).isEqualTo(1);
    154         assertThat(appSizes.getLong(0)).isEqualTo(2000);
    155     }
    156 
    157     @Test
    158     public void testDuplicatePackageNameIsNotMergedAcrossMultipleUsers() throws Exception {
    159         PackageStats app = new PackageStats("com.test.app");
    160         app.dataSize = 1000;
    161         app.externalDataSize = 1000;
    162         app.cacheSize = 20;
    163         app.userHandle = 0;
    164         mPackages.add(app);
    165 
    166         PackageStats secondApp = new PackageStats("com.test.app");
    167         secondApp.dataSize = 100;
    168         secondApp.externalDataSize = 100;
    169         secondApp.cacheSize = 2;
    170         secondApp.userHandle = 1;
    171         mPackages.add(secondApp);
    172 
    173         DiskStatsFileLogger logger = new DiskStatsFileLogger(
    174                 mMainResult, mDownloadsResult, mPackages, 0L);
    175         logger.dumpToFile(mOutputFile);
    176 
    177         JSONObject output = getOutputFileAsJson();
    178         assertThat(output.getLong(DiskStatsFileLogger.APP_SIZE_AGG_KEY)).isEqualTo(2000);
    179         assertThat(output.getLong(DiskStatsFileLogger.APP_CACHE_AGG_KEY)).isEqualTo(20);
    180         JSONArray packageNames = output.getJSONArray(DiskStatsFileLogger.PACKAGE_NAMES_KEY);
    181         assertThat(packageNames.length()).isEqualTo(1);
    182         assertThat(packageNames.getString(0)).isEqualTo("com.test.app");
    183 
    184         JSONArray appSizes = output.getJSONArray(DiskStatsFileLogger.APP_SIZES_KEY);
    185         assertThat(appSizes.length()).isEqualTo(1);
    186         assertThat(appSizes.getLong(0)).isEqualTo(2000);
    187 
    188         JSONArray cacheSizes = output.getJSONArray(DiskStatsFileLogger.APP_CACHES_KEY);
    189         assertThat(cacheSizes.length()).isEqualTo(1);
    190         assertThat(cacheSizes.getLong(0)).isEqualTo(20);
    191     }
    192 
    193     private JSONObject getOutputFileAsJson() throws Exception {
    194         return new JSONObject(IoUtils.readFileAsString(mOutputFile.getAbsolutePath()));
    195     }
    196 
    197     /**
    198      * This class exists for putting zipped app size information arrays into a set for comparison
    199      * purposes.
    200      */
    201     private class AppSizeGrouping {
    202         public String packageName;
    203         public long appSize;
    204         public long cacheSize;
    205 
    206         public AppSizeGrouping(String packageName, long appSize, long cacheSize) {
    207             this.packageName = packageName;
    208             this.appSize = appSize;
    209             this.cacheSize = cacheSize;
    210         }
    211 
    212         @Override
    213         public int hashCode() {
    214             int result = 17;
    215             result = 37 * result + (int)(appSize ^ (appSize >>> 32));
    216             result = 37 * result + (int)(cacheSize ^ (cacheSize >>> 32));
    217             result = 37 * result + packageName.hashCode();
    218             return result;
    219         }
    220 
    221         @Override
    222         public boolean equals(Object o) {
    223             if (!(o instanceof AppSizeGrouping)) {
    224                 return false;
    225             }
    226             if (this == o) {
    227                 return true;
    228             }
    229             AppSizeGrouping grouping = (AppSizeGrouping) o;
    230             return packageName.equals(grouping.packageName) && appSize == grouping.appSize &&
    231                     cacheSize == grouping.cacheSize;
    232         }
    233 
    234         @Override
    235         public String toString() {
    236             return packageName + " " + appSize + " " + cacheSize;
    237         }
    238     }
    239 }