package com.dgrid.plugins;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.junit.Test;
import org.junit.runner.JUnitCore;
import org.junit.runner.Request;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;
import junit.framework.TestCase;
import com.dgrid.api.JobletTypeHandler;
import com.dgrid.errors.TransportException;
import com.dgrid.gen.InvalidApiKey;
import com.dgrid.gen.InvalidJobId;
import com.dgrid.gen.JOB_STATUS;
import com.dgrid.gen.Joblet;
import com.dgrid.gen.JobletResult;
import com.dgrid.plugin.BaseDGridPlugin;
import com.dgrid.service.DGridClient;
import com.dgrid.service.DGridPluginManager;
import com.dgrid.util.StackTraceUtil;
public class JunitPlugin extends BaseDGridPlugin implements JobletTypeHandler {
private JUnitCore junitCore = new JUnitCore();
public String getDescription() {
return "Support for distributed junit test cases";
}
public void start() {
log.trace("start()");
DGridPluginManager pluginManager = (DGridPluginManager) super.pluginManager;
pluginManager.setJobletTypeHandler("junit", this);
}
public void stop() {
log.trace("stop()");
}
public JobletResult execute(Joblet joblet, DGridClient gridClient)
throws Throwable {
log.trace("execute()");
long start = System.currentTimeMillis();
String className = joblet.getParameters().get("class");
String methodName = joblet.getParameters().get("method");
Class cls = Class.forName(className);
JobletResult result = null;
if (methodName != null) {
result = executeTestMethod(cls, methodName, gridClient, joblet,
start);
} else if (inheritsFromTestCase(cls)) {
result = executeJunit3TestCases(cls, gridClient, joblet, start);
} else {
result = executeJunit4TestCases(cls, gridClient, joblet, start);
}
return result;
}
private JobletResult executeJunit3TestCases(Class cls,
DGridClient gridClient, Joblet joblet, long start)
throws TransportException, InvalidApiKey, InvalidJobId {
Method[] methods = cls.getMethods();
for (Method method : methods) {
if ((Modifier.isPublic(method.getModifiers()))
&& (method.getReturnType().equals(Void.TYPE))) {
String methodName = method.getName();
if (methodName.startsWith("test")) {
Map<String, String> params = new HashMap<String, String>(2);
params.put("class", cls.getName());
params.put("method", methodName);
Joblet joblet2 = new Joblet(0, 0l, 0, 0, joblet
.getSubmitter(), 1, "junit", methodName, params,
"", JOB_STATUS.RECEIVED);
gridClient.submitJoblet(joblet2, joblet.getJobId());
}
}
}
return new JobletResult(0, 0l, 0, (System.currentTimeMillis() - start),
JOB_STATUS.COMPLETED, "", joblet);
}
private JobletResult executeJunit4TestCases(Class cls,
DGridClient gridClient, Joblet joblet, long start) throws Exception {
Method[] methods = cls.getDeclaredMethods();
for (Method method : methods) {
Annotation testAnnotation = method.getAnnotation(Test.class);
if (testAnnotation != null) {
String methodName = method.getName();
Map<String, String> params = new HashMap<String, String>(2);
params.put("class", cls.getName());
params.put("method", methodName);
Joblet joblet2 = new Joblet(0, 0l, 0, 0, joblet.getSubmitter(),
1, "junit", methodName, params, "", JOB_STATUS.RECEIVED);
gridClient.submitJoblet(joblet2, joblet.getJobId());
}
}
return new JobletResult(0, 0l, 0, (System.currentTimeMillis() - start),
JOB_STATUS.COMPLETED, "", joblet);
}
private JobletResult executeTestMethod(Class cls, String methodName,
DGridClient gridClient, Joblet joblet, long start) throws Throwable {
log.trace("executeTestMethod()");
Method m = cls.getMethod(methodName, new Class[] {});
Object instance = cls.newInstance();
Request request = Request.method(cls, methodName);
Result result = junitCore.run(request);
boolean success = result.wasSuccessful();
if (success) {
return new JobletResult(0, 0l, 0,
(System.currentTimeMillis() - start), JOB_STATUS.COMPLETED,
"", joblet);
} else {
List<Failure> failures = result.getFailures();
Failure failure = failures.get(0);
return new JobletResult(0, 0l, 1,
(System.currentTimeMillis() - start), JOB_STATUS.FAILED,
StackTraceUtil.getStackTrace(failure.getException()),
joblet);
}
}
private boolean inheritsFromTestCase(Class cls) {
Class superClass = cls.getSuperclass();
if (superClass == null)
return false;
else {
if (superClass.equals(TestCase.class))
return true;
else
return inheritsFromTestCase(superClass);
}
}
}