• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.share;
27 
28 import java.io.DataInputStream;
29 import java.io.DataOutputStream;
30 import java.io.EOFException;
31 import java.io.IOException;
32 import java.net.InetAddress;
33 import java.net.InetSocketAddress;
34 import java.net.Socket;
35 import java.net.ServerSocket;
36 import java.net.UnknownHostException;
37 
38 import org.apache.harmony.jpda.tests.framework.DebuggeeSynchronizer;
39 import org.apache.harmony.jpda.tests.framework.LogWriter;
40 import org.apache.harmony.jpda.tests.framework.TestErrorException;
41 import org.apache.harmony.jpda.tests.framework.TestOptions;
42 
43 /**
44  * This class implements <code>DebuggeeSynchronizer</code> interface using
45  * TCP/IP sockets. All operations can be timed out according to default timeout.
46  */
47 public class JPDADebuggeeSynchronizer implements DebuggeeSynchronizer {
48 
49     public final static String SGNL_READY = "ready";
50 
51     public final static String SGNL_CONTINUE = "continue";
52 
53     protected Socket clientSocket = null;
54 
55     protected ServerSocket serverSocket = null;
56 
57     protected DataOutputStream out;
58 
59     protected DataInputStream in;
60 
61     protected TestOptions settings;
62 
63     protected LogWriter logWriter;
64 
65     /**
66      * A constructor that initializes an instance of the class with specified
67      * <code>LogWriter</code> and <code>TestOptions</code>.
68      *
69      * @param logWriter
70      *            The instance of implementation of LogWriter.
71      * @param settings
72      *            Instance of test options.
73      */
JPDADebuggeeSynchronizer(LogWriter logWriter, TestOptions settings)74     public JPDADebuggeeSynchronizer(LogWriter logWriter, TestOptions settings) {
75         super();
76         this.logWriter = logWriter;
77         this.settings = settings;
78     }
79 
80     /**
81      * Sends specified message to synchronization channel.
82      *
83      * @param message
84      *            a message to be sent.
85      */
86     @Override
sendMessage(String message)87     public synchronized void sendMessage(String message) {
88         try {
89             out.writeUTF(message);
90             out.flush();
91             logWriter.println("[SYNC] Message sent: " + message);
92         } catch (IOException e) {
93             throw new TestErrorException(e);
94         }
95     }
96 
97     /**
98      * Receives message from synchronization channel and compares it with the
99      * expected <code>message</code>.
100      *
101      * @param message
102      *            expected message.
103      * @return <code>true</code> if received string is equals to
104      *         <code>message</code> otherwise - <code>false</code>.
105      *
106      */
107     @Override
receiveMessage(String message)108     public synchronized boolean receiveMessage(String message) {
109         String msg;
110         try {
111             logWriter.println("[SYNC] Waiting for message: " + message);
112             msg = in.readUTF();
113             logWriter.println("[SYNC] Received message: " + msg);
114         } catch (EOFException e) {
115             return false;
116         } catch (IOException e) {
117             logWriter.printError(e);
118             return false;
119         }
120         return message.equalsIgnoreCase(msg);
121     }
122 
123     /**
124      * Receives message from synchronization channel.
125      *
126      * @return received string or null if connection was closed.
127      */
128     @Override
receiveMessage()129     public synchronized String receiveMessage() {
130         String msg;
131         try {
132             logWriter.println("[SYNC] Waiting for any messsage");
133             msg = in.readUTF();
134             logWriter.println("[SYNC] Received message: " + msg);
135         } catch (EOFException e) {
136             return null;
137         } catch (IOException e) {
138             throw new TestErrorException(e);
139         }
140         return msg;
141     }
142 
143     /**
144      * Receives message from synchronization channel without Exception.
145      *
146      * @return received string
147      */
receiveMessageWithoutException(String invoker)148     public synchronized String receiveMessageWithoutException(String invoker) {
149         String msg;
150         try {
151             logWriter.println("[SYNC] Waiting for any message");
152             msg = in.readUTF();
153             logWriter.println("[SYNC] Received message: " + msg);
154         } catch (Throwable thrown) {
155             if (invoker != null) {
156                 logWriter.println("#### receiveMessageWithoutException: Exception occurred:");
157                 logWriter.println("#### " + thrown);
158                 logWriter.println("#### Invoker = " + invoker);
159             }
160             msg = "" + thrown;
161         }
162         return msg;
163     }
164 
165     /**
166      * Returns socket address for connecting to the server.
167      *
168      * If <code>serverAddress.getPort()</code> returns 0 (i.e.,
169      * <code>org.apache.harmony.jpda.tests.framework.TestOptions.DEFAULT_SYNC_PORT</code>),
170      * a port will automatically be chosen by the OS when the server is bound to a socket.
171      *
172      * @return socket address
173      */
getSyncServerAddress()174     public InetSocketAddress getSyncServerAddress() {
175         // Use the LOOPBACK directly instead of doing a DNS lookup.
176         int port = settings.getSyncPortNumber();
177         try {
178             // Use IPv4 to ensure we do not depend on IPv6 to run these tests.
179             // TODO(25178637): Use InetAddress.getLoopbackAddress() instead.
180             return new InetSocketAddress(
181                 InetAddress.getByAddress(new byte[] { 127, 0, 0, 1 }), port);
182         } catch (UnknownHostException e) {
183             throw new TestErrorException(
184                     "[SYNC] Exception in binding for socket sync connection", e);
185         }
186     }
187 
188     /**
189      * Binds server to listen socket port.
190      *
191      * If <code>serverAddress.getPort()</code> returns 0 (i.e.,
192      * <code>org.apache.harmony.jpda.tests.framework.TestOptions.DEFAULT_SYNC_PORT</code>),
193      * the OS will choose a port automatically for this server socket.
194      *
195      * @return port number
196      */
bindServer()197     public synchronized int bindServer() {
198         InetSocketAddress serverAddress = getSyncServerAddress();
199         try {
200             logWriter.println("[SYNC] Binding socket on: " + serverAddress);
201             serverSocket = new ServerSocket(serverAddress.getPort(), 0, serverAddress.getAddress());
202             int localPort = serverSocket.getLocalPort();
203             logWriter.println("[SYNC] Bound socket on: " + serverAddress
204                     + " (local port: " + localPort + ")" );
205             return localPort;
206         } catch (IOException e) {
207             throw new TestErrorException(
208                     "[SYNC] Exception in binding for socket sync connection", e);
209         }
210     }
211 
212     /**
213      * Accepts sync connection form server side.
214      */
startServer()215     public synchronized void startServer() {
216         long timeout = settings.getTimeout();
217         try {
218             serverSocket.setSoTimeout((int) timeout);
219             logWriter.println("[SYNC] Accepting socket connection");
220             clientSocket = serverSocket.accept();
221             logWriter.println("[SYNC] Accepted socket connection");
222 
223             clientSocket.setSoTimeout((int) timeout);
224             out = new DataOutputStream(clientSocket.getOutputStream());
225             in = new DataInputStream(clientSocket.getInputStream());
226         } catch (IOException e) {
227             throw new TestErrorException(
228                     "[SYNC] Exception in accepting socket sync connection", e);
229         }
230     }
231 
232     /**
233      * Attaches for sync connection from client side..
234      */
startClient()235     public synchronized void startClient() {
236         long timeout = settings.getTimeout();
237         InetSocketAddress serverAddress = getSyncServerAddress();
238         try {
239             logWriter.println("[SYNC] Attaching socket to: " + serverAddress);
240             clientSocket = new Socket(serverAddress.getAddress(), serverAddress.getPort());
241             logWriter.println("[SYNC] Attached socket");
242 
243             clientSocket.setSoTimeout((int) timeout);
244             out = new DataOutputStream(clientSocket.getOutputStream());
245             in = new DataInputStream(clientSocket.getInputStream());
246         } catch (IOException e) {
247             throw new TestErrorException(
248                     "[SYNC] Exception in attaching for socket sync connection", e);
249         }
250     }
251 
252     /**
253      * Stops synchronization work. It ignores <code>IOException</code> but
254      * prints a message.
255      */
stop()256     public void stop() {
257         try {
258             if (out != null)
259                 out.close();
260             if (in != null)
261                 in.close();
262             if (clientSocket != null)
263                 clientSocket.close();
264             if (serverSocket != null)
265                 serverSocket.close();
266         } catch (IOException e) {
267             logWriter.println
268                     ("[SYNC] Ignoring exception in closing socket sync connection: " + e);
269         }
270         logWriter.println("[SYNC] Closed socket");
271     }
272 }
273