blob: cde71046ec0e63a4760f1dcc427459553cd91916 [file] [log] [blame]
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package io.v.v23;
import com.google.common.truth.Truth;
import com.google.common.util.concurrent.AsyncFunction;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import io.v.v23.context.VContext;
import io.v.v23.naming.Endpoint;
import io.v.v23.rpc.ListenSpec;
import io.v.v23.rpc.Server;
import io.v.v23.rpc.ServerCall;
import io.v.v23.security.VSecurity;
import io.v.v23.security.access.Permissions;
import io.v.v23.services.permissions.ObjectServer;
import io.v.v23.verror.VException;
import static com.google.common.truth.Truth.assertThat;
/**
* Various Vanadium test utilities.
*/
public class V23TestUtil {
public static VContext withDummyServer(VContext ctx) throws Exception {
ctx = V.withListenSpec(ctx, V.getListenSpec(ctx).withAddress(
new ListenSpec.Address("tcp", "localhost:0")));
return V.withNewServer(ctx, "", new ObjectServer() {
@Override
public ListenableFuture<Void> setPermissions(VContext ctx, ServerCall call,
Permissions permissions,
String version) {
return Futures.immediateFailedFuture(new VException("Unimplemented!"));
}
@Override
public ListenableFuture<ObjectServer.GetPermissionsOut> getPermissions(
VContext ctx, ServerCall call) {
return Futures.immediateFailedFuture(new VException("Unimplemented!"));
}
},
VSecurity.newAllowEveryoneAuthorizer());
}
/**
* Returns the first available endpoint for a server attached to the given context.
*/
public static Endpoint getServerEndpoint(VContext ctx) {
Server server = V.getServer(ctx);
assertThat(server).isNotNull();
assertThat(server.getStatus()).isNotNull();
assertThat(server.getStatus().getEndpoints()).isNotEmpty();
return server.getStatus().getEndpoints()[0];
}
/**
* Asserts that the given future is executed on the provided thread.
* <p>
* Note that this check is inherently racey: if the future has already completed, there is
* no way to check on which thread it got executed. Therefore, this method should be executed
* as close possible to the future's creation, to reduce the chance of the race happening.
* Additionally, the future could be created with an executor that delays execution for a time
* period that sufficient to all but prohibit races (e.g., 100ms).
*/
public static <T> void assertRunsOnThread(ListenableFuture<T> future, final Thread thread) {
try {
assertThat(future.isDone()).isFalse();
Futures.transform(future, new AsyncFunction<T, Void>() {
@Override
public ListenableFuture<Void> apply(T input) throws Exception {
assertThat(Thread.currentThread()).isEqualTo(thread);
return Futures.immediateFuture(null);
}
}).get();
} catch (Exception e) {
Truth.assertWithMessage("error asserting executor").that(e.getMessage()).isEmpty();
}
}
}