Clover coverage report - DrJava Test Coverage (drjava-20110828-r5448)
Coverage timestamp: Sun Aug 28 2011 03:13:33 CDT
file stats: LOC: 359   Methods: 16
NCLOC: 254   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
ConcJUnitUtils.java 2.1% 4.1% 25% 5.3%
coverage coverage
 1    /*BEGIN_COPYRIGHT_BLOCK
 2    *
 3    * Copyright (c) 2001-2010, JavaPLT group at Rice University (drjava@rice.edu)
 4    * All rights reserved.
 5    *
 6    * Redistribution and use in source and binary forms, with or without
 7    * modification, are permitted provided that the following conditions are met:
 8    * * Redistributions of source code must retain the above copyright
 9    * notice, this list of conditions and the following disclaimer.
 10    * * Redistributions in binary form must reproduce the above copyright
 11    * notice, this list of conditions and the following disclaimer in the
 12    * documentation and/or other materials provided with the distribution.
 13    * * Neither the names of DrJava, the JavaPLT group, Rice University, nor the
 14    * names of its contributors may be used to endorse or promote products
 15    * derived from this software without specific prior written permission.
 16    *
 17    * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 18    * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 19    * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 20    * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 21    * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 22    * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 23    * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 24    * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 25    * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 26    * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 27    * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 28    *
 29    * This software is Open Source Initiative approved Open Source Software.
 30    * Open Source Initative Approved is a trademark of the Open Source Initiative.
 31    *
 32    * This file is part of DrJava. Download the current version of this project
 33    * from http://www.drjava.org/ or http://sourceforge.net/projects/drjava/
 34    *
 35    * END_COPYRIGHT_BLOCK*/
 36   
 37    package edu.rice.cs.drjava.model.junit;
 38   
 39    import java.io.*;
 40    import java.util.jar.*;
 41    import javax.swing.*;
 42    import java.awt.*;
 43   
 44    import edu.rice.cs.drjava.DrJava;
 45    import edu.rice.cs.drjava.config.OptionConstants;
 46    import edu.rice.cs.util.FileOps;
 47    import edu.rice.cs.plt.concurrent.JVMBuilder;
 48    import edu.rice.cs.plt.lambda.Runnable1;
 49    import edu.rice.cs.util.swing.SwingWorker;
 50    import edu.rice.cs.util.swing.ProcessingDialog;
 51   
 52    /** Helpers for ConcJUnit.
 53    * @version $Id: ConcJUnitUtils.java 5175 2010-01-20 08:46:32Z mgricken $
 54    */
 55    public class ConcJUnitUtils {
 56    //-------------------------- ConcJUnit Utilities --------------------------//
 57    /** Check if the file is a valid jar file containing the files in the varargs.
 58    * @param f file to check
 59    * @param checkFilesInJar file names that should be in the jar file
 60    * @return true if f is a jar file and the files are in the jar */
 61  540 protected static boolean isValidJarFile(final File f, String... checkFilesInJar) {
 62  540 if ((f==null) || (FileOps.NULL_FILE.equals(f)) || (!f.exists())) return false;
 63  0 JarFile jf = null;
 64  0 try {
 65  0 jf = new JarFile(f);
 66  0 for(String s: checkFilesInJar) {
 67  0 JarEntry je = jf.getJarEntry(s);
 68  0 if (je==null) return false;
 69    }
 70  0 return true;
 71    // we already have a JUnit version 4.4 as junit.jar
 72    // running junit.runner.Version to get the version string
 73    // isn't a valid criterion for compatibility
 74    // JVMBuilder jvmb = JVMBuilder.DEFAULT.classPath(f);
 75    // Process p = jvmb.start("junit.runner.Version");
 76    // BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
 77    // String line = br.readLine();
 78    // try {
 79    // p.waitFor();
 80    // }
 81    // catch(InterruptedException ie) { return false; }
 82    // return "3.8.2".equals(line);
 83    }
 84  0 catch(IOException ioe) { return false; }
 85    finally {
 86  0 try {
 87  0 if (jf != null) jf.close();
 88    }
 89    catch(IOException ioe) { /* ignore, just trying to close the file */ }
 90    }
 91    }
 92   
 93    /** Check if the file is a valid junit.jar file.
 94    * @param f file to check
 95    * @return true if f is a valid junit.jar file */
 96  180 public static boolean isValidJUnitFile(final File f) {
 97  180 return isValidJarFile(f,
 98    "junit/framework/Test.class",
 99    "junit/runner/Version.class");
 100    }
 101   
 102    /** Check if the file is a valid concutest-junit-xxx-withrt.jar file.
 103    * @param f file to check
 104    * @return true if f is a valid concutest-junit-xxx-withrt.jar file */
 105  180 public static boolean isValidConcJUnitFile(final File f) {
 106  180 return isValidJarFile(f,
 107    "junit/framework/Test.class",
 108    "junit/runner/Version.class",
 109    "junit/runner/ConcutestVersion.class",
 110    "edu/rice/cs/cunit/concJUnit/ConcJUnitFileInstrumentorLauncher.class",
 111    "edu/rice/cs/cunit/concJUnit/MultithreadedTestError.class",
 112    "edu/rice/cs/cunit/concJUnit/ThreadSets.class");
 113    }
 114   
 115    /** Check if the file is a valid rt.concjunit.jar file.
 116    * @param f file to check
 117    * @return true if f is a valid rt.concjunit.jar file */
 118  180 public static boolean isValidRTConcJUnitFile(final File f) {
 119  180 return isValidJarFile(f,
 120    "java/lang/Object.class",
 121    "java/lang/Thread.class",
 122    "java/lang/String.class",
 123    "edu/rice/cs/cunit/concJUnit/ThreadSets.class");
 124    }
 125   
 126    /** Check if the file is a valid rt.concjunit.jar file that matches
 127    * the currently running Java version.
 128    * @param f file to check
 129    * @return true if f is a compatible rt.concjunit.jar file */
 130  0 public static boolean isCompatibleRTConcJUnitFile(final File f) {
 131  0 if (!isValidRTConcJUnitFile(f)) return false;
 132  0 try {
 133  0 JarFile jf = new JarFile(f);
 134  0 Manifest mf = jf.getManifest();
 135  0 if (mf==null) return false;
 136  0 String vendor = mf.getMainAttributes().getValue("Edu-Rice-Cs-CUnit-JavaVersion-Vendor");
 137  0 String version = mf.getMainAttributes().getValue("Edu-Rice-Cs-CUnit-JavaVersion");
 138  0 if ((vendor==null) || (version==null)) return false;
 139  0 return (vendor.equals(edu.rice.cs.plt.reflect.JavaVersion.CURRENT_FULL.vendor().toString()) &&
 140    version.equals(edu.rice.cs.plt.reflect.JavaVersion.CURRENT_FULL.toString()));
 141    }
 142  0 catch(IOException ioe) { return false; }
 143    }
 144   
 145    /** Ask the user if the rt.concjunit.jar file should be regenerated.
 146    * @param parentFrame parent frame
 147    * @return true if the user chose to regenerate
 148    */
 149  0 public static boolean showIncompatibleWantToRegenerateDialog(final Frame parentFrame,
 150    final Runnable yesRunnable,
 151    final Runnable noRunnable) {
 152  0 Object[] options = {"Yes","No"};
 153  0 int n = JOptionPane.showOptionDialog(parentFrame,
 154    "The specified ConcJUnit runtime file is incompatible with the\n"+
 155    "current version of Java. Do you wish to regenerate the file?",
 156    "Regenerate ConcJUnit Runtime",
 157    JOptionPane.YES_NO_OPTION,
 158    JOptionPane.QUESTION_MESSAGE,
 159    null,
 160    options,
 161    options[1]);
 162  0 if (n==0) {
 163    // yes
 164  0 File concJUnitJarFile = FileOps.getDrJavaFile();
 165  0 if (DrJava.getConfig().getSetting(OptionConstants.JUNIT_LOCATION_ENABLED)) {
 166  0 concJUnitJarFile = DrJava.getConfig().getSetting(OptionConstants.JUNIT_LOCATION);
 167    }
 168  0 File rtFile = DrJava.getConfig().getSetting(OptionConstants.RT_CONCJUNIT_LOCATION);
 169  0 showGenerateRTConcJUnitJarFileDialog(parentFrame,
 170    rtFile,
 171    concJUnitJarFile,
 172    new Runnable1<File>() {
 173  0 public void run(File targetFile) {
 174    // success
 175  0 DrJava.getConfig().setSetting(OptionConstants.RT_CONCJUNIT_LOCATION, targetFile);
 176  0 yesRunnable.run();
 177    }
 178    },
 179    new Runnable() {
 180  0 public void run() {
 181    // failure
 182  0 if (DrJava.getConfig().getSetting(OptionConstants.CONCJUNIT_CHECKS_ENABLED).
 183    equals(OptionConstants.ConcJUnitCheckChoices.NO_LUCKY)) {
 184  0 DrJava.getConfig().setSetting(OptionConstants.CONCJUNIT_CHECKS_ENABLED,
 185    OptionConstants.ConcJUnitCheckChoices.NO_LUCKY);
 186    }
 187  0 noRunnable.run();
 188    } });
 189  0 return true;
 190    }
 191    else {
 192    // no
 193  0 if (DrJava.getConfig().getSetting(OptionConstants.CONCJUNIT_CHECKS_ENABLED).
 194    equals(OptionConstants.ConcJUnitCheckChoices.NO_LUCKY)) {
 195  0 DrJava.getConfig().setSetting(OptionConstants.CONCJUNIT_CHECKS_ENABLED,
 196    OptionConstants.ConcJUnitCheckChoices.NO_LUCKY);
 197    }
 198  0 noRunnable.run();
 199  0 return false;
 200    }
 201    }
 202   
 203    /**
 204    * Show the "Generate ConcJUnit Runtime" dialog (ask for file name, etc.).
 205    * @param parentFrame parent frame
 206    * @param rtFile suggestion of where we should generate the runtime
 207    * @param concJUnitJarFile the concutest-junit-....-withrt.jar file that does the generation
 208    * @param successRunnable command to execute after successful generation, parameter is the file
 209    * @param failureRunnable command to execute if generation fails
 210    */
 211  0 public static void showGenerateRTConcJUnitJarFileDialog(final Frame parentFrame,
 212    File rtFile,
 213    final File concJUnitJarFile,
 214    final Runnable1<File> successRunnable,
 215    final Runnable failureRunnable) {
 216  0 if ((rtFile == null) || (FileOps.NULL_FILE.equals(rtFile))) {
 217    // no entry, suggest a place
 218  0 File drJavaFile = FileOps.getDrJavaApplicationFile();
 219  0 File parent = drJavaFile.getParentFile();
 220  0 if (parent == null) {
 221  0 parent = new File(System.getProperty("user.dir"));
 222    }
 223  0 rtFile = new File(parent, "rt.concjunit.jar");
 224    }
 225  0 JFileChooser saveChooser = new JFileChooser() {
 226  0 public void setCurrentDirectory(File dir) {
 227    //next two lines are order dependent!
 228  0 super.setCurrentDirectory(dir);
 229  0 setDialogTitle("Save: " + getCurrentDirectory());
 230    }
 231    };
 232  0 saveChooser.setPreferredSize(new Dimension(650, 410));
 233  0 saveChooser.setSelectedFile(rtFile);
 234  0 saveChooser.setFileFilter(new javax.swing.filechooser.FileFilter() {
 235  0 public boolean accept(File f) {
 236  0 return f.isDirectory() ||
 237    f.getPath().endsWith(".jar");
 238    }
 239  0 public String getDescription() {
 240  0 return "Java Archive Files (*.jar)";
 241    }
 242    });
 243  0 saveChooser.setMultiSelectionEnabled(false);
 244  0 int rc = saveChooser.showSaveDialog(parentFrame);
 245  0 if (rc == JFileChooser.APPROVE_OPTION) {
 246  0 final File targetFile = saveChooser.getSelectedFile();
 247  0 int n = JOptionPane.YES_OPTION;
 248  0 if (targetFile.exists()) {
 249  0 Object[] options = {"Yes","No"};
 250  0 n = JOptionPane.showOptionDialog(parentFrame,
 251    "This file already exists. Do you wish to overwrite the file?",
 252    "Confirm Overwrite",
 253    JOptionPane.YES_NO_OPTION,
 254    JOptionPane.QUESTION_MESSAGE,
 255    null,
 256    options,
 257    options[1]);
 258    }
 259  0 if (n == JOptionPane.YES_OPTION) {
 260  0 if (parentFrame!=null) parentFrame.setEnabled(false);
 261  0 final ProcessingDialog processingDialog =
 262    new ProcessingDialog(parentFrame, "Creating ConcJUnit Runtime", "Processing, please wait.");
 263  0 final JProgressBar pb = processingDialog.getProgressBar();
 264  0 processingDialog.setVisible(true);
 265  0 try {
 266  0 final File tmpDir = FileOps.createTempDirectory("DrJavaGenerateRTConcJUnitJar");
 267   
 268  0 SwingWorker worker = new SwingWorker() {
 269    volatile Boolean _success = null;
 270    Thread _processIncrementer = new Thread(new Runnable() {
 271  0 public void run() {
 272  0 File tmpFile = new File(tmpDir, "rt.concjunit.jar");
 273  0 boolean indeterminate = true;
 274  0 try {
 275  0 while (_success == null) {
 276  0 Thread.sleep(1000);
 277  0 if (tmpFile.exists()) {
 278  0 if (indeterminate) {
 279  0 pb.setIndeterminate(false);
 280  0 indeterminate = false;
 281    }
 282  0 pb.setValue((int)(100.0/(30*1024*1024)*tmpFile.length()));
 283    }
 284    }
 285    }
 286    catch(InterruptedException ie) {
 287  0 pb.setIndeterminate(true);
 288    }
 289    }
 290    });
 291  0 public Object construct() {
 292  0 _processIncrementer.start();
 293  0 _success = edu.rice.cs.drjava.model.junit.ConcJUnitUtils.
 294    generateRTConcJUnitJarFile(targetFile, concJUnitJarFile, tmpDir);
 295  0 return null;
 296    }
 297   
 298  0 public void finished() {
 299  0 pb.setValue(100);
 300  0 processingDialog.setVisible(false);
 301  0 processingDialog.dispose();
 302  0 if (parentFrame!=null) parentFrame.setEnabled(true);
 303  0 if ((_success != null) && (_success)) {
 304  0 successRunnable.run(targetFile);
 305  0 JOptionPane.showMessageDialog(parentFrame,
 306    "Successfully generated ConcJUnit Runtime File:\n"+targetFile,
 307    "Generation Successful",
 308    JOptionPane.INFORMATION_MESSAGE);
 309  0 edu.rice.cs.plt.io.IOUtil.deleteRecursively(tmpDir);
 310    }
 311    else {
 312  0 failureRunnable.run();
 313  0 JOptionPane.showMessageDialog(parentFrame,
 314    "Could not generate ConcJUnit Runtime File:\n"+targetFile,
 315    "Could Not Generate",
 316    JOptionPane.ERROR_MESSAGE);
 317    }
 318    }
 319    };
 320  0 worker.start();
 321    }
 322    catch(IOException ioe) {
 323  0 JOptionPane.showMessageDialog(parentFrame,
 324    "Could not generate ConcJUnit Runtime file:\n"+targetFile,
 325    "Could Not Generate",
 326    JOptionPane.ERROR_MESSAGE);
 327    }
 328    }
 329    }
 330    else {
 331  0 failureRunnable.run();
 332    }
 333    }
 334   
 335    /** Generate the rt.concjunit.jar file using the specified concutest-junit-XXX-withrt.jar file.
 336    * @param rtFile target rt.concjunit.jar file
 337    * @param concJUnitJarFile concutest-junit-XXX-withrt.jar file that contains the instrumentor
 338    * @param tmpDir temporary directory for the processing
 339    * @return true if successful */
 340  0 public static boolean generateRTConcJUnitJarFile(File rtFile, File concJUnitJarFile, File tmpDir) {
 341  0 if (!isValidConcJUnitFile(concJUnitJarFile)) return false;
 342   
 343  0 try {
 344  0 JVMBuilder jvmb = new JVMBuilder(tmpDir).classPath(concJUnitJarFile);
 345  0 Process p = jvmb.start("edu.rice.cs.cunit.concJUnit.ConcJUnitFileInstrumentorLauncher", "-r");
 346  0 BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
 347  0 String line;
 348  0 while((line = br.readLine()) != null) { /* just read and discard any output */ }
 349  0 try {
 350  0 p.waitFor();
 351    }
 352  0 catch(InterruptedException ie) { return false; }
 353  0 if (p.exitValue() != 0) { return false; }
 354  0 edu.rice.cs.plt.io.IOUtil.copyFile(new File(tmpDir, "rt.concjunit.jar"), rtFile);
 355  0 return isValidRTConcJUnitFile(rtFile);
 356    }
 357  0 catch(IOException ioe) { return false; }
 358    }
 359    }