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 Vitaly A. Provodin 21 */ 22 23 /** 24 * Created on 29.01.2005 25 */ 26 package org.apache.harmony.jpda.tests.jdwp.share; 27 28 import java.io.IOException; 29 30 import org.apache.harmony.jpda.tests.framework.LogWriter; 31 import org.apache.harmony.jpda.tests.framework.TestErrorException; 32 import org.apache.harmony.jpda.tests.framework.jdwp.TransportWrapper; 33 import org.apache.harmony.jpda.tests.share.JPDATestOptions; 34 35 /** 36 * This class provides DebuggeeWrapper implementation based on JUnit framework. 37 * Debuggee is always launched on local machine and attaches to debugger. 38 */ 39 public class JDWPUnitDebuggeeWrapper extends JDWPUnitDebuggeeProcessWrapper { 40 41 /** 42 * Auxiliary options passed to the target VM on its launch. 43 */ 44 public String savedVMOptions = null; 45 46 /** 47 * Wrapper around JDWP transport connection. 48 */ 49 protected TransportWrapper transport; 50 51 /** 52 * JDWP transport address. 53 */ 54 protected String address; 55 56 /** 57 * Is this a "listen" JDWP connection? (If false, it is a an "attach" connection.) 58 */ 59 boolean isListenConnection; 60 61 62 /** 63 * Creates new instance with given data. 64 * 65 * @param settings 66 * test run options 67 * @param logWriter 68 * where to print log messages 69 */ JDWPUnitDebuggeeWrapper(JPDATestOptions settings, LogWriter logWriter)70 public JDWPUnitDebuggeeWrapper(JPDATestOptions settings, LogWriter logWriter) { 71 super(settings, logWriter); 72 } 73 74 /** 75 * Set up server side JDWP connection before launching the debuggee. 76 */ setUpConnection()77 public void setUpConnection() { 78 isListenConnection = settings.isListenConnectorKind(); 79 transport = createTransportWrapper(); 80 address = settings.getTransportAddress(); 81 82 if (isListenConnection) { 83 logWriter.println("Start listening on: " + address); 84 try { 85 address = transport.startListening(address); 86 } catch (IOException e) { 87 throw new TestErrorException(e); 88 } 89 logWriter.println("Listening on: " + address); 90 } else { 91 logWriter.println("Attach to: " + address); 92 } 93 } 94 95 /** 96 * Launches new debuggee process according to test run options and 97 * establishes JDWP connection. 98 */ 99 @Override start()100 public void start() { 101 String cmdLine = settings.getDebuggeeJavaPath() + " -cp \"" 102 + settings.getDebuggeeClassPath() + "\" " 103 + settings.getDebuggeeAgentArgument() 104 + settings.getDebuggeeAgentName() + "=" 105 + settings.getDebuggeeAgentOptions(address, isListenConnection) 106 + " " + settings.getDebuggeeVMExtraOptions() + " " 107 + (savedVMOptions != null ? savedVMOptions : "") + " " 108 + settings.getDebuggeeClassName(); 109 110 logWriter.println("Launch: " + cmdLine); 111 112 try { 113 launchProcessAndRedirectors(cmdLine); 114 logWriter.println("Launched debuggee process"); 115 openConnection(); 116 logWriter.println("Established transport connection"); 117 } catch (Exception e) { 118 throw new TestErrorException(e); 119 } 120 } 121 122 /** 123 * Closes all connections, stops redirectors, and waits for debuggee process 124 * exit for default timeout. 125 */ 126 @Override stop()127 public void stop() { 128 disposeConnection(); 129 130 try { 131 finishProcessAndRedirectors(); 132 } finally { 133 // If the test has failed (e.g. a TestErrorException is 134 // thrown), make sure that the transport server socket (if 135 // any) is closed before leaving, as we may otherwise 136 // block the transport port for subsequent JDWP tests. 137 tearDownConnection(); 138 } 139 } 140 141 /** 142 * Opens connection with debuggee. 143 */ openConnection()144 protected void openConnection() { 145 try { 146 if (settings.isListenConnectorKind()) { 147 logWriter.println("Accepting JDWP connection"); 148 transport.accept(settings.getTimeout(), settings.getTimeout()); 149 } else { 150 String address = settings.getTransportAddress(); 151 logWriter.println("Attaching for JDWP connection"); 152 transport.attach(address, settings.getTimeout(), settings.getTimeout()); 153 } 154 setConnection(transport); 155 } catch (IOException e) { 156 logWriter.printError(e); 157 throw new TestErrorException(e); 158 } 159 } 160 161 /** 162 * Disposes JDWP connection stored in VmMirror. 163 */ disposeConnection()164 protected void disposeConnection() { 165 if (vmMirror != null) { 166 try { 167 vmMirror.dispose(); 168 } catch (Exception e) { 169 logWriter.println("Ignoring exception in disposing debuggee VM: " + e); 170 } 171 } 172 } 173 174 /** 175 * Closes JDWP connection stored in VmMirror. 176 */ closeConnection()177 protected void closeConnection() { 178 if (vmMirror != null) { 179 try { 180 vmMirror.closeConnection(); 181 } catch (IOException e) { 182 logWriter.println("Ignoring exception in closing connection: " + e); 183 } 184 } 185 } 186 187 /** 188 * Closes JDWP connection and for listen connectors, stops listening to transport. 189 */ tearDownConnection()190 private void tearDownConnection() { 191 closeConnection(); 192 if (settings.isListenConnectorKind()) { 193 try { 194 transport.stopListening(); 195 } catch (IOException e) { 196 logWriter.println("IOException in transport listening stopping: " + e); 197 } 198 } 199 } 200 } 201