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