1/**
2 * @test
3 * @bug 4836939
4 * @key intermittent
5 * @summary JDI add addSourceNameFilter to ClassPrepareRequest
6 * @author Robert Field / Jim Holmlund
7 *
8 * @library ..
9 *
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
41import com.sun.jdi.*;
42import com.sun.jdi.event.*;
43import com.sun.jdi.request.*;
44
45import java.util.*;
46import java.io.File;
47
48class 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
61public 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}
212