• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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