blob: 2aca702b809ca80c4bc9b5baf4b0feae04591a7d [file] [log] [blame]
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.storage;
import android.content.pm.PackageStats;
import android.test.AndroidTestCase;
import android.util.ArraySet;
import libcore.io.IoUtils;
import org.json.JSONArray;
import org.json.JSONObject;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import java.io.File;
import java.util.ArrayList;
import static com.google.common.truth.Truth.assertThat;
@RunWith(JUnit4.class)
public class DiskStatsFileLoggerTest extends AndroidTestCase {
@Rule public TemporaryFolder temporaryFolder;
public FileCollector.MeasurementResult mMainResult;
public FileCollector.MeasurementResult mDownloadsResult;
private ArrayList<PackageStats> mPackages;
private File mOutputFile;
@Before
public void setUp() throws Exception {
super.setUp();
temporaryFolder = new TemporaryFolder();
temporaryFolder.create();
mOutputFile = temporaryFolder.newFile();
mMainResult = new FileCollector.MeasurementResult();
mDownloadsResult = new FileCollector.MeasurementResult();
mPackages = new ArrayList<>();
}
@Test
public void testEmptyStorage() throws Exception {
DiskStatsFileLogger logger = new DiskStatsFileLogger(
mMainResult, mDownloadsResult,mPackages, 0L);
logger.dumpToFile(mOutputFile);
JSONObject output = getOutputFileAsJson();
assertThat(output.getLong(DiskStatsFileLogger.PHOTOS_KEY)).isEqualTo(0L);
assertThat(output.getLong(DiskStatsFileLogger.VIDEOS_KEY)).isEqualTo(0L);
assertThat(output.getLong(DiskStatsFileLogger.AUDIO_KEY)).isEqualTo(0L);
assertThat(output.getLong(DiskStatsFileLogger.DOWNLOADS_KEY)).isEqualTo(0L);
assertThat(output.getLong(DiskStatsFileLogger.SYSTEM_KEY)).isEqualTo(0L);
assertThat(output.getLong(DiskStatsFileLogger.MISC_KEY)).isEqualTo(0L);
assertThat(output.getLong(DiskStatsFileLogger.APP_SIZE_AGG_KEY)).isEqualTo(0L);
assertThat(output.getLong(DiskStatsFileLogger.APP_CACHE_AGG_KEY)).isEqualTo(0L);
assertThat(
output.getJSONArray(DiskStatsFileLogger.PACKAGE_NAMES_KEY).length()).isEqualTo(0L);
assertThat(output.getJSONArray(DiskStatsFileLogger.APP_SIZES_KEY).length()).isEqualTo(0L);
assertThat(output.getJSONArray(DiskStatsFileLogger.APP_CACHES_KEY).length()).isEqualTo(0L);
}
@Test
public void testMeasurementResultsReported() throws Exception {
mMainResult.audioSize = 1;
mMainResult.imagesSize = 10;
mMainResult.miscSize = 100;
mDownloadsResult.miscSize = 1000;
DiskStatsFileLogger logger = new DiskStatsFileLogger(
mMainResult, mDownloadsResult,mPackages, 3L);
logger.dumpToFile(mOutputFile);
JSONObject output = getOutputFileAsJson();
assertThat(output.getLong(DiskStatsFileLogger.AUDIO_KEY)).isEqualTo(1L);
assertThat(output.getLong(DiskStatsFileLogger.PHOTOS_KEY)).isEqualTo(10L);
assertThat(output.getLong(DiskStatsFileLogger.MISC_KEY)).isEqualTo(100L);
assertThat(output.getLong(DiskStatsFileLogger.DOWNLOADS_KEY)).isEqualTo(1000L);
assertThat(output.getLong(DiskStatsFileLogger.SYSTEM_KEY)).isEqualTo(3L);
}
@Test
public void testAppsReported() throws Exception {
PackageStats firstPackage = new PackageStats("com.test.app");
firstPackage.codeSize = 100;
firstPackage.dataSize = 1000;
firstPackage.cacheSize = 20;
mPackages.add(firstPackage);
PackageStats secondPackage = new PackageStats("com.test.app2");
secondPackage.codeSize = 10;
secondPackage.dataSize = 1;
secondPackage.cacheSize = 2;
mPackages.add(secondPackage);
DiskStatsFileLogger logger = new DiskStatsFileLogger(
mMainResult, mDownloadsResult, mPackages, 0L);
logger.dumpToFile(mOutputFile);
JSONObject output = getOutputFileAsJson();
assertThat(output.getLong(DiskStatsFileLogger.APP_SIZE_AGG_KEY)).isEqualTo(1111);
assertThat(output.getLong(DiskStatsFileLogger.APP_CACHE_AGG_KEY)).isEqualTo(22);
JSONArray packageNames = output.getJSONArray(DiskStatsFileLogger.PACKAGE_NAMES_KEY);
assertThat(packageNames.length()).isEqualTo(2);
JSONArray appSizes = output.getJSONArray(DiskStatsFileLogger.APP_SIZES_KEY);
assertThat(appSizes.length()).isEqualTo(2);
JSONArray cacheSizes = output.getJSONArray(DiskStatsFileLogger.APP_CACHES_KEY);
assertThat(cacheSizes.length()).isEqualTo(2);
// We need to do this crazy Set over this because the DiskStatsFileLogger provides no
// guarantee of the ordering of the apps in its output. By using a set, we avoid any order
// problems.
ArraySet<AppSizeGrouping> apps = new ArraySet<>();
for (int i = 0; i < packageNames.length(); i++) {
AppSizeGrouping app = new AppSizeGrouping(packageNames.getString(i),
appSizes.getLong(i), cacheSizes.getLong(i));
apps.add(app);
}
assertThat(apps).containsAllOf(new AppSizeGrouping("com.test.app", 1100, 20),
new AppSizeGrouping("com.test.app2", 11, 2));
}
@Test
public void testEmulatedExternalStorageCounted() throws Exception {
PackageStats app = new PackageStats("com.test.app");
app.dataSize = 1000;
app.externalDataSize = 1000;
app.cacheSize = 20;
mPackages.add(app);
DiskStatsFileLogger logger = new DiskStatsFileLogger(
mMainResult, mDownloadsResult, mPackages, 0L);
logger.dumpToFile(mOutputFile);
JSONObject output = getOutputFileAsJson();
JSONArray appSizes = output.getJSONArray(DiskStatsFileLogger.APP_SIZES_KEY);
assertThat(appSizes.length()).isEqualTo(1);
assertThat(appSizes.getLong(0)).isEqualTo(2000);
}
@Test
public void testDuplicatePackageNameIsMergedAcrossMultipleUsers() throws Exception {
PackageStats app = new PackageStats("com.test.app");
app.dataSize = 1000;
app.externalDataSize = 1000;
app.cacheSize = 20;
app.userHandle = 0;
mPackages.add(app);
PackageStats secondApp = new PackageStats("com.test.app");
secondApp.dataSize = 100;
secondApp.externalDataSize = 100;
secondApp.cacheSize = 2;
secondApp.userHandle = 1;
mPackages.add(secondApp);
DiskStatsFileLogger logger = new DiskStatsFileLogger(
mMainResult, mDownloadsResult, mPackages, 0L);
logger.dumpToFile(mOutputFile);
JSONObject output = getOutputFileAsJson();
assertThat(output.getLong(DiskStatsFileLogger.APP_SIZE_AGG_KEY)).isEqualTo(2200);
assertThat(output.getLong(DiskStatsFileLogger.APP_CACHE_AGG_KEY)).isEqualTo(22);
JSONArray packageNames = output.getJSONArray(DiskStatsFileLogger.PACKAGE_NAMES_KEY);
assertThat(packageNames.length()).isEqualTo(1);
assertThat(packageNames.getString(0)).isEqualTo("com.test.app");
JSONArray appSizes = output.getJSONArray(DiskStatsFileLogger.APP_SIZES_KEY);
assertThat(appSizes.length()).isEqualTo(1);
assertThat(appSizes.getLong(0)).isEqualTo(2200);
JSONArray cacheSizes = output.getJSONArray(DiskStatsFileLogger.APP_CACHES_KEY);
assertThat(cacheSizes.length()).isEqualTo(1);
assertThat(cacheSizes.getLong(0)).isEqualTo(22);
}
private JSONObject getOutputFileAsJson() throws Exception {
return new JSONObject(IoUtils.readFileAsString(mOutputFile.getAbsolutePath()));
}
/**
* This class exists for putting zipped app size information arrays into a set for comparison
* purposes.
*/
private class AppSizeGrouping {
public String packageName;
public long appSize;
public long cacheSize;
public AppSizeGrouping(String packageName, long appSize, long cacheSize) {
this.packageName = packageName;
this.appSize = appSize;
this.cacheSize = cacheSize;
}
@Override
public int hashCode() {
int result = 17;
result = 37 * result + (int)(appSize ^ (appSize >>> 32));
result = 37 * result + (int)(cacheSize ^ (cacheSize >>> 32));
result = 37 * result + packageName.hashCode();
return result;
}
@Override
public boolean equals(Object o) {
if (!(o instanceof AppSizeGrouping)) {
return false;
}
if (this == o) {
return true;
}
AppSizeGrouping grouping = (AppSizeGrouping) o;
return packageName.equals(grouping.packageName) && appSize == grouping.appSize &&
cacheSize == grouping.cacheSize;
}
@Override
public String toString() {
return packageName + " " + appSize + " " + cacheSize;
}
}
}