summaryrefslogtreecommitdiffstats
path: root/clustercontroller-utils/src/test/java/com
diff options
context:
space:
mode:
Diffstat (limited to 'clustercontroller-utils/src/test/java/com')
-rw-r--r--clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/communication/http/AsyncHttpClientWithBaseTest.java56
-rw-r--r--clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/communication/http/DummyAsyncHttpClient.java26
-rw-r--r--clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/communication/http/JsonAsyncHttpClientTest.java119
-rw-r--r--clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/communication/http/LoggingAsyncHttpClientTest.java55
-rw-r--r--clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/communication/http/ProxyAsyncHttpClientTest.java49
-rw-r--r--clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/communication/http/RequestQueueTest.java114
-rw-r--r--clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/communication/http/TimeoutHandlerTest.java127
-rw-r--r--clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/test/AsyncHttpClient.java18
-rw-r--r--clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/test/FakeClockTest.java42
-rw-r--r--clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/test/TestTransport.java186
10 files changed, 204 insertions, 588 deletions
diff --git a/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/communication/http/AsyncHttpClientWithBaseTest.java b/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/communication/http/AsyncHttpClientWithBaseTest.java
deleted file mode 100644
index 0175eab84c2..00000000000
--- a/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/communication/http/AsyncHttpClientWithBaseTest.java
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.vespa.clustercontroller.utils.communication.http;
-
-import com.yahoo.vespa.clustercontroller.utils.communication.async.AsyncOperation;
-import com.yahoo.vespa.clustercontroller.utils.communication.async.AsyncOperationImpl;
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotSame;
-import static org.junit.Assert.fail;
-
-public class AsyncHttpClientWithBaseTest {
-
- @Test
- public void testOverride() {
- class HttpClient implements AsyncHttpClient<HttpResult> {
- HttpRequest lastRequest;
- @Override
- public AsyncOperation<HttpResult> execute(HttpRequest r) {
- lastRequest = r;
- return new AsyncOperationImpl<>("test");
- }
- @Override
- public void close() {
- }
- }
-
- HttpClient client = new HttpClient();
- AsyncHttpClientWithBase<HttpResult> base = new AsyncHttpClientWithBase<>(client);
- // No override by default
- HttpRequest r = new HttpRequest().setPath("/foo").setHost("bar").setPort(50);
- base.execute(r);
- assertEquals(client.lastRequest, r);
- // Base request always set
- base.setHttpRequestBase(null);
- base.execute(r);
- assertEquals(client.lastRequest, r);
- // Set an override
- base.setHttpRequestBase(new HttpRequest().setHttpOperation(HttpRequest.HttpOp.DELETE));
- base.execute(r);
- assertNotSame(client.lastRequest, r);
- assertEquals(HttpRequest.HttpOp.DELETE, client.lastRequest.getHttpOperation());
-
- base.close();
- }
-
- @Test
- public void testClientMustBeSet() {
- try{
- new AsyncHttpClientWithBase<>(null);
- fail();
- } catch (IllegalArgumentException e) {
- }
- }
-
-}
diff --git a/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/communication/http/DummyAsyncHttpClient.java b/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/communication/http/DummyAsyncHttpClient.java
deleted file mode 100644
index 7070fb8570e..00000000000
--- a/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/communication/http/DummyAsyncHttpClient.java
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.vespa.clustercontroller.utils.communication.http;
-
-import com.yahoo.vespa.clustercontroller.utils.communication.async.AsyncOperation;
-import com.yahoo.vespa.clustercontroller.utils.communication.async.AsyncOperationImpl;
-
-public class DummyAsyncHttpClient implements AsyncHttpClient<HttpResult> {
- HttpResult result;
- HttpRequest lastRequest;
-
- public DummyAsyncHttpClient(HttpResult result) {
- this.result = result;
- }
-
- @Override
- public AsyncOperation<HttpResult> execute(HttpRequest r) {
- lastRequest = r;
- AsyncOperationImpl<HttpResult> op = new AsyncOperationImpl<>(r.toString());
- op.setResult(result);
- return op;
- }
-
- @Override
- public void close() {
- }
-}
diff --git a/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/communication/http/JsonAsyncHttpClientTest.java b/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/communication/http/JsonAsyncHttpClientTest.java
deleted file mode 100644
index 3d3cd517020..00000000000
--- a/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/communication/http/JsonAsyncHttpClientTest.java
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.vespa.clustercontroller.utils.communication.http;
-
-import com.yahoo.vespa.clustercontroller.utils.communication.async.AsyncOperation;
-import com.yahoo.vespa.clustercontroller.utils.communication.async.AsyncOperationImpl;
-import org.codehaus.jettison.json.JSONObject;
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-public class JsonAsyncHttpClientTest {
-
- @Test
- public void testJSONInJSONOut() throws Exception {
- DummyAsyncHttpClient dummy = new DummyAsyncHttpClient(
- new HttpResult().setContent(new JSONObject().put("bar", 42)));
- JsonAsyncHttpClient client = new JsonAsyncHttpClient(dummy);
- client.addJsonContentType(true);
- client.verifyRequestContentAsJson(true);
-
- HttpRequest r = new HttpRequest();
- r.setPostContent(new JSONObject().put("foo", 34));
-
- AsyncOperation<JsonHttpResult> result = client.execute(r);
-
- assertEquals(new JSONObject().put("bar", 42).toString(), result.getResult().getJson().toString());
- assertTrue(result.isSuccess());
-
- result.toString();
- client.close();
- }
-
- @Test
- public void testStringInJSONOut() throws Exception {
- DummyAsyncHttpClient dummy = new DummyAsyncHttpClient(
- new HttpResult().setContent(new JSONObject().put("bar", 42).toString()));
- JsonAsyncHttpClient client = new JsonAsyncHttpClient(dummy);
-
- HttpRequest r = new HttpRequest();
- r.setPostContent(new JSONObject().put("foo", 34).toString());
-
- AsyncOperation<JsonHttpResult> result = client.execute(r);
-
- assertEquals(new JSONObject().put("bar", 42).toString(), result.getResult().getJson().toString());
- }
-
- @Test
- public void testIllegalJsonIn() throws Exception {
- DummyAsyncHttpClient dummy = new DummyAsyncHttpClient(
- new HttpResult().setContent(new JSONObject().put("bar", 42)));
- JsonAsyncHttpClient client = new JsonAsyncHttpClient(dummy);
-
- try {
- HttpRequest r = new HttpRequest();
- r.setPostContent("my illegal json");
-
- client.execute(r);
- assertTrue(false);
- } catch (Exception e) {
-
- }
- }
-
- @Test
- public void testIllegalJSONOut() throws Exception {
- DummyAsyncHttpClient dummy = new DummyAsyncHttpClient(
- new HttpResult().setContent("my illegal json"));
- JsonAsyncHttpClient client = new JsonAsyncHttpClient(dummy);
-
- HttpRequest r = new HttpRequest();
- r.setPostContent(new JSONObject().put("foo", 34).toString());
-
- AsyncOperation<JsonHttpResult> result = client.execute(r);
-
- assertEquals("{\"error\":\"Invalid JSON in output: A JSONObject text must begin with '{' at character 1 of my illegal json\",\"output\":\"my illegal json\"}", result.getResult().getJson().toString());
- }
-
- @Test
- public void testEmptyReply() {
- class Client implements AsyncHttpClient<HttpResult> {
- AsyncOperationImpl<HttpResult> lastOp;
- @Override
- public AsyncOperation<HttpResult> execute(HttpRequest r) {
- return lastOp = new AsyncOperationImpl<>(r.toString());
- }
- @Override
- public void close() {
- }
- };
- Client client = new Client();
- JsonAsyncHttpClient jsonClient = new JsonAsyncHttpClient(client);
- AsyncOperation<JsonHttpResult> op = jsonClient.execute(new HttpRequest());
- client.lastOp.setResult(null);
- assertNull(op.getResult());
- }
-
- @Test
- public void testNotVerifyingJson() throws Exception {
- DummyAsyncHttpClient dummy = new DummyAsyncHttpClient(
- new HttpResult().setContent(new JSONObject().put("bar", 42)));
- JsonAsyncHttpClient client = new JsonAsyncHttpClient(dummy);
- client.addJsonContentType(true);
- client.verifyRequestContentAsJson(false);
-
- HttpRequest r = new HttpRequest();
- r.setPostContent(new JSONObject().put("foo", 34));
-
- AsyncOperation<JsonHttpResult> result = client.execute(r);
-
- assertEquals(new JSONObject().put("bar", 42).toString(), result.getResult().getJson().toString());
- assertTrue(result.isSuccess());
-
- result.toString();
- client.close();
- }
-
-}
diff --git a/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/communication/http/LoggingAsyncHttpClientTest.java b/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/communication/http/LoggingAsyncHttpClientTest.java
deleted file mode 100644
index 37841f7ca29..00000000000
--- a/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/communication/http/LoggingAsyncHttpClientTest.java
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.vespa.clustercontroller.utils.communication.http;
-
-import com.yahoo.vespa.clustercontroller.utils.communication.async.AsyncOperation;
-import com.yahoo.vespa.clustercontroller.utils.communication.async.AsyncOperationImpl;
-import org.junit.Test;
-
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import static org.junit.Assert.assertEquals;
-
-public class LoggingAsyncHttpClientTest {
-
- class HttpClient implements AsyncHttpClient<HttpResult> {
- AsyncOperationImpl<HttpResult> lastOp;
- @Override
- public AsyncOperation<HttpResult> execute(HttpRequest r) {
- return lastOp = new AsyncOperationImpl<>("test");
- }
- @Override
- public void close() {
- }
- }
-
- @Test
- public void testWithoutDebugLog() {
- doRequests();
- }
-
- @Test
- public void testWithDebugLog() {
- Logger log = Logger.getLogger(LoggingAsyncHttpClient.class.getName());
- log.setLevel(Level.FINE);
- doRequests();
- }
-
- private void doRequests() {
- {
- HttpClient client = new HttpClient();
- LoggingAsyncHttpClient<HttpResult> loggingClient = new LoggingAsyncHttpClient<>(client);
- AsyncOperation<HttpResult> op = loggingClient.execute(new HttpRequest());
- client.lastOp.setResult(new HttpResult().setContent("foo"));
- assertEquals("foo", op.getResult().getContent());
- }
- {
- HttpClient client = new HttpClient();
- LoggingAsyncHttpClient<HttpResult> loggingClient = new LoggingAsyncHttpClient<>(client);
- AsyncOperation<HttpResult> op = loggingClient.execute(new HttpRequest());
- client.lastOp.setFailure(new Exception("foo"));
- assertEquals("foo", op.getCause().getMessage());
- }
- }
-
-}
diff --git a/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/communication/http/ProxyAsyncHttpClientTest.java b/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/communication/http/ProxyAsyncHttpClientTest.java
deleted file mode 100644
index 062fd4aaa32..00000000000
--- a/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/communication/http/ProxyAsyncHttpClientTest.java
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.vespa.clustercontroller.utils.communication.http;
-
-import org.codehaus.jettison.json.JSONObject;
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-public class ProxyAsyncHttpClientTest {
-
- @Test
- public void testSimple() throws Exception {
- // Can't really test much here, but verifies that the code runs.
- DummyAsyncHttpClient dummy = new DummyAsyncHttpClient(
- new HttpResult().setContent(new JSONObject().put("bar", 42)));
- ProxyAsyncHttpClient client = new ProxyAsyncHttpClient<>(dummy, "myproxyhost", 1234);
-
- HttpRequest r = new HttpRequest();
- r.setPath("/foo");
- r.setHost("myhost");
- r.setPort(4567);
-
- r.setPostContent(new JSONObject().put("foo", 34));
-
- client.execute(r);
-
- assertEquals(new HttpRequest().setPath("/myhost:4567/foo")
- .setHost("myproxyhost")
- .setPort(1234)
- .setPostContent(new JSONObject().put("foo", 34)),
- dummy.lastRequest);
- }
-
- @Test
- public void testNoAndEmptyPath() throws Exception {
- DummyAsyncHttpClient dummy = new DummyAsyncHttpClient(
- new HttpResult().setContent(new JSONObject().put("bar", 42)));
- ProxyAsyncHttpClient client = new ProxyAsyncHttpClient<>(dummy, "myproxyhost", 1234);
- try{
- client.execute(new HttpRequest());
- assertTrue(false);
- } catch (IllegalStateException e) {
- assertTrue(e.getMessage().contains("Host and path must be set prior"));
- }
- client.execute(new HttpRequest().setHost("local").setPath(""));
- }
-
-}
diff --git a/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/communication/http/RequestQueueTest.java b/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/communication/http/RequestQueueTest.java
deleted file mode 100644
index 230920df53f..00000000000
--- a/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/communication/http/RequestQueueTest.java
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.vespa.clustercontroller.utils.communication.http;
-
-import com.yahoo.vespa.clustercontroller.utils.communication.async.AsyncCallback;
-import com.yahoo.vespa.clustercontroller.utils.communication.async.AsyncOperation;
-import com.yahoo.vespa.clustercontroller.utils.communication.async.AsyncOperationImpl;
-import org.junit.Test;
-
-import java.util.LinkedList;
-
-import static org.junit.Assert.assertEquals;
-
-public class RequestQueueTest {
-
- public static class Request {
- public final HttpRequest request;
- public final AsyncOperationImpl<HttpResult> result;
-
- public Request(HttpRequest r, AsyncOperationImpl<HttpResult> rr) {
- this.request = r;
- this.result = rr;
- }
- }
-
- public class TestClient implements AsyncHttpClient<HttpResult> {
- LinkedList<Request> requests = new LinkedList<>();
- @Override
- public AsyncOperation<HttpResult> execute(HttpRequest r) {
- Request p = new Request(r, new AsyncOperationImpl<HttpResult>(r.toString()));
- synchronized (requests) {
- requests.addLast(p);
- }
- return p.result;
- }
- @Override
- public void close() {}
- };
-
- @Test
- public void testNormalUsage() {
- TestClient client = new TestClient();
- RequestQueue<HttpResult> queue = new RequestQueue<>(client, 4);
- final LinkedList<HttpResult> results = new LinkedList<>();
- for (int i=0; i<10; ++i) {
- queue.schedule(new HttpRequest().setPath("/" + i), new AsyncCallback<HttpResult>() {
- @Override
- public void done(AsyncOperation<HttpResult> op) {
- if (op.isSuccess()) {
- results.add(op.getResult());
- } else {
- results.add(new HttpResult().setHttpCode(500, op.getCause().getMessage()));
- }
- }
- });
- }
- assertEquals(4, client.requests.size());
- for (int i=0; i<3; ++i) {
- Request p = client.requests.removeFirst();
- p.result.setResult(new HttpResult());
- assertEquals(true, results.getLast().isSuccess());
- }
- assertEquals(4, client.requests.size());
- for (int i=0; i<7; ++i) {
- Request p = client.requests.removeFirst();
- p.result.setFailure(new Exception("Fail"));
- assertEquals(false, results.getLast().isSuccess());
- }
- assertEquals(0, client.requests.size());
- assertEquals(true, queue.empty());
- assertEquals(10, results.size());
- }
-
- public class Waiter implements Runnable {
- boolean waiting = false;
- boolean completed = false;
- RequestQueue<HttpResult> queue;
- Waiter(RequestQueue<HttpResult> queue) {
- this.queue = queue;
- }
- public void run() {
- try{
- waiting = true;
- queue.waitUntilEmpty();
- } catch (InterruptedException e) { throw new Error(e); }
- completed = true;
- }
- }
-
- @Test
- public void testWaitUntilEmpty() throws Exception {
- TestClient client = new TestClient();
- RequestQueue<HttpResult> queue = new RequestQueue<>(client, 4);
- final LinkedList<HttpResult> result = new LinkedList<>();
- queue.schedule(new HttpRequest().setPath("/foo"), new AsyncCallback<HttpResult>() {
- @Override
- public void done(AsyncOperation<HttpResult> op) {
- result.add(op.getResult());
- }
- });
- Waiter waiter = new Waiter(queue);
- Thread thread = new Thread(waiter);
- thread.start();
- while (!waiter.waiting) {
- Thread.sleep(1);
- }
- assertEquals(0, result.size());
- client.requests.getFirst().result.setResult(new HttpResult());
- while (!waiter.completed) {
- Thread.sleep(1);
- }
- assertEquals(1, result.size());
- }
-
-}
diff --git a/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/communication/http/TimeoutHandlerTest.java b/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/communication/http/TimeoutHandlerTest.java
deleted file mode 100644
index 72a2a4eab8a..00000000000
--- a/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/communication/http/TimeoutHandlerTest.java
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.vespa.clustercontroller.utils.communication.http;
-
-import com.yahoo.vespa.clustercontroller.utils.communication.async.AsyncOperation;
-import com.yahoo.vespa.clustercontroller.utils.communication.async.AsyncOperationImpl;
-import com.yahoo.vespa.clustercontroller.utils.communication.async.AsyncUtils;
-import com.yahoo.vespa.clustercontroller.utils.test.FakeClock;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.concurrent.ArrayBlockingQueue;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-public class TimeoutHandlerTest {
-
- public class TestClient implements AsyncHttpClient<HttpResult> {
- AsyncOperationImpl<HttpResult> lastOp;
- @Override
- public AsyncOperation<HttpResult> execute(HttpRequest r) {
- return lastOp = new AsyncOperationImpl<>("test");
- }
- @Override
- public void close() {}
- };
-
- private ThreadPoolExecutor executor;
- private TestClient client;
- private FakeClock clock;
- private TimeoutHandler<HttpResult> handler;
-
- @Before
- public void setUp() {
- executor = new ThreadPoolExecutor(10, 100, 100, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(1000));
- clock = new FakeClock();
- client = new TestClient();
- handler = new TimeoutHandler<>(executor, clock, client);
- }
-
- @After
- public void tearDown() {
- handler.close();
- executor.shutdown();
- }
-
- @Test
- public void testTimeout() {
- AsyncOperation<HttpResult> op = handler.execute(new HttpRequest().setTimeout(1000));
- assertFalse(op.isDone());
- clock.adjust(999);
- // Give it a bit of time for timeout handler to have a chance of timout out prematurely
- try{ Thread.sleep(1); } catch (InterruptedException e) {}
- assertFalse(op.isDone());
- clock.adjust(1);
- AsyncUtils.waitFor(op);
- assertTrue(op.isDone());
- assertFalse(op.isSuccess());
- assertTrue(op.getCause().getMessage(), op.getCause().getMessage().contains("Operation timeout"));
- // After timeout, finishing the original request no longer matter
- client.lastOp.setResult(new HttpResult());
- assertFalse(op.isSuccess());
- assertTrue(op.getCause().getMessage(), op.getCause().getMessage().contains("Operation timeout"));
- }
-
- @Test
- public void testNoTimeout() {
- AsyncOperation<HttpResult> op = handler.execute(new HttpRequest().setTimeout(1000));
- clock.adjust(999);
- assertFalse(op.isDone());
- client.lastOp.setResult(new HttpResult().setContent("foo"));
- AsyncUtils.waitFor(op);
- assertTrue(op.isDone());
- assertTrue(op.isSuccess());
- assertEquals("foo", op.getResult().getContent());
- }
-
- @Test
- public void testNoTimeoutFailing() {
- AsyncOperation<HttpResult> op = handler.execute(new HttpRequest().setTimeout(1000));
- clock.adjust(999);
- assertFalse(op.isDone());
- client.lastOp.setFailure(new Exception("foo"));
- AsyncUtils.waitFor(op);
- assertTrue(op.isDone());
- assertFalse(op.isSuccess());
- assertEquals("foo", op.getCause().getMessage());
- }
-
- @Test
- public void testProvokeCompletedOpPurgeInTimeoutList() {
- AsyncOperation<HttpResult> op1 = handler.execute(new HttpRequest().setTimeout(1000));
- AsyncOperationImpl<HttpResult> op1Internal = client.lastOp;
- clock.adjust(300);
- AsyncOperation<HttpResult> op2 = handler.execute(new HttpRequest().setTimeout(1000));
- clock.adjust(300);
- op1Internal.setResult(new HttpResult().setContent("foo"));
- AsyncUtils.waitFor(op1);
- clock.adjust(800);
- AsyncUtils.waitFor(op2);
- assertEquals(true, op1.isDone());
- assertEquals(true, op2.isDone());
- assertEquals(true, op1.isSuccess());
- assertEquals(false, op2.isSuccess());
- }
-
- @Test
- public void testNothingButGetCoverage() {
- AsyncOperation<HttpResult> op = handler.execute(new HttpRequest().setTimeout(1000));
- op.getProgress();
- op.cancel();
- assertFalse(op.isCanceled()); // Cancel not currently supported
- client.lastOp.setResult(new HttpResult().setContent("foo"));
- AsyncUtils.waitFor(op);
- op.getProgress();
- op = handler.execute(new HttpRequest().setTimeout(1000));
- handler.performTimeoutHandlerTick();
- handler.performTimeoutHandlerTick();
- client.lastOp.setResult(new HttpResult().setContent("foo"));
- AsyncUtils.waitFor(op);
- }
-
-}
diff --git a/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/test/AsyncHttpClient.java b/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/test/AsyncHttpClient.java
new file mode 100644
index 00000000000..29f86842b34
--- /dev/null
+++ b/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/test/AsyncHttpClient.java
@@ -0,0 +1,18 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.clustercontroller.utils.test;
+
+import com.yahoo.vespa.clustercontroller.utils.communication.async.AsyncOperation;
+import com.yahoo.vespa.clustercontroller.utils.communication.http.HttpRequest;
+import com.yahoo.vespa.clustercontroller.utils.communication.http.HttpResult;
+
+/**
+ * Abstraction of an asynchronous HTTP client, such that applications don't need to depend directly on an HTTP client.
+ */
+public interface AsyncHttpClient<V extends HttpResult> {
+
+ AsyncOperation<V> execute(HttpRequest r);
+
+ /** Attempt to cancel all pending operations and shut down the client. */
+ void close();
+
+}
diff --git a/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/test/FakeClockTest.java b/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/test/FakeClockTest.java
deleted file mode 100644
index 47edd7ac55c..00000000000
--- a/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/test/FakeClockTest.java
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.vespa.clustercontroller.utils.test;
-
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-public class FakeClockTest {
-
- @Test
- public void testSimple() {
- FakeClock clock = new FakeClock();
- // Should not start at 0, as that is common not initialized yet value
- assertTrue(clock.getTimeInMillis() > 0);
- long start = clock.getTimeInMillis();
-
- clock.adjust(5);
- assertEquals(start + 5, clock.getTimeInMillis());
-
- clock.set(start + 10);
- assertEquals(start + 10, clock.getTimeInMillis());
-
- clock.adjust(5);
- assertEquals(start + 15, clock.getTimeInMillis());
- }
-
- // TODO: This should probably throw exceptions.. However, that doesn't seem to be current behavior.
- // I suspect some tests misuse the clock to reset things to run another test. Should probably be fixed.
- @Test
- public void testTurnTimeBack() {
- FakeClock clock = new FakeClock();
- clock.set(1000);
-
- clock.set(500);
- assertEquals(500, clock.getTimeInMillis());
-
- clock.adjust(-100);
- assertEquals(400, clock.getTimeInMillis());
- }
-
-}
diff --git a/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/test/TestTransport.java b/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/test/TestTransport.java
new file mode 100644
index 00000000000..d2e76cd77f9
--- /dev/null
+++ b/clustercontroller-utils/src/test/java/com/yahoo/vespa/clustercontroller/utils/test/TestTransport.java
@@ -0,0 +1,186 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.clustercontroller.utils.test;
+
+import com.yahoo.vespa.clustercontroller.utils.communication.async.AsyncOperation;
+import com.yahoo.vespa.clustercontroller.utils.communication.async.AsyncOperationImpl;
+import com.yahoo.vespa.clustercontroller.utils.communication.http.HttpRequest;
+import com.yahoo.vespa.clustercontroller.utils.communication.http.HttpRequestHandler;
+import com.yahoo.vespa.clustercontroller.utils.communication.http.HttpResult;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+/**
+ * This class is a utility for unit tests.. You can register HttpRequestHandler instances in it, and then
+ * you can extract an AsyncHttpClient&lt;HttpResult&gt; instance from it, which you can use to talk to the
+ * registered servers. Thus you can do end to end testing of components talking over HTTP without actually
+ * going through HTTP if you are using the HTTP abstraction layer in communication.http package.
+ */
+public class TestTransport {
+
+ private static final Logger log = Logger.getLogger(TestTransport.class.getName());
+ private static class Handler {
+ HttpRequestHandler handler;
+ String pathPrefix;
+ Handler(HttpRequestHandler h, String prefix) { this.handler = h; this.pathPrefix = prefix; }
+ }
+ private static class Socket {
+ public final String hostname;
+ public final int port;
+
+ Socket(String hostname, int port) {
+ this.hostname = hostname;
+ this.port = port;
+ }
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof Socket)) return false;
+ Socket other = (Socket) o;
+ return (hostname.equals(other.hostname) && port == other.port);
+ }
+ @Override
+ public int hashCode() {
+ return hostname.hashCode() * port;
+ }
+ }
+ private static class Request {
+ public final HttpRequest request;
+ public final AsyncOperationImpl<HttpResult> result;
+
+ Request(HttpRequest r, AsyncOperationImpl<HttpResult> rr) {
+ this.request = r;
+ this.result = rr;
+ }
+ }
+ private final Map<Socket, List<Handler>> handlers = new HashMap<>();
+ private final LinkedList<Request> requests = new LinkedList<>();
+ private final AsyncHttpClient<HttpResult> client = new AsyncHttpClient<HttpResult>() {
+ @Override
+ public AsyncOperation<HttpResult> execute(HttpRequest r) {
+ log.fine("Queueing request " + r);
+ if (r.getHttpOperation() == null) {
+ r = r.clone();
+ r.setHttpOperation(r.getPostContent() == null ? HttpRequest.HttpOp.GET : HttpRequest.HttpOp.POST);
+ }
+ r.verifyComplete();
+ AsyncOperationImpl<HttpResult> op = new AsyncOperationImpl<>(r.toString());
+ synchronized (requests) {
+ requests.addLast(new Request(r, op));
+ }
+ return op;
+ }
+ @Override
+ public void close() { TestTransport.this.close(); }
+ };
+ private boolean running = true;
+ private final Thread workerThread = new Thread() {
+ @Override
+ public void run() {
+ while (running) {
+ synchronized (requests) {
+ if (requests.isEmpty()) {
+ try {
+ requests.wait(100);
+ } catch (InterruptedException e) { return; }
+ } else {
+ Request request = requests.removeFirst();
+ HttpRequest r = request.request;
+ log.fine("Processing request " + r);
+ HttpRequestHandler handler = getHandler(r);
+ if (handler == null) {
+ if (log.isLoggable(Level.FINE)) {
+ log.fine("Failed to find target for request " + r.toString(true));
+ log.fine("Existing handlers:");
+ for (Socket socket : handlers.keySet()) {
+ log.fine(" Socket " + socket.hostname + ":" + socket.port);
+ for (Handler h : handlers.get(socket)) {
+ log.fine(" " + h.pathPrefix);
+ }
+ }
+ }
+ request.result.setResult(new HttpResult().setHttpCode(
+ 404, "No such server socket with suitable path prefix found open"));
+ } else {
+ try{
+ request.result.setResult(handler.handleRequest(r));
+ } catch (Exception e) {
+ HttpResult result = new HttpResult().setHttpCode(500, e.getMessage());
+ StringWriter sw = new StringWriter();
+ e.printStackTrace(new PrintWriter(sw));
+ result.setContent(sw.toString());
+ request.result.setResult(result);
+ }
+ }
+ //log.fine("Request " + r.toString(true) + " created result " + request.getSecond().getResult().toString(true));
+ }
+ }
+ }
+ }
+ };
+
+ public TestTransport() {
+ workerThread.start();
+ }
+
+ public void close() {
+ if (!running) return;
+ running = false;
+ synchronized (requests) { requests.notifyAll(); }
+ try {
+ workerThread.join();
+ } catch (InterruptedException e) {}
+ }
+
+ /** Get an HTTP client that talks to this test transport layer. */
+ public AsyncHttpClient<HttpResult> getClient() { return client; }
+
+ private HttpRequestHandler getHandler(HttpRequest r) {
+ Socket socket = new Socket(r.getHost(), r.getPort());
+ synchronized (this) {
+ List<Handler> handlerList = handlers.get(socket);
+ if (handlerList == null) {
+ log.fine("No socket match");
+ return null;
+ }
+ log.fine("Socket found");
+ for (Handler h : handlers.get(socket)) {
+ if (r.getPath().length() >= h.pathPrefix.length() && r.getPath().substring(0, h.pathPrefix.length()).equals(h.pathPrefix)) {
+ return h.handler;
+ }
+ }
+ log.fine("No path prefix match");
+ }
+ return null;
+ }
+
+ public void addServer(HttpRequestHandler server, String hostname, int port, String pathPrefix) {
+ Socket socket = new Socket(hostname, port);
+ synchronized (this) {
+ List<Handler> shandlers = handlers.get(socket);
+ if (shandlers == null) {
+ shandlers = new LinkedList<>();
+ handlers.put(socket, shandlers);
+ }
+ shandlers.add(new Handler(server, pathPrefix));
+ }
+ }
+
+ public void removeServer(HttpRequestHandler server, String hostname, int port, String pathPrefix) {
+ Socket socket = new Socket(hostname, port);
+ synchronized (this) {
+ List<Handler> shandlers = handlers.get(socket);
+ if (shandlers == null) return;
+ for (Handler h : shandlers) {
+ if (h.handler == server && h.pathPrefix.equals(pathPrefix)) {
+ shandlers.remove(h);
+ }
+ }
+ }
+ }
+
+}