Merge "Initial UsageStatsDatabase Perf tests"
This commit is contained in:
committed by
Android (Google) Code Review
commit
565aa50952
@@ -27,7 +27,9 @@ import android.util.ArraySet;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
class IntervalStats {
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
public class IntervalStats {
|
||||
public long beginTime;
|
||||
public long endTime;
|
||||
public long lastTimeSaved;
|
||||
@@ -149,7 +151,11 @@ class IntervalStats {
|
||||
&& eventType != UsageEvents.Event.STANDBY_BUCKET_CHANGED;
|
||||
}
|
||||
|
||||
void update(String packageName, long timeStamp, int eventType) {
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@VisibleForTesting
|
||||
public void update(String packageName, long timeStamp, int eventType) {
|
||||
UsageStats usageStats = getOrCreateUsageStats(packageName);
|
||||
|
||||
// TODO(adamlesinski): Ensure that we recover from incorrect event sequences
|
||||
|
||||
@@ -42,7 +42,7 @@ import java.util.List;
|
||||
/**
|
||||
* Provides an interface to query for UsageStat data from an XML database.
|
||||
*/
|
||||
class UsageStatsDatabase {
|
||||
public class UsageStatsDatabase {
|
||||
private static final int CURRENT_VERSION = 3;
|
||||
|
||||
// Current version of the backup schema
|
||||
@@ -369,7 +369,7 @@ class UsageStatsDatabase {
|
||||
/**
|
||||
* Figures out what to extract from the given IntervalStats object.
|
||||
*/
|
||||
interface StatCombiner<T> {
|
||||
public interface StatCombiner<T> {
|
||||
|
||||
/**
|
||||
* Implementations should extract interesting from <code>stats</code> and add it
|
||||
|
||||
34
tests/UsageStatsPerfTests/Android.mk
Normal file
34
tests/UsageStatsPerfTests/Android.mk
Normal file
@@ -0,0 +1,34 @@
|
||||
# Copyright (C) 2018 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.
|
||||
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE_TAGS := tests
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
$(call all-java-files-under, src)
|
||||
|
||||
LOCAL_STATIC_JAVA_LIBRARIES := \
|
||||
android-support-test \
|
||||
apct-perftests-utils \
|
||||
services.usage
|
||||
|
||||
LOCAL_PACKAGE_NAME := UsageStatsPerfTests
|
||||
LOCAL_PRIVATE_PLATFORM_APIS := true
|
||||
|
||||
# For android.permission.FORCE_STOP_PACKAGES permission
|
||||
LOCAL_CERTIFICATE := platform
|
||||
|
||||
include $(BUILD_PACKAGE)
|
||||
29
tests/UsageStatsPerfTests/AndroidManifest.xml
Normal file
29
tests/UsageStatsPerfTests/AndroidManifest.xml
Normal file
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2018 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.
|
||||
-->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.android.frameworks.perftests.usage">
|
||||
<uses-sdk
|
||||
android:minSdkVersion="21" />
|
||||
<uses-permission android:name="android.permission.DUMP" />
|
||||
<uses-permission android:name="android.permission.FORCE_STOP_PACKAGES" />
|
||||
|
||||
<application>
|
||||
<uses-library android:name="android.test.runner" />
|
||||
</application>
|
||||
|
||||
<instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
|
||||
android:targetPackage="com.android.frameworks.perftests.usage"/>
|
||||
</manifest>
|
||||
28
tests/UsageStatsPerfTests/AndroidTest.xml
Normal file
28
tests/UsageStatsPerfTests/AndroidTest.xml
Normal file
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2018 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.
|
||||
-->
|
||||
<configuration description="Runs UsageStats Performance Tests">
|
||||
<target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
|
||||
<option name="test-file-name" value="UsageStatsPerfTests.apk"/>
|
||||
<option name="cleanup-apks" value="true"/>
|
||||
</target_preparer>
|
||||
|
||||
<option name="test-suite-tag" value="apct"/>
|
||||
<option name="test-tag" value="UsageStatsPerfTests"/>
|
||||
<test class="com.android.tradefed.testtype.AndroidJUnitTest">
|
||||
<option name="package" value="com.android.frameworks.perftests.usage"/>
|
||||
<option name="runner" value="android.support.test.runner.AndroidJUnitRunner"/>
|
||||
</test>
|
||||
</configuration>
|
||||
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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.frameworks.perftests.usage.tests;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
|
||||
import com.android.server.usage.UsageStatsDatabase;
|
||||
import com.android.server.usage.UsageStatsDatabase.StatCombiner;
|
||||
import com.android.server.usage.IntervalStats;
|
||||
|
||||
import android.app.usage.EventList;
|
||||
import android.app.usage.UsageEvents;
|
||||
import android.app.usage.UsageStatsManager;
|
||||
import android.content.Context;
|
||||
import android.os.SystemClock;
|
||||
import android.perftests.utils.ManualBenchmarkState;
|
||||
import android.perftests.utils.PerfManualStatusReporter;
|
||||
import android.support.test.filters.LargeTest;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@LargeTest
|
||||
public class UsageStatsDatabasePerfTest {
|
||||
protected static Context sContext;
|
||||
private static UsageStatsDatabase sUsageStatsDatabase;
|
||||
private static File mTestDir;
|
||||
|
||||
// Represents how many apps might have used in a day by a user with a few apps
|
||||
final static int FEW_PKGS = 10;
|
||||
// Represent how many apps might have used in a day by a user with many apps
|
||||
final static int MANY_PKGS = 50;
|
||||
// Represents how many usage events per app a device might have with light usage
|
||||
final static int LIGHT_USE = 10;
|
||||
// Represents how many usage events per app a device might have with heavy usage
|
||||
final static int HEAVY_USE = 50;
|
||||
|
||||
private static final StatCombiner<UsageEvents.Event> sUsageStatsCombiner =
|
||||
new StatCombiner<UsageEvents.Event>() {
|
||||
@Override
|
||||
public void combine(IntervalStats stats, boolean mutable,
|
||||
List<UsageEvents.Event> accResult) {
|
||||
final int size = stats.events.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
accResult.add(stats.events.get(i));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@Rule
|
||||
public PerfManualStatusReporter mPerfManualStatusReporter = new PerfManualStatusReporter();
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpOnce() {
|
||||
sContext = InstrumentationRegistry.getTargetContext();
|
||||
mTestDir = new File(sContext.getFilesDir(), "UsageStatsDatabasePerfTest");
|
||||
sUsageStatsDatabase = new UsageStatsDatabase(mTestDir);
|
||||
sUsageStatsDatabase.init(1);
|
||||
}
|
||||
|
||||
private static void populateIntervalStats(IntervalStats intervalStats, int packageCount,
|
||||
int eventsPerPackage) {
|
||||
if (intervalStats.events == null) {
|
||||
intervalStats.events = new EventList();
|
||||
}
|
||||
for (int pkg = 0; pkg < packageCount; pkg++) {
|
||||
UsageEvents.Event event = new UsageEvents.Event();
|
||||
event.mPackage = "fake.package.name" + pkg;
|
||||
event.mTimeStamp = 1;
|
||||
event.mEventType = UsageEvents.Event.MOVE_TO_FOREGROUND;
|
||||
for (int evt = 0; evt < eventsPerPackage; evt++) {
|
||||
intervalStats.events.insert(event);
|
||||
intervalStats.update(event.mPackage, event.mTimeStamp, event.mEventType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void clearUsageStatsFiles() {
|
||||
File[] intervalDirs = mTestDir.listFiles();
|
||||
for (File intervalDir : intervalDirs) {
|
||||
if (intervalDir.isDirectory()) {
|
||||
File[] usageFiles = intervalDir.listFiles();
|
||||
for (File f : usageFiles) {
|
||||
f.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void runQueryUsageStatsTest(int packageCount, int eventsPerPackage) throws IOException {
|
||||
final ManualBenchmarkState benchmarkState = mPerfManualStatusReporter.getBenchmarkState();
|
||||
IntervalStats intervalStats = new IntervalStats();
|
||||
populateIntervalStats(intervalStats, packageCount, eventsPerPackage);
|
||||
sUsageStatsDatabase.putUsageStats(0, intervalStats);
|
||||
long elapsedTimeNs = 0;
|
||||
while (benchmarkState.keepRunning(elapsedTimeNs)) {
|
||||
final long startTime = SystemClock.elapsedRealtimeNanos();
|
||||
List<UsageEvents.Event> temp = sUsageStatsDatabase.queryUsageStats(
|
||||
UsageStatsManager.INTERVAL_DAILY, 0, 2, sUsageStatsCombiner);
|
||||
final long endTime = SystemClock.elapsedRealtimeNanos();
|
||||
elapsedTimeNs = endTime - startTime;
|
||||
assertEquals(packageCount * eventsPerPackage, temp.size());
|
||||
}
|
||||
}
|
||||
|
||||
private void runPutUsageStatsTest(int packageCount, int eventsPerPackage) throws IOException {
|
||||
final ManualBenchmarkState benchmarkState = mPerfManualStatusReporter.getBenchmarkState();
|
||||
IntervalStats intervalStats = new IntervalStats();
|
||||
populateIntervalStats(intervalStats, packageCount, eventsPerPackage);
|
||||
long elapsedTimeNs = 0;
|
||||
while (benchmarkState.keepRunning(elapsedTimeNs)) {
|
||||
final long startTime = SystemClock.elapsedRealtimeNanos();
|
||||
sUsageStatsDatabase.putUsageStats(0, intervalStats);
|
||||
final long endTime = SystemClock.elapsedRealtimeNanos();
|
||||
elapsedTimeNs = endTime - startTime;
|
||||
clearUsageStatsFiles();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueryUsageStats_FewPkgsLightUse() throws IOException {
|
||||
runQueryUsageStatsTest(FEW_PKGS, LIGHT_USE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPutUsageStats_FewPkgsLightUse() throws IOException {
|
||||
runPutUsageStatsTest(FEW_PKGS, LIGHT_USE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueryUsageStats_FewPkgsHeavyUse() throws IOException {
|
||||
runQueryUsageStatsTest(FEW_PKGS, HEAVY_USE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPutUsageStats_FewPkgsHeavyUse() throws IOException {
|
||||
runPutUsageStatsTest(FEW_PKGS, HEAVY_USE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueryUsageStats_ManyPkgsLightUse() throws IOException {
|
||||
runQueryUsageStatsTest(MANY_PKGS, LIGHT_USE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPutUsageStats_ManyPkgsLightUse() throws IOException {
|
||||
runPutUsageStatsTest(MANY_PKGS, LIGHT_USE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueryUsageStats_ManyPkgsHeavyUse() throws IOException {
|
||||
runQueryUsageStatsTest(MANY_PKGS, HEAVY_USE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPutUsageStats_ManyPkgsHeavyUse() throws IOException {
|
||||
runPutUsageStatsTest(MANY_PKGS, HEAVY_USE);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user