Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1864)

Unified Diff: chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/RecentTabsTest.java

Issue 2833653002: Last_n: instrumentation tests to verify timely snapshot deletion. (Closed)
Patch Set: Simplified page deletion monitoring Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/RecentTabsTest.java
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/RecentTabsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/RecentTabsTest.java
index 1808c6351b81581d193f6043dfc78079c3d80a97..6ab4db777c1df75c2da170399781d2e540534dc2 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/RecentTabsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/RecentTabsTest.java
@@ -35,6 +35,7 @@ import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
/** Integration tests for the Last 1 feature of Offline Pages. */
@RunWith(ChromeJUnit4ClassRunner.class)
@@ -45,11 +46,13 @@ public class RecentTabsTest {
public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule();
private static final String TEST_PAGE = "/chrome/test/data/android/about.html";
+ private static final String TEST_PAGE_2 = "/chrome/test/data/android/simple.html";
private static final int TIMEOUT_MS = 5000;
private OfflinePageBridge mOfflinePageBridge;
private EmbeddedTestServer mTestServer;
private String mTestPage;
+ private String mTestPage2;
private void initializeBridgeForProfile(final boolean incognitoProfile)
throws InterruptedException {
@@ -76,7 +79,7 @@ public class RecentTabsTest {
});
}
});
- Assert.assertTrue(semaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+ assertAcquire(semaphore);
}
@Before
@@ -85,11 +88,10 @@ public class RecentTabsTest {
ThreadUtils.runOnUiThreadBlocking(new Runnable() {
@Override
public void run() {
- // Ensure we start in an offline state.
- NetworkChangeNotifier.forceConnectivityState(false);
if (!NetworkChangeNotifier.isInitialized()) {
NetworkChangeNotifier.init();
}
+ NetworkChangeNotifier.forceConnectivityState(true);
}
});
@@ -98,6 +100,7 @@ public class RecentTabsTest {
mTestServer = EmbeddedTestServer.createAndStartServer(
InstrumentationRegistry.getInstrumentation().getContext());
mTestPage = mTestServer.getURL(TEST_PAGE);
+ mTestPage2 = mTestServer.getURL(TEST_PAGE_2);
}
@After
@@ -118,9 +121,9 @@ public class RecentTabsTest {
// The tab should be foreground and so no snapshot should exist.
Assert.assertNull(getPageByClientId(firstTabClientId));
- // Note, that switching to a new tab must occur after the SnapshotController believes the
- // page quality is good enough. With the debug flag, the delay after DomContentLoaded is 0
- // so we can definitely snapshot after onload (which is what |loadUrlInNewTab| waits for).
+ // Note: switching to a new tab must occur after the SnapshotController believes the page
+ // quality is good enough. With the debug flag, the delay after DomContentLoaded is 0 so we
+ // can definitely snapshot after onload (which is what |loadUrlInNewTab| waits for).
// Switch to a new tab to cause the WebContents hidden event.
mActivityTestRule.loadUrlInNewTab("about:blank");
@@ -129,10 +132,10 @@ public class RecentTabsTest {
}
/**
- * Note: this test relies on a sleeping period because some of the taking actions are
- * complicated to track otherwise, so there is the possibility of flakiness. I chose 100ms from
- * local testing and I expect it to be "safe" but it flakiness is detected it might have to be
- * further increased.
+ * Note: this test relies on a sleeping period because some of the monitored actions are
+ * difficult to track deterministically. A sleep time of 100 ms was chosen based on local
+ * testing and is expected to be "safe". Nevertheless if flakiness is detected it might have to
+ * be further increased.
*/
@Test
@CommandLineFlags.Add("short-offline-page-snapshot-delay-for-test")
@@ -188,10 +191,94 @@ public class RecentTabsTest {
waitForPageWithClientId(firstTabClientId);
}
- private void waitForPageWithClientId(final ClientId clientId) throws InterruptedException {
- if (getPageByClientId(clientId) != null) return;
+ /**
+ * Verifies that a snapshot created by last_n is properly deleted when the tab is navigated to
+ * another page. The deletion of snapshots for pages that should not be available anymore is a
+ * privacy requirement for last_n.
+ */
+ @Test
+ @CommandLineFlags.Add("short-offline-page-snapshot-delay-for-test")
+ @MediumTest
+ public void testLastNPageIsDeletedUponNavigation() throws Exception {
+ // The tab of interest.
+ final Tab tab = mActivityTestRule.loadUrlInNewTab(mTestPage);
+ final TabModelSelector tabModelSelector = tab.getTabModelSelector();
+
+ final ClientId firstTabClientId =
+ new ClientId(OfflinePageBridge.LAST_N_NAMESPACE, Integer.toString(tab.getId()));
+
+ // Switch to a new tab and wait for the snapshot to be created.
+ mActivityTestRule.loadUrlInNewTab("about:blank");
+ Assert.assertFalse(tab.equals(tabModelSelector.getCurrentTab()));
+ OfflinePageItem offlinePage = waitForPageWithClientId(firstTabClientId);
+
+ // Switch back to the initial tab.
+ ThreadUtils.runOnUiThreadBlocking(new Runnable() {
+ @Override
+ public void run() {
+ TabModel tabModel = tabModelSelector.getModelForTabId(tab.getId());
+ int tabIndex = TabModelUtils.getTabIndexById(tabModel, tab.getId());
+ TabModelUtils.setIndex(tabModel, tabIndex);
+ }
+ });
+ Assert.assertEquals(tabModelSelector.getCurrentTab(), tab);
+
+ // Navigate to a new page and confirm that the previously created snapshot has been deleted.
+ Semaphore deletionSemaphore = installPageDeletionSemaphore(offlinePage.getOfflineId());
+ mActivityTestRule.loadUrl(mTestPage2);
+ assertAcquire(deletionSemaphore);
+ }
+
+ /**
+ * Verifies that a snapshot created by last_n is properly deleted when the tab is closed. The
+ * deletion of snapshots for pages that should not be available anymore is a privacy requirement
+ * for last_n.
+ */
+ @Test
+ @CommandLineFlags.Add("short-offline-page-snapshot-delay-for-test")
+ @MediumTest
+ public void testLastNPageIsDeletedUponClosure() throws Exception {
+ // The tab of interest.
+ final Tab tab = mActivityTestRule.loadUrlInNewTab(mTestPage);
+ final TabModelSelector tabModelSelector = tab.getTabModelSelector();
+
+ final ClientId firstTabClientId =
+ new ClientId(OfflinePageBridge.LAST_N_NAMESPACE, Integer.toString(tab.getId()));
+
+ // Switch to a new tab and wait for the snapshot to be created.
+ mActivityTestRule.loadUrlInNewTab("about:blank");
+ OfflinePageItem offlinePage = waitForPageWithClientId(firstTabClientId);
+
+ // Requests closing the tab allowing for undo -- so to exercise the subscribed notification
+ // -- but immediately requests final closure.
+ final int tabId = tab.getId();
+ Semaphore deletionSemaphore = installPageDeletionSemaphore(offlinePage.getOfflineId());
+ ThreadUtils.runOnUiThreadBlocking(new Runnable() {
+ @Override
+ public void run() {
+ TabModel tabModel = tabModelSelector.getModelForTabId(tabId);
+ tabModel.closeTab(tab, false, false, true);
+ tabModel.commitTabClosure(tabId);
+ }
+ });
+
+ // Checks that the tab is no more and that the snapshot was deleted.
+ Assert.assertNull(tabModelSelector.getTabById(tabId));
+ assertAcquire(deletionSemaphore);
+ }
+
+ private void assertAcquire(Semaphore semaphore) throws InterruptedException {
+ Assert.assertTrue(semaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+ }
+
+ private OfflinePageItem waitForPageWithClientId(final ClientId clientId)
+ throws InterruptedException {
+ OfflinePageItem item = getPageByClientId(clientId);
+ if (item != null) return item;
final Semaphore semaphore = new Semaphore(0);
+ final AtomicReference<OfflinePageItem> itemReference =
+ new AtomicReference<OfflinePageItem>();
ThreadUtils.runOnUiThread(new Runnable() {
@Override
public void run() {
@@ -199,6 +286,7 @@ public class RecentTabsTest {
@Override
public void offlinePageAdded(OfflinePageItem newPage) {
if (newPage.getClientId().equals(clientId)) {
+ itemReference.set(newPage);
mOfflinePageBridge.removeObserver(this);
semaphore.release();
}
@@ -206,7 +294,27 @@ public class RecentTabsTest {
});
}
});
- Assert.assertTrue(semaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+ assertAcquire(semaphore);
+ return itemReference.get();
+ }
+
+ private Semaphore installPageDeletionSemaphore(final long offlineId) {
+ final Semaphore semaphore = new Semaphore(0);
+ ThreadUtils.runOnUiThreadBlocking(new Runnable() {
+ @Override
+ public void run() {
+ mOfflinePageBridge.addObserver(new OfflinePageModelObserver() {
+ @Override
+ public void offlinePageDeleted(DeletedPageInfo deletedPage) {
+ if (deletedPage.getOfflineId() == offlineId) {
+ mOfflinePageBridge.removeObserver(this);
+ semaphore.release();
+ }
+ }
+ });
+ }
+ });
+ return semaphore;
}
private OfflinePageItem getPageByClientId(ClientId clientId) throws InterruptedException {
@@ -230,7 +338,27 @@ public class RecentTabsTest {
});
}
});
- Assert.assertTrue(semaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+ assertAcquire(semaphore);
+ return result[0];
+ }
+
+ private OfflinePageItem getPageByOfflineId(final long offlineId) throws InterruptedException {
+ final OfflinePageItem[] result = {null};
+ final Semaphore semaphore = new Semaphore(0);
+
+ ThreadUtils.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mOfflinePageBridge.getPageByOfflineId(offlineId, new Callback<OfflinePageItem>() {
+ @Override
+ public void onResult(OfflinePageItem item) {
+ result[0] = item;
+ semaphore.release();
+ }
+ });
+ }
+ });
+ assertAcquire(semaphore);
return result[0];
}
}
« no previous file with comments | « chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698