blob: 7598d96b7943247135b5861867666ace5f280569 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005 IBM Corporation and others. 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: IBM Corporation - initial API and implementation
* Helen Hawkins - iniital version
******************************************************************************/
package org.eclipse.ajdt.core.tests.builder;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.ajdt.core.AspectJPlugin;
import org.eclipse.ajdt.core.tests.AJDTCoreTestCase;
import org.eclipse.ajdt.core.tests.testutils.ReaderInputStream;
import org.eclipse.ajdt.core.tests.testutils.TestLogger;
import org.eclipse.ajdt.core.tests.testutils.Utils;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
/**
* Bug 99133 - if A depends on B, and you make a change to
* B such that A should notice, A was not being built
*
* This test has been known to fail intermittently due to the timing checks in AjState.
*
* The tests in this testcase are different scenarios around this.
*/
public class Bug99133Test extends AJDTCoreTestCase {
IProject pA,pB;
TestLogger testLog;
/*
* @see TestCase#setUp()
*/
protected void setUp() throws Exception {
super.setUp();
pB = createPredefinedProject("bug99133b"); //$NON-NLS-1$
Utils.sleep(1001); // sleep to ensure timestamps are sufficiently far apart so that AjState thinks the builds are separate
pA = createPredefinedProject("bug99133a"); //$NON-NLS-1$
testLog = new TestLogger();
AspectJPlugin.getDefault().setAJLogger(testLog);
}
/*
* @see TestCase#tearDown()
*/
protected void tearDown() throws Exception {
super.tearDown();
AspectJPlugin.getDefault().setAJLogger(null);
testLog = null;
}
public void testBug84214() throws Exception {
// Adds 2 errors to the log when the dependency is removed.
checkForJDTBug84214(pA,pB);
waitForAutoBuild();
}
/**
* A depends on B and in particular calls a method in B
* and that method body changes. Ultimately, no build of project A should
* occur. However, AJDT can't tell whether to build or not and so we
* pass it down to the compiler. The compiler then uses A's incremental
* state to say that nothing has structurely changed and
* returns quickly.
* (both A and B are AJ projects)
*/
public void testBug99133a() throws Exception {
testLog.clearLog();
// change the contents of the method m1() in
// bug99133b\src\p\C1.java to include a sysout call
IFile c1 = getFile(pB,"p","C1.java"); //$NON-NLS-1$ //$NON-NLS-2$
BufferedReader br1 = new BufferedReader(new InputStreamReader(c1.getContents()));
StringBuffer sb1 = new StringBuffer();
int lineNumber1 = 1;
String line1 = br1.readLine();
while (line1 != null) {
if (lineNumber1 == 5) {
sb1.append("System.out.println(\"Hello\");"); //$NON-NLS-1$
} else {
sb1.append(line1);
}
sb1.append(System.getProperty("line.separator")); //$NON-NLS-1$
lineNumber1++;
line1 = br1.readLine();
}
br1.close();
StringReader reader1 = new StringReader(sb1.toString());
c1.setContents(new ReaderInputStream(reader1), true, true, null);
waitForAutoBuild();
waitForAutoBuild();
assertEquals("two more builds should have occured", //$NON-NLS-1$
2, testLog.getNumberOfBuildsRun());
// At the moment, can at least check that the build of the
// dependent project is an incremental build.
List buildLogB = testLog.getPreviousBuildEntry(2);
boolean incB = listContainsString(buildLogB,
"AspectJ reports build successful, build was: INCREMENTAL"); //$NON-NLS-1$
boolean fullB = listContainsString(buildLogB,
"AspectJ reports build successful, build was: FULL"); //$NON-NLS-1$
// if not an incremental build of project bug99133b build then fail
// printing out whether did a full build instead
if (!incB) {
fail("Changing method contents of a method in project bug99133b " //$NON-NLS-1$
+ "should cause an incremental build of project bug99133b " //$NON-NLS-1$
+ ": (did a full build instead:" + fullB+")"); //$NON-NLS-1$ //$NON-NLS-2$
}
List buildLogA = testLog.getPreviousBuildEntry(1);
boolean incA = listContainsString(buildLogA,
"AspectJ reports build successful, build was: INCREMENTAL"); //$NON-NLS-1$
boolean fullA = listContainsString(buildLogA,
"AspectJ reports build successful, build was: FULL"); //$NON-NLS-1$
// if not an incremental build of project bug99133a build then fail
// printing out whether did a full build instead
if (!incA) {
fail("Changing method contents of method in project bug99133b " //$NON-NLS-1$
+ "should cause an incremental build of dependent project " //$NON-NLS-1$
+ "bug99133a : (did a full build instead:" + fullA + ")"); //$NON-NLS-1$ //$NON-NLS-2$
}
}
/**
* A depends on B and in particular calls a method in B
* and the signature of that method changes. Then an
* incremental build of project B and a full build of project A
* should occurr (both A and B are AJ projects).
*/
// public void testBug99133b() throws Exception {
// //change the return type of the method m1() in bug99133b\src\p\C1.java
// IFile c1 = getFile(pB,"p","C1.java"); //$NON-NLS-1$ //$NON-NLS-2$
// BufferedReader br1 = new BufferedReader(new InputStreamReader(c1.getContents()));
//
// StringBuffer sb1 = new StringBuffer();
// int lineNumber1 = 1;
// String line1 = br1.readLine();
// while (line1 != null) {
// if (lineNumber1 == 4) {
// sb1.append("public String m1() {"); //$NON-NLS-1$
// } else if (lineNumber1 == 5) {
// sb1.append("return \"Hello\";"); //$NON-NLS-1$
// } else {
// sb1.append(line1);
// }
// sb1.append(System.getProperty("line.separator")); //$NON-NLS-1$
// lineNumber1++;
// line1 = br1.readLine();
// }
// br1.close();
// StringReader reader1 = new StringReader(sb1.toString());
// c1.setContents(new ReaderInputStream(reader1), true, true, null);
// waitForAutoBuild();
// waitForAutoBuild();
// waitForAutoBuild();
// waitForAutoBuild();
// assertEquals("two more builds should have occured", //$NON-NLS-1$
// numberOfBuilds + 2,
// testLog.getNumberOfBuildsRun());
//
// List buildLogB = testLog.getPreviousBuildEntry(2);
// boolean incB = listContainsString(buildLogB,
// "AspectJ reports build successful, build was: INCREMENTAL"); //$NON-NLS-1$
// boolean fullB = listContainsString(buildLogB,
// "AspectJ reports build successful, build was: FULL"); //$NON-NLS-1$
// // if not an incremental build of project bug99133b build then fail
// // printing out whether did a full build instead
// if (!incB) {
// fail("Changing the method signature of method in project bug99133b " //$NON-NLS-1$
// + "should cause an incremental build of project bug99133b " //$NON-NLS-1$
// + ": (did a full build instead:" + fullB+")"); //$NON-NLS-1$ //$NON-NLS-2$
// }
//
// List buildLogA = testLog.getPreviousBuildEntry(1);
// boolean incA = listContainsString(buildLogA,
// "AspectJ reports build successful, build was: INCREMENTAL"); //$NON-NLS-1$
// boolean fullA = listContainsString(buildLogA,
// "AspectJ reports build successful, build was: FULL"); //$NON-NLS-1$
// // if not a full build of project bug99133a build then fail
// // printing out whether did an incremental build instead
// if (!fullA) {
// fail("Changing the method signature of a method in project bug99133b " //$NON-NLS-1$
// + "should cause an full build of dependent project bug99133a " //$NON-NLS-1$
// + ": (did an incremental build instead:" + incA + ")"); //$NON-NLS-1$ //$NON-NLS-2$
// }
// }
/**
* A depends on B and in particular calls a method in B.
* The method body of a method not referenced in A changes.
*/
public void testBug99133c() throws Exception {
testLog.clearLog();
// change the contents of the method m1() in
// bug99133b\src\p\C1.java to include a sysout call
IFile c1 = getFile(pB,"p","C1.java"); //$NON-NLS-1$ //$NON-NLS-2$
BufferedReader br1 = new BufferedReader(new InputStreamReader(c1.getContents()));
StringBuffer sb1 = new StringBuffer();
int lineNumber1 = 1;
String line1 = br1.readLine();
while (line1 != null) {
if (lineNumber1 == 9) {
sb1.append("System.out.println(\"Hello\");"); //$NON-NLS-1$
} else {
sb1.append(line1);
}
sb1.append(System.getProperty("line.separator")); //$NON-NLS-1$
lineNumber1++;
line1 = br1.readLine();
}
br1.close();
StringReader reader1 = new StringReader(sb1.toString());
c1.setContents(new ReaderInputStream(reader1), true, true, null);
waitForAutoBuild();
assertEquals("two more builds should have occured", //$NON-NLS-1$
2, testLog.getNumberOfBuildsRun());
// At the moment, can at least check that the build is an
// incremental build.
List buildLogB = testLog.getPreviousBuildEntry(2);
boolean incB = listContainsString(buildLogB,
"AspectJ reports build successful, build was: INCREMENTAL"); //$NON-NLS-1$
boolean fullB = listContainsString(buildLogB,
"AspectJ reports build successful, build was: FULL"); //$NON-NLS-1$
// if not an incremental build of project bug99133b build then fail
// printing out whether did a full build instead
if (!incB) {
fail("Changing the method contents of a method in project bug99133b " //$NON-NLS-1$
+ "should cause an incremental build of project bug99133b " //$NON-NLS-1$
+ ": (did a full build instead:" + fullB+")"); //$NON-NLS-1$ //$NON-NLS-2$
}
List buildLogA = testLog.getPreviousBuildEntry(1);
boolean incA = listContainsString(buildLogA,
"AspectJ reports build successful, build was: INCREMENTAL"); //$NON-NLS-1$
boolean fullA = listContainsString(buildLogA,
"AspectJ reports build successful, build was: FULL"); //$NON-NLS-1$
// if not an incremental build of project bug99133a build then fail
// printing out whether did a full build instead
if (!incA) {
fail("Changing the method contents of an unreferenced method " //$NON-NLS-1$
+ "in project bug99133b should cause an incremental build " //$NON-NLS-1$
+ "of dependent project bug99133a " //$NON-NLS-1$
+ ": (did a full build instead:" + fullA + ")"); //$NON-NLS-1$ //$NON-NLS-2$
}
}
/**
* A depends on B and in particular calls a method in B.
* The signature of an unreferenced method in B changes. Then an
* incremental build of project B and a full build of project A
* should occur. (both A and B are AJ projects)
*/
// public void testBug99133d() throws Exception {
//
// //change the return type of the method m1() in bug99133b\src\p\C1.java
// IFile c1 = getFile(pB,"p","C1.java"); //$NON-NLS-1$ //$NON-NLS-2$
// BufferedReader br1 = new BufferedReader(new InputStreamReader(c1.getContents()));
//
// StringBuffer sb1 = new StringBuffer();
// int lineNumber1 = 1;
// String line1 = br1.readLine();
// while (line1 != null) {
// if (lineNumber1 == 8) {
// sb1.append("public String m2() {"); //$NON-NLS-1$
// } else if (lineNumber1 == 9) {
// sb1.append("return \"Hello\";"); //$NON-NLS-1$
// } else {
// sb1.append(line1);
// }
// sb1.append(System.getProperty("line.separator")); //$NON-NLS-1$
// lineNumber1++;
// line1 = br1.readLine();
// }
// br1.close();
// StringReader reader1 = new StringReader(sb1.toString());
// c1.setContents(new ReaderInputStream(reader1), true, true, null);
// waitForAutoBuild();
// waitForAutoBuild();
//
// assertEquals("two more builds should have occured", //$NON-NLS-1$
// numberOfBuilds + 2,
// testLog.getNumberOfBuildsRun());
//
// List buildLogB = testLog.getPreviousBuildEntry(2);
// boolean incB = listContainsString(buildLogB,
// "AspectJ reports build successful, build was: INCREMENTAL"); //$NON-NLS-1$
// boolean fullB = listContainsString(buildLogB,
// "AspectJ reports build successful, build was: FULL"); //$NON-NLS-1$
// // if not an incremental build of project bug99133b build then fail
// // printing out whether did a full build instead
// if (!incB) {
// fail("Changing the signature of a method in project bug99133b " //$NON-NLS-1$
// + "should cause an incremental build of project bug99133b " //$NON-NLS-1$
// + ": (did a full build instead:" + fullB+")"); //$NON-NLS-1$ //$NON-NLS-2$
// }
//
// List buildLogA = testLog.getPreviousBuildEntry(1);
// boolean incA = listContainsString(buildLogA,
// "AspectJ reports build successful, build was: INCREMENTAL"); //$NON-NLS-1$
// boolean fullA = listContainsString(buildLogA,
// "AspectJ reports build successful, build was: FULL"); //$NON-NLS-1$
// // if not a full build of project bug99133a build then fail
// // printing out whether did an incremental build instead
// if (!fullA) {
// fail("Changing the signature of an unreferenced method in" //$NON-NLS-1$
// + " project bug99133b should cause a full build of " //$NON-NLS-1$
// + " dependent project bug99133a " //$NON-NLS-1$
// + ": (did an incremental build instead:" + incA + ")"); //$NON-NLS-1$ //$NON-NLS-2$
// }
// }
//
// /**
// * A depends on B and in particular calls a method in B.
// * A new method is added to a class in B.
// * Then an incremental build of project B and a full build
// * of project A should occurr. (both A and B are AJ projects)
// */
// public void testBug99133e() throws Exception {
//
// //change the return type of the method m1() in bug99133b\src\p\C1.java
// IFile c1 = getFile(pB,"p","C1.java"); //$NON-NLS-1$ //$NON-NLS-2$
// BufferedReader br1 = new BufferedReader(new InputStreamReader(c1.getContents()));
//
// StringBuffer sb1 = new StringBuffer();
// int lineNumber1 = 1;
// String line1 = br1.readLine();
// while (line1 != null) {
// if (lineNumber1 == 10) {
// sb1.append("}"); //$NON-NLS-1$
// sb1.append(System.getProperty("line.separator")); //$NON-NLS-1$
// sb1.append("public void m3() {}"); //$NON-NLS-1$
// } else {
// sb1.append(line1);
// }
// sb1.append(System.getProperty("line.separator")); //$NON-NLS-1$
// lineNumber1++;
// line1 = br1.readLine();
// }
// br1.close();
// StringReader reader1 = new StringReader(sb1.toString());
// c1.setContents(new ReaderInputStream(reader1), true, true, null);
// waitForAutoBuild();
// waitForAutoBuild();
//
// assertEquals("two more builds should have occured", //$NON-NLS-1$
// numberOfBuilds + 2,
// testLog.getNumberOfBuildsRun());
//
// List buildLogB = testLog.getPreviousBuildEntry(2);
// boolean incB = listContainsString(buildLogB,
// "AspectJ reports build successful, build was: INCREMENTAL"); //$NON-NLS-1$
// boolean fullB = listContainsString(buildLogB,
// "AspectJ reports build successful, build was: FULL"); //$NON-NLS-1$
// // if not an incremental build of project bug99133b build then fail
// // printing out whether did a full build instead
// if (!incB) {
// fail("Adding a method in project bug99133b " //$NON-NLS-1$
// + "should cause an incremental build of project bug99133b " //$NON-NLS-1$
// + ": (did a full build instead:" + fullB+")"); //$NON-NLS-1$ //$NON-NLS-2$
// }
//
// List buildLogA = testLog.getPreviousBuildEntry(1);
// boolean incA = listContainsString(buildLogA,
// "AspectJ reports build successful, build was: INCREMENTAL"); //$NON-NLS-1$
// boolean fullA = listContainsString(buildLogA,
// "AspectJ reports build successful, build was: FULL"); //$NON-NLS-1$
// // if not a full build of project bug99133a build then fail
// // printing out whether did an incremental build instead
// if (!fullA) {
// fail("Adding a method in project bug99133b " //$NON-NLS-1$
// + "should cause an full build of dependent project bug99133b " //$NON-NLS-1$
// + ": (did an incremental build instead:" + incA + ")"); //$NON-NLS-1$ //$NON-NLS-2$
// }
//
// }
private void addProjectDependency(IProject project, IProject projectDependedOn) throws JavaModelException {
IJavaProject javaProject = JavaCore.create(project);
IClasspathEntry[] originalCP = javaProject.getRawClasspath();
IClasspathEntry newEntry = JavaCore.newProjectEntry(projectDependedOn.getFullPath());
int originalCPLength = originalCP.length;
IClasspathEntry[] newCP = new IClasspathEntry[originalCPLength + 1];
System.arraycopy(originalCP, 0, newCP, 0, originalCPLength);
newCP[originalCPLength] = newEntry;
javaProject.setRawClasspath(newCP, null);
waitForAutoBuild();
}
private void removeProjectDependency(IProject project, IProject projectDependedOn) throws JavaModelException {
IJavaProject javaProject = JavaCore.create(project);
IClasspathEntry[] cpEntry = javaProject.getRawClasspath();
List newEntries = new ArrayList();
for (int j = 0; j < cpEntry.length; j++) {
IClasspathEntry entry = cpEntry[j];
if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT) {
if (!entry.getPath().equals(projectDependedOn.getFullPath())
&& !entry.getPath().equals(
projectDependedOn.getFullPath().makeAbsolute())) {
newEntries.add(entry);
}
} else {
newEntries.add(entry);
}
}
IClasspathEntry[] newCP = (IClasspathEntry[]) newEntries
.toArray(new IClasspathEntry[newEntries.size()]);
javaProject.setRawClasspath(newCP, null);
}
private IFile getFile(IProject project, String packageName, String fileName) throws CoreException {
IFolder src = project.getFolder("src"); //$NON-NLS-1$
if (!src.exists()) {
src.create(true, true, null);
}
IFolder pack = src.getFolder(packageName);
if (!pack.exists()) {
pack.create(true, true, null);
}
assertNotNull("src folder should not be null", src); //$NON-NLS-1$
assertNotNull("package pack should not be null", pack); //$NON-NLS-1$
IFile f = pack.getFile(fileName);
assertNotNull(fileName + " should not be null", f); //$NON-NLS-1$
assertTrue(fileName + " should exist", f.exists()); //$NON-NLS-1$
return f;
}
/**
* There is JDT bug 84214 - sometimes project dependencies don't
* get picked up properly. Therefore, to work around this, if
* remove, then re-add the project dependency.
*
* @throws JavaModelException
*/
private void checkForJDTBug84214(IProject projectWhichShouldHaveDependency, IProject projectDependedOn) throws JavaModelException {
if (projectDependedOn.getReferencingProjects().length == 0) {
removeProjectDependency(projectWhichShouldHaveDependency,projectDependedOn);
addProjectDependency(projectWhichShouldHaveDependency,projectDependedOn);
}
assertEquals(" " + projectDependedOn + " should have " //$NON-NLS-1$ //$NON-NLS-2$
+ projectWhichShouldHaveDependency
+ " as it's list of referencing projects - if not, see JDT bug 84214", //$NON-NLS-1$
1, projectDependedOn.getReferencingProjects().length);
}
private boolean listContainsString(List l, String msg) {
for (Iterator iter = l.iterator(); iter.hasNext();) {
String logEntry = (String) iter.next();
if (logEntry.indexOf(msg) != -1) {
return true;
}
}
return false;
}
}