Use "dpm force-security-logs" in security logging test.
This is to avoid relying on implementation details like
how big is batch notification level and how long is the
delay between log fetching.
Change-Id: Ic00da14ce214f4f6958d4fc098e573579f2853dd
Bug: 70886042
Test: cts-tradefed run cts -m CtsDevicePolicyManagerTestCases -t
com.android.cts.devicepolicy.DeviceOwnerTest#testSecurityLoggingWithSingleUser
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SecurityLoggingTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SecurityLoggingTest.java
index bc4fe8d..17d52f7 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SecurityLoggingTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SecurityLoggingTest.java
@@ -16,6 +16,8 @@
package com.android.cts.deviceowner;
import android.app.admin.SecurityLog.SecurityEvent;
+import android.content.Context;
+import android.content.SharedPreferences;
import android.os.Parcel;
import android.support.test.InstrumentationRegistry;
@@ -24,7 +26,8 @@
public class SecurityLoggingTest extends BaseDeviceOwnerTest {
private static final String ARG_BATCH_NUMBER = "batchNumber";
- private static final int BUFFER_ENTRIES_NOTIFICATION_LEVEL = 1024;
+ private static final String PREF_KEY_PREFIX = "batch-last-id-";
+ private static final String PREF_NAME = "batchIds";
/**
* Test: retrieving security logs can only be done if there's one user on the device or all
@@ -52,25 +55,30 @@
/**
* Test: retrieving security logs. This test has should be called when security logging is
- * enabled and directly after reboot with device owner installed so that security logging
- * actually takes place and fetching the logs isn't subject to rate limiting.
+ * enabled and a batch of events is available.
*/
- public void testGetSecurityLogs() {
- List<SecurityEvent> events = mDevicePolicyManager.retrieveSecurityLogs(getWho());
- String param = InstrumentationRegistry.getArguments().getString(ARG_BATCH_NUMBER);
- int batchNumber = param == null ? 0 : Integer.parseInt(param);
+ public void testGetSecurityLogs() throws Exception {
+ List<SecurityEvent> events = null;
+ // Retry once after seeping for 1 second, in case "dpm force-security-logs" hasn't taken
+ // effect just yet.
+ for (int i = 0; i < 2 && events == null; i++) {
+ events = mDevicePolicyManager.retrieveSecurityLogs(getWho());
+ if (events == null) Thread.sleep(1000);
+ }
+
+ final String param = InstrumentationRegistry.getArguments().getString(ARG_BATCH_NUMBER);
+ final int batchNumber = param == null ? 0 : Integer.parseInt(param);
verifySecurityLogs(batchNumber, events);
}
- private static void verifySecurityLogs(int batchNumber, List<SecurityEvent> events) {
+ private void verifySecurityLogs(int batchNumber, List<SecurityEvent> events) {
assertTrue("Unable to get events", events != null && events.size() > 0);
- assertTrue(
- "First id in batch " + events.get(0).getId() + " is too small for the batch number "
- + batchNumber,
- events.get(0).getId() >= (BUFFER_ENTRIES_NOTIFICATION_LEVEL * batchNumber));
+
+ verifyContinuousIdsBetweenBatches(batchNumber, events);
+
// We don't know much about the events, so just call public API methods.
for (int i = 0; i < events.size(); i++) {
- SecurityEvent event = events.get(i);
+ final SecurityEvent event = events.get(i);
// Test id for monotonically increasing.
if (i > 0) {
@@ -84,7 +92,7 @@
p.setDataPosition(0);
// Restore from parcel and check contents.
- SecurityEvent restored = SecurityEvent.CREATOR.createFromParcel(p);
+ final SecurityEvent restored = SecurityEvent.CREATOR.createFromParcel(p);
p.recycle();
// For some events data is encapsulated into Object array.
@@ -107,6 +115,31 @@
}
/**
+ * Check that there are no gaps between ids in two consecutive batches. Shared preference is
+ * used to store these numbers between invocations.
+ */
+ private void verifyContinuousIdsBetweenBatches(int batchNumber, List<SecurityEvent> events) {
+ final SharedPreferences prefs =
+ mContext.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
+
+ final long firstId = events.get(0).getId();
+ if (batchNumber == 0) {
+ assertEquals("Event id wasn't reset.", 0L, firstId);
+ } else {
+ final String prevBatchLastIdKey = PREF_KEY_PREFIX + (batchNumber - 1);
+ assertTrue("Last event id from previous batch not found in shared prefs",
+ prefs.contains(prevBatchLastIdKey));
+ final long prevBatchLastId = prefs.getLong(prevBatchLastIdKey, 0);
+ assertEquals("Event ids aren't consecutive between batches",
+ firstId, prevBatchLastId + 1);
+ }
+
+ final String currBatchLastIdKey = PREF_KEY_PREFIX + batchNumber;
+ final long lastId = events.get(events.size() - 1).getId();
+ prefs.edit().putLong(currBatchLastIdKey, lastId).commit();
+ }
+
+ /**
* Test: Test enabling security logging. This test should be executed after installing a device
* owner so that we check that logging is not enabled by default. This test has a side effect:
* security logging is enabled after its execution.
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
index 72795ad..f4db369 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
@@ -56,7 +56,7 @@
private static final String TEST_APP_LOCATION = "/data/local/tmp/cts/packageinstaller/";
private static final String ARG_SECURITY_LOGGING_BATCH_NUMBER = "batchNumber";
- private static final int BUFFER_SECURITY_ENTRIES_NOTIFICATION_LEVEL = 1024;
+ private static final int SECURITY_EVENTS_BATCH_SIZE = 100;
private static final String ARG_NETWORK_LOGGING_BATCH_COUNT = "batchCount";
@@ -471,23 +471,22 @@
executeDeviceTestMethod(".SecurityLoggingTest", "testDisablingSecurityLogging");
// Generate more than enough events for a batch of security events.
- int batchSize = BUFFER_SECURITY_ENTRIES_NOTIFICATION_LEVEL + 100;
try {
executeDeviceTestMethod(".SecurityLoggingTest", "testEnablingSecurityLogging");
// Reboot to ensure ro.device_owner is set to true in logd.
rebootAndWaitUntilReady();
// First batch: retrieve and verify the events.
- runBatch(0, batchSize);
+ runBatch(0);
// Verify event ids are consistent across a consecutive batch.
- runBatch(1, batchSize);
+ runBatch(1);
// Reboot the device, so the security event ids are reset.
rebootAndWaitUntilReady();
// First batch after reboot: retrieve and verify the events.
- runBatch(0 /* batch number */, batchSize);
+ runBatch(0 /* batch number */);
// Immediately attempting to fetch events again should fail.
executeDeviceTestMethod(".SecurityLoggingTest",
@@ -498,16 +497,14 @@
}
}
- private void runBatch(int batchNumber, int batchSize) throws Exception {
+ private void runBatch(int batchNumber) throws Exception {
// Trigger security events of type TAG_ADB_SHELL_CMD.
- for (int i = 0; i < batchSize; i++) {
- getDevice().executeShellCommand("adb shell echo just_testing_" + i);
+ for (int i = 0; i < SECURITY_EVENTS_BATCH_SIZE; i++) {
+ getDevice().executeShellCommand("echo just_testing_" + i);
}
- // Sleep for ~1 minute so that SecurityLogMonitor fetches the security events. This is
- // an implementation detail we shouldn't rely on but there is no other way to do it
- // currently.
- Thread.sleep(TimeUnit.SECONDS.toMillis(70));
+ // Force log batch.
+ getDevice().executeShellCommand("dpm force-security-logs");
// Verify the contents of the batch.
executeDeviceTestMethod(".SecurityLoggingTest", "testGetSecurityLogs",