Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1c6c5dec authored by Zimuzo Ezeozue's avatar Zimuzo Ezeozue Committed by Android (Google) Code Review
Browse files

Merge "Fix flaky RollbackTest#testBadUpdateRollback"

parents 53cc8bf1 790a3ccf
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -62,6 +62,13 @@ class RollbackBroadcastReceiver extends BroadcastReceiver {
        return mRollbackBroadcasts.poll(timeout, unit);
    }

    /**
     * Waits forever for the next rollback broadcast.
     */
    Intent take() throws InterruptedException {
        return mRollbackBroadcasts.take();
    }

    /**
     * Unregisters this broadcast receiver.
     */
+8 −31
Original line number Diff line number Diff line
@@ -27,7 +27,6 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;

import android.Manifest;
import android.app.ActivityManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -46,8 +45,6 @@ import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

import java.util.Collections;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;

/**
@@ -859,34 +856,14 @@ public class RollbackTest {
                    rm.getAvailableRollbacks(), TEST_APP_B);
            assertRollbackInfoEquals(TEST_APP_B, 2, 1, rollbackB);

            BlockingQueue<Integer> crashQueue = new SynchronousQueue<>();
            // Register rollback committed receiver
            RollbackBroadcastReceiver rollbackReceiver = new RollbackBroadcastReceiver();

            IntentFilter crashCountFilter = new IntentFilter();
            crashCountFilter.addAction("com.android.tests.rollback.CRASH");
            crashCountFilter.addCategory(Intent.CATEGORY_DEFAULT);
            // Crash TEST_APP_A PackageWatchdog#TRIGGER_FAILURE_COUNT times to trigger rollback
            crashCountReceiver = RollbackTestUtils.sendCrashBroadcast(context, TEST_APP_A, 5);

            crashCountReceiver = new BroadcastReceiver() {
                    @Override
                    public void onReceive(Context context, Intent intent) {
                        try {
                            // Sleep long enough for packagewatchdog to be notified of crash
                            Thread.sleep(1000);
                            // Kill app and close AppErrorDialog
                            ActivityManager am = context.getSystemService(ActivityManager.class);
                            am.killBackgroundProcesses(TEST_APP_A);
                            // Allow another package launch
                            crashQueue.put(intent.getIntExtra("count", 0));
                        } catch (InterruptedException e) {
                            fail("Failed to communicate with test app");
                        }
                    }
                };
            context.registerReceiver(crashCountReceiver, crashCountFilter);

            // Start apps PackageWatchdog#TRIGGER_FAILURE_COUNT times so TEST_APP_A crashes
            do {
                RollbackTestUtils.launchPackage(TEST_APP_A);
            } while(crashQueue.take() < 5);
            // Verify we received a broadcast for the rollback.
            rollbackReceiver.take();

            // TEST_APP_A is automatically rolled back by the RollbackPackageHealthObserver
            assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+38 −1
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;

import android.app.ActivityManager;
import android.app.AlarmManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
@@ -47,6 +48,7 @@ import java.util.Arrays;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.SynchronousQueue;

/**
 * Utilities to facilitate testing rollbacks.
@@ -187,7 +189,7 @@ class RollbackTestUtils {
    }

    /** Launches {@code packageName} with {@link Intent#ACTION_MAIN}. */
    static void launchPackage(String packageName)
    private static void launchPackage(String packageName)
            throws InterruptedException, IOException {
        Context context = InstrumentationRegistry.getContext();
        Intent intent = new Intent(Intent.ACTION_MAIN);
@@ -488,4 +490,39 @@ class RollbackTestUtils {
        }
        return null;
    }

    /**
     * Send broadcast to crash {@code packageName} {@code count} times. If {@code count} is at least
     * {@link PackageWatchdog#TRIGGER_FAILURE_COUNT}, watchdog crash detection will be triggered.
     */
    static BroadcastReceiver sendCrashBroadcast(Context context, String packageName, int count)
            throws InterruptedException, IOException {
        BlockingQueue<Integer> crashQueue = new SynchronousQueue<>();
        IntentFilter crashCountFilter = new IntentFilter();
        crashCountFilter.addAction("com.android.tests.rollback.CRASH");
        crashCountFilter.addCategory(Intent.CATEGORY_DEFAULT);

        BroadcastReceiver crashCountReceiver = new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    try {
                        // Sleep long enough for packagewatchdog to be notified of crash
                        Thread.sleep(1000);
                        // Kill app and close AppErrorDialog
                        ActivityManager am = context.getSystemService(ActivityManager.class);
                        am.killBackgroundProcesses(packageName);
                        // Allow another package launch
                        crashQueue.put(intent.getIntExtra("count", 0));
                    } catch (InterruptedException e) {
                        fail("Failed to communicate with test app");
                    }
                }
            };
        context.registerReceiver(crashCountReceiver, crashCountFilter);

        do {
            launchPackage(packageName);
        } while(crashQueue.take() < count);
        return crashCountReceiver;
    }
}