summaryrefslogtreecommitdiff
path: root/js/test/Ice/acm/Client.js
diff options
context:
space:
mode:
authorBenoit Foucher <benoit@zeroc.com>2014-05-23 11:59:44 +0200
committerBenoit Foucher <benoit@zeroc.com>2014-05-23 11:59:44 +0200
commitd81701ca8182942b7936f9fd84a019b695e9c890 (patch)
treedc036c9d701fbbe1afad67782bd78572c0f61974 /js/test/Ice/acm/Client.js
parentFixed bug ICE-5543: stringToIdentity bug with escaped escapes (diff)
downloadice-d81701ca8182942b7936f9fd84a019b695e9c890.tar.bz2
ice-d81701ca8182942b7936f9fd84a019b695e9c890.tar.xz
ice-d81701ca8182942b7936f9fd84a019b695e9c890.zip
Added support for invocation timeouts and ACM heartbeats
Diffstat (limited to 'js/test/Ice/acm/Client.js')
-rw-r--r--js/test/Ice/acm/Client.js517
1 files changed, 517 insertions, 0 deletions
diff --git a/js/test/Ice/acm/Client.js b/js/test/Ice/acm/Client.js
new file mode 100644
index 00000000000..8749d1afac1
--- /dev/null
+++ b/js/test/Ice/acm/Client.js
@@ -0,0 +1,517 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 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.
+//
+// **********************************************************************
+
+(function(global){
+ var require = typeof(module) !== "undefined" ? module.require : function(){};
+ require("Ice/Ice");
+ var Ice = global.Ice;
+
+ require("Test");
+ var Test = global.Test;
+ var Promise = Ice.Promise;
+
+ var test = function(b)
+ {
+ if(!b)
+ {
+ throw new Error("test failed");
+ }
+ };
+
+ var LoggerI = Ice.Class({
+ __init__: function(out)
+ {
+ this._messages = [];
+ this._out = out;
+ },
+ print: function(msg)
+ {
+ this._messages.push(msg);
+ },
+ trace: function(category, message)
+ {
+ this._messages.push("[" + category + "] " + message);
+ },
+ warning: function(message)
+ {
+ this._messages.push("warning: " + message);
+ },
+ error: function(message)
+ {
+ this._messages.push("error: " + message);
+ },
+ cloneWithPrefix: function(prefix)
+ {
+ return this;
+ },
+ dump: function()
+ {
+ for(var i = 0; i < this._messages.length; ++i)
+ {
+ this._out.writeLine(this._messages[i]);
+ }
+ this._messages = [];
+ }
+ });
+
+ var TestCase = Ice.Class({
+ __init__: function(name, com, out)
+ {
+ this._name = name;
+ this._com = com;
+ this._logger = new LoggerI(out);
+
+ this._clientACMTimeout = -1;
+ this._clientACMClose = -1;
+ this._clientACMHeartbeat = -1;
+
+ this._serverACMTimeout = -1;
+ this._serverACMClose = -1;
+ this._serverACMHeartbeat = -1;
+
+ this._heartbeat = 0;
+ this._closed = false;
+ },
+ init: function()
+ {
+ var initData = new Ice.InitializationData();
+ initData.properties = this._com.ice_getCommunicator().getProperties().clone();
+ initData.logger = this._logger;
+ initData.properties.setProperty("Ice.ACM.Timeout", "1");
+ if(this._clientACMTimeout >= 0)
+ {
+ initData.properties.setProperty("Ice.ACM.Client.Timeout", "" + this._clientACMTimeout);
+ }
+ if(this._clientACMClose >= 0)
+ {
+ initData.properties.setProperty("Ice.ACM.Client.Close", "" + this._clientACMClose);
+ }
+ if(this._clientACMHeartbeat >= 0)
+ {
+ initData.properties.setProperty("Ice.ACM.Client.Heartbeat", "" + this._clientACMHeartbeat);
+ }
+ //initData.properties.setProperty("Ice.Trace.Protocol", "2");
+ //initData.properties.setProperty("Ice.Trace.Network", "2");
+ this._communicator = Ice.initialize(initData);
+
+ var self = this;
+ return this._com.createObjectAdapter(this._serverACMTimeout,
+ this._serverACMClose,
+ this._serverACMHeartbeat).then(function(adapter)
+ {
+ self._adapter = adapter;
+ });
+ },
+ destroy: function()
+ {
+ var self = this;
+ return this._adapter.deactivate().then(function()
+ {
+ return self._communicator.destroy();
+ });
+ },
+ join: function(out)
+ {
+ this._logger.dump();
+ out.write("testing " + this._name + "... ");
+ if(this._msg == null)
+ {
+ out.writeLine("ok");
+ }
+ else
+ {
+ out.writeLine("failed! " + this._msg);
+ test(false);
+ }
+ },
+ start: function()
+ {
+ var proxy = null;
+ var self = this;
+ return this._adapter.getTestIntf().then(
+ function(prx)
+ {
+ proxy = Test.TestIntfPrx.uncheckedCast(self._communicator.stringToProxy(prx.toString()));
+ return proxy.ice_getConnection();
+ }
+ ).then(
+ function(con)
+ {
+ con.setCallback(self);
+ return self.runTestCase(self._adapter, proxy);
+ }
+ ).exception(
+ function(ex)
+ {
+ self._msg = "unexpected exception:\n" + ex.stack;
+ }
+ );
+ },
+ heartbeat: function(con)
+ {
+ ++this._heartbeat;
+ },
+ closed: function(con)
+ {
+ this._closed = true;
+ },
+ runTestCase: function(adapter, proxy)
+ {
+ test(false); // Abstract
+ },
+ setClientACM: function(timeout, close, heartbeat)
+ {
+ this._clientACMTimeout = timeout;
+ this._clientACMClose = close;
+ this._clientACMHeartbeat = heartbeat;
+ },
+ setServerACM: function(timeout, close, heartbeat)
+ {
+ this._serverACMTimeout = timeout;
+ this._serverACMClose = close;
+ this._serverACMHeartbeat = heartbeat;
+ }
+ });
+
+ var InvocationHeartbeatTest = Ice.Class(TestCase, {
+ __init__: function(com, out)
+ {
+ TestCase.call(this, "invocation heartbeat", com, out);
+ },
+ runTestCase: function(adapter, proxy)
+ {
+ var self = this;
+ return proxy.sleep(2).then(
+ function()
+ {
+ test(self._heartbeat >= 2);
+ }
+ );
+ }
+ });
+
+ var InvocationHeartbeatOnHoldTest = Ice.Class(TestCase, {
+ __init__: function(com, out)
+ {
+ TestCase.call(this, "invocation with heartbeat on hold", com, out);
+ // Use default ACM configuration.
+ },
+ runTestCase: function(adapter, proxy)
+ {
+ // When the OA is put on hold, connections shouldn't
+ // send heartbeats, the invocation should therefore
+ // fail.
+ var self = this;
+ return proxy.sleepAndHold(10).then(
+ function()
+ {
+ test(false);
+ },
+ function(ex)
+ {
+ test(self._closed);
+ return adapter.activate().then(function()
+ {
+ return proxy.interruptSleep();
+ });
+ }
+ );
+ }
+ });
+
+ var InvocationNoHeartbeatTest = Ice.Class(TestCase, {
+ __init__: function(com, out)
+ {
+ TestCase.call(this, "invocation with no heartbeat", com, out);
+ this.setServerACM(1, 2, 0); // Disable heartbeat on invocations
+ },
+ runTestCase: function(adapter, proxy)
+ {
+ // Heartbeats are disabled on the server, the
+ // invocation should fail since heartbeats are
+ // expected.
+ var self = this;
+ return proxy.sleep(10).then(
+ function()
+ {
+ test(false);
+ },
+ function(ex)
+ {
+ test(self._heartbeat == 0);
+ test(self._closed);
+ return proxy.interruptSleep();
+ }
+ );
+ }
+ });
+
+ var InvocationHeartbeatCloseOnIdleTest = Ice.Class(TestCase, {
+ __init__: function(com, out)
+ {
+ TestCase.call(this, "invocation with no heartbeat and close on idle", com, out);
+ this.setClientACM(1, 1, 0); // Only close on idle.
+ this.setServerACM(1, 2, 0); // Disable heartbeat on invocations
+ },
+ runTestCase: function(adapter, proxy)
+ {
+ // No close on invocation, the call should succeed this
+ // time.
+ var self = this;
+ return proxy.sleep(2).then(function()
+ {
+ test(self._heartbeat == 0);
+ test(!self._closed);
+ });
+ }
+ });
+
+ var CloseOnIdleTest = Ice.Class(TestCase, {
+ __init__: function(com, out)
+ {
+ TestCase.call(this, "close on idle", com, out);
+ this.setClientACM(1, 1, 0); // Only close on idle
+ },
+ runTestCase: function(adapter, proxy)
+ {
+ var self = this;
+ return Ice.Promise.delay(1500).then(function()
+ {
+ test(self._heartbeat == 0);
+ test(self._closed);
+ });
+ }
+ });
+
+ var CloseOnInvocationTest = Ice.Class(TestCase, {
+ __init__: function(com, out)
+ {
+ TestCase.call(this, "close on invocation", com, out);
+ this.setClientACM(1, 2, 0); // Only close on invocation
+ },
+ runTestCase: function(adapter, proxy)
+ {
+ var self = this;
+ return Ice.Promise.delay(1500).then(function()
+ {
+ test(self._heartbeat == 0);
+ test(!self._closed);
+ });
+ }
+ });
+
+ var CloseOnIdleAndInvocationTest = Ice.Class(TestCase, {
+ __init__: function(com, out)
+ {
+ TestCase.call(this, "close on idle and invocation", com, out);
+ this.setClientACM(1, 3, 0); // Only close on idle and invocation
+ },
+ runTestCase: function(adapter, proxy)
+ {
+ //
+ // Put the adapter on hold. The server will not respond to
+ // the graceful close. This allows to test whether or not
+ // the close is graceful or forceful.
+ //
+ var self = this;
+ return adapter.hold().delay(1500).then(
+ function()
+ {
+ test(self._heartbeat == 0);
+ test(!self._closed); // Not closed yet because of graceful close.
+ return adapter.activate();
+ }
+ ).delay(500).then(
+ function()
+ {
+ test(self._closed); // Connection should be closed this time.
+ }
+ );
+ }
+ });
+
+ var ForcefullCloseOnIdleAndInvocationTest = Ice.Class(TestCase, {
+ __init__: function(com, out)
+ {
+ TestCase.call(this, "forcefull close on idle and invocation", com, out);
+ this.setClientACM(1, 4, 0); // Only close on idle and invocation
+ },
+ runTestCase: function(adapter, proxy)
+ {
+ var self = this;
+ return adapter.hold().delay(1500).then(
+ function()
+ {
+ test(self._heartbeat == 0);
+ test(self._closed); // Connection closed forcefully by ACM
+ });
+ }
+ });
+
+ var HeartbeatOnIdleTest = Ice.Class(TestCase, {
+ __init__: function(com, out)
+ {
+ TestCase.call(this, "heartbeat on idle", com, out);
+ this.setServerACM(1, -1, 2); // Enable server heartbeats.
+ },
+ runTestCase: function(adapter, proxy)
+ {
+ var self = this;
+ return Ice.Promise.delay(2000).then(
+ function()
+ {
+ test(self._heartbeat >= 3);
+ });
+ }
+ });
+
+ var HeartbeatAlwaysTest = Ice.Class(TestCase, {
+ __init__: function(com, out)
+ {
+ TestCase.call(this, "heartbeat always", com, out);
+ this.setServerACM(1, -1, 3); // Enable server heartbeats.
+ },
+ runTestCase: function(adapter, proxy)
+ {
+ var self = this;
+ var p = new Ice.Promise().succeed();
+ for(var i = 0; i < 10; ++i)
+ {
+ p = p.then(function()
+ {
+ return proxy.ice_ping();
+ }).delay(200);
+ }
+ return p.then(function()
+ {
+ test(self._heartbeat >= 3);
+ });
+ }
+ });
+
+ var SetACMTest = Ice.Class(TestCase, {
+ __init__: function(com, out)
+ {
+ TestCase.call(this, "setACM/getACM", com, out);
+ this.setClientACM(15, 4, 2);
+ },
+ runTestCase: function(adapter, proxy)
+ {
+ var acm = new Ice.ACM();
+ acm = proxy.ice_getCachedConnection().getACM();
+ test(acm.timeout === 15);
+ test(acm.close === Ice.ACMClose.CloseOnIdleForceful);
+ test(acm.heartbeat === Ice.ACMHeartbeat.HeartbeatOnIdle);
+
+ proxy.ice_getCachedConnection().setACM(undefined, undefined, undefined);
+ acm = proxy.ice_getCachedConnection().getACM();
+ test(acm.timeout === 15);
+ test(acm.close === Ice.ACMClose.CloseOnIdleForceful);
+ test(acm.heartbeat === Ice.ACMHeartbeat.HeartbeatOnIdle);
+
+ proxy.ice_getCachedConnection().setACM(20,
+ Ice.ACMClose.CloseOnInvocationAndIdle,
+ Ice.ACMHeartbeat.HeartbeatOnInvocation);
+ acm = proxy.ice_getCachedConnection().getACM();
+ test(acm.timeout === 20);
+ test(acm.close === Ice.ACMClose.CloseOnInvocationAndIdle);
+ test(acm.heartbeat === Ice.ACMHeartbeat.HeartbeatOnInvocation);
+
+ return new Ice.Promise().succeed();
+ }
+ });
+
+ var allTests = function(out, communicator)
+ {
+ var ref = "communicator:default -p 12010";
+ var com = Test.RemoteCommunicatorPrx.uncheckedCast(communicator.stringToProxy(ref));
+
+ var tests = [];
+ tests.push(new InvocationHeartbeatTest(com, out));
+ tests.push(new InvocationHeartbeatOnHoldTest(com, out));
+ tests.push(new InvocationNoHeartbeatTest(com, out));
+ tests.push(new InvocationHeartbeatCloseOnIdleTest(com, out));
+
+ tests.push(new CloseOnIdleTest(com, out));
+ tests.push(new CloseOnInvocationTest(com, out));
+ tests.push(new CloseOnIdleAndInvocationTest(com, out));
+ tests.push(new ForcefullCloseOnIdleAndInvocationTest(com, out));
+
+ tests.push(new HeartbeatOnIdleTest(com, out));
+ tests.push(new HeartbeatAlwaysTest(com, out));
+ tests.push(new SetACMTest(com, out));
+
+ var promises = [];
+ for(var test in tests)
+ {
+ promises.push(tests[test].init());
+ }
+
+ return Ice.Promise.all(promises).then(
+ function()
+ {
+ promises = [];
+ for(var test in tests)
+ {
+ promises.push(tests[test].start());
+ }
+ return Ice.Promise.all(promises);
+ }
+ ).then(
+ function()
+ {
+ for(var test in tests)
+ {
+ tests[test].join(out);
+ }
+ }
+ ).then(
+ function()
+ {
+ promises = [];
+ for(var test in tests)
+ {
+ promises.push(tests[test].destroy());
+ }
+ return Ice.Promise.all(promises);
+ }
+ ).then(
+ function()
+ {
+ out.write("shutting down... ");
+ return com.shutdown();
+ }
+ ).then(
+ function()
+ {
+ out.writeLine("ok");
+ }
+ );
+ };
+
+ var run = function(out, id)
+ {
+ return Promise.try(
+ function()
+ {
+ id.properties.setProperty("Ice.Warn.Connections", "0");
+ var c = Ice.initialize(id);
+ return allTests(out, c).finally(
+ function()
+ {
+ if(c)
+ {
+ return c.destroy();
+ }
+ });
+ });
+ };
+ global.__test__ = run;
+ global.__runServer__ = true;
+}(typeof (global) === "undefined" ? window : global));