1 /**
   2  *  @test
   3  *  @bug 4836939
   4  *  @summary JDI add addSourceNameFilter to ClassPrepareRequest
   5  *
   6  *  @author Robert Field / Jim Holmlund
   7  *
   8  *  @key intermittent
   9  *  @library ..
  10  *  @modules jdk.jdi
  11  *  @run build TestScaffold VMConnection TargetListener TargetAdapter InstallSDE
  12  *  @run compile FilterMangleTest.java
  13  *  @run compile -g onion/pickle/Mangle.java
  14  *  @run driver FilterMangleTest
  15  *  @run driver FilterMangleTest SDE-pMangle.java*
  16  *  @run driver FilterMangleTest SDE-pMangle.jav*
  17  *  @run driver FilterMangleTest SDE-pMangle.j*
  18  *  @run driver FilterMangleTest SDE-p*Mangle.java
  19  *  @run driver FilterMangleTest SDE-p*angle.java
  20  *  @run driver FilterMangleTest SDE-p*java
  21  *  @run driver FilterMangleTest SDE-pMangle.xyz
  22  *  @run driver FilterMangleTest SDE-pIncl.rats*
  23  *  @run driver FilterMangleTest SDE-pIncl.rat*
  24  *  @run driver FilterMangleTest SDE-p*angle.rats
  25  *  @run driver FilterMangleTest SDE-f*Incl.rat
  26  *  @run driver FilterMangleTest SDE-ffred
  27  *  @run driver FilterMangleTest SDE-f*ratsx
  28  *  @run driver FilterMangleTest SDE-fMangle.javax*
  29  */
  30 
  31 /*
  32  * In this test, the file name that contains the class being
  33  * prepared is Mangle.java.
  34  * But, an SDE is created for it that contains the names Mangle.java,
  35  * Mangle.xyz, Incl.xyz, Mangel.rats, Incl.rats.
  36  * This test proves that specifying various patterns for these names
  37  * in a SourceNameFilter allows the class prepared event thru
  38  * (SDE-p prefix in the above names) or does not allow the event
  39  * thru (SDE-f prefix).
  40  */
  41 
  42 import com.sun.jdi.*;
  43 import com.sun.jdi.event.*;
  44 import com.sun.jdi.request.*;
  45 
  46 import java.util.*;
  47 import java.io.File;
  48 
  49 class FilterMangleTarg {
  50     public static void bkpt() {
  51     }
  52     public static void main(String[] args) {
  53         System.out.println("calling mangle");
  54         onion.pickle.Mangle.main(args);
  55         System.out.println("calling mangle");
  56         bkpt();
  57         System.out.println("bkpt done");
  58     }
  59 
  60 }
  61 
  62 public class FilterMangleTest extends TestScaffold {
  63     ClassPrepareRequest cpReq;
  64     boolean shouldResume = false;
  65     boolean gotIt = false;
  66 
  67     static boolean shouldPass = true;
  68     static String pattern;
  69 
  70     static final String op = "onion" + File.separator + "pickle" + File.separator;
  71     ReferenceType targetClass;
  72 
  73     FilterMangleTest (String args[]) {
  74         super(args);
  75     }
  76 
  77     public static void main(String[] args)      throws Exception {
  78         testSetUp();
  79         if (args.length != 0) {
  80             if (args[0].startsWith("SDE-")) {
  81                 // this is a pattern to test
  82                 if (args[0].charAt(4) == 'f') {
  83                     shouldPass = false;
  84                 }
  85                 pattern = args[0].substring(5);
  86                 String[] args2 = new String[args.length - 1];
  87                 System.arraycopy(args, 1, args2, 0, args.length - 1);
  88                 new FilterMangleTest(args2).startTests();
  89                 return;
  90             }
  91             // could be -trace 255 or whatever
  92             pattern = "Mangle.java";
  93         } else {
  94             // no args at all
  95             pattern = "Mangle.java";
  96         }
  97 
  98         new FilterMangleTest(args).startTests();
  99     }
 100 
 101     /********** test set-up **********/
 102 
 103     static void testSetUp() throws Exception {
 104         InstallSDE.install(new File(System.getProperty("test.classes", "."),
 105                                     op + "Mangle.class"),
 106                            new File(System.getProperty("test.src", "."),
 107                                     "Mangle.sde"));
 108     }
 109     /********** test core **********/
 110 
 111 
 112     public void eventSetComplete(EventSet set) {
 113         if (shouldResume) {
 114             set.resume();
 115             shouldResume = false;
 116         }
 117     }
 118 
 119 
 120     public void classPrepared(ClassPrepareEvent event) {
 121         if (event.request() == cpReq) {
 122             ReferenceType rt = event.referenceType();
 123             String rtname = rt.name();
 124             if (rtname.equals("onion.pickle.Mangle")) {
 125                 gotIt = true;
 126             }
 127             shouldResume = true;
 128 
 129             // debug code
 130             if (false) {
 131                 println("Got ClassPrepareEvent for : " + rtname);
 132                 try {
 133                     println("    sourceName = " + rt.sourceName());
 134                 } catch (AbsentInformationException ee) {
 135                     failure("failure: absent info on sourceName(): " + ee);
 136                 }
 137 
 138                 String stratum = rt.defaultStratum();
 139                 println("    defaultStratum = " + stratum);
 140 
 141                 try {
 142                     println("    sourceNames = " + rt.sourceNames(stratum));
 143                 } catch (AbsentInformationException ee) {
 144                     failure("failure: absent info on sourceNames(): " + ee);
 145                 }
 146                 println("Available strata:  " + rt.availableStrata() + "\n");
 147             }
 148         }
 149     }
 150 
 151     protected void runTests() throws Exception {
 152         /*
 153          * Be very careful with class prepare requests!
 154          * For example, if you try to set a bkpt on a class not yet
 155          * loaded, TestScaffold will create a class prepare request
 156          * to catch the load of that class so the bkpt can be
 157          * set after the class is loaded.  If our event handler
 158          * resumes the event set, then I think that the debuggee
 159          * runs off to completion before the bkpt can actually be
 160          * set.
 161          */
 162         BreakpointEvent bpe = startToMain("FilterMangleTarg");
 163         targetClass = bpe.location().declaringType();
 164 
 165         if (!vm().canGetSourceDebugExtension()) {
 166             failure("FAIL: canGetSourceDebugExtension() is false");
 167         } else {
 168             println("canGetSourceDebugExtension() is true");
 169         }
 170 
 171         EventRequestManager erm = vm().eventRequestManager();
 172         cpReq = erm.createClassPrepareRequest();
 173         if (true)  {
 174             cpReq.addSourceNameFilter(pattern);
 175         } else {
 176             // a manual test for passing mulitple filters.
 177             cpReq.addSourceNameFilter("Mangle.j*");
 178             cpReq.addSourceNameFilter("Mangle.jav*");
 179         }
 180         cpReq.enable();
 181         addListener(this);
 182 
 183         resumeTo("FilterMangleTarg", "bkpt", "()V");
 184 
 185         /*
 186          * resume the target listening for events
 187          */
 188         listenUntilVMDisconnect();
 189 
 190         if (!gotIt) {
 191             if (shouldPass) {
 192                 failure("FAIL: Did not get class prepare event for " +
 193                     "onion.pickle.Mangle, pattern = " + pattern);
 194             }
 195         } else {
 196             if (!shouldPass) {
 197                 failure("FAIL: Got unexpected class prepare event for " +
 198                     "onion.pickle.Mangle, pattern = " + pattern);
 199             }
 200         }
 201 
 202         /*
 203          * deal with results of test
 204          * if anything has called failure("foo") testFailed will be true
 205          */
 206         if (!testFailed) {
 207             println("FilterMangleTest: passed: pattern = " + pattern);
 208         } else {
 209             throw new Exception("FilterMangleTest: failed");
 210         }
 211     }
 212 }