This is the mail archive of the mauve-patches@sourceware.org mailing list for the Mauve project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

small Harness improvement .. auto-detect bootclasspath


Thanks to an idea by Tom Fitzsimmons, the Harness now auto-detects the
bootclasspath for the compiler based on the VM that is used to run the
tests.  Because of this, auto-compilation can be enabled by default.
The README is updated to reflect these changes.


2006-04-26  Anthony Balkissoon  <abalkiss@redhat.com>

	* Harness.java:
	(bcp_timeout): New field.
	(showCompilationErrors): Set to true by default.
	(setupHarness): Changed -showcompilefails option to -hidecompilefails
	since fails are shown by default now.  Also changed 
	-classpath-install-dir option to -bootclasspath to match the 
	configure option.
	(getClasspathInstallString): If no bootclasspath was specified on the
	command line or in configure, then auto-detect it with the new method
	getBootClassPath.
	(getBootClassPath): New method.
	* README: Changed --with-classpath-install-dir to --with-bootclasspath,
	changed text to reflect the fact that auto-compilation is now enabeld
	by default.  Added the -hidecompilefails option to the text.
	* configure: Regenerated.
	* configure.in: Changed --with-classpath-install-dir to 
	--with-bootclasspath, changed auto-compilation to be enabled by 
	default.
	* gnu/testlet/DetectBootclasspath.java: New file.

--Tony
Index: Harness.java
===================================================================
RCS file: /cvs/mauve/mauve/Harness.java,v
retrieving revision 1.3
diff -u -r1.3 Harness.java
--- Harness.java	25 Apr 2006 16:22:36 -0000	1.3
+++ Harness.java	26 Apr 2006 18:04:26 -0000
@@ -73,6 +73,9 @@
   // The location of the eclipse-ecj.jar file
   private static String ecjJarLocation = null;
   
+  // How long the bootclasspath finder program can run before termination
+  private static long bcp_timeout = 60000;
+  
   // How long a test may run before it is considered hung
   private static long runner_timeout = 60000;
 
@@ -93,7 +96,7 @@
   private static boolean compileTests = true;
   
   // Whether we should display information for failing compilations
-  private static boolean showCompilationErrors = false;
+  private static boolean showCompilationErrors = true;
   
   // The total number of tests run
   private static int total_tests = 0;
@@ -244,8 +247,8 @@
             else if (args[i].equals("no") || args[i].equals("false"))
               compileTests = false;
           }
-        else if (args[i].equals("-showcompilefails"))
-          showCompilationErrors = true;
+        else if (args[i].equals("-hidecompilefails"))
+          showCompilationErrors = false;
         else if (args[i].equals("-help") || args[i].equals("--help")
                  || args[i].equals("-h"))
           printHelpMessage();
@@ -256,13 +259,13 @@
               throw new RuntimeException("No file path after '-file'.  Exit");
             inputFile = args[i];
           }
-        else if (args[i].equalsIgnoreCase("-classpath-install-dir"))
+        else if (args[i].equalsIgnoreCase("-bootclasspath"))
           {
             // User is specifying the classpath installation folder to use
             // as the compiler's bootclasspath.
             if (++i >= args.length)
               throw new RuntimeException("No file path " +
-                    "after '-classpath-install-dir'.  Exit");
+                    "after '-bootclasspath'.  Exit");
             classpathInstallDir = args[i];
           }
         else if (args[i].equalsIgnoreCase("-ecj-jar"))
@@ -400,7 +403,7 @@
                          " It is indirectly\n    referenced from required " +
                          ".class files,'\n\nthen try setting the " +
                          "bootclasspath by using the\n" +
-                         "--with-classpath-install-dir=CPINSTALLDIR option " +
+                         "--with-bootclasspath=CPINSTALLDIR option " +
                          "in configure.");
     ecjWriterErr.println("\nThe compiler command used was: \n    " +
                          compileStringBase + "\n");
@@ -427,23 +430,103 @@
    */
   private static String getClasspathInstallString()
   {
-    String temp = classpathInstallDir; 
+    String temp = classpathInstallDir;
+    
+    // If classpathInstallDir is null that means no bootclasspath was 
+    // specified on the command line using -bootclasspath.  In this case
+    // check if anything was supplied to configure with --with-bootclasspath.
     if (temp == null)
       {
         temp = config.cpInstallDir;
+        
+        // If temp is the empty string then nothing was supplied to configure
+        // so auto-detect the bootclasspath using getBootClasspath().
         if (temp.equals(""))
-          return temp;
+          {
+            temp = getBootClassPath();
+            
+            // If auto-detect returned null we cannot auto-detect the 
+            // bootclasspath and we should try invoking the compiler without
+            // specifying the bootclasspath.  Otherwise, we should add
+            // " -bootclasspath " followed by the detected path.
+            if (temp != null)              
+              return " -bootclasspath " + temp;
+            return temp;
+          }
       }
+    
+    // This section is for bootclasspath's specified with
+    // -bootclasspath or --with-bootclasspath (in configure), we need
+    // to add "/share/classpath/glibj.zip" onto the end and
+    // " -bootclasspath onto the start".
     temp = " -bootclasspath " + temp;
     if (!temp.endsWith(File.separator))
       temp += File.separator;
     temp += "share" + File.separator + "classpath";
     
+    // If (for some reason) there is no glibj.zip file in the specified
+    // folder, just use the folder as the bootclasspath, perhaps the folder
+    // contains an expanded view of the resources.
     File f = new File (temp.substring(16) + File.separator + "glibj.zip");
     if (f.exists())
       temp += File.separator + "glibj.zip";
     return temp;
   }
+  
+  /**
+   * Forks a process to run gnu/testlet/DetectBootclasspath on the VM that is
+   * being tested.  This program detects the bootclasspath so we can use
+   * it for the compiler's bootclasspath.
+   * @return the bootclasspath as found, or null if none could be found.
+   */
+  private static String getBootClassPath()
+  {
+    try
+    {
+      String c = vmCommand + " gnu" + File.separator + "testlet"
+                   + File.separator + "DetectBootclasspath";
+      Process p = Runtime.getRuntime().exec(c);      
+      BufferedReader br = 
+        new BufferedReader
+        (new InputStreamReader(p.getInputStream()));
+      String bcpOutput = null;
+      // Create a timer to watch this new process.
+      TimeoutWatcher tw = new TimeoutWatcher(bcp_timeout);
+      tw.start();
+      while (true)
+        {
+          // If for some reason the process hangs, return null, indicating we
+          // cannot auto-detect the bootclasspath.
+          if (testIsHung)
+            {
+              synchronized (runner_lock)
+              {
+                testIsHung = false;
+              }
+              br.close();
+              p.destroy();
+              return null;
+            }
+          if (br.ready())
+            {
+              bcpOutput = br.readLine();
+              if (bcpOutput.startsWith("BCP_FINDER:"))
+                return bcpOutput.substring(11);
+              else
+                {
+                  // This means the auto-detection failed.
+                  System.out.println(bcpOutput);
+                  return null;
+                }
+            }
+        }
+    }
+    catch (IOException ioe)
+    {
+      // Couldn't auto-fetch the bootclasspath.
+      return null;
+    }
+  }
 
   /**
    * This method takes a String and puts it into a consistent format so we can
@@ -518,7 +601,7 @@
       "\n\nOutput Options:\n" +
       "  -showpasses:             display passing tests as well as failing " +
       "ones\n" +
-      "  -showcompilefails:       display errors from the compiler when " +
+      "  -hidecompilefails:       hide errors from the compiler when " +
       "tests fail to compile\n" +
       "  -exceptions:             print stack traces for uncaught " +
       "exceptions\n" +
@@ -940,8 +1023,7 @@
           
           // If temp is null, we didn't find it.  Otherwise, look for each
           // individual failing compilation, count it as a fail, exclude it
-          // from the test run, and if -showcompilefails was used, print 
-          // out the info.
+          // from the test run, and print out the info.
           while (temp != null)
             {
               // If we've reached a part of the file that pertains to another
@@ -956,8 +1038,11 @@
               loc = temp.indexOf("gnu" + File.separatorChar + "testlet");
               if (loc != - 1)
                 {
-                  String name = temp.substring(loc);                  
-                  String shortName = stripPrefix(name);
+                  String name = temp.substring(loc);
+                  String shortName = 
+                    stripPrefix(name).replace(File.separatorChar, '.');
+                  if (shortName.endsWith(".java"))
+                    shortName = shortName.substring(0, shortName.length() - 5);
                   if (verbose && lastFailingTest != null)
                     System.out.println
                       ("TEST FAILED: compilation failed " + lastFailingTest);
@@ -967,7 +1052,7 @@
                     System.out.println
                       ("TEST: " + shortName + "\n  FAIL: compilation failed.");
                   else
-                    System.out.println("FAIL: " + stripPrefix(name)
+                    System.out.println("FAIL: " + shortName
                                        + ": compilation failed");
                   if (!showCompilationErrors)
                     System.out.println
@@ -1120,7 +1205,7 @@
             }
           }
         if (config.cpInstallDir.equals(""))
-          System.out.println("  Try setting --with-classpath-install-dir " +
+          System.out.println("  Try setting --with-bootclasspath " +
                 "when running configure.\n  See the README file for details");
         if (verbose)
           System.out.println("TEST FAILED: compilation failed " + shortName);
Index: README
===================================================================
RCS file: /cvs/mauve/mauve/README,v
retrieving revision 1.23
diff -u -r1.23 README
--- README	24 Apr 2006 19:42:02 -0000	1.23
+++ README	26 Apr 2006 18:04:26 -0000
@@ -38,7 +38,7 @@
   If you plan to use the auto-compilation feature of the Harness, which
   compiles tests inline before running them (so new tests, or changed
   tests are run properly without an additional step), you need to be sure
-  it is properly configured.  The following options are associated
+  it is properly configured. The following options are associated
   with auto-compilation:
 
 	 --enable-auto-compilation  	Enable the auto-compilation feature
@@ -49,9 +49,11 @@
 	 								machine is different from this.  If no valid
 	 								ecj jar is found, auto-compilation will be 
 	 								turned off.
-	 --with-classpath-install-dir	Specify the location of the java implemenation
-	 								installation.  This will be used as the
-	 								bootclasspath for the compiler.
+	 --with-bootclasspath			Specify the bootclasspath for the compiler.
+
+  Auto-compilation is enabled by default, and the bootclasspath is found
+  automatically.  If you wish to disable auto-compilation or change the
+  bootclasspath you should use the appropriate option(s) above.
 
 
 2. Environment variables for configure.
@@ -118,7 +120,7 @@
   done via command line options to the Harness (which override the configure
   options).  To set the VM via the command line, use:
   
-  -testvm [vmpath] 
+  -vm [vmpath] 
   
   If, for example, I wanted to run all the JTable tests using JamVM, and then 
   run them all on Sun's VM for comparison, I would type:
@@ -211,45 +213,49 @@
   only prints minimal information about uncaught exceptions. The following
   options affect what is printed:
   
-  -verbose: prints information about each passing harness.check() call within
-  the tests, whether they pass or fail.
+  -hidecompilefails: hides failures from the compiler.  These can still be 
+					 found in the .ecjErr file.
+  
+  -verbose: 		 prints information about each passing harness.check() call
+					 within the tests, whether they pass or fail.
   
-  -exceptions: prints full stack traces for uncaught exceptions
+  -exceptions: 		 prints full stack traces for uncaught exceptions
   
-  -showpasses: prints one-line summaries for passing tests
+  -showpasses: 		 prints one-line summaries for passing tests
   
-  -debug:      prints toString() information when a 
-               harness.check(Object, Object) call fails.
+  -debug:      		 prints toString() information when a 
+               		 harness.check(Object, Object) call fails.
 
 
-6.  Turning on (or off) test auto-compilation
-  The auto-compilation feature is diabled by default, but can be turned on by 
-  using the --enable-auto-compilation option to configure.  You can also turn
-  on by using the following Harness option:
+6.  Turning off (or on) test auto-compilation
+  The auto-compilation feature is enabled by default, but can be turned off by 
+  using the --disable-auto-compilation option to configure.  You can also turn
+  off the option by using the following Harness option:
   
-  -compile yes 	   OR    -compile true
+  -compile no	   OR    -compile false
   
-  If you have enabled auto-compilation in configure but wish to turn it off
+  If you have disabled auto-compilation in configure but wish to turn it on
   for a particular test run, use
   
-  -compile no      OR    -compile false
+  -compile yes     OR    -compile true
   
   Note that auto-compilation requires a correct path to eclipse-ecj.jar and 
   a correct bootclasspath.  The following options deal with this:
   
-  -classpath-install-dir CP_INSTALL_DIR
+  -bootclasspath BOOTCLASSPATH
   -ecj-jar ECJ_JAR_LOCATION
   
   These can also be specified at configure time via 
-  --with-classpath-installation-dir and --with-ecj-jar, the latter defaulting
-  to /usr/share/java/eclipse-ecj.jar if no location is specified.
-  
-  The following example is for the case where auto-compilation is disabled by
-  default in configure, but is turned on after a cvs update so that new tests
-  are compiled and run.
-  
-  Example:
-    - configure using --with-classpath-install-dir=CP_INSTALL_DIR
-    - cvs update (downloads the new testcases)
-    - HARNESSVM Harness -compile true  
+  --with-bootclasspath and --with-ecj-jar, the latter defaulting
+  to /usr/share/java/eclipse-ecj.jar if no location is specified.  The default
+  bootclasspath is found automatically and shouldn't need to be changed unless
+  you specifically want to specify an alternate location.
+  
+  So the default setup of:
+    1.  ./configure
+    2.  make
+    3.  HARNESSVM Harness
+    
+  will run with auto-compilation enabled with the ecj jar being 
+  /usr/share/java/eclipse-ecj.jar and the bootclasspath found automatically.
 
Index: configure.in
===================================================================
RCS file: /cvs/mauve/mauve/configure.in,v
retrieving revision 1.15
diff -u -r1.15 configure.in
--- configure.in	24 Apr 2006 19:42:02 -0000	1.15
+++ configure.in	26 Apr 2006 18:04:27 -0000
@@ -21,13 +21,9 @@
 AM_CONDITIONAL(USE_GCJ, test "$with_gcj" = yes)
 
 
-AC_ARG_WITH(classpath-install-dir,
-[  --with-classpath-install-dir=CPINSTALL   Specify the location of Classpath's install dir],
-CP_INSTALL_DIR="$with_classpath_install_dir")
-if ! test -d "$CP_INSTALL_DIR"
-then
-CP_INSTALL_DIR=""
-fi
+AC_ARG_WITH(bootclasspath,
+[  --with-bootclasspath=BOOTCP   Specify the bootclasspath for the compiler],
+CP_INSTALL_DIR="$with_bootclasspath")
 AC_SUBST(CP_INSTALL_DIR)
 
 
@@ -49,7 +45,7 @@
 dnl have the correct bootclasspath
 AC_ARG_ENABLE(auto-compile,
 [  --enable-auto-compile            Use ecj to compile tests on the fly],
-AUTO_COMPILE="$enable_auto_compile",AUTO_COMPILE="no")
+AUTO_COMPILE="$enable_auto_compile",AUTO_COMPILE="yes")
 AC_SUBST(AUTO_COMPILE)
 
 dnl See if the user prefers to build .class files with gcj, or whether
Index: gnu/testlet/DetectBootclasspath.java
===================================================================
RCS file: gnu/testlet/DetectBootclasspath.java
diff -N gnu/testlet/DetectBootclasspath.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gnu/testlet/DetectBootclasspath.java	26 Apr 2006 18:04:27 -0000
@@ -0,0 +1,54 @@
+package gnu.testlet;
+
+
+/**
+ * This tiny class is used for finding the bootclasspath of the VM used
+ * to run the tests.
+ * @author Anthony Balkissoon abalkiss at redhat dot com
+ *
+ */
+public class DetectBootclasspath
+{
+  /**
+   * Look in the system properties for the bootclasspath of the VM and return
+   * it to the process that forked this process via the System.out stream.
+   * 
+   * Tries first to get the property "sun.boot.class.path", if there is none,
+   * then it tries "java.boot.class.path", if there is still no match, looks
+   * to see if there is a unique property key that contains "boot.class.path".
+   * If this fails too, prints an error message.
+   */
+  public static void main (String[] args)
+  {
+    String result = "BCP_FINDER:";
+    // Sun's VM stores the bootclasspath as "sun.boot.class.path".
+    String temp = System.getProperty("sun.boot.class.path");
+    if (temp == null)
+      // JamVM stores it as "boot.class.path"
+      temp = System.getProperty("java.boot.class.path");
+    if (temp == null)
+      {        
+        String[] s = (String[])(System.getProperties().keySet().toArray());
+        int count = 0;
+        String key = null;
+        for (int i = 0; i < s.length; i++)
+          {
+            if (s[i].indexOf("boot.class.path") != -1)
+              {
+                count ++;
+                key = s[i];                
+              }
+          }
+        if (count == 1)
+          temp = System.getProperty(key);
+        else
+          {
+            System.out.println("WARNING: Cannot auto-detect the " +
+                    "bootclasspath for your VM, please file a bug report" +
+                    " specifying which VM you are testing.");
+            return;
+          }
+      }
+    System.out.println(result + temp);
+  }
+}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]