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 package org.apache.harmony.jpda.tests.jdwp.Events; 20 21 import org.apache.harmony.jpda.tests.framework.jdwp.Event; 22 import org.apache.harmony.jpda.tests.framework.jdwp.EventBuilder; 23 import org.apache.harmony.jpda.tests.framework.jdwp.EventPacket; 24 import org.apache.harmony.jpda.tests.framework.jdwp.JDWPConstants; 25 import org.apache.harmony.jpda.tests.framework.jdwp.Location; 26 import org.apache.harmony.jpda.tests.framework.jdwp.ParsedEvent; 27 import org.apache.harmony.jpda.tests.framework.jdwp.ReplyPacket; 28 import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer; 29 30 import java.util.HashSet; 31 import java.util.Set; 32 33 /** 34 * Base class to test event with LocationOnly modifier. 35 */ 36 abstract class EventLocationEventTestCase extends JDWPEventTestCase { 37 38 private Set<Integer> requestIds = new HashSet<Integer>(); 39 getDebuggeeSignature()40 protected abstract String getDebuggeeSignature(); getExpectedLocationMethodName()41 protected abstract String getExpectedLocationMethodName(); createEventBuilder(EventBuilder builder)42 protected abstract void createEventBuilder(EventBuilder builder); checkEvent(ParsedEvent event)43 protected abstract void checkEvent(ParsedEvent event); 44 runEventWithLocationTest(byte eventKind)45 protected void runEventWithLocationTest(byte eventKind) { 46 synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY); 47 48 // Request event for all possible locations in the expected 49 // method. 50 requestEventForAllLocations(eventKind); 51 52 synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE); 53 54 // Wait for the event. 55 EventPacket event = debuggeeWrapper.vmMirror.receiveEvent(); 56 ParsedEvent[] parsedEvents = ParsedEvent.parseEventPacket(event); 57 58 // We expect only one event. 59 assertEquals("Invalid number of events,", 1, parsedEvents.length); 60 61 ParsedEvent parsedEvent = parsedEvents[0]; 62 63 // Check this is the event we expect. 64 assertEquals("Invalid event kind,", 65 eventKind, 66 parsedEvent.getEventKind(), 67 JDWPConstants.EventKind.getName(eventKind), 68 JDWPConstants.EventKind.getName(parsedEvent.getEventKind())); 69 70 // Check this is one event we requested. 71 int eventRequestId = parsedEvent.getRequestID(); 72 assertTrue("Unexpected event request " + eventRequestId, 73 requestIds.contains(Integer.valueOf(eventRequestId))); 74 75 // Check the event is the expected one. 76 checkEvent(parsedEvent); 77 78 // Clear all event requests. 79 clearAllEvents(eventKind); 80 81 // Resume debuggee before leaving. 82 resumeDebuggee(); 83 } 84 85 /** 86 * Since we don't know the location where the event can be reported, 87 * we send a request for all possible locations inside the method. 88 */ requestEventForAllLocations(byte eventKind)89 private void requestEventForAllLocations(byte eventKind) { 90 // Ensure we start with no request. 91 requestIds.clear(); 92 93 // Find the method where we expect the event to occur. 94 long typeId = getClassIDBySignature(getDebuggeeSignature()); 95 long methodId = getMethodID(typeId, getExpectedLocationMethodName()); 96 97 // Get its line table 98 ReplyPacket replyPacket = getLineTable(typeId, methodId); 99 long startIndex = replyPacket.getNextValueAsLong(); 100 long endIndex = replyPacket.getNextValueAsLong(); 101 logWriter.println("Method code index starts at " + startIndex + 102 " and ends at " + endIndex); 103 104 // Request event at all possible locations. We'd like to do 105 // this for each code instruction but we do not know them and 106 // do not know their size. Therefore we include any code 107 // index between start and end. 108 logWriter.println("Creating request for each possible index"); 109 for (long idx = startIndex; idx <= endIndex; ++idx) { 110 Location location = new Location(JDWPConstants.TypeTag.CLASS, 111 typeId, methodId, idx); 112 EventBuilder builder = new EventBuilder(eventKind, 113 JDWPConstants.SuspendPolicy.ALL); 114 createEventBuilder(builder); 115 setEvent(builder, location); 116 117 } 118 logWriter.println("Created " + requestIds.size() + " requests"); 119 } 120 setEvent(EventBuilder builder, Location location)121 private void setEvent(EventBuilder builder, Location location) { 122 builder.setLocationOnly(location); 123 Event event = builder.build(); 124 ReplyPacket reply = debuggeeWrapper.vmMirror.setEvent(event); 125 int requestId = reply.getNextValueAsInt(); 126 logWriter.println("=> New request " + requestId); 127 requestIds.add(Integer.valueOf(requestId)); 128 } 129 clearAllEvents(byte eventKind)130 private void clearAllEvents(byte eventKind) { 131 logWriter.println("Clear all field requests"); 132 for (Integer requestId : requestIds) { 133 clearEvent(eventKind, requestId.intValue()); 134 } 135 requestIds.clear(); 136 } 137 clearEvent(byte fieldEventKind, int requestId)138 private void clearEvent(byte fieldEventKind, int requestId) { 139 logWriter.println("=> Clear request " + requestId); 140 debuggeeWrapper.vmMirror.clearEvent(fieldEventKind, requestId); 141 } 142 } 143