org.eclipse.ajdt.core.tests.builder.Bug99133Test.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.ajdt.core.tests.builder.Bug99133Test.java

Source

/*******************************************************************************
 * 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;
    }

}