1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements.  See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *
15 *  See the License for the specific language governing permissions and
16 *  limitations under the License.
17 */
18
19/**
20 * @author Aleksander V. Budniy
21 */
22
23/**
24 * Created on 06.04.2005
25 */
26package org.apache.harmony.jpda.tests.jdwp.Events;
27
28import org.apache.harmony.jpda.tests.framework.TestErrorException;
29import org.apache.harmony.jpda.tests.framework.jdwp.EventPacket;
30import org.apache.harmony.jpda.tests.framework.jdwp.JDWPConstants;
31import org.apache.harmony.jpda.tests.framework.jdwp.ParsedEvent;
32import org.apache.harmony.jpda.tests.framework.jdwp.ReplyPacket;
33import org.apache.harmony.jpda.tests.framework.jdwp.exceptions.TimeoutException;
34import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer;
35
36/**
37 * JDWP Unit test for CLASS_UNLOAD event.
38 */
39public class ClassUnloadTest extends JDWPEventTestCase {
40
41	public static final String TESTED_CLASS_NAME =
42		"org.apache.harmony.jpda.tests.jdwp.Events.ClassUnloadTestedClass";
43
44	public static final String TESTED_CLASS_SIGNATURE =
45		"L" + TESTED_CLASS_NAME.replace('.', '/') + ";";
46
47    protected String getDebuggeeClassName() {
48        return ClassUnloadDebuggee.class.getName();
49    }
50
51    /**
52     * This testcase is for CLASS_UNLOAD event.
53     */
54    public void testClassUnloadEvent() {
55        logWriter.println("==> testClassUnloadEvent started");
56
57        synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY);
58
59        ReplyPacket reply = null;
60        int foundClasses = 0;
61
62        // commented out because it may leave JNI references to the tested class,
63        //   which will prevent it from garbage collecting and unloading
64/*
65        // check that tested class is loaded before unloading it
66        logWriter.println("=> Find tested class by signature: " + TESTED_CLASS_SIGNATURE);
67        reply = debuggeeWrapper.vmMirror.getClassBySignature(TESTED_CLASS_SIGNATURE);
68        foundClasses = reply.getNextValueAsInt();
69        logWriter.println("=> Found clases: " + foundClasses);
70
71        if (foundClasses <= 0) {
72        	fail("Tested class was not found: count=" + foundClasses);
73        }
74*/
75
76        logWriter.println("=> Set request for ClasUnload event: " + TESTED_CLASS_NAME);
77        reply = debuggeeWrapper.vmMirror.setClassUnload(TESTED_CLASS_NAME);
78        checkReplyPacket(reply, "Set CLASS_UNLOAD event");
79        int requestID = reply.getNextValueAsInt();
80        logWriter.println("=> Created requestID for ClassUnload event: " + requestID);
81
82        logWriter.println("=> Release debuggee");
83        synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE);
84
85        logWriter.println("=> Wait for class unload event");
86		EventPacket event = null;
87        try {
88			event = debuggeeWrapper.vmMirror.receiveEvent(settings.getTimeout());
89	        logWriter.println("=> Event received");
90		} catch (TimeoutException e) {
91	        logWriter.println("=> ClassUnload event was not received (class might be not really unloaded)");
92		} catch (Exception e) {
93	        logWriter.println("=> Exception during receiving ClassUnload event: " + e);
94	        throw new TestErrorException(e);
95		}
96
97        logWriter.println("=> Clear request for ClassUnload event");
98        reply = debuggeeWrapper.vmMirror.clearEvent(JDWPConstants.EventKind.CLASS_UNLOAD, requestID);
99
100        logWriter.println("=> Try to find tested class by signature: " + TESTED_CLASS_SIGNATURE);
101        reply = debuggeeWrapper.vmMirror.getClassBySignature(TESTED_CLASS_SIGNATURE);
102        foundClasses = reply.getNextValueAsInt();
103        logWriter.println("=> Found clases: " + foundClasses);
104
105		logWriter.println("=> Wait for class status message from debuggee");
106        String status = synchronizer.receiveMessage();
107        logWriter.println("=> Debuggee reported class status: " + status);
108
109        if (event != null) {
110			// check event data
111			ParsedEvent[] parsedEvents = ParsedEvent.parseEventPacket(event);
112
113	        assertEquals("Invalid number of events,", 1, parsedEvents.length);
114	        assertEquals("Invalid event kind,", JDWPConstants.EventKind.CLASS_UNLOAD
115	        		, parsedEvents[0].getEventKind()
116	                , JDWPConstants.EventKind.getName(JDWPConstants.EventKind.CLASS_UNLOAD)
117	                , JDWPConstants.EventKind.getName(parsedEvents[0].getEventKind()));
118	        assertEquals("Invalid event request,", requestID
119	        		, parsedEvents[0].getRequestID());
120
121	        // check that unloaded class was not found after event
122	        if (foundClasses > 0) {
123	        	fail("Tested class was found after ClasUnload event: count=" + foundClasses);
124	        }
125
126	        logWriter.println("=> Resume debuggee on event");
127	        debuggeeWrapper.resume();
128		} else {
129	        // check if tested class not found without event
130	        if (foundClasses <= 0) {
131	        	fail("No ClassUnload event, but tested class not found: count=" + foundClasses);
132	        }
133
134	        // check if debuggee reported tested class unloaded without event
135	        if ("UNLOADED".equals(status)) {
136	        	fail("No ClassUnload event, but tested class was unloaded");
137	        }
138		}
139
140        logWriter.println("=> Release debuggee");
141        synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE);
142        logWriter.println("==> testClassUnloadEvent ended");
143    }
144}
145