DiskStatsFileLoggerTest.java revision e47eac74f7c80738017734342f66b615189e7596
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
17package com.android.server.storage;
18
19import android.content.pm.PackageStats;
20import android.test.AndroidTestCase;
21import android.util.ArraySet;
22import libcore.io.IoUtils;
23import org.json.JSONArray;
24import org.json.JSONObject;
25import org.junit.Before;
26import org.junit.Rule;
27import org.junit.Test;
28import org.junit.rules.TemporaryFolder;
29import org.junit.runner.RunWith;
30import org.junit.runners.JUnit4;
31
32import java.io.File;
33import java.util.ArrayList;
34
35import static com.google.common.truth.Truth.assertThat;
36
37@RunWith(JUnit4.class)
38public 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}