/** * Try a few times to get a client-side error, since the client-side socket may not reflect the * server-side close immediately. */ private void waitForError(TestClient client, String secret) throws Exception { final AtomicBoolean helloSent = new AtomicBoolean(); eventually(Duration.ofSeconds(1), Duration.ofMillis(10), () -> { try { if (!helloSent.get()) { client.send(new Hello(secret, "1.4.0")); helloSent.set(true); } else { client.send(new SetAppId("appId")); } fail("Expected error but message went through."); } catch (IllegalStateException | IOException e) { // Expected. } }); }
/** * Try a few times to get a client-side error, since the client-side socket may not reflect the * server-side close immediately. */ private void waitForError(TestClient client, String secret) throws Exception { boolean helloSent = false; int maxTries = 10; for (int i = 0; i < maxTries; i++) { try { if (!helloSent) { client.send(new Hello(secret, "1.4.0")); helloSent = true; } else { client.send(new SetAppId("appId")); } fail("Expected error but message went through."); } catch (IllegalStateException | IOException e) { // Expected. break; } catch (AssertionError e) { if (i < maxTries - 1) { Thread.sleep(100); } else { throw new AssertionError("Test failed after " + maxTries + " attempts.", e); } } } }
@Test public void testAppHandleDisconnect() throws Exception { LauncherServer server = LauncherServer.getOrCreateServer(); ChildProcAppHandle handle = new ChildProcAppHandle(server); String secret = server.registerHandle(handle); TestClient client = null; try { Socket s = new Socket(InetAddress.getLoopbackAddress(), server.getPort()); client = new TestClient(s); client.send(new Hello(secret, "1.4.0")); client.send(new SetAppId("someId")); // Wait until we know the server has received the messages and matched the handle to the // connection before disconnecting. eventually(Duration.ofSeconds(1), Duration.ofMillis(10), () -> { assertEquals("someId", handle.getAppId()); }); handle.disconnect(); waitForError(client, secret); } finally { handle.kill(); close(client); client.clientThread.join(); } }
client.send(new Hello(handle.getSecret(), "1.4.0")); assertTrue(semaphore.tryAcquire(30, TimeUnit.SECONDS)); client.send(new SetAppId("app-id")); assertTrue(semaphore.tryAcquire(30, TimeUnit.SECONDS)); assertEquals("app-id", handle.getAppId()); client.send(new SetState(SparkAppHandle.State.RUNNING)); assertTrue(semaphore.tryAcquire(1, TimeUnit.SECONDS)); assertEquals(SparkAppHandle.State.RUNNING, handle.getState());
client.send(new Hello(secret, "1.4.0")); assertTrue(semaphore.tryAcquire(30, TimeUnit.SECONDS)); client.send(new SetAppId("app-id")); assertTrue(semaphore.tryAcquire(30, TimeUnit.SECONDS)); assertEquals("app-id", handle.getAppId()); client.send(new SetState(SparkAppHandle.State.RUNNING)); assertTrue(semaphore.tryAcquire(1, TimeUnit.SECONDS)); assertEquals(SparkAppHandle.State.RUNNING, handle.getState());
client.send(new Hello(secret, "1.4.0")); assertTrue(semaphore.tryAcquire(30, TimeUnit.SECONDS));
@Test public void testSparkSubmitVmShutsDown() throws Exception { ChildProcAppHandle handle = LauncherServer.newAppHandle(); TestClient client = null; final Semaphore semaphore = new Semaphore(0); try { Socket s = new Socket(InetAddress.getLoopbackAddress(), LauncherServer.getServerInstance().getPort()); handle.addListener(new SparkAppHandle.Listener() { public void stateChanged(SparkAppHandle handle) { semaphore.release(); } public void infoChanged(SparkAppHandle handle) { semaphore.release(); } }); client = new TestClient(s); client.send(new Hello(handle.getSecret(), "1.4.0")); assertTrue(semaphore.tryAcquire(30, TimeUnit.SECONDS)); // Make sure the server matched the client to the handle. assertNotNull(handle.getConnection()); close(client); assertTrue(semaphore.tryAcquire(30, TimeUnit.SECONDS)); assertEquals(SparkAppHandle.State.LOST, handle.getState()); } finally { kill(handle); close(client); client.clientThread.join(); } }
@Test public void testStreamFiltering() throws Exception { ChildProcAppHandle handle = LauncherServer.newAppHandle(); TestClient client = null; try { Socket s = new Socket(InetAddress.getLoopbackAddress(), LauncherServer.getServerInstance().getPort()); client = new TestClient(s); try { client.send(new EvilPayload()); } catch (SocketException se) { // SPARK-21522: this can happen if the server closes the socket before the full message has // been written, so it's expected. It may cause false positives though (socket errors // happening for other reasons). } waitForError(client, handle.getSecret()); assertEquals(0, EvilPayload.EVIL_BIT); } finally { kill(handle); close(client); client.clientThread.join(); } }
@Test public void testStreamFiltering() throws Exception { LauncherServer server = LauncherServer.getOrCreateServer(); ChildProcAppHandle handle = new ChildProcAppHandle(server); String secret = server.registerHandle(handle); TestClient client = null; try { Socket s = new Socket(InetAddress.getLoopbackAddress(), server.getPort()); client = new TestClient(s); try { client.send(new EvilPayload()); } catch (SocketException se) { // SPARK-21522: this can happen if the server closes the socket before the full message has // been written, so it's expected. It may cause false positives though (socket errors // happening for other reasons). } waitForError(client, secret); assertEquals(0, EvilPayload.EVIL_BIT); } finally { handle.kill(); close(client); client.clientThread.join(); } }