blob: e5c119deaa7ba12fdcc0048c13c0ee0159e68298 [file] [log] [blame]
// Copyright 2018 The Bazel Authors. All rights reserved.
//
// 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 com.google.devtools.build.lib.skylarkdebug.server;
import static com.google.common.truth.Truth.assertThat;
import com.google.devtools.build.lib.events.EventKind;
import com.google.devtools.build.lib.events.util.EventCollectionApparatus;
import com.google.devtools.build.lib.skylarkdebugging.SkylarkDebuggingProtos.ContinueExecutionResponse;
import com.google.devtools.build.lib.skylarkdebugging.SkylarkDebuggingProtos.DebugEvent;
import com.google.devtools.build.lib.skylarkdebugging.SkylarkDebuggingProtos.DebugRequest;
import com.google.devtools.build.lib.skylarkdebugging.SkylarkDebuggingProtos.StartDebuggingRequest;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/** Unit tests for {@link DebugServerTransport}. */
@RunWith(JUnit4.class)
public class DebugServerTransportTest {
private static final ExecutorService executor = Executors.newFixedThreadPool(1);
private final EventCollectionApparatus events =
new EventCollectionApparatus(EventKind.ALL_EVENTS);
/** A simple debug client for testing purposes. */
private static class MockDebugClient {
Socket clientSocket;
void connect(Duration timeout, ServerSocket serverSocket) {
long startTimeMillis = System.currentTimeMillis();
IOException exception = null;
while (System.currentTimeMillis() - startTimeMillis < timeout.toMillis()) {
try {
clientSocket = new Socket();
clientSocket.connect(
new InetSocketAddress(serverSocket.getInetAddress(), serverSocket.getLocalPort()),
100);
return;
} catch (IOException e) {
exception = e;
}
}
throw new RuntimeException("Couldn't connect to the debug server", exception);
}
List<DebugEvent> readEvents() throws Exception {
List<DebugEvent> events = new ArrayList<>();
while (clientSocket.getInputStream().available() != 0) {
events.add(DebugEvent.parseDelimitedFrom(clientSocket.getInputStream()));
}
return events;
}
void sendRequest(DebugRequest request) throws IOException {
request.writeDelimitedTo(clientSocket.getOutputStream());
}
}
@Test
public void testConnectAndReceiveRequest() throws Exception {
ServerSocket serverSocket = new ServerSocket(0, 1, InetAddress.getByName(null));
Future<DebugServerTransport> future =
executor.submit(
() ->
DebugServerTransport.createAndWaitForClient(
events.reporter(), serverSocket, false));
MockDebugClient client = new MockDebugClient();
client.connect(Duration.ofSeconds(10), serverSocket);
DebugServerTransport serverTransport = future.get(10, TimeUnit.SECONDS);
assertThat(serverTransport).isNotNull();
DebugRequest request =
DebugRequest.newBuilder()
.setSequenceNumber(10)
.setStartDebugging(StartDebuggingRequest.getDefaultInstance())
.build();
client.sendRequest(request);
assertThat(serverTransport.readClientRequest()).isEqualTo(request);
serverTransport.close();
}
@Test
public void testConnectAndPostEvent() throws Exception {
ServerSocket serverSocket = new ServerSocket(0, 1, InetAddress.getByName(null));
Future<DebugServerTransport> future =
executor.submit(
() ->
DebugServerTransport.createAndWaitForClient(
events.reporter(), serverSocket, false));
MockDebugClient client = new MockDebugClient();
client.connect(Duration.ofSeconds(10), serverSocket);
DebugServerTransport serverTransport = future.get(10, TimeUnit.SECONDS);
assertThat(serverTransport).isNotNull();
DebugEvent event =
DebugEvent.newBuilder()
.setSequenceNumber(10)
.setContinueExecution(ContinueExecutionResponse.getDefaultInstance())
.build();
serverTransport.postEvent(event);
assertThat(client.readEvents()).containsExactly(event);
serverTransport.close();
}
}