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