Skip to content

Commit 29b30c3

Browse files
authored
Fix TestProjectCreator to not produce broken JDT projects (#1591)
WTP's JavaFacetInstallDelegate skips project configuration if it finds there's already a Java nature. Use the WTP/JST Java facets for configuring JDT instead.
1 parent 3c53443 commit 29b30c3

8 files changed

Lines changed: 98 additions & 64 deletions

File tree

plugins/com.google.cloud.tools.eclipse.appengine.facets.test/src/com/google/cloud/tools/eclipse/appengine/facets/StandardFacetInstallationTest.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,9 @@ public void testStandardFacetInstallation_doesNotOverwriteWebXml()
117117
private static void createFolders(IContainer parent, IPath path) throws CoreException {
118118
if (!path.isEmpty()) {
119119
IFolder folder = parent.getFolder(new Path(path.segment(0)));
120-
folder.create(true, true, null);
120+
if (!folder.exists()) {
121+
folder.create(true, true, null);
122+
}
121123
createFolders(folder, path.removeFirstSegments(1));
122124
}
123125
}

plugins/com.google.cloud.tools.eclipse.appengine.facets.test/src/com/google/cloud/tools/eclipse/appengine/facets/convert/AppEngineStandardProjectConvertJobTest.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import java.util.concurrent.TimeUnit;
2525
import org.eclipse.core.runtime.CoreException;
2626
import org.eclipse.core.runtime.jobs.Job;
27+
import org.eclipse.jst.common.project.facet.core.JavaFacet;
2728
import org.eclipse.wst.common.project.facet.core.IFacetedProject;
2829
import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
2930
import org.junit.Rule;
@@ -33,7 +34,9 @@ public class AppEngineStandardProjectConvertJobTest {
3334
@Rule
3435
public ThreadDumpingWatchdog timer = new ThreadDumpingWatchdog(2, TimeUnit.MINUTES);
3536

36-
@Rule public final TestProjectCreator projectCreator = new TestProjectCreator();
37+
@Rule
38+
public final TestProjectCreator projectCreator =
39+
new TestProjectCreator().withFacetVersions(JavaFacet.VERSION_1_7);
3740

3841
@Test
3942
public void testAppEngineFacetAdded() throws CoreException, InterruptedException {

plugins/com.google.cloud.tools.eclipse.appengine.libraries.test/META-INF/MANIFEST.MF

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ Import-Package: com.google.cloud.tools.eclipse.test.util,
1313
com.google.cloud.tools.eclipse.test.util.project,
1414
org.eclipse.core.resources,
1515
org.eclipse.core.runtime.spi;version="3.4.0",
16+
org.eclipse.jst.common.project.facet.core,
17+
org.eclipse.wst.common.project.facet.core,
1618
org.mockito;provider=google;version="1.10.19",
1719
org.mockito.invocation;provider=google;version="1.10.19",
1820
org.mockito.runners;provider=google;version="1.10.19",

plugins/com.google.cloud.tools.eclipse.appengine.libraries.test/src/com/google/cloud/tools/eclipse/appengine/libraries/LibraryClasspathContainerInitializerTest.java

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import static org.hamcrest.Matchers.is;
2020
import static org.junit.Assert.assertFalse;
2121
import static org.junit.Assert.assertThat;
22+
import static org.junit.Assert.fail;
2223
import static org.mockito.Matchers.any;
2324
import static org.mockito.Mockito.doThrow;
2425
import static org.mockito.Mockito.mock;
@@ -40,6 +41,8 @@
4041
import org.eclipse.jdt.core.IClasspathEntry;
4142
import org.eclipse.jdt.core.IJavaProject;
4243
import org.eclipse.jdt.core.JavaCore;
44+
import org.eclipse.jst.common.project.facet.core.JavaFacet;
45+
import org.hamcrest.Matchers;
4346
import org.junit.Rule;
4447
import org.junit.Test;
4548
import org.junit.rules.TemporaryFolder;
@@ -78,7 +81,9 @@ public class LibraryClasspathContainerInitializerTest {
7881
public ThreadDumpingWatchdog watchdog = new ThreadDumpingWatchdog(2, TimeUnit.MINUTES);
7982

8083
@Rule
81-
public TestProjectCreator testProject = new TestProjectCreator().withClasspathContainerPath(TEST_LIBRARY_PATH);
84+
public TestProjectCreator testProject = new TestProjectCreator()
85+
.withFacetVersions(JavaFacet.VERSION_1_7).withClasspathContainerPath(TEST_LIBRARY_PATH);
86+
8287
@Rule
8388
public TemporaryFolder temporaryFolder = new TemporaryFolder();
8489

@@ -179,9 +184,14 @@ public void testInitialize_ifSourcePathIsNullContainerIsNotResolvedAgain() throw
179184
containerInitializer.initialize(new Path(TEST_LIBRARY_PATH), testProject.getJavaProject());
180185
testProject.getJavaProject().getRawClasspath();
181186
IClasspathEntry[] resolvedClasspath = testProject.getJavaProject().getResolvedClasspath(false);
182-
assertThat(resolvedClasspath.length, is(2));
183-
assertThat(resolvedClasspath[1].getPath().toOSString(), is(artifactFile.getAbsolutePath()));
184-
verifyContainerWasNotResolvedFromScratch();
187+
assertThat(resolvedClasspath.length, Matchers.greaterThan(2));
188+
for (IClasspathEntry resolvedEntry : resolvedClasspath) {
189+
if (resolvedEntry.getPath().toOSString().equals(artifactFile.getAbsolutePath())) {
190+
verifyContainerWasNotResolvedFromScratch();
191+
return;
192+
}
193+
}
194+
fail("classpath entry not found");
185195
}
186196

187197
@Test
@@ -202,11 +212,16 @@ public void testInitialize_ifSourcePathIsValidContainerIsNotResolvedAgain() thro
202212
containerInitializer.initialize(new Path(TEST_LIBRARY_PATH), testProject.getJavaProject());
203213
testProject.getJavaProject().getRawClasspath();
204214
IClasspathEntry[] resolvedClasspath = testProject.getJavaProject().getResolvedClasspath(false);
205-
assertThat(resolvedClasspath.length, is(2));
206-
assertThat(resolvedClasspath[1].getPath().toOSString(), is(artifactFile.getAbsolutePath()));
207-
assertThat(resolvedClasspath[1].getSourceAttachmentPath().toOSString(),
208-
is(sourceArtifactFile.getAbsolutePath()));
209-
verifyContainerWasNotResolvedFromScratch();
215+
assertThat(resolvedClasspath.length, Matchers.greaterThan(2));
216+
for (IClasspathEntry resolvedEntry : resolvedClasspath) {
217+
if (resolvedEntry.getPath().toOSString().equals(artifactFile.getAbsolutePath())) {
218+
assertThat(resolvedEntry.getSourceAttachmentPath().toOSString(),
219+
is(sourceArtifactFile.getAbsolutePath()));
220+
verifyContainerWasNotResolvedFromScratch();
221+
return;
222+
}
223+
}
224+
fail("classpath entry not found");
210225
}
211226

212227
private IStatus verifyContainerResolvedFromScratch() {

plugins/com.google.cloud.tools.eclipse.appengine.localserver.test/src/com/google/cloud/tools/eclipse/appengine/localserver/launching/LaunchHelperTest.java

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
import com.google.cloud.tools.eclipse.appengine.facets.AppEngineStandardFacet;
2525
import com.google.cloud.tools.eclipse.appengine.localserver.ui.ServerTracker;
2626
import com.google.cloud.tools.eclipse.test.util.project.TestProjectCreator;
27-
import com.google.common.collect.Lists;
2827
import java.util.Collection;
2928
import java.util.Collections;
3029
import org.eclipse.core.commands.ExecutionException;
@@ -60,13 +59,11 @@ public class LaunchHelperTest {
6059
private IServer serverToReturn = null;
6160

6261
@Rule
63-
public TestProjectCreator appEngineStandardProject1 =
64-
new TestProjectCreator().withFacetVersions(Lists.newArrayList(JavaFacet.VERSION_1_7,
65-
WebFacetUtils.WEB_25, APPENGINE_STANDARD_FACET_VERSION_1));
62+
public TestProjectCreator appEngineStandardProject1 = new TestProjectCreator().withFacetVersions(
63+
JavaFacet.VERSION_1_7, WebFacetUtils.WEB_25, APPENGINE_STANDARD_FACET_VERSION_1);
6664
@Rule
67-
public TestProjectCreator appEngineStandardProject2 =
68-
new TestProjectCreator().withFacetVersions(Lists.newArrayList(JavaFacet.VERSION_1_7,
69-
WebFacetUtils.WEB_25, APPENGINE_STANDARD_FACET_VERSION_1));
65+
public TestProjectCreator appEngineStandardProject2 = new TestProjectCreator().withFacetVersions(
66+
JavaFacet.VERSION_1_7, WebFacetUtils.WEB_25, APPENGINE_STANDARD_FACET_VERSION_1);
7067

7168

7269
@Before

plugins/com.google.cloud.tools.eclipse.test.util/META-INF/MANIFEST.MF

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ Import-Package: com.google.cloud.tools.eclipse.appengine.facets,
2929
org.eclipse.jetty.server.handler;version="9.2.13",
3030
org.eclipse.jetty.util.component;version="9.2.13",
3131
org.eclipse.jface.viewers,
32+
org.eclipse.jst.common.project.facet.core,
3233
org.eclipse.swt.widgets,
3334
org.eclipse.ui.internal.registry,
3435
org.eclipse.wst.common.componentcore.internal.builder,

plugins/com.google.cloud.tools.eclipse.test.util/src/com/google/cloud/tools/eclipse/test/util/project/TestProjectCreator.java

Lines changed: 55 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,13 @@
2020
import static org.junit.Assert.fail;
2121

2222
import com.google.cloud.tools.eclipse.appengine.facets.WebProjectUtil;
23+
import com.google.common.base.Preconditions;
2324
import com.google.common.base.Strings;
2425
import java.io.ByteArrayInputStream;
2526
import java.io.InputStream;
2627
import java.nio.charset.StandardCharsets;
2728
import java.util.ArrayList;
29+
import java.util.Collections;
2830
import java.util.HashSet;
2931
import java.util.List;
3032
import java.util.Set;
@@ -41,6 +43,7 @@
4143
import org.eclipse.jdt.core.IJavaProject;
4244
import org.eclipse.jdt.core.JavaCore;
4345
import org.eclipse.jdt.core.JavaModelException;
46+
import org.eclipse.jst.common.project.facet.core.JavaFacet;
4447
import org.eclipse.wst.common.componentcore.internal.builder.DependencyGraphImpl;
4548
import org.eclipse.wst.common.componentcore.internal.builder.IDependencyGraph;
4649
import org.eclipse.wst.common.project.facet.core.IFacetedProject;
@@ -51,8 +54,13 @@
5154
import org.eclipse.wst.server.core.ServerUtil;
5255
import org.junit.rules.ExternalResource;
5356

57+
/**
58+
* Utility class to create and configure a Faceted Project. Installs a Java 1.7 facet if no facets
59+
* are specified with {@link #withFacetVersions}.
60+
*/
5461
public final class TestProjectCreator extends ExternalResource {
5562

63+
private IProject project;
5664
private IJavaProject javaProject;
5765
private String containerPath;
5866
private String appEngineServiceId;
@@ -63,6 +71,11 @@ public TestProjectCreator withClasspathContainerPath(String containerPath) {
6371
return this;
6472
}
6573

74+
public TestProjectCreator withFacetVersions(IProjectFacetVersion... projectFacetVersions) {
75+
Collections.addAll(this.projectFacetVersions, projectFacetVersions);
76+
return this;
77+
}
78+
6679
public TestProjectCreator withFacetVersions(List<IProjectFacetVersion> projectFacetVersions) {
6780
this.projectFacetVersions.addAll(projectFacetVersions);
6881
return this;
@@ -75,51 +88,51 @@ public TestProjectCreator withAppEngineServiceId(String serviceId) {
7588

7689
@Override
7790
protected void before() throws Throwable {
78-
createJavaProject("test" + Math.random());
91+
createProject("test" + Math.random());
7992
}
8093

8194
@Override
8295
protected void after() {
8396
// Wait for any jobs to complete as WTP validation runs without the workspace protection lock
84-
ProjectUtils.waitForProjects(javaProject.getProject());
97+
ProjectUtils.waitForProjects(project);
8598
try {
86-
javaProject.getProject().delete(true, null);
99+
project.delete(true, null);
87100
} catch (CoreException e) {
88101
fail("Could not delete project");
89102
}
90103
}
91104

105+
public IModule getModule() {
106+
return ServerUtil.getModule(project);
107+
}
108+
92109
public IJavaProject getJavaProject() {
93110
return javaProject;
94111
}
95112

96113
public IProject getProject() {
97-
return javaProject.getProject();
114+
return project;
98115
}
99116

100-
public IModule getModule() {
101-
return ServerUtil.getModule(javaProject.getProject());
102-
}
103-
104-
private void createJavaProject(String projectName) throws CoreException, JavaModelException {
117+
private void createProject(String projectName) throws CoreException, JavaModelException {
105118
IProjectDescription newProjectDescription =
106119
ResourcesPlugin.getWorkspace().newProjectDescription(projectName);
107120
newProjectDescription.setNatureIds(
108-
new String[]{JavaCore.NATURE_ID, FacetedProjectNature.NATURE_ID});
109-
IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
121+
new String[] {FacetedProjectNature.NATURE_ID});
122+
project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
110123
project.create(newProjectDescription, null);
111124
project.open(null);
112-
javaProject = JavaCore.create(project);
113125

114-
addContainerPathToRawClasspath();
115126
addFacets();
127+
addContainerPathToRawClasspath();
116128
if (appEngineServiceId != null) {
117129
setAppEngineServiceId(appEngineServiceId);
118130
}
119131
}
120132

121133
private void addContainerPathToRawClasspath() throws JavaModelException {
122134
if (!Strings.isNullOrEmpty(containerPath)) {
135+
Preconditions.checkNotNull(javaProject);
123136
IClasspathEntry[] rawClasspath = javaProject.getRawClasspath();
124137
IClasspathEntry[] newRawClasspath = new IClasspathEntry[rawClasspath.length + 1];
125138
System.arraycopy(rawClasspath, 0, newRawClasspath, 0, rawClasspath.length);
@@ -130,31 +143,37 @@ private void addContainerPathToRawClasspath() throws JavaModelException {
130143
}
131144

132145
private void addFacets() throws CoreException {
133-
if (!projectFacetVersions.isEmpty()) {
134-
IFacetedProject facetedProject = ProjectFacetsManager.create(getProject());
135-
Set<IFacetedProject.Action> facetInstallSet = new HashSet<>();
136-
for (IProjectFacetVersion projectFacetVersion : projectFacetVersions) {
137-
facetInstallSet.add(new IFacetedProject.Action(IFacetedProject.Action.Type.INSTALL,
138-
projectFacetVersion, null));
139-
}
140-
// Workaround deadlock bug described in Eclipse bug (https://bugs.eclipse.org/511793).
141-
// There are graph update jobs triggered by the completion of the CreateProjectOperation
142-
// above (from resource notifications) and from other resource changes from modifying the
143-
// project facets. So we force the dependency graph to defer updates.
146+
IFacetedProject facetedProject = ProjectFacetsManager.create(getProject());
147+
148+
Set<IFacetedProject.Action> facetInstallSet = new HashSet<>();
149+
for (IProjectFacetVersion projectFacetVersion : projectFacetVersions) {
150+
facetInstallSet.add(new IFacetedProject.Action(IFacetedProject.Action.Type.INSTALL,
151+
projectFacetVersion, null));
152+
}
153+
154+
// Workaround deadlock bug described in Eclipse bug (https://bugs.eclipse.org/511793).
155+
// There are graph update jobs triggered by the completion of the CreateProjectOperation
156+
// above (from resource notifications) and from other resource changes from modifying the
157+
// project facets. So we force the dependency graph to defer updates.
158+
try {
159+
IDependencyGraph.INSTANCE.preUpdate();
144160
try {
145-
IDependencyGraph.INSTANCE.preUpdate();
146-
try {
147-
Job.getJobManager().join(DependencyGraphImpl.GRAPH_UPDATE_JOB_FAMILY, null);
148-
} catch (OperationCanceledException | InterruptedException ex) {
149-
throw new RuntimeException("Exception waiting for DependencyGraph job", ex);
150-
}
151-
152-
facetedProject.modify(facetInstallSet, null);
153-
} finally {
154-
IDependencyGraph.INSTANCE.postUpdate();
161+
Job.getJobManager().join(DependencyGraphImpl.GRAPH_UPDATE_JOB_FAMILY, null);
162+
} catch (OperationCanceledException | InterruptedException ex) {
163+
throw new RuntimeException("Exception waiting for DependencyGraph job", ex);
155164
}
156-
// App Engine runtime is added via a Job, so wait.
157-
ProjectUtils.waitForProjects(getProject());
165+
166+
facetedProject.modify(facetInstallSet, null);
167+
} finally {
168+
IDependencyGraph.INSTANCE.postUpdate();
169+
}
170+
171+
// App Engine runtime is added via a Job, so wait.
172+
ProjectUtils.waitForProjects(getProject());
173+
174+
if (facetedProject.hasProjectFacet(JavaFacet.FACET)) {
175+
javaProject = JavaCore.create(project);
176+
assertTrue(javaProject.exists());
158177
}
159178
}
160179

plugins/com.google.cloud.tools.eclipse.util.test/src/com/google/cloud/tools/eclipse/util/NatureUtilsTest.java

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,22 +35,17 @@ public class NatureUtilsTest {
3535
@Test
3636
public void testRemoveNature() throws CoreException {
3737
IProject project = projectCreator.getProject();
38-
// By default, project has Java nature and faceted project nature.
39-
assertArrayEquals(new String[] {JavaCore.NATURE_ID, FACETED_NATURE_ID},
40-
project.getDescription().getNatureIds());
38+
// By default, project has faceted project nature.
39+
assertArrayEquals(new String[] {FACETED_NATURE_ID}, project.getDescription().getNatureIds());
4140

42-
NatureUtils.removeNature(project, JavaCore.NATURE_ID);
43-
assertArrayEquals(new String[] {FACETED_NATURE_ID},
44-
project.getDescription().getNatureIds());
41+
NatureUtils.removeNature(project, FACETED_NATURE_ID);
42+
assertArrayEquals(new String[] {}, project.getDescription().getNatureIds());
4543
}
4644

4745
@Test
4846
public void testRemoveNature_nonExistingNature() throws CoreException {
4947
IProject project = projectCreator.getProject();
5048
NatureUtils.removeNature(project, JavaCore.NATURE_ID);
51-
52-
NatureUtils.removeNature(project, JavaCore.NATURE_ID);
53-
assertArrayEquals(new String[] {FACETED_NATURE_ID},
54-
project.getDescription().getNatureIds());
49+
assertArrayEquals(new String[] {FACETED_NATURE_ID}, project.getDescription().getNatureIds());
5550
}
5651
}

0 commit comments

Comments
 (0)