// Path: core/src/main/java/com/threerings/nexus/distrib/DService.java
// public abstract class DService<T extends NexusService> implements DAttribute
// {
//     /** Used to create service attributes. */
//     public interface Factory<T extends NexusService>
//     {
//         /** Creates a service attribute with the supplied owner. */
//         DService<T> createService (NexusObject owner);
//     }
// 
//     /** An implementation detail used by service dispatchers. */
//     public static abstract class Dispatcher<T extends NexusService> extends DService<T> {
//         /** Dispatches a service call that came in over the network. */
//         public RFuture<?> dispatchCall (short methodId, Object[] args) {
//             throw new IllegalArgumentException("Unknown service method [id=" + methodId +
//                                                ", obj=" + _owner.getClass().getName() +
//                                                ", attrIdx=" + _index + "]");
//         }
// 
//         protected Dispatcher (NexusObject owner) {
//             super(owner);
//         }
// 
//         /** Used to concisely, and without warning, cast arguments of generic type. */
//         @SuppressWarnings("unchecked")
//         protected final <C> C cast (Object obj) {
//             return (C)obj;
//         }
//     }
// 
//     /** Returns the service encapsulated by this attribute. */
//     public abstract T get ();
// 
//     /** Returns the class for the service encapsulated by this attribute. */
//     public abstract Class<T> getServiceClass ();
// 
//     @Override public void readContents (Streamable.Input in) {
//         // NOOP
//     }
// 
//     @Override public void writeContents (Streamable.Output out) {
//         // NOOP
//     }
// 
//     protected DService (NexusObject owner) {
//         _owner = owner;
//         _index = owner.registerAttr(this);
//     }
// 
//     /** Used by marshallers to dispatch calls over the network. */
//     protected <R> RFuture<R> postCall (short methodId, Object... args) {
//         RPromise<R> result = RPromise.create();
//         _owner.postCall(_index, methodId, args, result);
//         return result;
//     }
// 
//     /** Used by marshallers to dispatch calls over the network. */
//     protected void postVoidCall (short methodId, Object... args) {
//         _owner.postCall(_index, methodId, args, null);
//     }
// 
//     /** The object that owns this attribute. */
//     protected final NexusObject _owner;
// 
//     /** The index of this attribute in its containing object. */
//     protected final short _index;
// }
// 
// Path: test-support/src/main/java/com/threerings/nexus/distrib/Factory_TestService.java
// public class Factory_TestService implements DService.Factory<TestService>
// {
//     @Override
//     public DService<TestService> createService (NexusObject owner)
//     {
//         return new Marshaller(owner);
//     }
// 
//     public static DService.Factory<TestService> createDispatcher (final TestService service)
//     {
//         return new DService.Factory<TestService>() {
//             public DService<TestService> createService (NexusObject owner) {
//                 return new DService.Dispatcher<TestService>(owner) {
//                     @Override public TestService get () {
//                         return service;
//                     }
// 
//                     @Override public Class<TestService> getServiceClass () {
//                         return TestService.class;
//                     }
// 
//                     @Override public RFuture<?> dispatchCall (short methodId, Object[] args) {
//                         RFuture<?> result = null;
//                         switch (methodId) {
//                         case 1:
//                             result = service.addOne(
//                                 this.<Integer>cast(args[0]));
//                             break;
//                         case 2:
//                             service.launchMissiles();
//                             break;
//                         default:
//                             result = super.dispatchCall(methodId, args);
//                             break;
//                         }
//                         return result;
//                     }
//                 };
//             }
//         };
//     }
// 
//     protected static class Marshaller extends DService<TestService> implements TestService
//     {
//         public Marshaller (NexusObject owner) {
//             super(owner);
//         }
//         @Override public TestService get () {
//             return this;
//         }
//         @Override public Class<TestService> getServiceClass () {
//             return TestService.class;
//         }
//         @Override public RFuture<Integer> addOne (int value) {
//             return this.<Integer>postCall((short)1, value);
//         }
//         @Override public void launchMissiles () {
//             postCall((short)2);
//         }
//     }
// }
// 
// Path: test-support/src/main/java/com/threerings/nexus/distrib/TestService.java
// public interface TestService extends NexusService
// {
//     /** Adds one to the supplied value. */
//     RFuture<Integer> addOne (int value);
// 
//     /** Launches the missiles. Who needs confirmation for that? Pah! */
//     void launchMissiles ();
// }


import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
import react.RFuture;
import com.threerings.nexus.distrib.DService;
import com.threerings.nexus.distrib.Factory_TestService;
import com.threerings.nexus.distrib.TestService;
import org.junit.Assert;
//
// Nexus JVMServer - server-side support for Nexus java.nio-based services
// http://github.com/threerings/nexus/blob/master/LICENSE

package com.threerings.nexus.server;





/**
 * Test-related utility methods.
 */
public class TestUtil
{
    public static NexusConfig createTestConfig () {
        Properties props = new Properties();
        props.setProperty("nexus.node", "test");
        props.setProperty("nexus.hostname", "localhost");
        props.setProperty("nexus.rpc_timeout", "1000");
        return new NexusConfig(props);
    }

    public static void awaitTermination (ExecutorService exec) {
        try {
            if (!exec.awaitTermination(2, TimeUnit.SECONDS)) { // TODO: change back to 10
                Assert.fail("Executor failed to terminate after 10 seconds.");
            }
        } catch (InterruptedException ie) {
            Assert.fail("Executor interrupted?");
        }
    }

// Path: core/src/main/java/com/threerings/nexus/distrib/DService.java
// public abstract class DService<T extends NexusService> implements DAttribute
// {
//     /** Used to create service attributes. */
//     public interface Factory<T extends NexusService>
//     {
//         /** Creates a service attribute with the supplied owner. */
//         DService<T> createService (NexusObject owner);
//     }
// 
//     /** An implementation detail used by service dispatchers. */
//     public static abstract class Dispatcher<T extends NexusService> extends DService<T> {
//         /** Dispatches a service call that came in over the network. */
//         public RFuture<?> dispatchCall (short methodId, Object[] args) {
//             throw new IllegalArgumentException("Unknown service method [id=" + methodId +
//                                                ", obj=" + _owner.getClass().getName() +
//                                                ", attrIdx=" + _index + "]");
//         }
// 
//         protected Dispatcher (NexusObject owner) {
//             super(owner);
//         }
// 
//         /** Used to concisely, and without warning, cast arguments of generic type. */
//         @SuppressWarnings("unchecked")
//         protected final <C> C cast (Object obj) {
//             return (C)obj;
//         }
//     }
// 
//     /** Returns the service encapsulated by this attribute. */
//     public abstract T get ();
// 
//     /** Returns the class for the service encapsulated by this attribute. */
//     public abstract Class<T> getServiceClass ();
// 
//     @Override public void readContents (Streamable.Input in) {
//         // NOOP
//     }
// 
//     @Override public void writeContents (Streamable.Output out) {
//         // NOOP
//     }
// 
//     protected DService (NexusObject owner) {
//         _owner = owner;
//         _index = owner.registerAttr(this);
//     }
// 
//     /** Used by marshallers to dispatch calls over the network. */
//     protected <R> RFuture<R> postCall (short methodId, Object... args) {
//         RPromise<R> result = RPromise.create();
//         _owner.postCall(_index, methodId, args, result);
//         return result;
//     }
// 
//     /** Used by marshallers to dispatch calls over the network. */
//     protected void postVoidCall (short methodId, Object... args) {
//         _owner.postCall(_index, methodId, args, null);
//     }
// 
//     /** The object that owns this attribute. */
//     protected final NexusObject _owner;
// 
//     /** The index of this attribute in its containing object. */
//     protected final short _index;
// }
// 
// Path: test-support/src/main/java/com/threerings/nexus/distrib/Factory_TestService.java
// public class Factory_TestService implements DService.Factory<TestService>
// {
//     @Override
//     public DService<TestService> createService (NexusObject owner)
//     {
//         return new Marshaller(owner);
//     }
// 
//     public static DService.Factory<TestService> createDispatcher (final TestService service)
//     {
//         return new DService.Factory<TestService>() {
//             public DService<TestService> createService (NexusObject owner) {
//                 return new DService.Dispatcher<TestService>(owner) {
//                     @Override public TestService get () {
//                         return service;
//                     }
// 
//                     @Override public Class<TestService> getServiceClass () {
//                         return TestService.class;
//                     }
// 
//                     @Override public RFuture<?> dispatchCall (short methodId, Object[] args) {
//                         RFuture<?> result = null;
//                         switch (methodId) {
//                         case 1:
//                             result = service.addOne(
//                                 this.<Integer>cast(args[0]));
//                             break;
//                         case 2:
//                             service.launchMissiles();
//                             break;
//                         default:
//                             result = super.dispatchCall(methodId, args);
//                             break;
//                         }
//                         return result;
//                     }
//                 };
//             }
//         };
//     }
// 
//     protected static class Marshaller extends DService<TestService> implements TestService
//     {
//         public Marshaller (NexusObject owner) {
//             super(owner);
//         }
//         @Override public TestService get () {
//             return this;
//         }
//         @Override public Class<TestService> getServiceClass () {
//             return TestService.class;
//         }
//         @Override public RFuture<Integer> addOne (int value) {
//             return this.<Integer>postCall((short)1, value);
//         }
//         @Override public void launchMissiles () {
//             postCall((short)2);
//         }
//     }
// }
// 
// Path: test-support/src/main/java/com/threerings/nexus/distrib/TestService.java
// public interface TestService extends NexusService
// {
//     /** Adds one to the supplied value. */
//     RFuture<Integer> addOne (int value);
// 
//     /** Launches the missiles. Who needs confirmation for that? Pah! */
//     void launchMissiles ();
// }


// Path: jvm-server/src/test/java/com/threerings/nexus/server/TestUtil.java
import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
import react.RFuture;
import com.threerings.nexus.distrib.DService;
import com.threerings.nexus.distrib.Factory_TestService;
import com.threerings.nexus.distrib.TestService;
import org.junit.Assert;

//
// Nexus JVMServer - server-side support for Nexus java.nio-based services
// http://github.com/threerings/nexus/blob/master/LICENSE

package com.threerings.nexus.server;





/**
 * Test-related utility methods.
 */
public class TestUtil
{
    public static NexusConfig createTestConfig () {
        Properties props = new Properties();
        props.setProperty("nexus.node", "test");
        props.setProperty("nexus.hostname", "localhost");
        props.setProperty("nexus.rpc_timeout", "1000");
        return new NexusConfig(props);
    }

    public static void awaitTermination (ExecutorService exec) {
        try {
            if (!exec.awaitTermination(2, TimeUnit.SECONDS)) { // TODO: change back to 10
                Assert.fail("Executor failed to terminate after 10 seconds.");
            }
        } catch (InterruptedException ie) {
            Assert.fail("Executor interrupted?");
        }
    }

    public static DService.Factory<TestService> createTestServiceAttr () {