Fix tests when running from the command line

When loading classes from the jar file, we can't just use the
URLClassLoader since it can not enumerate files in a jar directory.
Restoring the ModuleClassLoader and making all paths relative to the
system class loader (as opposed to relative to the class location).

Change-Id: Ib3f5d12dd5c964d0ba9cc6c5ec9cb556c989e653
(cherry picked from commit 2a4a6c81f8a103be5c48d8a0605a3e4416e8f7f1)
This commit is contained in:
Diego Perez
2016-11-17 13:20:04 +00:00
committed by Jerome Gaillard
parent 3e416cf4a8
commit dc3bb324ce
5 changed files with 74 additions and 8 deletions

View File

@@ -17,7 +17,9 @@ LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# Only compile source java files in this lib.
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_SRC_FILES := \
$(call all-java-files-under, src) \
$(call all-java-files-under, res/testApp/MyApplication/src/main/myapplication.widgets)
LOCAL_JAVA_RESOURCE_DIRS := res
LOCAL_MODULE := layoutlib-tests

View File

@@ -64,7 +64,7 @@ public class ImageUtils {
double scale = THUMBNAIL_SIZE / (double)maxDimension;
BufferedImage thumbnail = scale(image, scale, scale);
InputStream is = ImageUtils.class.getResourceAsStream(relativePath);
InputStream is = ImageUtils.class.getClassLoader().getResourceAsStream(relativePath);
if (is == null) {
String message = "Unable to load golden thumbnail: " + relativePath + "\n";
message = saveImageAndAppendMessage(thumbnail, message, relativePath);

View File

@@ -121,7 +121,7 @@ public class Main {
private static final String PLATFORM_DIR;
private static final String TEST_RES_DIR;
/** Location of the app to test inside {@link #TEST_RES_DIR}*/
private static final String APP_TEST_DIR = "/testApp/MyApplication";
private static final String APP_TEST_DIR = "testApp/MyApplication";
/** Location of the app's res dir inside {@link #TEST_RES_DIR}*/
private static final String APP_TEST_RES = APP_TEST_DIR + "/src/main/res";
private static final String APP_CLASSES_LOCATION =
@@ -138,8 +138,7 @@ public class Main {
// Default class loader with access to the app classes
private ClassLoader mDefaultClassLoader =
new URLClassLoader(new URL[]{this.getClass().getResource(APP_CLASSES_LOCATION)},
getClass().getClassLoader());
new ModuleClassLoader(APP_CLASSES_LOCATION, getClass().getClassLoader());
@Rule
public TestWatcher sRenderMessageWatcher = new TestWatcher() {
@@ -313,7 +312,8 @@ public class Main {
sFrameworkRepo.loadPublicResources(getLogger());
sProjectResources =
new ResourceRepository(new FolderWrapper(TEST_RES_DIR + APP_TEST_RES), false) {
new ResourceRepository(new FolderWrapper(TEST_RES_DIR + "/" + APP_TEST_RES),
false) {
@NonNull
@Override
protected ResourceItem createResourceItem(@NonNull String name) {

View File

@@ -0,0 +1,62 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.layoutlib.bridge.intensive;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import libcore.io.Streams;
/**
* Module class loader that loads classes from the test project.
*/
public class ModuleClassLoader extends ClassLoader {
private final Map<String, Class<?>> mClasses = new HashMap<>();
private String myModuleRoot;
/**
* @param moduleRoot The path to the module root
* @param parent The parent class loader
*/
public ModuleClassLoader(String moduleRoot, ClassLoader parent) {
super(parent);
myModuleRoot = moduleRoot + (moduleRoot.endsWith("/") ? "" : "/");
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
try {
return super.findClass(name);
} catch (ClassNotFoundException ignored) {
}
Class<?> clazz = mClasses.get(name);
if (clazz == null) {
String path = name.replace('.', '/').concat(".class");
try {
byte[] b = Streams.readFully(getResourceAsStream(myModuleRoot + path));
clazz = defineClass(name, b, 0, b.length);
mClasses.put(name, clazz);
} catch (IOException ignore) {
throw new ClassNotFoundException(name + " not found");
}
}
return clazz;
}
}

View File

@@ -42,9 +42,11 @@ public class LayoutPullParser extends KXmlParser implements ILayoutPullParser{
* @param layoutPath Must start with '/' and be relative to test resources.
*/
public LayoutPullParser(String layoutPath) {
assert layoutPath.startsWith("/");
if (layoutPath.startsWith("/")) {
layoutPath = layoutPath.substring(1);
}
try {
init(getClass().getResourceAsStream(layoutPath));
init(getClass().getClassLoader().getResourceAsStream(layoutPath));
} catch (XmlPullParserException e) {
throw new IOError(e);
}