summaryrefslogtreecommitdiff
path: root/java
diff options
context:
space:
mode:
authorJose <jose@zeroc.com>2011-05-04 19:46:35 +0200
committerJose <jose@zeroc.com>2011-05-04 19:46:35 +0200
commitd163d1324bb09a5dd00bb0b1cc784d6cb7cc1c25 (patch)
treebdb670583f5fee0ca095ab53a1faee4eff7047c0 /java
parentRPM fixes for RHEL6 (diff)
downloadice-d163d1324bb09a5dd00bb0b1cc784d6cb7cc1c25.tar.bz2
ice-d163d1324bb09a5dd00bb0b1cc784d6cb7cc1c25.tar.xz
ice-d163d1324bb09a5dd00bb0b1cc784d6cb7cc1c25.zip
5053 - Glacier2 helper deadlock
Diffstat (limited to 'java')
-rwxr-xr-xjava/allTests.py1
-rw-r--r--java/build.xml3
-rw-r--r--java/src/Glacier2/SessionHelper.java207
-rw-r--r--java/test/Glacier2/sessionHelper/Callback.ice43
-rw-r--r--java/test/Glacier2/sessionHelper/CallbackI.java40
-rw-r--r--java/test/Glacier2/sessionHelper/Client.java422
-rw-r--r--java/test/Glacier2/sessionHelper/Server.java44
-rw-r--r--java/test/Glacier2/sessionHelper/passwords1
-rwxr-xr-xjava/test/Glacier2/sessionHelper/run.py45
9 files changed, 722 insertions, 84 deletions
diff --git a/java/allTests.py b/java/allTests.py
index df988e7565f..4aa445a64cd 100755
--- a/java/allTests.py
+++ b/java/allTests.py
@@ -69,6 +69,7 @@ tests = [
("Freeze/evictor", ["core"]),
("Freeze/fileLock", ["once"]),
("Glacier2/router", ["service"]),
+ ("Glacier2/sessionHelper", ["service"]),
("IceGrid/simple", ["service"]),
("IceSSL/configuration", ["once"])
]
diff --git a/java/build.xml b/java/build.xml
index 004e4c757e4..3b856c78802 100644
--- a/java/build.xml
+++ b/java/build.xml
@@ -349,6 +349,9 @@
<fileset dir="test/Glacier2/router/">
<include name="Callback.ice" />
</fileset>
+ <fileset dir="test/Glacier2/sessionHelper/">
+ <include name="Callback.ice" />
+ </fileset>
<fileset dir="test/IceGrid/simple/">
<include name="Test.ice" />
</fileset>
diff --git a/java/src/Glacier2/SessionHelper.java b/java/src/Glacier2/SessionHelper.java
index 25e788c8b09..9e1feab644c 100644
--- a/java/src/Glacier2/SessionHelper.java
+++ b/java/src/Glacier2/SessionHelper.java
@@ -108,37 +108,40 @@ public class SessionHelper
* Once the session has been destroyed, {@link SessionCallback.disconnected} is called on
* the associated callback object.
*/
- synchronized public void
+ public void
destroy()
{
- if(_destroy)
+ synchronized(this)
{
- return;
- }
- _destroy = true;
- if(_refreshThread == null)
- {
- //
- // In this case a connecting session is being
- // destroyed. The communicator and session will be
- // destroyed when the connection establishment has
- // completed.
- //
- return;
- }
- _session = null;
+ if(_destroy)
+ {
+ return;
+ }
+ _destroy = true;
+ if(_refreshThread == null)
+ {
+ //
+ // In this case a connecting session is being
+ // destroyed. The communicator and session will be
+ // destroyed when the connection establishment has
+ // completed.
+ //
+ return;
+ }
+ _session = null;
- try
- {
- Runtime.getRuntime().removeShutdownHook(_shutdownHook);
- }
- catch(IllegalStateException ex)
- {
- // Ignore
- }
- catch(SecurityException ex)
- {
- // Ignore
+ try
+ {
+ Runtime.getRuntime().removeShutdownHook(_shutdownHook);
+ }
+ catch(IllegalStateException ex)
+ {
+ // Ignore
+ }
+ catch(SecurityException ex)
+ {
+ // Ignore
+ }
}
//
@@ -311,81 +314,119 @@ public class SessionHelper
});
}
- synchronized private void
+ private void
connected(RouterPrx router, SessionPrx session)
{
- _router = router;
+ Ice.Connection conn = router.ice_getCachedConnection();
+ long timeout = router.getSessionTimeout();
+ String category = router.getCategoryForClient();
- if(_destroy)
+ synchronized(this)
{
- destroyInternal();
- return;
- }
-
- //
- // Cache the category.
- //
- _category = _router.getCategoryForClient();
-
- //
- // Assign the session after _destroy is checked.
- //
- _session = session;
- _connected = true;
-
- assert _refreshThread == null;
- _refreshThread = new SessionRefreshThread(_router, (_router.getSessionTimeout() * 1000)/2);
- _refreshThread.start();
+ _router = router;
- _shutdownHook = new Thread("Shutdown hook")
- {
- public void run()
+ if(_destroy)
{
- SessionHelper.this.destroy();
+ //
+ // Run the destroyInternal in a thread. This is because it
+ // destroyInternal makes remote invocations.
+ //
+ new Thread(new Runnable()
+ {
+ public void run()
+ {
+ destroyInternal();
+ }
+ }).start();
+ return;
}
- };
- try
- {
- Runtime.getRuntime().addShutdownHook(_shutdownHook);
- }
- catch(IllegalStateException e)
- {
//
- // Shutdown in progress, ignored
+ // Cache the category.
//
- }
- catch(SecurityException ex)
- {
+ _category = category;
+
//
- // Ignore. Unsigned applets cannot registered shutdown hooks.
+ // Assign the session after _destroy is checked.
//
- }
+ _session = session;
+ _connected = true;
- dispatchCallback(new Runnable()
- {
- public void run()
+ assert _refreshThread == null;
+ _refreshThread = new SessionRefreshThread(_router, (timeout * 1000)/2);
+ _refreshThread.start();
+
+ _shutdownHook = new Thread("Shutdown hook")
{
- try
- {
- _callback.connected(SessionHelper.this);
- }
- catch(SessionNotExistException ex)
+ public void run()
{
SessionHelper.this.destroy();
}
+ };
+
+ try
+ {
+ Runtime.getRuntime().addShutdownHook(_shutdownHook);
+ }
+ catch(IllegalStateException e)
+ {
+ //
+ // Shutdown in progress, ignored
+ //
+ }
+ catch(SecurityException ex)
+ {
+ //
+ // Ignore. Unsigned applets cannot registered shutdown hooks.
+ //
}
- }, _session.ice_getCachedConnection());
+ }
+
+ dispatchCallback(new Runnable()
+ {
+ public void run()
+ {
+ try
+ {
+ _callback.connected(SessionHelper.this);
+ }
+ catch(SessionNotExistException ex)
+ {
+ SessionHelper.this.destroy();
+ }
+ }
+ }, conn);
}
- synchronized private void
+ private void
destroyInternal()
{
assert _destroy;
+ Glacier2.RouterPrx router = null;
+ Ice.Communicator communicator = null;
+ SessionRefreshThread refreshThread = null;
+ synchronized(this)
+ {
+ if(_router == null)
+ {
+ return;
+ }
+
+ router = _router;
+ _router = null;
+
+ refreshThread = _refreshThread;
+ _refreshThread = null;
+
+ communicator = _communicator;
+ _communicator = null;
+ }
+
+ assert communicator != null;
try
{
- _router.destroySession();
+ router.destroySession();
}
catch(Ice.ConnectionLostException e)
{
@@ -404,36 +445,33 @@ public class SessionHelper
//
// Not expected.
//
- _communicator.getLogger().warning("SessionHelper: unexpected exception when destroying the session:\n" + e);
+ communicator.getLogger().warning("SessionHelper: unexpected exception when destroying the session:\n" + e);
}
- _router = null;
_connected = false;
- if(_refreshThread != null)
+ if(refreshThread != null)
{
- _refreshThread.done();
+ refreshThread.done();
while(true)
{
try
{
- _refreshThread.join();
+ refreshThread.join();
break;
}
catch(InterruptedException e)
{
}
}
- _refreshThread = null;
}
try
{
- _communicator.destroy();
+ communicator.destroy();
}
catch(Throwable ex)
{
}
- _communicator = null;
//
// Notify the callback that the session is gone.
@@ -493,6 +531,7 @@ public class SessionHelper
try
{
_communicator.destroy();
+ _communicator = null;
}
catch(Throwable ex1)
{
diff --git a/java/test/Glacier2/sessionHelper/Callback.ice b/java/test/Glacier2/sessionHelper/Callback.ice
new file mode 100644
index 00000000000..38b591ed67c
--- /dev/null
+++ b/java/test/Glacier2/sessionHelper/Callback.ice
@@ -0,0 +1,43 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2010 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#ifndef CALLBACK_ICE
+#define CALLBACK_ICE
+
+[["java:package:test.Glacier2.sessionHelper"]]
+module Test
+{
+
+exception CallbackException
+{
+ double someValue;
+ string someString;
+};
+
+interface CallbackReceiver
+{
+ void callback();
+
+ void callbackEx()
+ throws CallbackException;
+};
+
+interface Callback
+{
+ void initiateCallback(CallbackReceiver* proxy);
+
+ void initiateCallbackEx(CallbackReceiver* proxy)
+ throws CallbackException;
+
+ void shutdown();
+};
+
+};
+
+#endif
diff --git a/java/test/Glacier2/sessionHelper/CallbackI.java b/java/test/Glacier2/sessionHelper/CallbackI.java
new file mode 100644
index 00000000000..8ad5c72d052
--- /dev/null
+++ b/java/test/Glacier2/sessionHelper/CallbackI.java
@@ -0,0 +1,40 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2010 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+package test.Glacier2.sessionHelper;
+
+import test.Glacier2.sessionHelper.Test.CallbackException;
+import test.Glacier2.sessionHelper.Test.CallbackReceiverPrx;
+import test.Glacier2.sessionHelper.Test._CallbackDisp;
+
+final class CallbackI extends _CallbackDisp
+{
+ CallbackI()
+ {
+ }
+
+ public void
+ initiateCallback(CallbackReceiverPrx proxy, Ice.Current current)
+ {
+ proxy.callback(current.ctx);
+ }
+
+ public void
+ initiateCallbackEx(CallbackReceiverPrx proxy, Ice.Current current)
+ throws CallbackException
+ {
+ proxy.callbackEx(current.ctx);
+ }
+
+ public void
+ shutdown(Ice.Current current)
+ {
+ current.adapter.getCommunicator().shutdown();
+ }
+}
diff --git a/java/test/Glacier2/sessionHelper/Client.java b/java/test/Glacier2/sessionHelper/Client.java
new file mode 100644
index 00000000000..f0ebe58f2c6
--- /dev/null
+++ b/java/test/Glacier2/sessionHelper/Client.java
@@ -0,0 +1,422 @@
+
+package test.Glacier2.sessionHelper;
+
+import javax.swing.SwingUtilities;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import test.Glacier2.sessionHelper.Test.CallbackException;
+import test.Glacier2.sessionHelper.Test.CallbackPrx;
+import test.Glacier2.sessionHelper.Test.CallbackPrxHelper;
+import test.Glacier2.sessionHelper.Test.CallbackReceiverPrx;
+import test.Glacier2.sessionHelper.Test.CallbackReceiverPrxHelper;
+
+public class Client extends test.Util.Application
+{
+ Client()
+ {
+ out = getWriter();
+ me = this;
+ }
+
+ private static void
+ test(boolean b)
+ {
+ if(!b)
+ {
+ throw new RuntimeException();
+ }
+ }
+
+ public int run(String[] args)
+ {
+ Ice.InitializationData initData = new Ice.InitializationData();
+ initData.properties = Ice.Util.createProperties(args);
+ initData.properties.setProperty("Ice.Default.Router", "Glacier2/router:default -p 12347");
+
+ initData.dispatcher = new Ice.Dispatcher()
+ {
+ public void
+ dispatch(Runnable runnable, Ice.Connection connection)
+ {
+ SwingUtilities.invokeLater(runnable);
+ }
+ };
+
+ _factory = new Glacier2.SessionFactoryHelper(initData, new Glacier2.SessionCallback()
+ {
+ public void
+ connected(Glacier2.SessionHelper session)
+ throws Glacier2.SessionNotExistException
+ {
+ test(false);
+ }
+
+ public void
+ disconnected(Glacier2.SessionHelper session)
+ {
+ test(false);
+ }
+
+ public void
+ connectFailed(Glacier2.SessionHelper session, Throwable exception)
+ {
+ try
+ {
+ throw exception;
+ }
+ catch(Glacier2.PermissionDeniedException ex)
+ {
+ out.println("ok");
+ synchronized(test.Glacier2.sessionHelper.Client.this)
+ {
+ test.Glacier2.sessionHelper.Client.wakeUp();
+ }
+ }
+ catch(Throwable ex)
+ {
+ test(false);
+ }
+ }
+
+ public void
+ createdCommunicator(Glacier2.SessionHelper session)
+ {
+ test(session.communicator() != null);
+ }
+ });
+
+ //
+ // Test to create a session with wrong userid/password
+ //
+ synchronized(this)
+ {
+ out.print("testing SessionHelper connect with wrong userid/password... ");
+ out.flush();
+
+ _factory.setRouterHost("127.0.0.1");
+ _factory.setPort(12347);
+ _factory.setRouterIdentity(Ice.Util.stringToIdentity("Glacier2/router"));
+ _factory.setSecure(false);
+ _session = _factory.connect("userid", "xxx");
+ while(true)
+ {
+ try
+ {
+ wait();
+ break;
+ }
+ catch(java.lang.InterruptedException ex)
+ {
+ }
+ }
+ }
+
+ _factory = new Glacier2.SessionFactoryHelper(initData, new Glacier2.SessionCallback()
+ {
+ public void
+ connected(Glacier2.SessionHelper session)
+ throws Glacier2.SessionNotExistException
+ {
+ out.println("ok");
+ synchronized(test.Glacier2.sessionHelper.Client.this)
+ {
+ test.Glacier2.sessionHelper.Client.wakeUp();
+ }
+ }
+
+ public void
+ disconnected(Glacier2.SessionHelper session)
+ {
+ out.println("ok");
+ synchronized(test.Glacier2.sessionHelper.Client.this)
+ {
+ test.Glacier2.sessionHelper.Client.wakeUp();
+ }
+ }
+
+ public void
+ connectFailed(Glacier2.SessionHelper session, Throwable ex)
+ {
+ test(false);
+ }
+
+ public void
+ createdCommunicator(Glacier2.SessionHelper session)
+ {
+ test(session.communicator() != null);
+ }
+ });
+
+ synchronized(this)
+ {
+ out.print("testing SessionHelper connect... ");
+ out.flush();
+ _factory.setRouterHost("127.0.0.1");
+ _factory.setPort(12347);
+ _factory.setRouterIdentity(Ice.Util.stringToIdentity("Glacier2/router"));
+ _factory.setSecure(false);
+ _session = _factory.connect("userid", "abc123");
+ while(true)
+ {
+ try
+ {
+ wait();
+ break;
+ }
+ catch(java.lang.InterruptedException ex)
+ {
+ }
+ }
+
+ out.print("testing SessionHelper isConnected after connect... ");
+ out.flush();
+ test(_session.isConnected());
+ out.println("ok");
+
+ out.print("testing SessionHelper categoryForClient after connect... ");
+ out.flush();
+ try
+ {
+ test(!_session.categoryForClient().equals(""));
+ }
+ catch(Glacier2.SessionNotExistException ex)
+ {
+ test(false);
+ }
+ out.println("ok");
+
+// try
+// {
+// test(_session.session() != null);
+// }
+// catch(Glacier2.SessionNotExistException ex)
+// {
+// test(false);
+// }
+
+ out.print("testing stringToProxy for server object... ");
+ out.flush();
+ Ice.ObjectPrx base = _session.communicator().stringToProxy("callback:tcp -p 12010");
+ out.println("ok");
+
+ out.print("pinging server after session creation... ");
+ out.flush();
+ base.ice_ping();
+ out.println("ok");
+
+ out.print("testing checked cast for server object... ");
+ out.flush();
+ CallbackPrx twoway = CallbackPrxHelper.checkedCast(base);
+ test(twoway != null);
+ out.println("ok");
+
+ out.print("testing server shutdown... ");
+ out.flush();
+ twoway.shutdown();
+ out.println("ok");
+
+ test(_session.communicator() != null);
+ out.print("testing SessionHelper destroy... ");
+ out.flush();
+ _session.destroy();
+ while(true)
+ {
+ try
+ {
+ wait();
+ break;
+ }
+ catch(java.lang.InterruptedException ex)
+ {
+ }
+ }
+
+ out.print("testing SessionHelper isConnected after destroy... ");
+ out.flush();
+ test(_session.isConnected() == false);
+ out.println("ok");
+
+ out.print("testing SessionHelper categoryForClient after destroy... ");
+ out.flush();
+ try
+ {
+ test(!_session.categoryForClient().equals(""));
+ test(false);
+ }
+ catch(Glacier2.SessionNotExistException ex)
+ {
+ }
+ out.println("ok");
+
+ out.print("testing SessionHelper session after destroy... ");
+ try
+ {
+ Glacier2.SessionPrx session = _session.session();
+ test(false);
+ }
+ catch(Glacier2.SessionNotExistException ex)
+ {
+ }
+ out.println("ok");
+
+ out.print("testing SessionHelper communicator after destroy... ");
+ out.flush();
+ test(_session.communicator() == null);
+ out.println("ok");
+
+
+ out.print("uninstalling router with communicator... ");
+ out.flush();
+ communicator().setDefaultRouter(null);
+ out.println("ok");
+
+ Ice.ObjectPrx processBase;
+ {
+ out.print("testing stringToProxy for process object... ");
+ processBase = communicator().stringToProxy("Glacier2/admin -f Process:tcp -h 127.0.0.1 -p 12348");
+ out.println("ok");
+ }
+
+
+ Ice.ProcessPrx process;
+ {
+ out.print("testing checked cast for admin object... ");
+ process = Ice.ProcessPrxHelper.checkedCast(processBase);
+ test(process != null);
+ out.println("ok");
+ }
+
+ out.print("testing Glacier2 shutdown... ");
+ process.shutdown();
+ try
+ {
+ process.ice_ping();
+ test(false);
+ }
+ catch(Ice.LocalException ex)
+ {
+ out.println("ok");
+ }
+ }
+
+ _factory = new Glacier2.SessionFactoryHelper(initData, new Glacier2.SessionCallback()
+ {
+ public void
+ connected(Glacier2.SessionHelper session)
+ throws Glacier2.SessionNotExistException
+ {
+ test(false);
+ }
+
+ public void
+ disconnected(Glacier2.SessionHelper session)
+ {
+ test(false);
+ }
+
+ public void
+ connectFailed(Glacier2.SessionHelper session, Throwable exception)
+ {
+ try
+ {
+ throw exception;
+ }
+ catch(Ice.ConnectionRefusedException ex)
+ {
+ out.println("ok");
+ synchronized(test.Glacier2.sessionHelper.Client.this)
+ {
+ test.Glacier2.sessionHelper.Client.wakeUp();
+ }
+ }
+ catch(Throwable ex)
+ {
+ test(false);
+ }
+ }
+
+ public void
+ createdCommunicator(Glacier2.SessionHelper session)
+ {
+ test(session.communicator() != null);
+ }
+ });
+
+ //
+ // Wait a bit to ensure glaci2router has been shutdown.
+ //
+ while(true)
+ {
+ try
+ {
+ Thread.sleep(100);
+ break;
+ }
+ catch(java.lang.InterruptedException ex)
+ {
+ }
+ }
+
+ synchronized(this)
+ {
+ out.print("testing SessionHelper connect after router shutdown... ");
+ out.flush();
+
+ _factory.setRouterHost("127.0.0.1");
+ _factory.setPort(12347);
+ _factory.setRouterIdentity(Ice.Util.stringToIdentity("Glacier2/router"));
+ _factory.setSecure(false);
+ _session = _factory.connect("userid", "abc123");
+ while(true)
+ {
+ try
+ {
+ wait();
+ break;
+ }
+ catch(java.lang.InterruptedException ex)
+ {
+ }
+ }
+
+ out.print("testing SessionHelper isConnect after connect failure... ");
+ out.flush();
+ test(_session.isConnected() == false);
+ out.println("ok");
+
+ out.print("testing SessionHelper communicator after connect failure... ");
+ out.flush();
+ test(_session.communicator() == null);
+ out.println("ok");
+
+ out.print("testing SessionHelper destroy after connect failure... ");
+ out.flush();
+ _session.destroy();
+ out.println("ok");
+ }
+
+ return 0;
+ }
+
+ public static void
+ wakeUp()
+ {
+ me.notify();
+ }
+
+ public static void
+ main(String[] args)
+ {
+ Client c = new Client();
+ int status = c.main("Client", args);
+
+ System.gc();
+ System.exit(status);
+ }
+
+ private Glacier2.SessionHelper _session;
+ private Glacier2.SessionFactoryHelper _factory;
+ static public Client me;
+ final public PrintWriter out;
+}
diff --git a/java/test/Glacier2/sessionHelper/Server.java b/java/test/Glacier2/sessionHelper/Server.java
new file mode 100644
index 00000000000..ae9838f3523
--- /dev/null
+++ b/java/test/Glacier2/sessionHelper/Server.java
@@ -0,0 +1,44 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2010 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+package test.Glacier2.sessionHelper;
+
+public class Server extends test.Util.Application
+{
+ public int
+ run(String[] args)
+ {
+ communicator().getProperties().setProperty("CallbackAdapter.Endpoints", "tcp -p 12010");
+ Ice.ObjectAdapter adapter = communicator().createObjectAdapter("CallbackAdapter");
+ adapter.add(new CallbackI(), communicator().stringToIdentity("callback"));
+ adapter.activate();
+ communicator().waitForShutdown();
+ return 0;
+ }
+
+
+ protected Ice.InitializationData getInitData(Ice.StringSeqHolder argsH)
+ {
+ Ice.InitializationData initData = new Ice.InitializationData();
+ initData.properties = Ice.Util.createProperties(argsH);
+ initData.properties.setProperty("Ice.Package.Test", "test.Glacier2.router");
+
+ return initData;
+ }
+
+ public static void
+ main(String[] args)
+ {
+ Server c = new Server();
+ int status = c.main("Server", args);
+
+ System.gc();
+ System.exit(status);
+ }
+}
diff --git a/java/test/Glacier2/sessionHelper/passwords b/java/test/Glacier2/sessionHelper/passwords
new file mode 100644
index 00000000000..a1527dec2b9
--- /dev/null
+++ b/java/test/Glacier2/sessionHelper/passwords
@@ -0,0 +1 @@
+userid xxMqsnnDcK8tw \ No newline at end of file
diff --git a/java/test/Glacier2/sessionHelper/run.py b/java/test/Glacier2/sessionHelper/run.py
new file mode 100755
index 00000000000..37c77de8169
--- /dev/null
+++ b/java/test/Glacier2/sessionHelper/run.py
@@ -0,0 +1,45 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# Copyright (c) 2003-2010 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+import os, sys
+
+path = [ ".", "..", "../..", "../../..", "../../../.." ]
+head = os.path.dirname(sys.argv[0])
+if len(head) > 0:
+ path = [os.path.join(head, p) for p in path]
+path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ]
+if len(path) == 0:
+ raise "can't find toplevel directory!"
+sys.path.append(os.path.join(path[0]))
+from scripts import *
+
+router = os.path.join(TestUtil.getCppBinDir(), "glacier2router")
+
+args = ' --Ice.Warn.Dispatch=0' + \
+ ' --Ice.Warn.Connections=0' + \
+ ' --Glacier2.SessionTimeout="30"' + \
+ ' --Glacier2.Client.Endpoints="default -p 12347"' + \
+ ' --Glacier2.Server.Endpoints="tcp -h 127.0.0.1"' \
+ ' --Ice.Admin.Endpoints="tcp -h 127.0.0.1 -p 12348"' + \
+ ' --Ice.Admin.InstanceName=Glacier2' + \
+ ' --Glacier2.CryptPasswords="' + os.path.join(os.getcwd(), "passwords") + '"'
+
+print "starting router...",
+routerConfig = TestUtil.DriverConfig("server")
+routerConfig.lang = "cpp"
+starterProc = TestUtil.startServer(router, args, count=2, config=routerConfig)
+print "ok"
+
+
+
+TestUtil.clientServerTest(additionalClientOptions=" --shutdown")
+
+starterProc.waitTestSuccess()
+