Merge "Add tests to verify job scheduling on events"

This commit is contained in:
Victor Hsieh
2023-01-31 21:10:19 +00:00
committed by Android (Google) Code Review
3 changed files with 78 additions and 8 deletions

View File

@@ -96,7 +96,6 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
/**
@@ -287,7 +286,7 @@ public class BinaryTransparencyService extends SystemService {
* - dynamically installed mobile bundled apps (MBAs) (new in Android U)
*/
public void recordMeasurementsForAllPackages() {
// check if we should record the resulting measurements
// check if we should measure and record
long currentTimeMs = System.currentTimeMillis();
if ((currentTimeMs - mMeasurementsLastRecordedMs) < RECORD_MEASUREMENTS_COOLDOWN_MS) {
Slog.d(TAG, "Skip measurement since the last measurement was only taken at "
@@ -1230,10 +1229,8 @@ public class BinaryTransparencyService extends SystemService {
* JobService to measure all covered binaries and record result to Westworld.
*/
public static class UpdateMeasurementsJobService extends JobService {
private static AtomicBoolean sScheduled = new AtomicBoolean();
private static long sTimeLastRanMs = 0;
private static final int DO_BINARY_MEASUREMENTS_JOB_ID =
UpdateMeasurementsJobService.class.hashCode();
private static final int DO_BINARY_MEASUREMENTS_JOB_ID = 1740526926;
@Override
public boolean onStartJob(JobParameters params) {
@@ -1256,7 +1253,6 @@ public class BinaryTransparencyService extends SystemService {
return;
}
sTimeLastRanMs = System.currentTimeMillis();
sScheduled.set(false);
jobFinished(params, false);
}).start();
@@ -1277,7 +1273,7 @@ public class BinaryTransparencyService extends SystemService {
return;
}
if (sScheduled.get()) {
if (jobScheduler.getPendingJob(DO_BINARY_MEASUREMENTS_JOB_ID) != null) {
Slog.d(TAG, "A measurement job has already been scheduled.");
return;
}
@@ -1303,7 +1299,6 @@ public class BinaryTransparencyService extends SystemService {
Slog.e(TAG, "Failed to schedule job to measure binaries.");
return;
}
sScheduled.set(true);
Slog.d(TAG, TextUtils.formatSimple(
"Job %d to measure binaries was scheduled successfully.",
DO_BINARY_MEASUREMENTS_JOB_ID));

View File

@@ -35,6 +35,7 @@ java_test_host {
data: [
":BinaryTransparencyTestApp",
":EasterEgg",
":com.android.apex.cts.shim.v2_rebootless_prebuilt",
],
test_suites: [
"general-tests",

View File

@@ -17,6 +17,7 @@
package android.transparency.test;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
@@ -29,14 +30,22 @@ import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.concurrent.TimeUnit;
// TODO: Add @Presubmit
@RunWith(DeviceJUnit4ClassRunner.class)
public final class BinaryTransparencyHostTest extends BaseHostJUnit4Test {
private static final String PACKAGE_NAME = "android.transparency.test.app";
private static final String JOB_ID = "1740526926";
/** Waiting time for the job to be scheduled */
private static final int JOB_CREATION_MAX_SECONDS = 5;
@After
public void tearDown() throws Exception {
uninstallPackage("com.android.egg");
uninstallRebootlessApex();
}
@Test
@@ -63,6 +72,28 @@ public final class BinaryTransparencyHostTest extends BaseHostJUnit4Test {
runDeviceTest("testCollectAllUpdatedPreloadInfo");
}
@Test
public void testRebootlessApexUpdateTriggersJobScheduling() throws Exception {
cancelPendingJob();
installRebootlessApex();
// Verify
expectJobToBeScheduled();
// Just cancel since we can't verifying very meaningfully.
cancelPendingJob();
}
@Test
public void testPreloadUpdateTriggersJobScheduling() throws Exception {
cancelPendingJob();
installPackage("EasterEgg.apk");
// Verify
expectJobToBeScheduled();
// Just cancel since we can't verifying very meaningfully.
cancelPendingJob();
}
@Test
public void testMeasureMbas() throws Exception {
// TODO(265244016): figure out a way to install an MBA
@@ -74,4 +105,47 @@ public final class BinaryTransparencyHostTest extends BaseHostJUnit4Test {
options.setTestMethodName(method);
runDeviceTests(options);
}
private void cancelPendingJob() throws DeviceNotAvailableException {
CommandResult result = getDevice().executeShellV2Command(
"cmd jobscheduler cancel android " + JOB_ID);
assertTrue(result.getStatus() == CommandStatus.SUCCESS);
}
private void expectJobToBeScheduled() throws Exception {
for (int i = 0; i < JOB_CREATION_MAX_SECONDS; i++) {
CommandResult result = getDevice().executeShellV2Command(
"cmd jobscheduler get-job-state android " + JOB_ID);
String state = result.getStdout().toString();
if (state.startsWith("unknown")) {
// The job hasn't been scheduled yet. So try again.
TimeUnit.SECONDS.sleep(1);
} else if (result.getExitCode() != 0) {
fail("Failing due to unexpected job state: " + result);
} else {
// The job exists, which is all we care about here
return;
}
}
fail("Timed out waiting for the job to be scheduled");
}
private void installRebootlessApex() throws Exception {
installPackage("com.android.apex.cts.shim.v2_rebootless.apex", "--force-non-staged");
}
private void uninstallRebootlessApex() throws DeviceNotAvailableException {
// Reboot only if the APEX is not the pre-install one.
CommandResult result = getDevice().executeShellV2Command(
"pm list packages -f --apex-only |grep com.android.apex.cts.shim");
assertTrue(result.getStatus() == CommandStatus.SUCCESS);
if (result.getStdout().contains("/data/apex/active/")) {
uninstallPackage("com.android.apex.cts.shim");
getDevice().reboot();
// Reboot enforces SELinux. Make it permissive again.
CommandResult runResult = getDevice().executeShellV2Command("setenforce 0");
assertTrue(runResult.getStatus() == CommandStatus.SUCCESS);
}
}
}