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