/*
* Copyright 2015 Julien Viet
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.termd.core.http.websocket;
import io.termd.core.http.websocket.client.Client;
import io.termd.core.http.websocket.server.TaskStatusUpdateEvent;
import io.termd.core.http.websocket.server.TermServer;
import io.termd.core.pty.Status;
import io.termd.core.util.MockProcess;
import io.termd.core.util.Wait;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import java.net.HttpURLConnection;
import java.net.URL;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
/**
* @author <a href="mailto:matejonnet@gmail.com">Matej Lazar</a>
*/
public class UndertowServerTest {
private static final String TEST_COMMAND = "java -cp ./target/test-classes/ " + MockProcess.class.getName() + " 1 500";
TermServer termServer;
@Before
public void startTermServer() throws InterruptedException {
termServer = TermServer.start();
}
@Test
public void serverShouldStart() throws Exception {
URL url = new URL("http://" + Configurations.HOST + ":" + termServer.getPort() + "/");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setDoOutput(true);
Assert.assertEquals(200, connection.getResponseCode());
}
@Test
public void remoteCommandShouldBeExecutedAndResponsesReceived() throws Exception {
doRemoteCommandShouldBeExecutedAndResponsesReceived("");
}
@Test
public void remoteCommandShouldBeExecutedAndResponsesReceivedWithContext() throws Exception {
doRemoteCommandShouldBeExecutedAndResponsesReceived("/the_context");
}
@Test
public void clientShouldBeAbleToReConnectToARunningSession() throws Exception {
String context = "/my-context";
String processSocketUrl = "http://" + Configurations.HOST + ":" + termServer.getPort() + Configurations.TERM_PATH + context;
StringBuilder responseData = new StringBuilder();
Consumer<String> responseConsumer = (data) -> {
responseData.append(data);
};
Client client = Client.connectCommandExecutingClient(processSocketUrl, Optional.of(responseConsumer));
Client.executeRemoteCommand(client, TEST_COMMAND);
Wait.forCondition(() -> responseData.toString().contains(MockProcess.WELCOME_MESSAGE), 60, ChronoUnit.SECONDS);
client.close();
StringBuilder reConnectingResponseData = new StringBuilder();
Consumer<String> reConnectingResponseConsumer = (data) -> {
reConnectingResponseData.append(data);
};
Client reConnectingClient = Client.connectCommandExecutingClient(processSocketUrl, Optional.of(reConnectingResponseConsumer));
Wait.forCondition(() -> reConnectingResponseData.toString().contains(MockProcess.FINAL_MESSAGE), 60, ChronoUnit.SECONDS);
Assert.assertTrue("Missing response data.", reConnectingResponseData.toString().contains(MockProcess.FINAL_MESSAGE));
Assert.assertTrue("Missing response data.", reConnectingResponseData.toString().contains(MockProcess.FINAL_MESSAGE));
}
@Test
public void clientShouldBeAbleToConnectToARunningSession() throws Exception {
String context = "/my-multi-client-context";
String processSocketUrl = "http://" + Configurations.HOST + ":" + termServer.getPort() + Configurations.TERM_PATH + context;
StringBuilder responseData = new StringBuilder();
Consumer<String> responseConsumer = (data) -> {
responseData.append(data);
};
Client client = Client.connectCommandExecutingClient(processSocketUrl, Optional.of(responseConsumer));
Client.executeRemoteCommand(client, TEST_COMMAND);
Wait.forCondition(() -> responseData.toString().contains(MockProcess.WELCOME_MESSAGE), 60, ChronoUnit.SECONDS);
StringBuilder reConnectingResponseData = new StringBuilder();
Consumer<String> reConnectingResponseConsumer = (data) -> {
reConnectingResponseData.append(data);
};
Client reConnectingClient = Client.connectCommandExecutingClient(processSocketUrl, Optional.of(reConnectingResponseConsumer));
Wait.forCondition(() -> reConnectingResponseData.toString().contains(MockProcess.FINAL_MESSAGE), 60, ChronoUnit.SECONDS);
Assert.assertTrue("Missing response data.", reConnectingResponseData.toString().contains(MockProcess.FINAL_MESSAGE));
Assert.assertTrue("Missing response data.", reConnectingResponseData.toString().contains(MockProcess.FINAL_MESSAGE));
}
private void doRemoteCommandShouldBeExecutedAndResponsesReceived(String context) throws Exception {
String updatesSocketUrl = "http://" + Configurations.HOST + ":" + termServer.getPort() + Configurations.PROCESS_UPDATES_PATH + context;
List<Status> receivedEventUpdates = new ArrayList<>();
Consumer<TaskStatusUpdateEvent> onStatusUpdate = (statusUpdateEvent) -> {
receivedEventUpdates.add(statusUpdateEvent.getNewStatus());
};
Client.connectStatusListenerClient(updatesSocketUrl, onStatusUpdate);
String processSocketUrl = "http://" + Configurations.HOST + ":" + termServer.getPort() + Configurations.TERM_PATH + context;
StringBuilder responseData = new StringBuilder();
Consumer<String> responseConsumer = (data) -> {
responseData.append(data);
};
Client client = Client.connectCommandExecutingClient(processSocketUrl, Optional.of(responseConsumer));
Client.executeRemoteCommand(client, TEST_COMMAND);
Wait.forCondition(() -> receivedEventUpdates.contains(Status.COMPLETED), 60, ChronoUnit.SECONDS);
Assert.assertTrue("Missing response data.", responseData.toString().contains(MockProcess.FINAL_MESSAGE));
}
}