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    @Override
48    protected String getDebuggeeClassName() {
49        return ClassUnloadDebuggee.class.getName();
50    }
51
52    /**
53     * This testcase is for CLASS_UNLOAD event.
54     */
55    public void testClassUnloadEvent() {
56        logWriter.println("==> testClassUnloadEvent started");
57
58        synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY);
59
60        ReplyPacket reply = null;
61        int foundClasses = 0;
62
63        // commented out because it may leave JNI references to the tested class,
64        //   which will prevent it from garbage collecting and unloading
65/*
66        // check that tested class is loaded before unloading it
67        logWriter.println("=> Find tested class by signature: " + TESTED_CLASS_SIGNATURE);
68        reply = debuggeeWrapper.vmMirror.getClassBySignature(TESTED_CLASS_SIGNATURE);
69        foundClasses = reply.getNextValueAsInt();
70        logWriter.println("=> Found clases: " + foundClasses);
71
72        if (foundClasses <= 0) {
73        	fail("Tested class was not found: count=" + foundClasses);
74        }
75*/
76
77        logWriter.println("=> Set request for ClasUnload event: " + TESTED_CLASS_NAME);
78        reply = debuggeeWrapper.vmMirror.setClassUnload(TESTED_CLASS_NAME);
79        checkReplyPacket(reply, "Set CLASS_UNLOAD event");
80        int requestID = reply.getNextValueAsInt();
81        logWriter.println("=> Created requestID for ClassUnload event: " + requestID);
82
83        logWriter.println("=> Release debuggee");
84        synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE);
85
86        logWriter.println("=> Wait for class unload event");
87		EventPacket event = null;
88        try {
89			event = debuggeeWrapper.vmMirror.receiveEvent(settings.getTimeout());
90	        logWriter.println("=> Event received");
91		} catch (TimeoutException e) {
92	        logWriter.println("=> ClassUnload event was not received (class might be not really unloaded)");
93		} catch (Exception e) {
94	        logWriter.println("=> Exception during receiving ClassUnload event: " + e);
95	        throw new TestErrorException(e);
96		}
97
98        logWriter.println("=> Clear request for ClassUnload event");
99        reply = debuggeeWrapper.vmMirror.clearEvent(JDWPConstants.EventKind.CLASS_UNLOAD, requestID);
100
101        logWriter.println("=> Try to find tested class by signature: " + TESTED_CLASS_SIGNATURE);
102        reply = debuggeeWrapper.vmMirror.getClassBySignature(TESTED_CLASS_SIGNATURE);
103        foundClasses = reply.getNextValueAsInt();
104        logWriter.println("=> Found clases: " + foundClasses);
105
106		logWriter.println("=> Wait for class status message from debuggee");
107        String status = synchronizer.receiveMessage();
108        logWriter.println("=> Debuggee reported class status: " + status);
109
110        if (event != null) {
111			// check event data
112			ParsedEvent[] parsedEvents = ParsedEvent.parseEventPacket(event);
113
114	        assertEquals("Invalid number of events,", 1, parsedEvents.length);
115	        assertEquals("Invalid event kind,", JDWPConstants.EventKind.CLASS_UNLOAD
116	        		, parsedEvents[0].getEventKind()
117	                , JDWPConstants.EventKind.getName(JDWPConstants.EventKind.CLASS_UNLOAD)
118	                , JDWPConstants.EventKind.getName(parsedEvents[0].getEventKind()));
119	        assertEquals("Invalid event request,", requestID
120	        		, parsedEvents[0].getRequestID());
121
122	        // check that unloaded class was not found after event
123	        if (foundClasses > 0) {
124	        	fail("Tested class was found after ClasUnload event: count=" + foundClasses);
125	        }
126
127	        logWriter.println("=> Resume debuggee on event");
128	        debuggeeWrapper.resume();
129		} else {
130	        // check if tested class not found without event
131	        if (foundClasses <= 0) {
132	        	fail("No ClassUnload event, but tested class not found: count=" + foundClasses);
133	        }
134
135	        // check if debuggee reported tested class unloaded without event
136	        if ("UNLOADED".equals(status)) {
137	        	fail("No ClassUnload event, but tested class was unloaded");
138	        }
139		}
140
141        logWriter.println("=> Release debuggee");
142        synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE);
143        logWriter.println("==> testClassUnloadEvent ended");
144    }
145}
146