1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.compatibility.common.tradefed.testtype; 17 18 import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper; 19 import com.android.tradefed.build.IBuildInfo; 20 import com.android.tradefed.config.Option; 21 import com.android.tradefed.config.Option.Importance; 22 import com.android.tradefed.testtype.HostTest; 23 import com.android.tradefed.testtype.IAbi; 24 import com.android.tradefed.testtype.IAbiReceiver; 25 import com.android.tradefed.testtype.IBuildReceiver; 26 import com.android.tradefed.testtype.IRemoteTest; 27 import com.android.tradefed.testtype.IRuntimeHintProvider; 28 import com.android.tradefed.util.TimeVal; 29 30 import junit.framework.Test; 31 32 import java.io.File; 33 import java.io.IOException; 34 import java.lang.reflect.Modifier; 35 import java.net.URL; 36 import java.net.URLClassLoader; 37 import java.util.Enumeration; 38 import java.util.HashSet; 39 import java.util.List; 40 import java.util.Set; 41 import java.util.jar.JarEntry; 42 import java.util.jar.JarFile; 43 44 /** 45 * Test runner for host-side JUnit tests. 46 */ 47 public class JarHostTest extends HostTest implements IAbiReceiver, IBuildReceiver, 48 IRuntimeHintProvider { 49 50 @Option(name="jar", description="The jars containing the JUnit test class to run.", 51 importance = Importance.IF_UNSET) 52 private Set<String> mJars = new HashSet<>(); 53 54 @Option(name = "runtime-hint", 55 isTimeVal = true, 56 description="The hint about the test's runtime.") 57 private long mRuntimeHint = 60000;// 1 minute 58 59 private IAbi mAbi; 60 private IBuildInfo mBuild; 61 private CompatibilityBuildHelper mHelper; 62 63 /** 64 * {@inheritDoc} 65 */ 66 @Override setAbi(IAbi abi)67 public void setAbi(IAbi abi) { 68 mAbi = abi; 69 } 70 71 /** 72 * {@inheritDoc} 73 */ 74 @Override setBuild(IBuildInfo build)75 public void setBuild(IBuildInfo build) { 76 mBuild = build; 77 mHelper = new CompatibilityBuildHelper(build); 78 } 79 80 /** 81 * {@inheritDoc} 82 */ 83 @Override getRuntimeHint()84 public long getRuntimeHint() { 85 return mRuntimeHint; 86 } 87 88 /** 89 * {@inheritDoc} 90 */ 91 @Override getClasses()92 protected List<Class<?>> getClasses() throws IllegalArgumentException { 93 List<Class<?>> classes = super.getClasses(); 94 for (String jarName : mJars) { 95 JarFile jarFile = null; 96 try { 97 File file = new File(mHelper.getTestsDir(), jarName); 98 jarFile = new JarFile(file); 99 Enumeration<JarEntry> e = jarFile.entries(); 100 URL[] urls = { 101 new URL(String.format("jar:file:%s!/", file.getAbsolutePath())) 102 }; 103 URLClassLoader cl = URLClassLoader.newInstance(urls); 104 105 while (e.hasMoreElements()) { 106 JarEntry je = e.nextElement(); 107 if (je.isDirectory() || !je.getName().endsWith(".class") 108 || je.getName().contains("$")) { 109 continue; 110 } 111 String className = getClassName(je.getName()); 112 try { 113 Class<?> cls = cl.loadClass(className); 114 int modifiers = cls.getModifiers(); 115 if ((IRemoteTest.class.isAssignableFrom(cls) 116 || Test.class.isAssignableFrom(cls)) 117 && !Modifier.isStatic(modifiers) 118 && !Modifier.isPrivate(modifiers) 119 && !Modifier.isProtected(modifiers) 120 && !Modifier.isInterface(modifiers) 121 && !Modifier.isAbstract(modifiers)) { 122 classes.add(cls); 123 } 124 } catch (ClassNotFoundException cnfe) { 125 throw new IllegalArgumentException( 126 String.format("Cannot find test class %s", className)); 127 } 128 } 129 } catch (IOException e) { 130 e.printStackTrace(); 131 } finally { 132 if (jarFile != null) { 133 try { 134 jarFile.close(); 135 } catch (IOException e) { 136 // Ignored 137 } 138 } 139 } 140 } 141 return classes; 142 } 143 getClassName(String name)144 private static String getClassName(String name) { 145 // -6 because of .class 146 return name.substring(0, name.length() - 6).replace('/', '.'); 147 } 148 149 /** 150 * {@inheritDoc} 151 */ 152 @Override loadObject(Class<?> classObj)153 protected Object loadObject(Class<?> classObj) throws IllegalArgumentException { 154 Object object = super.loadObject(classObj); 155 if (object instanceof IAbiReceiver) { 156 ((IAbiReceiver) object).setAbi(mAbi); 157 } 158 if (object instanceof IBuildReceiver) { 159 ((IBuildReceiver) object).setBuild(mBuild); 160 } 161 return object; 162 } 163 } 164