Skip to content
Snippets Groups Projects
Commit f2585e4d authored by Aditya Belsare's avatar Aditya Belsare
Browse files

Enable crystall benchmarks for RemoteProvisioner tests

Adds a basic crystalball performance test to evaluate the round trip
performance from the device to request and obtain certificates from the remote key provisioning server. Test does include the setup time needed on the device to create the Certificate Request. The test is run normally using atest, and can be setup to run on multiple platforms with forrest.

Test: atest RemoteProvisionerPerfTests
Change-Id: I64e2ca3bb5332078ec08b4ab7e84a4a23b334617
parent d246d424
No related branches found
No related tags found
No related merge requests found
......@@ -2,6 +2,7 @@
vikramgaur@google.com
jbires@google.com
sethmo@google.com
asbel@google.com
# Reviewers (Avoid bothering unless somehow none of the above are available)
mpgroover@google.com
......
......@@ -8,7 +8,7 @@ Provisioning (RKP) between the device and server.
The application registers a periodic job using
[WorkManager](https://developer.android.com/jetpack/androidx/releases/work). This job is scheduled
to run once every ~24 hours in order to check the status of the attestation key pool and determine
if further provisining is needed. An active network connection is set as a prerequisite for the job
if further provisioning is needed. An active network connection is set as a prerequisite for the job
to be executed.
### On Demand Provisioning
......@@ -65,7 +65,7 @@ executing `atest <<name>>` from a terminal and Android checkout that is initiali
### [RemoteProvisionerUnitTests](/tests/unittests/Android.bp)
These tests exercise and validate the expected functionality of the entire remote provisioning tech
stack for the device. This suite includes full end to end tests which coordinate a provisioning step
stack for the device. This suite includes full end-to-end tests which coordinate a provisioning step
between the device and the backend server infrastructure.
### [RemoteProvisionerRegistrationTest](2)
......@@ -78,5 +78,9 @@ These tests validate behavior which requires host orchestration that would not b
`RemoteProvisionerUnitTests`. This is primarily related to validation of service behavior along
with metrics collection.
### [RemoteProvisionerPerfTests](/tests/perftests/Android.bp)
These tests measure the round-trip performance in terms of time taken to send a certificate request
and receive the certificates from the remote provisioning server.
[1]: https://cs.android.com/android/platform/superproject/+/master:frameworks/base/keystore/java/android/security/IGenerateRkpKeyService.aidl
[2]: /tests/unittests/src/com/android/remoteprovisioner/unittest/KeyRegisteredTest.java
// Copyright (C) 2022 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 {
default_applicable_licenses: ["Android-Apache-2.0"],
}
android_test {
name: "RemoteProvisionerPerfTests",
srcs: ["src/**/*.java"],
libs: ["android.test.runner.stubs"],
static_libs: [
"androidx.test.core",
"androidx.test.rules",
"androidx.work_work-runtime",
"androidx.work_work-testing",
"android.security.remoteprovisioning-java",
"platform-test-annotations",
"ub-uiautomator",
"cbor-java",
"apct-perftests-utils",
"collector-device-lib-platform",
],
data: [
":perfetto_artifacts",
],
platform_apis: true,
test_config: "AndroidTest.xml",
test_suites: ["device-tests"],
instrumentation_for: "RemoteProvisioner",
}
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2022 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.remoteprovisioner.perftest">
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application>
<uses-library android:name="android.test.runner" />
</application>
<instrumentation
android:name="androidx.test.runner.AndroidJUnitRunner"
android:targetPackage="com.android.remoteprovisioner"
android:label="RemoteProvisioner app perf tests" />
</manifest>
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2022 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 RemoteProvisioner app perf tests.">
<option name="test-suite-tag" value="apct" />
<option name="test-suite-tag" value="apct-metric-instrumentation" />
<object type="module_controller"
class="com.android.tradefed.testtype.suite.module.MinApiLevelModuleController">
<option name="min-api-level" value="31" />
<option name="api-level-prop" value="ro.product.first_api_level" />
</object>
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
<option name="test-file-name" value="RemoteProvisionerPerfTests.apk" />
</target_preparer>
<target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
<option name="force-root" value="true" />
</target_preparer>
<target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
<option name="push-file"
key="trace_config_detailed.textproto"
value="/data/misc/perfetto-traces/trace_config.textproto" />
</target_preparer>
<!-- Needed for storing the perfetto trace files in the sdcard/test_results-->
<option name="isolated-storage" value="false" />
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="com.android.remoteprovisioner.perftest" />
<option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
<option name="test-filter-dir" value="/data/data/com.android.remoteprovisioner" />
<!-- Listener related args for collecting the traces and waiting
for the device to stabilize. -->
<option name="device-listeners" value="android.device.collectors.ProcLoadListener" />
<option name="device-listeners" value="android.device.collectors.PerfettoListener" />
<!-- Guarantee that user defined RunListeners will be running before
any of the default listeners defined in this runner. -->
<option name="instrumentation-arg" key="newRunListenerMode" value="true" />
<!-- ProcLoadListener related arguments -->
<!-- Wait for device last minute threshold to reach 3 with 2 minute timeout
before starting the test run -->
<option name="instrumentation-arg" key="procload-collector:per_run" value="true" />
<option name="instrumentation-arg" key="proc-loadavg-threshold" value="3" />
<option name="instrumentation-arg" key="proc-loadavg-timeout" value="120000" />
<option name="instrumentation-arg" key="proc-loadavg-interval" value="10000" />
<!-- PerfettoListener related arguments -->
<option name="instrumentation-arg" key="perfetto_config_text_proto" value="true" />
<option name="instrumentation-arg"
key="perfetto_config_file" value="trace_config.textproto" />
<option name="instrumentation-arg" key="newRunListenerMode" value="true" />
</test>
</configuration>
/*
* Copyright (C) 2022 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.remoteprovisioner.perftest;
import static android.hardware.security.keymint.SecurityLevel.TRUSTED_ENVIRONMENT;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import android.content.Context;
import android.os.ServiceManager;
import android.perftests.utils.BenchmarkState;
import android.perftests.utils.PerfStatusReporter;
import android.security.remoteprovisioning.AttestationPoolStatus;
import android.security.remoteprovisioning.IRemoteProvisioning;
import android.security.remoteprovisioning.ImplInfo;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.runner.AndroidJUnit4;
import com.android.remoteprovisioner.GeekResponse;
import com.android.remoteprovisioner.Provisioner;
import com.android.remoteprovisioner.ProvisionerMetrics;
import com.android.remoteprovisioner.ServerInterface;
import com.android.remoteprovisioner.SettingsManager;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.time.Duration;
@RunWith(AndroidJUnit4.class)
public class ServerToSystemPerfTest {
private static final String SERVICE = "android.security.remoteprovisioning";
private static Context sContext;
private static IRemoteProvisioning sBinder;
private static int sCurve = 0;
private Duration mDuration;
private void assertPoolStatus(int total, int attested,
int unassigned, int expiring, Duration time) throws Exception {
AttestationPoolStatus pool = sBinder.getPoolStatus(time.toMillis(), TRUSTED_ENVIRONMENT);
assertEquals(total, pool.total);
assertEquals(attested, pool.attested);
assertEquals(unassigned, pool.unassigned);
assertEquals(expiring, pool.expiring);
}
@Rule
public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
@BeforeClass
public static void init() throws Exception {
sContext = ApplicationProvider.getApplicationContext();
sBinder =
IRemoteProvisioning.Stub.asInterface(ServiceManager.getService(SERVICE));
assertNotNull(sBinder);
ImplInfo[] info = sBinder.getImplementationInfo();
for (int i = 0; i < info.length; i++) {
if (info[i].secLevel == TRUSTED_ENVIRONMENT) {
sCurve = info[i].supportedCurve;
break;
}
}
}
@Before
public void setUp() throws Exception {
SettingsManager.clearPreferences(sContext);
sBinder.deleteAllKeys();
mDuration = Duration.ofMillis(System.currentTimeMillis());
}
@After
public void tearDown() throws Exception {
SettingsManager.clearPreferences(sContext);
sBinder.deleteAllKeys();
}
@Test
public void testFullRoundTrip() throws Exception {
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
setUp();
ProvisionerMetrics metrics = ProvisionerMetrics.createScheduledAttemptMetrics(sContext);
int numTestKeys = 1;
sBinder.generateKeyPair(SettingsManager.IS_TEST_MODE, TRUSTED_ENVIRONMENT);
GeekResponse geek = ServerInterface.fetchGeek(sContext, metrics);
assertNotNull(geek);
int numProvisioned =
Provisioner.provisionCerts(numTestKeys, TRUSTED_ENVIRONMENT,
geek.getGeekChain(sCurve), geek.getChallenge(), sBinder,
sContext, metrics);
assertEquals(numTestKeys, numProvisioned);
assertPoolStatus(numTestKeys, numTestKeys, numTestKeys, 0, mDuration);
tearDown();
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment