/******************************************************************************* * Copyright (c) 2012 VMWare, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VMWare, Inc. - initial API and implementation *******************************************************************************/ package org.grails.ide.eclipse.test; import java.io.File; import java.io.IOException; import java.net.URL; import java.util.Collection; import junit.framework.AssertionFailedError; import org.codehaus.jdt.groovy.model.GroovyNature; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProjectDescription; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.resources.WorkspaceJob; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.JavaCore; import org.grails.ide.eclipse.commands.GrailsCommandUtils; import org.grails.ide.eclipse.commands.GroovyCompilerVersionCheck; import org.grails.ide.eclipse.commands.test.AbstractCommandTest; import org.grails.ide.eclipse.core.GrailsCoreActivator; import org.grails.ide.eclipse.core.internal.GrailsNature; import org.grails.ide.eclipse.core.internal.classpath.SourceFolderJob; import org.grails.ide.eclipse.core.model.GrailsVersion; import org.grails.ide.eclipse.core.model.IGrailsInstall; import org.grails.ide.eclipse.ui.internal.importfixes.GrailsProjectVersionFixer; import org.springsource.ide.eclipse.commons.core.FileUtil; import org.springsource.ide.eclipse.commons.core.ZipFileUtil; import org.springsource.ide.eclipse.commons.frameworks.test.util.ACondition; import org.springsource.ide.eclipse.commons.tests.util.StsTestUtil; /** * @author Kris De Volder */ public class GrailsProjectVersionFixerTest extends AbstractCommandTest { @Override protected void setUp() throws Exception { super.setUp(); GrailsProjectVersionFixer.DEBUG = true; GrailsCommandUtils.DEBUG = true; // Want to see info about refresh // dependencies ops being executed. GroovyCompilerVersionCheck.testMode(); // GrailsCoreActivator.getDefault().setKeepGrailsRunning(true); GrailsProjectVersionFixer.globalAskToConvertToGrailsProjectAnswer = true; StsTestUtil.setAutoBuilding(true); System.out.println("Waiting for autobuild..."); StsTestUtil.waitForAutoBuild(); System.out.println("Done autobuild"); // Ensure the test project doesn't exist in the workspace before test // begins StsTestUtil.deleteAllProjects(); // clearGrailsState(); //Workaround for // http://jira.grails.org/browse/GRAILS-7655 (ivy cache corruption) } @Override protected void tearDown() throws Exception { GrailsProjectVersionFixer.testMode(); // reset "precanned answers" for // other test runs. super.tearDown(); GrailsProjectVersionFixer.DEBUG = false; GrailsCommandUtils.DEBUG = false; } // public void testImportVeryOldProjectAsLinkedProject() throws Throwable { // final URL zipFileURL = // this.getClass().getClassLoader().getResource("OldTestApp.zip"); // final String projectName = "OldTestApp"; // // importAsLinkedProject(zipFileURL, projectName); // // ///////////////////////////////////////////////////////////////////////////////////////////////// // //Check a few things about this test project // checkImportedProject(); // } /** * Tests whether our 'ensureDefaultGrailsVersion' test utility method works * properly. */ public void testEnsureDefaultGrailsVersion() throws Throwable { // Yes, we swithc back and forth quite a few times. This ensures that // all code paths // through 'ensureDefaultGrailsVersion' get executed (different paths // when install // was already configured). ensureDefaultGrailsVersion(GrailsVersion.PREVIOUS_PREVIOUS); assertEquals(GrailsVersion.PREVIOUS_PREVIOUS, GrailsVersion.getDefault()); ensureDefaultGrailsVersion(GrailsVersion.PREVIOUS); assertEquals(GrailsVersion.PREVIOUS, GrailsVersion.getDefault()); ensureDefaultGrailsVersion(GrailsVersion.MOST_RECENT); assertEquals(GrailsVersion.MOST_RECENT, GrailsVersion.getDefault()); ensureDefaultGrailsVersion(GrailsVersion.PREVIOUS); assertEquals(GrailsVersion.PREVIOUS, GrailsVersion.getDefault()); ensureDefaultGrailsVersion(GrailsVersion.PREVIOUS_PREVIOUS); assertEquals(GrailsVersion.PREVIOUS_PREVIOUS, GrailsVersion.getDefault()); } /** * @param zipFileURL * @param projectName * @throws Throwable */ public void importAsLinkedProject(final URL zipFileURL, final String projectName) throws Throwable { WorkspaceJob atomic = new WorkspaceJob("Create linked project from zip") { @Override public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException { try { // Create project folder from zipfile in some random place // outside the workspace File unzipLoc = FileUtil.createTempDirectory(); ZipFileUtil.unzip(zipFileURL, unzipLoc, new NullProgressMonitor()); IWorkspaceRoot workspaceRoot = ResourcesPlugin .getWorkspace().getRoot(); project = workspaceRoot.getProject(projectName); IProjectDescription desc = ResourcesPlugin.getWorkspace() .newProjectDescription(project.getName()); desc.setLocation(new Path(unzipLoc.toString()) .append(project.getName())); project.create(desc, null); project.open(null); // project.refreshLocal(IResource.DEPTH_INFINITE, null); } catch (IOException e) { return new Status(IStatus.ERROR, GrailsCoreActivator.PLUGIN_ID, "bad", e); } return Status.OK_STATUS; } }; IStatus status = atomic.run(new NullProgressMonitor()); assertOK(status); assertTrue(project.isAccessible()); assertTrue(project.getFolder("grails-app").exists()); } public static void assertOK(IStatus status) throws Throwable { if (status.isOK()) return; if (status.getException() != null) throw status.getException(); throw new AssertionFailedError(status.getMessage()); } public void pl() throws Throwable { final URL zipFileURL = this.getClass().getClassLoader() .getResource("OldTestApp.zip"); final String projectName = "OldTestApp"; importProject(zipFileURL, projectName); // /////////////////////////////////////////////////////////////////////////////////////////////// // Check a few things about this test project checkImportedProject(); } // /** // * Test for the case were a project using an older version of grails is // being imported, where the // * older version is not configured in the workspace and the user asks to // upgrade the project. // */ // public void testImportNotSoOldProject() throws Throwable { // final URL zipFileURL = // this.getClass().getClassLoader().getResource("NotSoOldTestApp.zip"); // final String projectName = "NotSoOldTestApp"; // // importProject(zipFileURL, projectName); // // ///////////////////////////////////////////////////////////////////////////////////////////////// // //Check a few things about this test project // checkImportedProject(); // } /** * Test for the case where we import a project that doesn't have eclipse * specific files committed. So all configuration of Eclipse stuff has to be * done by our fixer. * <p> * This test is a kind of 'proxy' for importing projects from SVN/CVS, where * none of the Eclipse settings files have been committed. * <p> * The project being imported has a version that is the same as the default * Grails install of the workspace. */ public void testImportBareBonesProjectWithMatchingVersion() throws Throwable { GrailsVersion version = GrailsVersion.MOST_RECENT; if (GrailsVersion.MOST_RECENT.isSnapshot()) { // Don't run this for snapshot builds. Too much work to create test // projects for moving target. return; } ensureDefaultGrailsVersion(version); final URL zipFileURL = getProjectZip("bareBonesProject", version); final String projectName = "testProject"; importProject(zipFileURL, projectName); // This test is intended to check importing of project who's grails // version is the same as // the workspace default install... assertEquals(GrailsVersion.getDefault(), GrailsVersion.getGrailsVersion(project)); // /////////////////////////////////////////////////////////////////////////////////////////////// // Check a few things about this test project checkImportedProject(); } /** * Test for the case where we import a project that doesn't have eclipse * specific files committed. So all configuration of Eclipse stuff has to be * done by our fixer. * <p> * The project being imported has a version that is older than the default * Grails install of the workspace. */ public void testImportBareBonesProjectWithOlderVersion() throws Throwable { if (GrailsVersion.MOST_RECENT.isSnapshot()) { // Don't run this for snapshot builds. Too much work to create test // projects for moving target. return; } if (GrailsVersion.MOST_RECENT.equals(GrailsVersion.V_2_3_0)) { // test failing because of bug in grails: // http://jira.grails.org/browse/GRAILS-10531 return; } ensureDefaultGrailsVersion(GrailsVersion.PREVIOUS); final URL zipFileURL = getProjectZip("bareBonesProject", GrailsVersion.PREVIOUS); final String projectName = "testProject"; importProject(zipFileURL, projectName); // This test is intended to check importing of project who's grails // version is older than // the workspace default install... assertEquals(GrailsVersion.PREVIOUS, GrailsVersion.getGrailsVersion(project)); // /////////////////////////////////////////////////////////////////////////////////////////////// // Check a few things about this test project checkImportedProject(); } /** * Checks a bunch of stuff about the "very old test project" once it has * been imported in the workspace. * * @throws Throwable */ private void checkImportedProject() throws Exception { // Check project config, like classpath related stuff. // The config may not be right initially... but should eventually become // correct as a background // refresh dependency job should get scheduled. // ACondition new ACondition("check importe project: " + project.getName()) { @Override public boolean test() throws Exception { System.out.println("Checking project config..."); IJavaProject javaProject = JavaCore.create(project); assertDefaultOutputFolder(javaProject); assertTrue(project.hasNature(JavaCore.NATURE_ID)); // Should // have Java // Nature at // this // point assertTrue(GroovyNature.hasGroovyNature(project)); // Should // also have // Groovy // nature assertTrue(GrailsNature.isGrailsAppProject(project)); // Should // look // like // a // Grails // app // to // grails // tooling // ///////////////////////////////// // Check resolved classpath stuff IClasspathEntry[] classPath = javaProject .getResolvedClasspath(false); // A whole bunch of libraries should be there, check for just a // few of those assertClassPathEntry(IClasspathEntry.CPE_LIBRARY, "/jsse.jar", classPath); assertClassPathEntry(IClasspathEntry.CPE_LIBRARY, "grails-core", classPath); assertClassPathEntry(IClasspathEntry.CPE_LIBRARY, "grails-bootstrap", classPath); assertClassPathEntry(IClasspathEntry.CPE_LIBRARY, "groovy-all", classPath); // assertClassPathEntry(IClasspathEntry.CPE_LIBRARY, // "servlet-api", classPath); // System.out.println(">>>Resolved classpath"); // for (IClasspathEntry entry : classPath) { // System.out.println(kindString(entry.getEntryKind())+": "+entry.getPath()); // } // System.out.println("<<<Resolved classpath"); // ///////////////////////////////// // Check raw classpath stuff classPath = javaProject.getRawClasspath(); // for (IClasspathEntry classpathEntry : classPath) { // System.out.println(kindString(classpathEntry.getEntryKind())+": "+classpathEntry.getPath()); // } // The usual source folders: assertClassPathEntry(IClasspathEntry.CPE_SOURCE, "src/java", classPath); assertClassPathEntry(IClasspathEntry.CPE_SOURCE, "src/groovy", classPath); assertClassPathEntry(IClasspathEntry.CPE_SOURCE, "grails-app/conf", classPath); assertClassPathEntry(IClasspathEntry.CPE_SOURCE, "grails-app/controllers", classPath); assertClassPathEntry(IClasspathEntry.CPE_SOURCE, "grails-app/domain", classPath); assertClassPathEntry(IClasspathEntry.CPE_SOURCE, "grails-app/services", classPath); assertClassPathEntry(IClasspathEntry.CPE_SOURCE, "grails-app/taglib", classPath); assertClassPathEntry(IClasspathEntry.CPE_SOURCE, "test/integration", classPath); assertClassPathEntry(IClasspathEntry.CPE_SOURCE, "test/unit", classPath); // The classpath containers for Java and Grails assertClassPathEntry(IClasspathEntry.CPE_CONTAINER, "org.eclipse.jdt.launching.JRE_CONTAINER", classPath); assertClassPathEntry(IClasspathEntry.CPE_CONTAINER, "org.grails.ide.eclipse.core.CLASSPATH_CONTAINER", classPath); // Installed plugins source folders assertDefaultPluginSourceFolders(project); System.out.println("Checking project config => OK!"); return true; } }.waitFor(10*60000); } /** * Relates to https://issuetracker.springsource.com/browse/STS-1518. Fix for * this bug revamped representation of plugin source folders in STS * projects. This creates a need to clean up legacy linked source folders. * <p> * This assert checks whether there is anything looking like a legacy source * folder * * @throws Exception * @throws CoreException */ public void testCleanupLegacyLinkedSourceFolders() throws Exception { final GrailsVersion version = GrailsVersion.V_1_3_6; ensureDefaultGrailsVersion(version); final String projectName = "gTunes"; // This project was zipped before // we converted to the new // source folder layout final URL zipFileURL = getProjectZip(projectName, version); importProject(zipFileURL, projectName); new ACondition() { @Override public boolean test() throws Exception { assertNoLegacyLinkedFolders(); return true; } }.waitFor(120000); } private void assertNoLegacyLinkedFolders() throws CoreException { IResource[] children = project.members(true); boolean seenALink = false; for (IResource r : children) { if (r.isLinked()) { seenALink = true; // The only thing we expect to see is a single link to the // toplevel of the grails plugins folder assertEquals("Legacy link not cleaned up?", SourceFolderJob.PLUGINS_FOLDER_LINK, r.getName()); } } assertTrue( "No linked resources found in project. Expected a link called: " + SourceFolderJob.PLUGINS_FOLDER_LINK, seenALink); } /** * Assert that the grails version as apparant from libs on resolved project classpath matches * a given version. */ private void assertClasspathVersion(GrailsVersion version) throws Exception { IClasspathEntry[] classpath = JavaCore.create(project).getResolvedClasspath(true); String expectedLib = "grails-core-"+version; assertClassPathEntry(IClasspathEntry.CPE_LIBRARY, expectedLib, classpath); } public void testSTS1604UserChangesProjectSpecificGrailsInstall() throws Throwable { if (GrailsVersion.MOST_RECENT.equals(GrailsVersion.V_2_3_0)) { // upgrade comand from 2.2.x to 2.3 doesn't work. return; } System.out .println(">>>>>>>>>>>>>>>>>>>>>>>>>testSTS1604UserChangesProjectSpecificGrailsInstall"); ensureDefaultGrailsVersion(GrailsVersion.MOST_RECENT); ensureDefaultGrailsVersion(GrailsVersion.PREVIOUS); final String projectName = "gTunes"; final URL zipFileURL = getProjectZip(projectName, GrailsVersion.PREVIOUS); importProject(zipFileURL, projectName); // Double check that project was created ok with correct version numbers // in both eclipse settings and application.properties assertEquals(GrailsVersion.PREVIOUS, GrailsVersion.getEclipseGrailsVersion(project)); assertEquals(GrailsVersion.PREVIOUS, GrailsVersion.getGrailsVersion(project)); checkImportedProject(); assertClasspathVersion(GrailsVersion.PREVIOUS); setGrailsVersion(project, GrailsVersion.MOST_RECENT); new ACondition() { @Override public boolean test() throws Exception { assertEquals("Project eclipse conf not correct", GrailsVersion.MOST_RECENT, GrailsVersion.getEclipseGrailsVersion(project)); assertEquals("Project not upgraded", GrailsVersion.MOST_RECENT, GrailsVersion.getGrailsVersion(project)); assertClasspathVersion(GrailsVersion.MOST_RECENT); return true; } }.waitFor(180000); checkImportedProject(); System.out .println("<<<<<<<<<<<<<<<<<<<<<<<<<<testSTS1604UserChangesProjectSpecificGrailsInstall"); } private void setGrailsVersion(IProject project, GrailsVersion version) throws Exception { version.setOn(project, false); } public void testImportProjectWithSameNameAsDeletedProject() throws Exception { if (GrailsVersion.MOST_RECENT.isSnapshot()) { // Don't run this for snapshot builds. Too much work to create test // projects for moving target. return; } // When a project is deleted, stale classpath data of this project // should not end up in a new project that may have the same name. final String projectName = "gTunes"; // Get gTunes project with older version in workspace GrailsVersion version = GrailsVersion.PREVIOUS; ensureDefaultGrailsVersion(version); URL zipFileURL = getProjectZip(projectName, version); importProject(zipFileURL, projectName); assertEquals(version, GrailsVersion.getEclipseGrailsVersion(project)); assertEquals(version, GrailsVersion.getGrailsVersion(project)); checkImportedProject(); project.delete(true, true, new NullProgressMonitor()); version = GrailsVersion.MOST_RECENT; ensureDefaultGrailsVersion(version); zipFileURL = getProjectZip(projectName, version); importProject(zipFileURL, projectName); assertEquals(version, GrailsVersion.getEclipseGrailsVersion(project)); assertEquals(version, GrailsVersion.getGrailsVersion(project)); checkImportedProject(); } public void testSTS1799ImportSpringSecurityACLSample() throws Exception { // Sample project from // http://burtbeckwith.github.com/grails-spring-security-acl/docs/manual/index.html // But with upgraded plugins to most recent version available now and // compatible with Grails 1.3.7 final GrailsVersion version = GrailsVersion.V_1_3_7; // assertTrue("This test's test project needs updating to a more recent Grails version", // version.equals(GrailsVersion.MOST_RECENT) || // version.equals(GrailsVersion.PREVIOUS)); String projectName = "grails-contacts"; ensureDefaultGrailsVersion(version); System.out.println(">>>>> Grails installs known to STS"); Collection<IGrailsInstall> installs = GrailsCoreActivator.getDefault() .getInstallManager().getAllInstalls(); for (IGrailsInstall install : installs) { System.out.println("--------------------------"); System.out.println("name = '" + install.getName() + "'"); System.out .println("version = '" + install.getVersion() + "'"); System.out.println("versionString = '" + install.getVersionString() + "'"); System.out.println("home = '" + install.getHome() + "'"); System.out.println("isDefault = '" + install.isDefault() + "'"); } System.out.println("<<<<< Grails installs known to STS ===="); URL zipFileURL = getProjectZip(projectName, version); importProject(zipFileURL, projectName); new ACondition() { // Need ACondition on build server because initially // will be '<unknown>' grails version // until version fixer has run and fixed the problem. @Override public boolean test() throws Exception { assertEquals(version, GrailsVersion.getEclipseGrailsVersion(project)); return true; } }.waitFor(3000); assertEquals(version, GrailsVersion.getGrailsVersion(project)); checkImportedProject(); StsTestUtil.assertNoErrors(project); } }