/*
* 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.tty;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.After;
import javax.websocket.ClientEndpointConfig;
import javax.websocket.CloseReason;
import javax.websocket.ContainerProvider;
import javax.websocket.Endpoint;
import javax.websocket.EndpointConfig;
import javax.websocket.MessageHandler;
import javax.websocket.Session;
import javax.websocket.WebSocketContainer;
import java.io.IOException;
import java.io.PipedReader;
import java.io.PipedWriter;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
/**
* @author <a href="mailto:julien@julienviet.com">Julien Viet</a>
*/
public abstract class WebsocketTtyTestBase extends TtyTestBase {
private Endpoint endpoint;
private Session session;
private PipedReader in;
@After
public void after() throws Exception {
if (session != null) {
try {
session.close();
} finally {
in = null;
session = null;
endpoint = null;
}
}
}
@Override
public boolean checkDisconnected() {
return session == null || !session.isOpen();
}
@Override
protected void assertConnect(String term) throws Exception {
if (endpoint != null) {
throw failure("Already a session");
}
CountDownLatch latch = new CountDownLatch(1);
PipedWriter out = new PipedWriter();
in = new PipedReader(out);
endpoint = new Endpoint() {
@Override
public void onOpen(Session session, EndpointConfig endpointConfig) {
session.addMessageHandler(new MessageHandler.Whole<String>() {
@Override
public void onMessage(String message) {
try {
out.write(message);
} catch (IOException e) {
e.printStackTrace();
}
}
});
latch.countDown();
}
@Override
public void onClose(Session sess, CloseReason closeReason) {
session = null;
endpoint = null;
in = null;
}
@Override
public void onError(Session session, Throwable thr) {
}
};
ClientEndpointConfig clientEndpointConfig = ClientEndpointConfig.Builder.create().build();
WebSocketContainer webSocketContainer = ContainerProvider.getWebSocketContainer();
session = webSocketContainer.connectToServer(endpoint, clientEndpointConfig, new URI("http://localhost:8080/ws"));
latch.await();
}
@Override
protected void assertWrite(String s) throws Exception {
Map<String, String> msg = new HashMap<>();
msg.put("action", "read");
msg.put("data", s);
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(msg);
session.getBasicRemote().sendText(json);
}
@Override
protected String assertReadString(int len) throws Exception {
char[] buf = new char[len];
while (len > 0) {
int count = in.read(buf, buf.length - len, len);
if (count == -1) {
throw failure("Could not read enough");
}
len -= count;
}
return new String(buf);
}
@Override
protected void assertWriteln(String s) throws Exception {
assertWrite(s + "\r");
}
@Override
protected void assertDisconnect(boolean clean) throws Exception {
if (clean) {
session.close();
} else {
// No way ???
session.close();
}
}
@Override
protected void resize(int width, int height) throws Exception {
Map<String, Object> msg = new HashMap<>();
msg.put("action", "resize");
msg.put("cols", width);
msg.put("rows", height);
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(msg);
session.getBasicRemote().sendText(json);
}
@Override
public void testDifferentCharset() throws Exception {
// Don't test, charset in this case is always UTF-8 for text frames
}
}