File: signature001.java

package info (click to toggle)
openjdk-25 25.0.1%2B8-1~deb13u1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 825,408 kB
  • sloc: java: 5,585,680; cpp: 1,333,948; xml: 1,321,242; ansic: 488,034; asm: 404,003; objc: 21,088; sh: 15,106; javascript: 13,265; python: 8,319; makefile: 2,518; perl: 357; awk: 351; pascal: 103; exp: 83; sed: 72; jsp: 24
file content (386 lines) | stat: -rw-r--r-- 16,321 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
/*
 * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package nsk.jdi.ClassUnloadEvent.classSignature;

import com.sun.jdi.*;
import com.sun.jdi.event.*;
import com.sun.jdi.request.*;

import java.io.*;
import java.util.List;
import java.util.Iterator;

import nsk.share.*;
import nsk.share.jpda.*;
import nsk.share.jdi.*;


// This class is the debugger in the test

// NOTE: Test does not check array class because of difficulty of
//       providing reliable technique for unloading such class.
//       So all these testcases are commented in the test.

public class signature001 {
    static final int PASSED = 0;
    static final int FAILED = 2;
    static final int JCK_STATUS_BASE = 95;

    static final int TIMEOUT_DELTA = 1000; // milliseconds

    static final String COMMAND_READY    = "ready";
    static final String COMMAND_QUIT     = "quit";
    static final String COMMAND_LOAD     = "load";
    static final String COMMAND_LOADED   = "loaded";
    static final String COMMAND_UNLOAD   = "unload";
    static final String COMMAND_UNLOADED = "unloaded";

    static final String PREFIX = "nsk.jdi.ClassUnloadEvent.classSignature";
    static final String DEBUGGEE_NAME     = PREFIX + ".signature001a";
    static final String CHECKED_CLASS     = PREFIX + ".signature001c";
    static final String CHECKED_INTERFACE = PREFIX + ".signature001b";
    static final String CHECKED_ARRAY     = PREFIX + ".signature001c[]";
    static final String KLASSLOADER       = ClassUnloader.INTERNAL_CLASS_LOADER_NAME;

    static private Debugee debuggee;
    static private VirtualMachine vm;
    static private IOPipe pipe;
    static private Log log;
    static private ArgumentHandler argHandler;
    static private EventSet eventSet;

    static private ClassUnloadRequest checkedRequest;

    static private long eventTimeout;
    static private boolean testFailed;
    static private boolean eventsReceived;
    static private boolean eventForClass, eventForInterface, eventForArray;

    public static void main (String argv[]) {
         int result = run(argv,System.out);
         if (result != 0) {
             throw new RuntimeException("TEST FAILED with result " + result);
         }
    }

    public static int run(final String args[], final PrintStream out) {

        testFailed = false;
        eventsReceived = false;

        argHandler = new ArgumentHandler(args);
        log = new Log(out, argHandler);
        eventTimeout = argHandler.getWaitTime() * 60 * 1000; // milliseconds

        // launch debugee

        Binder binder = new Binder(argHandler, log);
        log.display("Connecting to debuggee");
        debuggee = binder.bindToDebugee(DEBUGGEE_NAME);
        debuggee.redirectStderr(log, "signature001a >");

        pipe = debuggee.createIOPipe();
        vm = debuggee.VM();

        // create request and wait for ClassUnloadEvent

        try {

            // resume debugee and wait for it becomes ready

            log.display("Resuming debuggee");
            debuggee.resume();

            log.display("Waiting for command: " + COMMAND_READY);
            String command = pipe.readln();
            if (command == null || !command.equals(COMMAND_READY)) {
                throw new Failure("TEST BUG: unexpected debuggee's command: " + command);
            }

            // get mirror of debugee class

            ReferenceType rType;
            if ((rType = debuggee.classByName(DEBUGGEE_NAME)) == null) {
                throw new Failure("TEST BUG: cannot find debuggee's class " + DEBUGGEE_NAME);
            }

            // send command to load checked class and waits for a confirmation

            pipe.println(COMMAND_LOAD);
            log.display("Waiting for checked class is loaded");
            command = pipe.readln();

            if (command == null || !command.equals(COMMAND_LOADED)) {
                throw new Failure("TEST BUG: unexpected debuggee's command: " + command);
            }

            // checked class has been loaded!
            log.display("Checked classes have been loaded in debuggee!");

            // create request for class unload event

            log.display("Creating request for ClassUnloadEvent");
            EventRequestManager erManager = vm.eventRequestManager();
            if ((checkedRequest = erManager.createClassUnloadRequest()) == null) {
                throw new Failure("TEST BUG: unable to create ClassUnloadRequest");
            } else {
                log.display("ClassUnloadRequest created");
            }
//            checkedRequest.addClassFilter("nsk.jdi.ClassUnloadEvent.classSignature.*");

            log.display("Enabling event request");
            checkedRequest.enable();

            List unloadRequests = vm.eventRequestManager().classUnloadRequests();
            if (unloadRequests == null) {
                throw new Failure("TEST_BUG: ClassUnloadRequest is not created");
            }

            // force checked classes to be unloaded from debuggee

            // turn off pipe pinging
            pipe.setPingTimeout(0);

            log.display("Waiting for checked class is unloaded");
            pipe.println(COMMAND_UNLOAD);
            command = pipe.readln();

            // end test if checked classes have not been actually unloaded or error occurs

            if (command != null && command.equals(COMMAND_LOADED)) {
//                throw new Failure("TEST INCOMPLETE: unable to unload classes");
                throw new Warning("TEST INCOMPLETE: unable to unload classes");
            }

            if (command == null || !command.equals(COMMAND_UNLOADED)) {
                throw new Failure("TEST BUG: unexpected debuggee's command: " + command);
            }

            // checked classes have been unloaded
            log.display("Checked classes forced to be unloaded from debuggee!");

            // waiting for event untill timeout exceeds
            log.display("Waiting for ClassUnloadEvent for checked class");
            long timeToFinish = System.currentTimeMillis() + eventTimeout;
            while (!eventsReceived && System.currentTimeMillis() < timeToFinish) {

                // get next event set
                eventSet = null;
                try {
                    eventSet = vm.eventQueue().remove(TIMEOUT_DELTA);
                } catch (Exception e) {
                    throw new Failure("TEST INCOMPLETE: Unexpected exception while getting event: " + e);
                }
                if (eventSet == null)
                    continue;

                // handle each event from the event set
                EventIterator eventIterator = eventSet.eventIterator();
                while (eventIterator.hasNext()) {

                    Event event = eventIterator.nextEvent();
                    log.display("\nEvent received:\n  " + event);

                    // handle ClassUnloadEvent
                    if (event instanceof ClassUnloadEvent) {

                        ClassUnloadEvent castedEvent = (ClassUnloadEvent)event;
                        log.display("Received event is ClassUnloadEvent:\n" + castedEvent);

                        // check that received event is for checked request
                        EventRequest eventRequest = castedEvent.request();
                        if (!(checkedRequest.equals(eventRequest))) {
                            log.complain("FAILURE 1: eventRequest is not equal to checked request");
                            testFailed = true;
                        }

                        // check that received event is for checked VM
                        VirtualMachine eventMachine = castedEvent.virtualMachine();
                        if (!(vm.equals(eventMachine))) {
                            log.complain("FAILURE 2: eventVirtualMachine is not equal to checked vm");
                            testFailed = true;
                        }

                        // test method ClassUnloadEvent.
                        String refSignature = castedEvent.classSignature();
                        log.display("ClassUnloadEvent is received for " + refSignature);

                        // check that received event is for checked class
                        if ((refSignature == null) || (refSignature.equals(""))) {

                            log.complain("FAILURE 3: ClassUnloadEvent.classSignature() returns null or empty string");
                            testFailed = true;

                        } else if (refSignature.equals("L" + CHECKED_CLASS.replace('.','/') + ";")) {

                            // mark that ClassUnloadEvent for checked class received
                            eventForClass = true;
                            log.display("Expected ClassUnloadEvent for checked class received!");

/*
                            // check that checked class is not included in debuggee's list of loaded classes
                            List loadedClasses = vm.classesByName(CHECKED_CLASS);
                            if (loadedClasses != null) {
                                log.complain("FAILURE 4: Class " + CHECKED_CLASS +
                                    " is not unloaded while ClassUnloadEvent is received");
                                testFailed = true;
                            }
*/

                        } else if (refSignature.equals("L" + CHECKED_INTERFACE.replace('.','/') + ";")) {

                            // mark that ClassUnloadEvent for checked interface received
                            eventForInterface = true;
                            log.display("Expected ClassUnloadEvent for checked class received!");

/*
                            // check that checked interface is not included in debuggee's list of loaded classes
                            List loadedClasses = vm.classesByName(CHECKED_INTERFACE);
                            if (loadedClasses != null) {
                                log.complain("FAILURE 4: Class " + CHECKED_INTERFACE +
                                    " is not unloaded while ClassUnloadEvent is received");
                                testFailed = true;
                            }
*/

/*
                        } else if (refSignature.equals("L" + CHECKED_ARRAY.replace('.','/') + ";")) {

                            // mark that ClassUnloadEvent for checked array class received
                            eventForArray = true;
                            log.display("Expected ClassUnloadEvent for checked array class received!");

                            // check that checked array class is not included in debuggee's list of loaded classes
                            List loadedClasses = vm.classesByName(CHECKED_ARRAY);
                            if (loadedClasses != null) {
                                log.complain("FAILURE 4: Class " + CHECKED_ARRAY +
                                    " is not unloaded while ClassUnloadEvent is received");
                                testFailed = true;
                            }

*/
                        } else {

                            // ClassUnloadEvent for another class received; just display it
                            log.display("ClassUnloadEvent was received for loaded class " + refSignature);
                        }
                    }

                    // ignore all other events
                 }

                 eventSet.resume();
                 eventsReceived = eventForClass && eventForInterface /* && eventForArray */;
            }

            log.display("");

            // check that expected event has been received for checked class
            log.display("Searching checked class in debuggee");
            rType = debuggee.classByName(CHECKED_CLASS);
            if (rType != null) {
                if (eventForClass) {
                    log.complain("FAILURE 4: ClassUnloadEvent is received for class to be unloaded\n"
                               + "           but class still presents in the list of all debuggee classes");
                    testFailed = true;
                } else {
                    log.display("WARNING: Unable to test ClassUnloadEvent because checked class\n"
                              + "         was not actually unloaded");
                }
            } else {
                if (!eventForClass) {
                    log.complain("FAILURE 5: ClassUnloadEvent was not received for class to be unloaded\n"
                               + "           but class no longe presents in the list of all debuggee classes ");
                    testFailed = true;
                }
            }

            // check that expected event has been received for checked interface
            log.display("Searching checked interface in debuggee");
            rType = debuggee.classByName(CHECKED_INTERFACE);
            if (rType != null) {
                if (eventForInterface) {
                    log.complain("FAILURE 6: ClassUnloadEvent is received for interface to be unloaded\n"
                               + "           but class still presents in the list of all debuggee classes");
                    testFailed = true;
                } else {
                    log.display("WARNING: Unable to test ClassUnloadEvent because checked interface\n"
                              + "         was not actually unloaded");
                }
            } else {
                if (!eventForInterface) {
                    log.complain("FAILURE 7: ClassUnloadEvent was not received for interface to be unloaded\n"
                               + "           but class no longe presents in the list of all debuggee classes ");
                    testFailed = true;
                }
            }

        } catch (Warning e) {
            log.display("WARNING: " + e.getMessage());
        } catch (Failure e) {
            log.complain("TEST FAILURE: " + e.getMessage());
            testFailed = true;
        } catch (Exception e) {
            log.complain("Unexpected exception: " + e);
            e.printStackTrace(out);
            testFailed = true;
        } finally {

            // disable event request to prevent appearance of further events
            if (checkedRequest != null) {
                log.display("Disabling event request");
                checkedRequest.disable();
            }

            // force debugee to exit
            log.display("Sending command: " + COMMAND_QUIT);
            pipe.println(COMMAND_QUIT);

            // wait for debugee terminates and check its exit code
            log.display("Waiting for debuggee terminating");
            int debuggeeStatus = debuggee.endDebugee();
            if (debuggeeStatus == PASSED + JCK_STATUS_BASE) {
                log.display("Debuggee PASSED with exit code: " + debuggeeStatus);
            } else {
                log.complain("Debuggee FAILED with exit code: " + debuggeeStatus);
                testFailed = true;
            }

        }

        // check test results
        if (testFailed) {
            log.complain("TEST FAILED");
            return FAILED;
        }
        return PASSED;
    }

    static class Warning extends Failure {
        Warning(String msg) {
            super(msg);
        }
    }

}