blob: 87b551a490057f1c87cd63764ad7960159865246 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.netbeans.modules.testng.maven;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.maven.project.MavenProject;
import org.netbeans.api.java.classpath.ClassPath;
import org.netbeans.api.project.FileOwnerQuery;
import org.netbeans.api.project.Project;
import org.netbeans.api.project.ProjectUtils;
import org.netbeans.modules.java.testrunner.JavaUtils;
import org.netbeans.modules.maven.api.ModelUtils;
import org.netbeans.modules.maven.api.NbMavenProject;
import org.netbeans.modules.maven.api.execute.RunConfig;
import org.netbeans.modules.maven.api.execute.RunUtils;
import org.netbeans.modules.maven.model.ModelOperation;
import org.netbeans.modules.maven.model.Utilities;
import org.netbeans.modules.maven.model.pom.Dependency;
import org.netbeans.modules.maven.model.pom.DependencyManagement;
import org.netbeans.modules.maven.model.pom.POMModel;
import org.netbeans.modules.testng.api.TestNGSupport.Action;
import org.netbeans.modules.testng.spi.TestConfig;
import org.netbeans.modules.testng.spi.TestNGSupportImplementation;
import org.netbeans.modules.testng.spi.XMLSuiteSupport;
import org.openide.execution.ExecutorTask;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;
import org.openide.util.NbBundle;
import org.openide.util.RequestProcessor;
import org.openide.util.lookup.Lookups;
import org.openide.util.lookup.ServiceProvider;
/**
*
* @author lukas
*/
@ServiceProvider(service=TestNGSupportImplementation.class)
public class MavenTestNGSupport extends TestNGSupportImplementation {
private static final Logger LOGGER = Logger.getLogger(MavenTestNGSupport.class.getName());
private static final Set<Action> SUPPORTED_ACTIONS;
static {
Set<Action> s = new HashSet<Action>();
// s.add(Action.CREATE_TEST);
// s.add(Action.RUN_FAILED);
// s.add(Action.RUN_TESTMETHOD);
s.add(Action.RUN_TESTSUITE);
s.add(Action.DEBUG_TESTSUITE);
SUPPORTED_ACTIONS = Collections.unmodifiableSet(s);
}
@Override
public boolean isSupportEnabled(FileObject[] activatedFOs) {
return JavaUtils.isSupportEnabled(NbMavenProject.class, activatedFOs);
}
public boolean isActionSupported(Action action,Project p) {
return p != null && p.getLookup().lookup(NbMavenProject.class) != null && SUPPORTED_ACTIONS.contains(action);
}
@NbBundle.Messages("remove_junit3_when_adding_testng=Removing JUnit 3.x dependency as TestNG has transitive dependency to JUnit 4.x.")
public void configureProject(FileObject createdFile) {
ClassPath cp = ClassPath.getClassPath(createdFile, ClassPath.COMPILE);
FileObject ng = cp.findResource("org.testng.annotations.Test"); //NOI18N
if (ng == null) {
final Project p = FileOwnerQuery.getOwner(createdFile);
FileObject pom = p.getProjectDirectory().getFileObject("pom.xml"); //NOI18N
ModelOperation<POMModel> operation = new ModelOperation<POMModel>() {
public @Override
void performOperation(POMModel model) {
String groupID = "org.testng"; //NOI18N
String artifactID = "testng"; //NOI18N
if (!hasEffectiveDependency(groupID, artifactID, p.getLookup().lookup(NbMavenProject.class))) {
fixJUnitDependency(model, p.getLookup().lookup(NbMavenProject.class));
Dependency dep = ModelUtils.checkModelDependency(model, groupID, artifactID, true);
dep.setVersion("6.8.1"); //NOI18N
dep.setScope("test"); //NOI18N
}
}
};
Utilities.performPOMModelOperations(pom, Collections.singletonList(operation));
RequestProcessor RP = new RequestProcessor("Configure TestNG project task", 1, true); //NOI18N
RP.post(new Runnable() {
public void run() {
p.getLookup().lookup(NbMavenProject.class).downloadDependencyAndJavadocSource(true);
}
});
}
}
private boolean hasEffectiveDependency(String groupId, String artifactId, NbMavenProject prj) {
MavenProject mp = prj.getMavenProject();
List<org.apache.maven.model.Dependency> dl = new ArrayList<org.apache.maven.model.Dependency>();
dl.addAll(mp.getDependencies());
org.apache.maven.model.DependencyManagement dm = mp.getDependencyManagement();
if (dm != null) {
dl.addAll(dm.getDependencies());
}
for (org.apache.maven.model.Dependency d : dl) {
if (groupId.equals(d.getGroupId()) && artifactId.equals(d.getArtifactId())) {
return true;
}
}
return false;
}
private void fixJUnitDependency(POMModel model, NbMavenProject prj) {
String junitGroupID = "junit"; //NOI18N
String junitArtifactID = "junit"; //NOI18N
MavenProject mp = prj.getMavenProject();
List<org.apache.maven.model.Dependency> dl = new ArrayList<org.apache.maven.model.Dependency>();
dl.addAll(mp.getDependencies());
dl.add(null); //null is the marker to separate managed from dependencies
org.apache.maven.model.DependencyManagement dm = mp.getDependencyManagement();
if (dm != null) {
dl.addAll(dm.getDependencies());
}
boolean has3xJUnit = false;
boolean hasJUnit = false;
boolean hasManaged = false;
boolean inManagedList = false;
for (org.apache.maven.model.Dependency d : dl) {
if (d == null) {
inManagedList = true;
continue;
}
if (junitGroupID.equals(d.getGroupId()) && junitArtifactID.equals(d.getArtifactId())) {
hasJUnit = true;
if (inManagedList) {
hasManaged = true;
}
if (d.getVersion() != null && d.getVersion().startsWith("3.")) {
has3xJUnit = true;
}
}
}
org.netbeans.modules.maven.model.pom.Project pomProject = model.getProject();
DependencyManagement dependencyManagement = pomProject.getDependencyManagement();
if (hasManaged) {
if (dependencyManagement != null) {//1.a
Dependency managed = dependencyManagement.findDependencyById(junitGroupID, junitArtifactID, null);
if (managed != null) {
if (has3xJUnit) {//1.a.aa
LOGGER.log(Level.FINE, Bundle.remove_junit3_when_adding_testng());
dependencyManagement.removeDependency(managed);
} else {//1.a.bb.bbb
Dependency dep = pomProject.getModel().getFactory().createDependency();
dep.setGroupId(junitGroupID);
dep.setArtifactId(junitArtifactID);
dep.setVersion("4.10"); //NOI18N
pomProject.addDependency(dep);
}
return;
}
}
}
Dependency unmanaged = pomProject.findDependencyById(junitGroupID, junitArtifactID, null);
if (unmanaged != null) {//2.a.aa
if (unmanaged.getVersion() != null) {
LOGGER.log(Level.FINE, Bundle.remove_junit3_when_adding_testng());
pomProject.removeDependency(unmanaged);
}
} else {//2.a.ab
//dependency defined somewhere in parent poms..
if (has3xJUnit || hasManaged) {
Dependency dep = pomProject.getModel().getFactory().createDependency();
dep.setGroupId(junitGroupID);
dep.setArtifactId(junitArtifactID);
dep.setVersion("4.10"); //NOI18N
pomProject.addDependency(dep);
}
}
}
public TestExecutor createExecutor(Project p) {
return new MavenExecutor(p);
}
private static class MavenExecutor implements TestExecutor {
private static final String failedConfPath = "target/surefire-reports/testng-failed.xml"; //NOI18N
private static final String failedConfPath2 = "target/surefire-reports/testng-native-results/testng-failed.xml"; //NOI18N
private static final String resultsPath = "target/surefire-reports/testng-native-results/testng-results.xml"; //NOI18N
private Project p;
public MavenExecutor(Project p) {
this.p = p;
}
public boolean hasFailedTests() {
return getFailedConfig() != null;
}
public void execute(Action action, TestConfig config) throws IOException {
RunConfig rc;
if (Action.DEBUG_TESTSUITE.equals(action)
|| Action.DEBUG_TEST.equals(action)
|| Action.DEBUG_TESTMETHOD.equals(action)) {
rc = new TestNGActionsProvider().createConfigForDefaultAction("testng.debug", p, Lookups.singleton(config.getTest()));
} else {
rc = new TestNGActionsProvider().createConfigForDefaultAction("testng.test", p, Lookups.singleton(config.getTest()));
}
// MavenProject mp = rc.getMavenProject();
rc.setProperty("netbeans.testng.action", "true"); //NOI18N
if (config.doRerun()) {
copy(getFailedConfig());
// mp.addPlugin(createPluginDef(failedConfPath));
} else {
File f = null;
if (Action.RUN_TESTSUITE.equals(action) || Action.DEBUG_TESTSUITE.equals(action)) {
f = FileUtil.toFile(config.getTest());
} else {
f = XMLSuiteSupport.createSuiteforMethod(
new File(System.getProperty("java.io.tmpdir")), //NOI18N
ProjectUtils.getInformation(p).getDisplayName(),
config.getPackageName(),
config.getClassName(),
config.getMethodName());
}
f = FileUtil.normalizeFile(f);
copy(FileUtil.toFileObject(f));
// mp.addPlugin(createPluginDef(FileUtil.getRelativePath(p.getProjectDirectory(), FileUtil.toFileObject(f))));
}
ExecutorTask task = RunUtils.executeMaven(rc);
}
private FileObject getFailedConfig() {
FileObject fo = p.getProjectDirectory();
//XXX - should rather listen on a fileobject??
FileUtil.refreshFor(FileUtil.toFile(fo));
FileObject cfg = fo.getFileObject(failedConfPath);
if (cfg == null || !cfg.isValid()) {
cfg = fo.getFileObject(failedConfPath2);
}
return cfg;
}
private FileObject copy(FileObject source) throws IOException {
FileObject fo = p.getProjectDirectory();
//target/nb-private/tesng-suite.xml
FileObject folder = FileUtil.createFolder(fo, "target/nb-private"); //NOI18N
FileObject cfg = folder.getFileObject("testng-suite", "xml"); //NOI18N
if (cfg != null) {
cfg.delete();
}
return FileUtil.copyFile(source, folder, "testng-suite"); //NOI18N
}
// private Plugin createPluginDef(String testDesc) {
// Plugin plugin = new Plugin();
// plugin.setGroupId("org.apache.maven.plugins");
// plugin.setArtifactId("maven-surefire-plugin");
// plugin.setVersion("2.4.2");
//
// Xpp3Dom dom = (Xpp3Dom) plugin.getConfiguration();
// if (dom == null) {
// dom = new Xpp3Dom("configuration");
// plugin.setConfiguration(dom);
// }
//
// Xpp3Dom dom2 = dom.getChild("suiteXmlFiles");
// if (dom2 == null) {
// dom2 = new Xpp3Dom("suiteXmlFiles");
// dom.addChild(dom2);
// }
// Xpp3Dom dom3 = dom2.getChild("suiteXmlFile");
// if (dom3 == null) {
// dom3 = new Xpp3Dom("suiteXmlFile");
// dom3.setValue(testDesc);
// dom2.addChild(dom3);
// }
// return plugin;
// }
}
}