| /* |
| * Copyright 2000-2014 JetBrains s.r.o. |
| * |
| * 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 org.jetbrains.idea.maven; |
| |
| import com.intellij.openapi.application.ApplicationManager; |
| import com.intellij.openapi.application.Result; |
| import com.intellij.openapi.application.WriteAction; |
| import com.intellij.openapi.command.WriteCommandAction; |
| import com.intellij.openapi.module.Module; |
| import com.intellij.openapi.module.ModuleManager; |
| import com.intellij.openapi.module.ModuleType; |
| import com.intellij.openapi.module.StdModuleTypes; |
| import com.intellij.openapi.progress.EmptyProgressIndicator; |
| import com.intellij.openapi.project.Project; |
| import com.intellij.openapi.util.SystemInfo; |
| import com.intellij.openapi.util.io.FileUtil; |
| import com.intellij.openapi.vfs.LocalFileSystem; |
| import com.intellij.openapi.vfs.VirtualFile; |
| import com.intellij.testFramework.IdeaTestCase; |
| import com.intellij.testFramework.PsiTestUtil; |
| import com.intellij.testFramework.UsefulTestCase; |
| import com.intellij.testFramework.fixtures.IdeaProjectTestFixture; |
| import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory; |
| import com.intellij.util.ui.UIUtil; |
| import gnu.trove.THashSet; |
| import org.intellij.lang.annotations.Language; |
| import org.jetbrains.annotations.NonNls; |
| import org.jetbrains.annotations.NotNull; |
| import org.jetbrains.idea.maven.indices.MavenIndicesManager; |
| import org.jetbrains.idea.maven.project.*; |
| import org.jetbrains.idea.maven.utils.MavenProgressIndicator; |
| |
| import java.awt.*; |
| import java.io.File; |
| import java.io.IOException; |
| import java.lang.reflect.Field; |
| import java.lang.reflect.Modifier; |
| import java.util.*; |
| import java.util.List; |
| |
| public abstract class MavenTestCase extends UsefulTestCase { |
| protected static final MavenConsole NULL_MAVEN_CONSOLE = new NullMavenConsole(); |
| // should not be static |
| protected static MavenProgressIndicator EMPTY_MAVEN_PROCESS = new MavenProgressIndicator(new EmptyProgressIndicator()); |
| |
| private static File ourTempDir; |
| |
| protected IdeaProjectTestFixture myTestFixture; |
| |
| protected Project myProject; |
| |
| protected File myDir; |
| protected VirtualFile myProjectRoot; |
| |
| protected VirtualFile myProjectPom; |
| protected List<VirtualFile> myAllPoms = new ArrayList<VirtualFile>(); |
| |
| static { |
| IdeaTestCase.initPlatformPrefix(); |
| } |
| |
| @Override |
| protected void setUp() throws Exception { |
| super.setUp(); |
| |
| ensureTempDirCreated(); |
| |
| myDir = new File(ourTempDir, getTestName(false)); |
| myDir.mkdirs(); |
| |
| setUpFixtures(); |
| |
| myProject = myTestFixture.getProject(); |
| |
| MavenWorkspaceSettingsComponent.getInstance(myProject).loadState(new MavenWorkspaceSettings()); |
| |
| String home = getTestMavenHome(); |
| if (home != null) { |
| getMavenGeneralSettings().setMavenHome(home); |
| } |
| |
| UIUtil.invokeAndWaitIfNeeded(new Runnable() { |
| @Override |
| public void run() { |
| try { |
| restoreSettingsFile(); |
| } |
| catch (IOException e) { |
| throw new RuntimeException(e); |
| } |
| |
| ApplicationManager.getApplication().runWriteAction(new Runnable() { |
| @Override |
| public void run() { |
| try { |
| setUpInWriteAction(); |
| } |
| catch (Throwable e) { |
| try { |
| tearDown(); |
| } |
| catch (Exception e1) { |
| e1.printStackTrace(); |
| } |
| throw new RuntimeException(e); |
| } |
| } |
| }); |
| } |
| }); |
| |
| } |
| |
| private static void ensureTempDirCreated() { |
| if (ourTempDir != null) return; |
| |
| ourTempDir = new File(FileUtil.getTempDirectory(), "mavenTests"); |
| FileUtil.delete(ourTempDir); |
| ourTempDir.mkdirs(); |
| } |
| |
| protected void setUpFixtures() throws Exception { |
| myTestFixture = IdeaTestFixtureFactory.getFixtureFactory().createFixtureBuilder(getName()).getFixture(); |
| myTestFixture.setUp(); |
| } |
| |
| protected void setUpInWriteAction() throws Exception { |
| File projectDir = new File(myDir, "project"); |
| projectDir.mkdirs(); |
| myProjectRoot = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(projectDir); |
| } |
| |
| @Override |
| protected void tearDown() throws Exception { |
| try { |
| myProject = null; |
| UIUtil.invokeAndWaitIfNeeded(new Runnable() { |
| @Override |
| public void run() { |
| try { |
| tearDownFixtures(); |
| } |
| catch (Exception e) { |
| throw new RuntimeException(e); |
| } |
| } |
| }); |
| if (!FileUtil.delete(myDir) && myDir.exists()) { |
| System.err.println("Cannot delete " + myDir); |
| //printDirectoryContent(myDir); |
| myDir.deleteOnExit(); |
| } |
| |
| MavenIndicesManager.getInstance().clear(); |
| } |
| finally { |
| super.tearDown(); |
| resetClassFields(getClass()); |
| } |
| } |
| |
| private static void printDirectoryContent(File dir) { |
| File[] files = dir.listFiles(); |
| if (files == null) return; |
| |
| for (File file : files) { |
| System.out.println(file.getAbsolutePath()); |
| |
| if (file.isDirectory()) { |
| printDirectoryContent(file); |
| } |
| } |
| } |
| |
| protected void tearDownFixtures() throws Exception { |
| myTestFixture.tearDown(); |
| myTestFixture = null; |
| } |
| |
| private void resetClassFields(final Class<?> aClass) { |
| if (aClass == null) return; |
| |
| final Field[] fields = aClass.getDeclaredFields(); |
| for (Field field : fields) { |
| final int modifiers = field.getModifiers(); |
| if ((modifiers & Modifier.FINAL) == 0 |
| && (modifiers & Modifier.STATIC) == 0 |
| && !field.getType().isPrimitive()) { |
| field.setAccessible(true); |
| try { |
| field.set(this, null); |
| } |
| catch (IllegalAccessException e) { |
| e.printStackTrace(); |
| } |
| } |
| } |
| |
| if (aClass == MavenTestCase.class) return; |
| resetClassFields(aClass.getSuperclass()); |
| } |
| |
| @Override |
| protected void runTest() throws Throwable { |
| try { |
| if (runInWriteAction()) { |
| new WriteAction() { |
| @Override |
| protected void run(Result result) throws Throwable { |
| MavenTestCase.super.runTest(); |
| } |
| }.executeSilently().throwException(); |
| } |
| else { |
| MavenTestCase.super.runTest(); |
| } |
| } |
| catch (Exception throwable) { |
| Throwable each = throwable; |
| do { |
| if (each instanceof HeadlessException) { |
| printIgnoredMessage("Doesn't work in Headless environment"); |
| return; |
| } |
| } |
| while ((each = each.getCause()) != null); |
| throw throwable; |
| } |
| } |
| |
| @Override |
| protected void invokeTestRunnable(@NotNull Runnable runnable) throws Exception { |
| runnable.run(); |
| } |
| |
| protected boolean runInWriteAction() { |
| return false; |
| } |
| |
| protected static String getRoot() { |
| if (SystemInfo.isWindows) return "c:"; |
| return ""; |
| } |
| |
| protected static String getEnvVar() { |
| if (SystemInfo.isWindows) return "TEMP"; |
| else if (SystemInfo.isLinux) return "HOME"; |
| return "TMPDIR"; |
| } |
| |
| protected MavenGeneralSettings getMavenGeneralSettings() { |
| return MavenProjectsManager.getInstance(myProject).getGeneralSettings(); |
| } |
| |
| protected MavenImportingSettings getMavenImporterSettings() { |
| return MavenProjectsManager.getInstance(myProject).getImportingSettings(); |
| } |
| |
| protected String getRepositoryPath() { |
| String path = getRepositoryFile().getPath(); |
| return FileUtil.toSystemIndependentName(path); |
| } |
| |
| protected File getRepositoryFile() { |
| return getMavenGeneralSettings().getEffectiveLocalRepository(); |
| } |
| |
| protected void setRepositoryPath(String path) { |
| getMavenGeneralSettings().setLocalRepository(path); |
| } |
| |
| protected String getProjectPath() { |
| return myProjectRoot.getPath(); |
| } |
| |
| protected String getParentPath() { |
| return myProjectRoot.getParent().getPath(); |
| } |
| |
| protected String pathFromBasedir(String relPath) { |
| return pathFromBasedir(myProjectRoot, relPath); |
| } |
| |
| protected static String pathFromBasedir(VirtualFile root, String relPath) { |
| return FileUtil.toSystemIndependentName(root.getPath() + "/" + relPath); |
| } |
| |
| protected VirtualFile updateSettingsXml(String content) throws IOException { |
| return updateSettingsXmlFully(createSettingsXmlContent(content)); |
| } |
| |
| protected VirtualFile updateSettingsXmlFully(@NonNls @Language("XML") String content) throws IOException { |
| File ioFile = new File(myDir, "settings.xml"); |
| ioFile.createNewFile(); |
| VirtualFile f = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(ioFile); |
| setFileContent(f, content, true); |
| getMavenGeneralSettings().setUserSettingsFile(f.getPath()); |
| return f; |
| } |
| |
| protected void deleteSettingsXml() throws IOException { |
| new WriteCommandAction.Simple(myProject) { |
| @Override |
| protected void run() throws Throwable { |
| VirtualFile f = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(new File(myDir, "settings.xml")); |
| if (f != null) f.delete(this); |
| } |
| }.execute().throwException(); |
| } |
| |
| private static String createSettingsXmlContent(String content) { |
| String mirror = System.getProperty("idea.maven.test.mirror", |
| "http://maven.labs.intellij.net:8081/nexus/content/groups/public/"); |
| return "<settings>" + |
| content + |
| "<mirrors>" + |
| " <mirror>" + |
| " <id>Nexus</id>" + |
| " <url>" + mirror + "</url>" + |
| " <mirrorOf>*</mirrorOf>" + |
| " </mirror>" + |
| "</mirrors>" + |
| "</settings>"; |
| } |
| |
| protected void restoreSettingsFile() throws IOException { |
| updateSettingsXml(""); |
| } |
| |
| protected Module createModule(String name) throws IOException { |
| return createModule(name, StdModuleTypes.JAVA); |
| } |
| |
| protected Module createModule(final String name, final ModuleType type) throws IOException { |
| return new WriteCommandAction<Module>(myProject) { |
| @Override |
| protected void run(Result<Module> moduleResult) throws Throwable { |
| VirtualFile f = createProjectSubFile(name + "/" + name + ".iml"); |
| Module module = ModuleManager.getInstance(myProject).newModule(f.getPath(), type.getId()); |
| PsiTestUtil.addContentRoot(module, f.getParent()); |
| moduleResult.setResult(module); |
| } |
| }.execute().getResultObject(); |
| } |
| |
| protected VirtualFile createProjectPom(@NonNls String xml) throws IOException { |
| return myProjectPom = createPomFile(myProjectRoot, xml); |
| } |
| |
| protected VirtualFile createModulePom(String relativePath, String xml) throws IOException { |
| return createPomFile(createProjectSubDir(relativePath), xml); |
| } |
| |
| protected VirtualFile createPomFile(final VirtualFile dir, String xml) throws IOException { |
| VirtualFile f = dir.findChild("pom.xml"); |
| if (f == null) { |
| f = new WriteAction<VirtualFile>() { |
| @Override |
| protected void run(Result<VirtualFile> result) throws Throwable { |
| VirtualFile res = dir.createChildData(null, "pom.xml"); |
| result.setResult(res); |
| } |
| }.execute().getResultObject(); |
| myAllPoms.add(f); |
| } |
| setFileContent(f, createPomXml(xml), true); |
| return f; |
| } |
| |
| @NonNls @Language(value="XML") |
| public static String createPomXml(@NonNls @Language(value="XML", prefix="<xml>", suffix="</xml>") String xml) { |
| return "<?xml version=\"1.0\"?>" + |
| "<project xmlns=\"http://maven.apache.org/POM/4.0.0\"" + |
| " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" + |
| " xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">" + |
| " <modelVersion>4.0.0</modelVersion>" + |
| xml + |
| "</project>"; |
| } |
| |
| protected VirtualFile createProfilesXmlOldStyle(String xml) throws IOException { |
| return createProfilesFile(myProjectRoot, xml, true); |
| } |
| |
| protected VirtualFile createProfilesXmlOldStyle(String relativePath, String xml) throws IOException { |
| return createProfilesFile(createProjectSubDir(relativePath), xml, true); |
| } |
| |
| protected VirtualFile createProfilesXml(String xml) throws IOException { |
| return createProfilesFile(myProjectRoot, xml, false); |
| } |
| |
| protected VirtualFile createProfilesXml(String relativePath, String xml) throws IOException { |
| return createProfilesFile(createProjectSubDir(relativePath), xml, false); |
| } |
| |
| private static VirtualFile createProfilesFile(VirtualFile dir, String xml, boolean oldStyle) throws IOException { |
| return createProfilesFile(dir, createValidProfiles(xml, oldStyle)); |
| } |
| |
| protected VirtualFile createFullProfilesXml(String content) throws IOException { |
| return createProfilesFile(myProjectRoot, content); |
| } |
| |
| protected VirtualFile createFullProfilesXml(String relativePath, String content) throws IOException { |
| return createProfilesFile(createProjectSubDir(relativePath), content); |
| } |
| |
| private static VirtualFile createProfilesFile(final VirtualFile dir, String content) throws IOException { |
| VirtualFile f = dir.findChild("profiles.xml"); |
| if (f == null) { |
| f = new WriteAction<VirtualFile>() { |
| @Override |
| protected void run(Result<VirtualFile> result) throws Throwable { |
| VirtualFile res = dir.createChildData(null, "profiles.xml"); |
| result.setResult(res); |
| } |
| }.execute().getResultObject(); |
| } |
| setFileContent(f, content, true); |
| return f; |
| } |
| |
| @Language("XML") |
| private static String createValidProfiles(String xml, boolean oldStyle) { |
| if (oldStyle) { |
| return "<?xml version=\"1.0\"?>" + |
| "<profiles>" + |
| xml + |
| "</profiles>"; |
| } |
| return "<?xml version=\"1.0\"?>" + |
| "<profilesXml>" + |
| "<profiles>" + |
| xml + |
| "</profiles>" + |
| "</profilesXml>"; |
| } |
| |
| protected void deleteProfilesXml() throws IOException { |
| new WriteCommandAction.Simple(myProject) { |
| @Override |
| protected void run() throws Throwable { |
| VirtualFile f = myProjectRoot.findChild("profiles.xml"); |
| if (f != null) f.delete(this); |
| } |
| }.execute().throwException(); |
| } |
| |
| protected void createStdProjectFolders() { |
| createProjectSubDirs("src/main/java", |
| "src/main/resources", |
| "src/test/java", |
| "src/test/resources"); |
| } |
| |
| protected void createProjectSubDirs(String... relativePaths) { |
| for (String path : relativePaths) { |
| createProjectSubDir(path); |
| } |
| } |
| |
| protected VirtualFile createProjectSubDir(String relativePath) { |
| File f = new File(getProjectPath(), relativePath); |
| f.mkdirs(); |
| return LocalFileSystem.getInstance().refreshAndFindFileByIoFile(f); |
| } |
| |
| protected VirtualFile createProjectSubFile(String relativePath) throws IOException { |
| File f = new File(getProjectPath(), relativePath); |
| f.getParentFile().mkdirs(); |
| f.createNewFile(); |
| return LocalFileSystem.getInstance().refreshAndFindFileByIoFile(f); |
| } |
| |
| protected VirtualFile createProjectSubFile(String relativePath, String content) throws IOException { |
| VirtualFile file = createProjectSubFile(relativePath); |
| setFileContent(file, content, false); |
| return file; |
| } |
| |
| private static void setFileContent(final VirtualFile file, final String content, final boolean advanceStamps) throws IOException { |
| new WriteAction<VirtualFile>() { |
| @Override |
| protected void run(Result<VirtualFile> result) throws Throwable { |
| if (advanceStamps) { |
| file.setBinaryContent(content.getBytes(), -1, file.getTimeStamp() + 4000); |
| } |
| else { |
| file.setBinaryContent(content.getBytes(), file.getModificationStamp(), file.getTimeStamp()); |
| } |
| } |
| }.execute().getResultObject(); |
| } |
| |
| protected static <T, U> void assertOrderedElementsAreEqual(Collection<U> actual, Collection<T> expected) { |
| assertOrderedElementsAreEqual(actual, expected.toArray()); |
| } |
| |
| protected static <T> void assertUnorderedElementsAreEqual(Collection<T> actual, Collection<T> expected) { |
| assertEquals(new HashSet<T>(expected), new HashSet<T>(actual)); |
| } |
| protected static void assertUnorderedPathsAreEqual(Collection<String> actual, Collection<String> expected) { |
| assertEquals(new SetWithToString<String>(new THashSet<String>(expected, FileUtil.PATH_HASHING_STRATEGY)), |
| new SetWithToString<String>(new THashSet<String>(actual, FileUtil.PATH_HASHING_STRATEGY))); |
| } |
| |
| protected static <T> void assertUnorderedElementsAreEqual(T[] actual, T... expected) { |
| assertUnorderedElementsAreEqual(Arrays.asList(actual), expected); |
| } |
| |
| protected static <T> void assertUnorderedElementsAreEqual(Collection<T> actual, T... expected) { |
| assertUnorderedElementsAreEqual(actual, Arrays.asList(expected)); |
| } |
| |
| protected static <T, U> void assertOrderedElementsAreEqual(Collection<U> actual, T... expected) { |
| String s = "\nexpected: " + Arrays.asList(expected) + "\nactual: " + new ArrayList<U>(actual); |
| assertEquals(s, expected.length, actual.size()); |
| |
| List<U> actualList = new ArrayList<U>(actual); |
| for (int i = 0; i < expected.length; i++) { |
| T expectedElement = expected[i]; |
| U actualElement = actualList.get(i); |
| assertEquals(s, expectedElement, actualElement); |
| } |
| } |
| |
| protected static <T> void assertContain(List<? extends T> actual, T... expected) { |
| List<T> expectedList = Arrays.asList(expected); |
| assertTrue("expected: " + expectedList + "\n" + "actual: " + actual.toString(), actual.containsAll(expectedList)); |
| } |
| |
| protected static <T> void assertDoNotContain(List<T> actual, T... expected) { |
| List<T> actualCopy = new ArrayList<T>(actual); |
| actualCopy.removeAll(Arrays.asList(expected)); |
| assertEquals(actual.toString(), actualCopy.size(), actual.size()); |
| } |
| |
| protected boolean ignore() { |
| printIgnoredMessage(null); |
| return true; |
| } |
| |
| protected boolean hasMavenInstallation() { |
| boolean result = getTestMavenHome() != null; |
| if (!result) printIgnoredMessage("Maven installation not found"); |
| return result; |
| } |
| |
| private void printIgnoredMessage(String message) { |
| String toPrint = "Ignored"; |
| if (message != null) { |
| toPrint += ", because " + message; |
| } |
| toPrint += ": " + getClass().getSimpleName() + "." + getName(); |
| System.out.println(toPrint); |
| } |
| |
| private static String getTestMavenHome() { |
| return System.getProperty("idea.maven.test.home"); |
| } |
| |
| private static class SetWithToString<T> extends AbstractSet<T> { |
| |
| private final Set<T> myDelegate; |
| |
| public SetWithToString(@NotNull Set<T> delegate) { |
| myDelegate = delegate; |
| } |
| |
| @Override |
| public int size() { |
| return myDelegate.size(); |
| } |
| |
| @Override |
| public boolean contains(Object o) { |
| return myDelegate.contains(o); |
| } |
| |
| @NotNull |
| @Override |
| public Iterator<T> iterator() { |
| return myDelegate.iterator(); |
| } |
| |
| @Override |
| public boolean containsAll(Collection<?> c) { |
| return myDelegate.containsAll(c); |
| } |
| |
| @Override |
| public boolean equals(Object o) { |
| return myDelegate.equals(o); |
| } |
| |
| @Override |
| public int hashCode() { |
| return myDelegate.hashCode(); |
| } |
| } |
| |
| } |