public void replace(Map<Address, Response> newResponses) { assertFalse(request.resultFuture.isDone()); log.tracef("Replacing responses for %s: %s (was %s)", request.getCommand(), newResponses, responseMap); newResponses.forEach(request::collectResponse); if (!request.isDone()) { request.collectFinish(); } }
public void receive(Map<Address, Response> responses) { log.tracef("Faking responses for %s: %s", request.getCommand(), responses); responses.forEach((sender, response) -> { // For staggered requests we allow the test to specify only the primary owner's response assertTrue(responses.containsKey(sender)); request.collectResponse(sender, response); }); if (!request.isDone()) { assertEquals(responses.keySet(), request.responseFutures.keySet()); request.collectFinish(); } }
private void queueFinish() { log.tracef("Queueing finish for command %s", command); Map<Address, Response> responseMap = new LinkedHashMap<>(); for (Map.Entry<Address, CompletableFuture<Response>> entry : responseFutures.entrySet()) { Address sender = entry.getKey(); CompletableFuture<Response> responseFuture = entry.getValue(); // Don't wait for all responses in case this is a staggered request if (responseFuture.isDone()) { responseMap.put(sender, uncheckedGet(responseFuture)); } else { responseFuture.complete(null); } } boolean completedNow = finishFuture.complete(responseMap); if (!completedNow) { fail(new IllegalStateException("Finish queued more than once")); } }
(rpcOptions != null && rpcOptions.deliverOrder() != DeliverOrder.TOTAL) ? realOne.getAddress() : null; ControlledRequest<T> controlledRequest = new ControlledRequest<>(command, targets, collector, invoker, executor, excluded); requests.add(controlledRequest); try { () -> { TimeoutException e = new TimeoutException("Timed out waiting for test to unblock command " + controlledRequest.getCommand()); addGlobalError(e); controlledRequest.fail(e); }, TIMEOUT_SECONDS * 2, SECONDS);
public T getCommand() { return (T) request.getCommand(); }
public void fail(Exception e) { request.fail(e); }
public Collection<Address> getTargets() { return request.getTargets(); }
/** * Expect a command to be invoked remotely and send replies using the {@link BlockedRequest} methods. */ public <T extends ReplicableCommand> CompletableFuture<BlockedRequest> expectCommandAsync(Class<T> expectedCommandClass) { throwGlobalError(); log.tracef("Waiting for command %s", expectedCommandClass); CompletableFuture<ControlledRequest> future = new CompletableFuture<>(); waiters.add(future); return future.thenApply(request -> { log.tracef("Blocked command %s", request.command); assertTrue("Expecting a " + expectedCommandClass.getName() + ", got " + request.getCommand(), expectedCommandClass.isInstance(request.getCommand())); return new BlockedRequest<T>(request); }); }
/** * Unblock the request, sending it to its targets. * <p> * It will block again when waiting for responses. */ public SentRequest send() { log.tracef("Sending command %s", request.getCommand()); request.send(); if (request.hasCollector()) { return new SentRequest(request); } else { return null; } }
public Collection<Address> getTargets() { return request.getTargets(); }
private void queueResponse(Address sender, Response response) { log.tracef("Queueing response from %s for command %s", sender, command); CompletableFuture<Response> responseFuture = responseFutures.get(sender); boolean completedNow = responseFuture.complete(response); if (!completedNow) { fail(new IllegalStateException("Duplicate response received from " + sender + ": " + response)); } }
/** * Expect a command to be invoked remotely and send replies using the {@link BlockedRequest} methods. */ public <T extends ReplicableCommand> BlockedRequest expectCommand(Class<T> expectedCommandClass, Consumer<T> checker) { BlockedRequest blockedRequest = uncheckedGet(expectCommandAsync(expectedCommandClass)); T command = expectedCommandClass.cast(blockedRequest.request.getCommand()); checker.accept(command); return blockedRequest; }
public CompletionStage<BlockedResponse> expectResponseAsync(Address sender) { request.throwIfFailed(); assertFalse(request.isDone()); return request.responseFuture(sender).thenApply(response -> { log.debugf("Got response for %s from %s: %s", request.getCommand(), sender, response); return new BlockedResponse(request, this, sender, response); }); }
/** * Complete the request with a custom exception. */ private void fail(Throwable e) { assertFalse(request.resultFuture.isDone()); request.fail(e); }
public Address getTarget() { Collection<Address> targets = request.getTargets(); assertEquals(1, targets.size()); return targets.iterator().next(); } }
/** * Process the response from this {@code BlockedResponse}'s target. * <p> * Note that processing the last response will NOT complete the request, you still need to call * {@link SentRequest#receiveAll()}. */ public SentRequest receive() { log.tracef("Unblocking response from %s: %s", sender, response); request.collectResponse(this.sender, response); return sentRequest; }
/** * Replace the response from this {@code BlockedResponse}'s target with a fake response and process it. */ public SentRequest replace(Response newResponse) { log.tracef("Replacing response from %s: %s (was %s)", sender, newResponse, response); request.collectResponse(this.sender, newResponse); return sentRequest; }
/** * Complete a request after expecting and receiving responses individually, e.g. with * {@link #expectResponse(Address)}. * * This method blocks until all the responses have been received internally, but doesn't pass them on * to the original response collector (it only calls {@link ResponseCollector#finish()}). */ public void finish() { request.collectFinish(); }
public CompletionStage<BlockedResponseMap> expectAllResponsesAsync() { request.throwIfFailed(); assertFalse(request.isDone()); return request.finishFuture() .thenApply(responseMap -> new BlockedResponseMap(request, responseMap)); } }