3333import java .net .HttpURLConnection ;
3434import java .net .InetAddress ;
3535import java .net .MalformedURLException ;
36+ import java .net .ServerSocket ;
3637import java .net .URI ;
3738import java .net .URL ;
3839import java .util .Collections ;
4243import java .util .Set ;
4344import java .util .concurrent .CountDownLatch ;
4445import java .util .concurrent .atomic .AtomicBoolean ;
46+ import java .util .concurrent .atomic .AtomicInteger ;
4547import java .util .concurrent .atomic .AtomicReference ;
4648
4749import static org .junit .Assert .assertEquals ;
6466 */
6567public class MultiEngineTest extends EnginesGCedTest {
6668
67- private static final int PORT = 9229 ;
68-
6969 private static final String [] INITIAL_MESSAGES = {
7070 "{\" id\" :1,\" method\" :\" Runtime.enable\" }" ,
7171 "{\" id\" :2,\" method\" :\" Debugger.enable\" }" ,
@@ -121,28 +121,29 @@ public void testMultipleEnginesSerial() {
121121 isUp [i ] = new CountDownLatch (1 );
122122 }
123123 AtomicReference <Throwable > error = new AtomicReference <>();
124- verifySerialDebug (isUp , error );
124+ AtomicInteger port = new AtomicInteger (0 );
125+ verifySerialDebug (port , isUp , error );
125126 ByteArrayOutputStream out = new ByteArrayOutputStream ();
126127 for (int i = 0 ; i < sources .length ; i ++) {
127- runEngine (sources [i ], out , isUp [i ]);
128+ runEngine (sources [i ], port , out , isUp [i ]);
128129 }
129130 if (error .get () != null ) {
130131 throw new AssertionError (error .get ());
131132 }
132133 String output = new String (out .toByteArray ());
133134 for (int i = 0 ; i < sources .length ; i ++) {
134- assertTrue (output , output .contains (PORT + "/" + sources [i ].getName ()));
135+ assertTrue (output , output .contains (port . get () + "/" + sources [i ].getName ()));
135136 }
136137 }
137138
138- private static void verifySerialDebug (CountDownLatch [] isUp , AtomicReference <Throwable > error ) {
139+ private static void verifySerialDebug (AtomicInteger port , CountDownLatch [] isUp , AtomicReference <Throwable > error ) {
139140 new Thread (() -> {
140141 try {
141142 for (int i = 0 ; i < isUp .length ; i ++) {
142143 isUp [i ].await ();
143144 String path = "MTest" + (i + 1 ) + ".sl." + SecureInspectorPathGenerator .getToken ();
144- checkInfo (path );
145- checkSuspendAndResume (path );
145+ checkInfo (port . get (), path );
146+ checkSuspendAndResume (port . get (), path );
146147 }
147148 } catch (Throwable thr ) {
148149 thr .printStackTrace ();
@@ -152,7 +153,7 @@ private static void verifySerialDebug(CountDownLatch[] isUp, AtomicReference<Thr
152153 }
153154
154155 @ Test
155- public void testMultipleEnginesParallel () throws InterruptedException {
156+ public void testMultipleEnginesParallel () throws InterruptedException , IOException {
156157 Source [] sources = new Source []{
157158 Source .newBuilder ("sl" , CODE1 , "MTest1.sl" ).buildLiteral (),
158159 Source .newBuilder ("sl" , CODE2 , "MTest2.sl" ).buildLiteral (),
@@ -164,14 +165,15 @@ public void testMultipleEnginesParallel() throws InterruptedException {
164165 isUp [i ] = new CountDownLatch (1 );
165166 }
166167 List <Throwable > errors = Collections .synchronizedList (new LinkedList <>());
167- verifyParallelDebug (isUp , errors );
168168 ByteArrayOutputStream out = new ByteArrayOutputStream ();
169169 Thread [] threads = new Thread [sources .length ];
170+ int port = getFreePort ();
171+ verifyParallelDebug (port , isUp , errors );
170172 for (int i = 0 ; i < sources .length ; i ++) {
171173 int index = i ;
172174 Thread t = new Thread (() -> {
173175 try {
174- runEngine (sources [index ], out , isUp [index ]);
176+ runEngine (sources [index ], new AtomicInteger ( port ), out , isUp [index ]);
175177 } catch (Throwable thr ) {
176178 thr .printStackTrace ();
177179 errors .add (thr );
@@ -192,7 +194,14 @@ public void testMultipleEnginesParallel() throws InterruptedException {
192194 }
193195 String output = new String (out .toByteArray ());
194196 for (int i = 0 ; i < sources .length ; i ++) {
195- assertTrue (output , output .contains (PORT + "/" + sources [i ].getName ()));
197+ assertTrue (output , output .contains (port + "/" + sources [i ].getName ()));
198+ }
199+ }
200+
201+ private static int getFreePort () throws IOException {
202+ try (ServerSocket socket = new ServerSocket (0 )) {
203+ socket .setReuseAddress (true );
204+ return socket .getLocalPort ();
196205 }
197206 }
198207
@@ -206,9 +215,10 @@ public void testMultipleEnginesSamePath() throws Exception {
206215 ByteArrayOutputStream out = new ByteArrayOutputStream ();
207216 CountDownLatch isUp = new CountDownLatch (1 );
208217 final String samePath = "samePath" + SecureInspectorPathGenerator .getToken ();
218+ AtomicInteger port = new AtomicInteger (0 );
209219 Thread t = new Thread (() -> {
210220 try {
211- runEngine (sources [0 ], samePath , out , isUp );
221+ runEngine (sources [0 ], port , samePath , out , isUp );
212222 } catch (Throwable thr ) {
213223 errors .add (thr );
214224 isUp .countDown ();
@@ -217,13 +227,13 @@ public void testMultipleEnginesSamePath() throws Exception {
217227 t .start ();
218228 isUp .await ();
219229 try {
220- runEngine (sources [1 ], samePath , out , isUp );
230+ runEngine (sources [1 ], port , samePath , out , isUp );
221231 fail ();
222232 } catch (Throwable thr ) {
223233 String message = thr .getMessage ();
224234 assertTrue (message , message .contains ("Inspector session with the same path exists already" ));
225235 }
226- checkSuspendAndResume (samePath );
236+ checkSuspendAndResume (port . get (), samePath );
227237 t .join ();
228238 if (!errors .isEmpty ()) {
229239 AssertionError err = new AssertionError ();
@@ -234,7 +244,7 @@ public void testMultipleEnginesSamePath() throws Exception {
234244 }
235245 }
236246
237- private static void verifyParallelDebug (CountDownLatch [] isUp , List <Throwable > errors ) {
247+ private static void verifyParallelDebug (int port , CountDownLatch [] isUp , List <Throwable > errors ) {
238248 new Thread (() -> {
239249 try {
240250 for (int i = 0 ; i < isUp .length ; i ++) {
@@ -244,12 +254,12 @@ private static void verifyParallelDebug(CountDownLatch[] isUp, List<Throwable> e
244254 for (int i = 0 ; i < paths .length ; i ++) {
245255 paths [i ] = "MTest" + (i + 1 ) + ".sl." + SecureInspectorPathGenerator .getToken ();
246256 }
247- checkInfo (paths );
257+ checkInfo (port , paths );
248258 for (int i = 0 ; i < paths .length ; i ++) {
249259 int index = i ;
250260 new Thread (() -> {
251261 try {
252- checkSuspendAndResume (paths [index ]);
262+ checkSuspendAndResume (port , paths [index ]);
253263 } catch (Throwable thr ) {
254264 thr .printStackTrace ();
255265 errors .add (thr );
@@ -263,14 +273,17 @@ private static void verifyParallelDebug(CountDownLatch[] isUp, List<Throwable> e
263273 }).start ();
264274 }
265275
266- private String runEngine (Source src , OutputStream out , CountDownLatch isUp ) {
267- return runEngine (src , src .getName () + "." + SecureInspectorPathGenerator .getToken (), out , isUp );
276+ private String runEngine (Source src , AtomicInteger port , OutputStream out , CountDownLatch isUp ) {
277+ return runEngine (src , port , src .getName () + "." + SecureInspectorPathGenerator .getToken (), out , isUp );
268278 }
269279
270- private String runEngine (Source src , String path , OutputStream out , CountDownLatch isUp ) {
271- try (Engine e = Engine .newBuilder ().option ("inspect.Path" , path ).err (out ).build ()) {
280+ private String runEngine (Source src , AtomicInteger port , String path , OutputStream out , CountDownLatch isUp ) {
281+ try (Engine e = Engine .newBuilder ().option ("inspect" , Integer . toString ( port . get ())). option ( "inspect .Path" , path ).err (out ).build ()) {
272282 addEngineReference (e );
273283 Context c = Context .newBuilder ().engine (e ).allowAllAccess (true ).build ();
284+ if (port .get () == 0 ) {
285+ port .set (InspectorAddressTest .parseWSPort (out .toString ()));
286+ }
274287 isUp .countDown ();
275288 Value result = c .eval (src );
276289 if (result .fitsInLong ()) {
@@ -282,8 +295,8 @@ private String runEngine(Source src, String path, OutputStream out, CountDownLat
282295 }
283296
284297 @ SuppressWarnings ("deprecation" )
285- private static void checkInfo (String ... paths ) throws MalformedURLException , IOException {
286- URL url = new URL ("http" , InetAddress .getLoopbackAddress ().getHostAddress (), PORT , "/json" );
298+ private static void checkInfo (int port , String ... paths ) throws MalformedURLException , IOException {
299+ URL url = new URL ("http" , InetAddress .getLoopbackAddress ().getHostAddress (), port , "/json" );
287300 HttpURLConnection connection = ((HttpURLConnection ) url .openConnection ());
288301 assertEquals ("application/json; charset=UTF-8" , connection .getContentType ());
289302 StringWriter out = new StringWriter (connection .getContentLength ());
@@ -298,7 +311,7 @@ private static void checkInfo(String... paths) throws MalformedURLException, IOE
298311 assertEquals (message , paths .length , infos .length ());
299312 Set <String > endWs = new HashSet <>();
300313 for (int i = 0 ; i < paths .length ; i ++) {
301- endWs .add (PORT + "/" + paths [i ]);
314+ endWs .add (port + "/" + paths [i ]);
302315 }
303316 for (int i = 0 ; i < paths .length ; i ++) {
304317 JSONObject info = (JSONObject ) infos .get (i );
@@ -316,11 +329,11 @@ private static void checkInfo(String... paths) throws MalformedURLException, IOE
316329 assertTrue (endWs .isEmpty ());
317330 }
318331
319- private static void checkSuspendAndResume (String path ) throws Exception {
332+ private static void checkSuspendAndResume (int port , String path ) throws Exception {
320333 CountDownLatch closed = new CountDownLatch (1 );
321334 AtomicBoolean paused = new AtomicBoolean (false );
322335 AtomicReference <Exception > exception = new AtomicReference <>(null );
323- final String url = "ws://" + InetAddress .getLoopbackAddress ().getHostAddress () + ":" + PORT + "/" + path ;
336+ final String url = "ws://" + InetAddress .getLoopbackAddress ().getHostAddress () + ":" + port + "/" + path ;
324337 WebSocketClient wsc = new WebSocketClient (new URI (url )) {
325338 @ Override
326339 public void onOpen (ServerHandshake sh ) {
0 commit comments