blob: 88d97e37a0027d9b8bff305a6212b13a1c8173c5 [file] [log] [blame]
/******************************************************************************
* Copyright (c) 2016-2018 TypeFox and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
******************************************************************************/
package org.eclipse.lsp4j.debug.test;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.eclipse.lsp4j.debug.Capabilities;
import org.eclipse.lsp4j.debug.InitializeRequestArguments;
import org.eclipse.lsp4j.debug.OutputEventArguments;
import org.eclipse.lsp4j.debug.launch.DSPLauncher;
import org.eclipse.lsp4j.debug.services.IDebugProtocolClient;
import org.eclipse.lsp4j.debug.services.IDebugProtocolServer;
import org.eclipse.lsp4j.jsonrpc.Endpoint;
import org.eclipse.lsp4j.jsonrpc.Launcher;
import org.eclipse.lsp4j.jsonrpc.json.StreamMessageProducer;
import org.eclipse.lsp4j.jsonrpc.services.ServiceEndpoints;
import org.eclipse.xtext.xbase.lib.Pair;
import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class DSPLauncherTest {
private static final long TIMEOUT = 2000;
@Test
public void testNotification() throws IOException {
OutputEventArguments p = new OutputEventArguments();
p.setOutput("Hello World");
client.expectedNotifications.put("output", p);
serverLauncher.getRemoteProxy().output(p);
client.joinOnEmpty();
}
@Test
public void testRequest() throws Exception {
InitializeRequestArguments p = new InitializeRequestArguments();
p.setClientID("test");
Capabilities result = new Capabilities();
result.setSupportTerminateDebuggee(true);
result.setSupportsCompletionsRequest(false);
server.expectedRequests.put("initialize", new Pair<>(p, result));
CompletableFuture<Capabilities> future = clientLauncher.getRemoteProxy().initialize(p);
Assert.assertEquals(result.toString(), future.get(TIMEOUT, TimeUnit.MILLISECONDS).toString());
client.joinOnEmpty();
}
static class AssertingEndpoint implements Endpoint {
public Map<String, Pair<Object, Object>> expectedRequests = new LinkedHashMap<>();
@Override
public CompletableFuture<?> request(String method, Object parameter) {
Assert.assertTrue(expectedRequests.containsKey(method));
Pair<Object, Object> result = expectedRequests.remove(method);
Assert.assertEquals(result.getKey().toString(), parameter.toString());
return CompletableFuture.completedFuture(result.getValue());
}
public Map<String, Object> expectedNotifications = new LinkedHashMap<>();
@Override
public void notify(String method, Object parameter) {
Assert.assertTrue(expectedNotifications.containsKey(method));
Object object = expectedNotifications.remove(method);
Assert.assertEquals(object.toString(), parameter.toString());
}
/**
* wait max 1 sec for all expectations to be removed
*/
public void joinOnEmpty() {
long before = System.currentTimeMillis();
do {
if (expectedNotifications.isEmpty() && expectedNotifications.isEmpty()) {
return;
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} while (System.currentTimeMillis() < before + 1000);
Assert.fail("expectations weren't empty " + toString());
}
@Override
public String toString() {
return new ToStringBuilder(this).addAllFields().toString();
}
}
private AssertingEndpoint server;
private Launcher<IDebugProtocolClient> serverLauncher;
private Future<?> serverListening;
private AssertingEndpoint client;
private Launcher<IDebugProtocolServer> clientLauncher;
private Future<?> clientListening;
private Level logLevel;
@Before
public void setup() throws IOException {
PipedInputStream inClient = new PipedInputStream();
PipedOutputStream outClient = new PipedOutputStream();
PipedInputStream inServer = new PipedInputStream();
PipedOutputStream outServer = new PipedOutputStream();
inClient.connect(outServer);
outClient.connect(inServer);
server = new AssertingEndpoint();
serverLauncher = DSPLauncher.createServerLauncher(
ServiceEndpoints.toServiceObject(server, IDebugProtocolServer.class), inServer, outServer);
serverListening = serverLauncher.startListening();
client = new AssertingEndpoint();
clientLauncher = DSPLauncher.createClientLauncher(
ServiceEndpoints.toServiceObject(client, IDebugProtocolClient.class), inClient, outClient);
clientListening = clientLauncher.startListening();
Logger logger = Logger.getLogger(StreamMessageProducer.class.getName());
logLevel = logger.getLevel();
logger.setLevel(Level.SEVERE);
}
@After
public void teardown() throws InterruptedException, ExecutionException {
clientListening.cancel(true);
serverListening.cancel(true);
Thread.sleep(10);
Logger logger = Logger.getLogger(StreamMessageProducer.class.getName());
logger.setLevel(logLevel);
}
}