1/*
2 * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/**
25 * @test
26 * @bug 4836939 6646613
27 * @summary JDI add addSourceNameFilter to ClassPrepareRequest
28 * @author jjh
29 *
30 * @run build TestScaffold VMConnection TargetListener TargetAdapter
31 * @run compile -g SourceNameFilterTest.java
32 * @run driver SourceNameFilterTest
33 * @run compile -g:none SourceNameFilterTest.java
34 * @run driver SourceNameFilterTest
35 */
36// The compile -g:none suppresses the lineNumber table to trigger bug 6646613.
37
38import com.sun.jdi.*;
39import com.sun.jdi.event.*;
40import com.sun.jdi.request.*;
41
42import java.util.*;
43
44    /********** target program **********/
45
46class SourceNameFilterTarg {
47    static  void bkpt() {
48    }
49
50    public static void main(String[] args){
51        System.out.println("Howdy!");
52
53        LoadedLater1.doit();
54        bkpt();
55
56        LoadedLater2.doit();
57        bkpt();
58
59        LoadedLater3.doit();
60        bkpt();
61        System.out.println("Goodbye from SourceNameFilterTarg!");
62    }
63}
64class LoadedLater1 {
65    public static void doit() {
66        System.out.println("didit1");
67    }
68}
69
70class LoadedLater2 {
71    public static void doit() {
72        System.out.println("didit2");
73    }
74}
75
76class LoadedLater3 {
77    public static void doit() {
78        System.out.println("didit3");
79    }
80}
81
82    /********** test program **********/
83
84public class SourceNameFilterTest extends TestScaffold {
85    ReferenceType targetClass;
86    ThreadReference mainThread;
87    boolean gotEvent1 = false;
88    boolean gotEvent2 = false;
89    boolean gotEvent3 = false;
90    ClassPrepareRequest cpReq;
91    boolean shouldResume = false;
92    SourceNameFilterTest (String args[]) {
93        super(args);
94    }
95
96    public static void main(String[] args)      throws Exception {
97        new SourceNameFilterTest(args).startTests();
98    }
99    public void eventSetComplete(EventSet set) {
100        //System.out.println("jj: resuming, set = " + set);
101        if (shouldResume) {
102            set.resume();
103            shouldResume = false;
104        }
105    }
106
107    public void classPrepared(ClassPrepareEvent event) {
108        shouldResume = true;
109
110        ReferenceType rt = event.referenceType();
111        String rtname = rt.name();
112
113        if (rtname.equals("LoadedLater1")) {
114            gotEvent1 = true;
115        }
116
117        if (rtname.equals("LoadedLater2")) {
118            gotEvent2 = true;
119        }
120
121        if (rtname.equals("LoadedLater3")) {
122            gotEvent3 = true;
123        }
124
125        // debug code
126        if (false) {
127            println("Got ClassPrepareEvent for : " + rtname);
128            try {
129                println("    sourceName = " + rt.sourceName());
130            } catch (AbsentInformationException ee) {
131                failure("failure: absent info on sourceName(): " + ee);
132            }
133
134            String stratum = rt.defaultStratum();
135            println("    defaultStratum = " + stratum);
136
137            try {
138                println("    sourceNames = " + rt.sourceNames(stratum));
139            } catch (AbsentInformationException ee) {
140                failure("failure: absent info on sourceNames(): " + ee);
141            }
142            println("\nAvailable strata:  " + rt.availableStrata());
143        }
144    }
145
146
147    /********** test core **********/
148
149    protected void runTests() throws Exception {
150        /*
151         * Get to the top of main()
152         * to determine targetClass and mainThread
153         */
154        BreakpointEvent bpe = startToMain("SourceNameFilterTarg");
155        targetClass = bpe.location().declaringType();
156        boolean noSourceName = false;
157        try {
158            targetClass.sourceName();
159        } catch (AbsentInformationException ee) {
160            noSourceName = true;
161        }
162        if (noSourceName) {
163            println("-- Running with no source names");
164        } else {
165            println("-- Running with source names");
166        }
167
168        mainThread = bpe.thread();
169        EventRequestManager erm = vm().eventRequestManager();
170        addListener(this);
171
172        /*
173         * Resume the target listening for events
174         * This should cause a class prepare event for LoadedLater1
175         */
176        cpReq = erm.createClassPrepareRequest();
177        cpReq.enable();
178        resumeTo("SourceNameFilterTarg", "bkpt", "()V");
179
180        /*
181         * This should cause us to not get a class prepared for
182         * LoadedLater2 since it doesn't come from "jj"
183         */
184        cpReq.disable();
185        cpReq.addSourceNameFilter("jj");
186        cpReq.enable();
187        resumeTo("SourceNameFilterTarg", "bkpt", "()V");
188        cpReq.disable();
189
190        /*
191         * This should cause us to get a class prepare event for
192         * LoadedLater3 except in the case where -g:none
193         * was used to compile so that there is no LineNumberTable
194         * and therefore, no source name for the class.
195         */
196        cpReq = erm.createClassPrepareRequest();
197        cpReq.addSourceNameFilter("SourceNameFilterTest.java");
198        cpReq.enable();
199        resumeTo("SourceNameFilterTarg", "bkpt", "()V");
200
201        listenUntilVMDisconnect();
202
203        if (!gotEvent1) {
204            failure("failure: Did not get a class prepare request " +
205                    "for LoadedLater1");
206        }
207
208        if (gotEvent2) {
209            failure("failure: Did get a class prepare request " +
210                    "for LoadedLater2");
211        }
212
213        if (gotEvent3 && noSourceName) {
214            failure("failure: Did get a class prepare request " +
215                    "for LoadedLater3");
216        }
217        else if (!gotEvent3 && !noSourceName) {
218            failure("failure: Did not get a class prepare request " +
219                    "for LoadedLater3");
220        }
221
222        /*
223         * deal with results of test
224         * if anything has called failure("foo") testFailed will be true
225         */
226        if (!testFailed) {
227            println("SourceNameFilterTest: passed");
228        } else {
229            throw new Exception("SourceNameFilterTest: failed");
230        }
231    }
232}
233