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

Unified Diff: chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/HostBrowserClassLoaderTest.java

Issue 2179163002: Make HostBrowserClassLoader#getClassLoaderInstance() work if Chrome gets updated (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Merge branch 'master' into webapk_chrome_updated Created 4 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
Index: chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/HostBrowserClassLoaderTest.java
diff --git a/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/HostBrowserClassLoaderTest.java b/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/HostBrowserClassLoaderTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..2df3aa6f7d9ee590c9ce52e8bfc5c6c8bc601624
--- /dev/null
+++ b/chrome/android/webapk/shell_apk/junit/src/org/chromium/webapk/shell_apk/HostBrowserClassLoaderTest.java
@@ -0,0 +1,171 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.webapk.shell_apk;
+
+import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.res.AssetManager;
+
+import org.chromium.testing.local.LocalRobolectricTestRunner;
+import org.chromium.webapk.lib.common.WebApkVersionUtils;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.robolectric.Robolectric;
+import org.robolectric.annotation.Config;
+import org.robolectric.res.builder.RobolectricPackageManager;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.InputStream;
+
+/**
+ * Tests HostBrowserClassLoader.
+ */
+@RunWith(LocalRobolectricTestRunner.class)
+@Config(manifest = Config.NONE)
+public class HostBrowserClassLoaderTest {
+
+ /**
+ * Mock package name for the remote host browser.
+ */
+ private static final String REMOTE_PACKAGE_NAME = "remote_package";
+
+ private static final int REMOTE_DEX_VERSION = 1;
+ private static final int REMOTE_VERSION_CODE = 5;
+
+ private Context mContext;
+ private Context mRemoteContext;
+ private AssetManager mRemoteAssetManager;
+ private RobolectricPackageManager mPackageManager;
+
+ /**
+ * Stub DexLoader. Used to verify the version of the runtime library dex which is used to build
+ * the ClassLoader.
+ */
+ private DexLoader mMockDexLoader;
+
+ @Before
+ public void setUp() {
+ mContext = Robolectric.application;
+ mPackageManager = (RobolectricPackageManager) mContext.getPackageManager();
+ setRemoteVersionCode(REMOTE_VERSION_CODE);
+
+ mRemoteAssetManager = Mockito.mock(AssetManager.class);
+ setRemoteDexVersion(REMOTE_DEX_VERSION);
+
+ mRemoteContext = Mockito.mock(Context.class);
+ Mockito.when(mRemoteContext.getAssets()).thenReturn(mRemoteAssetManager);
+ Mockito.when(mRemoteContext.getPackageName()).thenReturn(REMOTE_PACKAGE_NAME);
+ Mockito.when(mRemoteContext.getPackageManager()).thenReturn(mPackageManager);
+
+ mMockDexLoader = Mockito.mock(DexLoader.class);
+ }
+
+ /**
+ * Test upgrading to a new runtime dex version.
+ */
+ @Test
+ public void testNewRuntimeDexVersion() {
+ HostBrowserClassLoader.createClassLoader(mContext, mRemoteContext, mMockDexLoader, null);
+
+ String expectedDexName = WebApkVersionUtils.getRuntimeDexName(REMOTE_DEX_VERSION);
+ verifyDexLoaderLoadCall(expectedDexName);
+ Mockito.reset(mMockDexLoader);
+
+ setRemoteVersionCode(REMOTE_VERSION_CODE + 1);
+ setRemoteDexVersion(REMOTE_DEX_VERSION + 1);
+ HostBrowserClassLoader.createClassLoader(mContext, mRemoteContext, mMockDexLoader, null);
+
+ expectedDexName = WebApkVersionUtils.getRuntimeDexName(REMOTE_DEX_VERSION + 1);
+ verifyDexLoaderLoadCall(expectedDexName);
+ }
+
+ /**
+ * Test that HostBrowserClassLoader#deleteCachedDexes() is not called if nothing has changed
+ * between calls to HostBrowserClassLoader#createClassLoader().
+ */
+ @Test
+ public void testCreateClassLoaderTwiceSameCachedData() {
+ String expectedDexName = WebApkVersionUtils.getRuntimeDexName(REMOTE_DEX_VERSION);
+ HostBrowserClassLoader.createClassLoader(mContext, mRemoteContext, mMockDexLoader, null);
+ verifyDexLoaderLoadCall(expectedDexName);
+ Mockito.reset(mMockDexLoader);
+
+ HostBrowserClassLoader.createClassLoader(mContext, mRemoteContext, mMockDexLoader, null);
+ verifyDexLoaderLoadCall(expectedDexName);
+ Mockito.verify(mMockDexLoader, Mockito.never()).deleteCachedDexes(Mockito.any(File.class));
+ }
+
+ /**
+ * Test that the ClassLoader is reused if nothing changed since the last call to
+ * HostBrowserClassLoader#createClassLoader() and HostBrowserClassLoader is still running.
+ * Reusing the ClassLoader whenever possible is important because building the ClassLoader is
+ * expensive.
+ */
+ @Test
+ public void testCanReuseClassLoader() {
+ HostBrowserClassLoader.createClassLoader(mContext, mRemoteContext, mMockDexLoader, null);
+ Assert.assertTrue(
+ HostBrowserClassLoader.canReuseClassLoaderInstance(mContext, mRemoteContext));
+ }
+
+ /**
+ * Test that the ClassLoader is not reused (even if there is no new runtime dex version) if
+ * Chrome is updated but WebAPK is still running.
+ */
+ @Test
+ public void testDontReuseClassLoaderRemoteVersionCodeChange() {
+ HostBrowserClassLoader.createClassLoader(mContext, mRemoteContext, mMockDexLoader, null);
+ setRemoteVersionCode(REMOTE_VERSION_CODE + 1);
+ Assert.assertFalse(
+ HostBrowserClassLoader.canReuseClassLoaderInstance(mContext, mRemoteContext));
+ }
+
+ /**
+ * Creates an InputStream with {@link value} as its data.
+ */
+ public InputStream createIntInputStream(int value) {
+ String stringValue = "" + value;
+ return new ByteArrayInputStream(stringValue.getBytes());
+ }
+
+ /**
+ * Sets the remote host browser's version code.
+ */
+ public void setRemoteVersionCode(int versionCode) {
+ PackageInfo packageInfo = new PackageInfo();
+ packageInfo.packageName = REMOTE_PACKAGE_NAME;
+ packageInfo.versionCode = versionCode;
+ mPackageManager.addPackage(packageInfo);
+ }
+
+ /**
+ * Sets the version of the current runtime library dex stored in the remote host browser's
+ * assets.
+ */
+ public void setRemoteDexVersion(int dexVersion) {
+ try {
+ Mockito.when(mRemoteAssetManager.open("webapk_dex_version.txt"))
+ .thenReturn(createIntInputStream(dexVersion));
+ } catch (Exception e) {
+ Assert.fail();
+ }
+ }
+
+ /**
+ * Verifies {@link DexLoader#load()} call.
+ * @param expectedDexName The name of the dex in the remote host browser's assets that
+ * {@link DexLoader#load()} should have been called with.
+ */
+ public void verifyDexLoaderLoadCall(String expectedDexName) {
+ Mockito.verify(mMockDexLoader)
+ .load(Mockito.any(Context.class), Mockito.eq(expectedDexName), Mockito.anyString(),
+ Mockito.any(File.class), Mockito.any(File.class));
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698