bufferedchannel_test.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. // Copyright 2010 The Closure Library Authors. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS-IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. goog.provide('goog.messaging.BufferedChannelTest');
  15. goog.setTestOnly('goog.messaging.BufferedChannelTest');
  16. goog.require('goog.debug.Console');
  17. goog.require('goog.dom');
  18. goog.require('goog.dom.TagName');
  19. goog.require('goog.log');
  20. goog.require('goog.log.Level');
  21. goog.require('goog.messaging.BufferedChannel');
  22. goog.require('goog.testing.MockClock');
  23. goog.require('goog.testing.MockControl');
  24. goog.require('goog.testing.async.MockControl');
  25. goog.require('goog.testing.jsunit');
  26. goog.require('goog.testing.messaging.MockMessageChannel');
  27. var clock;
  28. var messages = [
  29. {serviceName: 'firstService', payload: 'firstPayload'},
  30. {serviceName: 'secondService', payload: 'secondPayload'}
  31. ];
  32. var mockControl;
  33. var asyncMockControl;
  34. function setUpPage() {
  35. if (goog.global.console) {
  36. new goog.debug.Console().setCapturing(true);
  37. }
  38. var logger = goog.log.getLogger('goog.messaging');
  39. logger.setLevel(goog.log.Level.ALL);
  40. goog.log.addHandler(logger, function(logRecord) {
  41. var msg = goog.dom.createDom(goog.dom.TagName.DIV);
  42. msg.innerHTML = logRecord.getMessage();
  43. goog.dom.appendChild(goog.dom.getElement('debug-div'), msg);
  44. });
  45. clock = new goog.testing.MockClock();
  46. mockControl = new goog.testing.MockControl();
  47. asyncMockControl = new goog.testing.async.MockControl(mockControl);
  48. }
  49. function setUp() {
  50. clock.install();
  51. }
  52. function tearDown() {
  53. clock.uninstall();
  54. mockControl.$tearDown();
  55. }
  56. function assertMessageArraysEqual(ma1, ma2) {
  57. assertEquals('message array lengths differ', ma1.length, ma2.length);
  58. for (var i = 0; i < ma1.length; i++) {
  59. assertEquals(
  60. 'message array serviceNames differ', ma1[i].serviceName,
  61. ma2[i].serviceName);
  62. assertEquals(
  63. 'message array payloads differ', ma1[i].payload, ma2[i].payload);
  64. }
  65. }
  66. function testDelegationToWrappedChannel() {
  67. var mockChannel = new goog.testing.messaging.MockMessageChannel(mockControl);
  68. var channel = new goog.messaging.BufferedChannel(mockChannel);
  69. channel.registerDefaultService(
  70. asyncMockControl.asyncAssertEquals(
  71. 'default service should be delegated', 'defaultServiceName',
  72. 'default service payload'));
  73. channel.registerService(
  74. 'normalServiceName',
  75. asyncMockControl.asyncAssertEquals(
  76. 'normal service should be delegated', 'normal service payload'));
  77. mockChannel.send(
  78. goog.messaging.BufferedChannel.USER_CHANNEL_NAME_ + ':message',
  79. 'payload');
  80. mockControl.$replayAll();
  81. channel.peerReady_ = true; // Prevent buffering so we delegate send calls.
  82. mockChannel.receive(
  83. goog.messaging.BufferedChannel.USER_CHANNEL_NAME_ + ':defaultServiceName',
  84. 'default service payload');
  85. mockChannel.receive(
  86. goog.messaging.BufferedChannel.USER_CHANNEL_NAME_ + ':normalServiceName',
  87. 'normal service payload');
  88. channel.send('message', 'payload');
  89. mockControl.$verifyAll();
  90. }
  91. function testOptionalConnectCallbackExecutes() {
  92. var mockChannel = new goog.testing.messaging.MockMessageChannel(mockControl);
  93. var channel = new goog.messaging.BufferedChannel(mockChannel);
  94. var mockConnectCb = mockControl.createFunctionMock('mockConnectCb');
  95. mockConnectCb();
  96. mockControl.$replayAll();
  97. channel.connect(mockConnectCb);
  98. mockControl.$verifyAll();
  99. }
  100. function testSendExceptionsInSendReadyPingStopsTimerAndReraises() {
  101. var mockChannel = new goog.testing.messaging.MockMessageChannel(mockControl);
  102. var channel = new goog.messaging.BufferedChannel(mockChannel);
  103. var errorMessage = 'errorMessage';
  104. mockChannel
  105. .send(
  106. goog.messaging.BufferedChannel.CONTROL_CHANNEL_NAME_ + ':' +
  107. goog.messaging.BufferedChannel.PEER_READY_SERVICE_NAME_,
  108. /* payload */ '')
  109. .$throws(Error(errorMessage));
  110. channel.timer_.enabled = true;
  111. mockControl.$replayAll();
  112. var exception = assertThrows(function() { channel.sendReadyPing_(); });
  113. assertContains(errorMessage, exception.message);
  114. assertFalse(channel.timer_.enabled);
  115. mockControl.$verifyAll();
  116. }
  117. function testPollingIntervalDefaultAndOverride() {
  118. var mockChannel = new goog.testing.messaging.MockMessageChannel(mockControl);
  119. var channel = new goog.messaging.BufferedChannel(mockChannel);
  120. assertEquals(
  121. goog.messaging.BufferedChannel.DEFAULT_INTERVAL_MILLIS_,
  122. channel.timer_.getInterval());
  123. var interval = 100;
  124. var longIntervalChannel = new goog.messaging.BufferedChannel(
  125. new goog.testing.messaging.MockMessageChannel(mockControl), interval);
  126. assertEquals(interval, longIntervalChannel.timer_.getInterval());
  127. }
  128. function testBidirectionalCommunicationBuffersUntilReadyPingsSucceed() {
  129. var mockChannel1 = new goog.testing.messaging.MockMessageChannel(mockControl);
  130. var mockChannel2 = new goog.testing.messaging.MockMessageChannel(mockControl);
  131. var bufferedChannel1 = new goog.messaging.BufferedChannel(mockChannel1);
  132. var bufferedChannel2 = new goog.messaging.BufferedChannel(mockChannel2);
  133. mockChannel1
  134. .send(
  135. goog.messaging.BufferedChannel.CONTROL_CHANNEL_NAME_ +
  136. ':setPeerReady_',
  137. '')
  138. .$does(function() { bufferedChannel2.setPeerReady_(''); });
  139. mockChannel2
  140. .send(
  141. goog.messaging.BufferedChannel.CONTROL_CHANNEL_NAME_ +
  142. ':setPeerReady_',
  143. '1')
  144. .$does(function() { bufferedChannel1.setPeerReady_('1'); });
  145. mockChannel1
  146. .send(
  147. goog.messaging.BufferedChannel.CONTROL_CHANNEL_NAME_ +
  148. ':setPeerReady_',
  149. '1')
  150. .$does(function() { bufferedChannel2.setPeerReady_('1'); });
  151. mockChannel1.send(
  152. goog.messaging.BufferedChannel.USER_CHANNEL_NAME_ + ':' +
  153. messages[0].serviceName,
  154. messages[0].payload);
  155. mockChannel2.send(
  156. goog.messaging.BufferedChannel.USER_CHANNEL_NAME_ + ':' +
  157. messages[1].serviceName,
  158. messages[1].payload);
  159. mockControl.$replayAll();
  160. bufferedChannel1.send(messages[0].serviceName, messages[0].payload);
  161. bufferedChannel2.send(messages[1].serviceName, messages[1].payload);
  162. assertMessageArraysEqual([messages[0]], bufferedChannel1.buffer_);
  163. assertMessageArraysEqual([messages[1]], bufferedChannel2.buffer_);
  164. // First tick causes setPeerReady_ to fire, which in turn flushes the buffers.
  165. clock.tick(goog.messaging.BufferedChannel.DEFAULT_INTERVAL_MILLIS_);
  166. assertEquals(bufferedChannel1.buffer_, null);
  167. assertEquals(bufferedChannel2.buffer_, null);
  168. // Now that peers are ready, a second tick causes no more sends.
  169. clock.tick(goog.messaging.BufferedChannel.DEFAULT_INTERVAL_MILLIS_);
  170. mockControl.$verifyAll();
  171. }
  172. function testBidirectionalCommunicationReconnectsAfterOneSideRestarts() {
  173. var mockChannel1 = new goog.testing.messaging.MockMessageChannel(mockControl);
  174. var mockChannel2 = new goog.testing.messaging.MockMessageChannel(mockControl);
  175. var mockChannel3 = new goog.testing.messaging.MockMessageChannel(mockControl);
  176. var bufferedChannel1 = new goog.messaging.BufferedChannel(mockChannel1);
  177. var bufferedChannel2 = new goog.messaging.BufferedChannel(mockChannel2);
  178. var bufferedChannel3 = new goog.messaging.BufferedChannel(mockChannel3);
  179. // First tick
  180. mockChannel1
  181. .send(
  182. goog.messaging.BufferedChannel.CONTROL_CHANNEL_NAME_ +
  183. ':setPeerReady_',
  184. '')
  185. .$does(function() { bufferedChannel2.setPeerReady_(''); });
  186. mockChannel2
  187. .send(
  188. goog.messaging.BufferedChannel.CONTROL_CHANNEL_NAME_ +
  189. ':setPeerReady_',
  190. '1')
  191. .$does(function() { bufferedChannel1.setPeerReady_('1'); });
  192. mockChannel1
  193. .send(
  194. goog.messaging.BufferedChannel.CONTROL_CHANNEL_NAME_ +
  195. ':setPeerReady_',
  196. '1')
  197. .$does(function() { bufferedChannel2.setPeerReady_('1'); });
  198. mockChannel3.send(
  199. goog.messaging.BufferedChannel.CONTROL_CHANNEL_NAME_ + ':setPeerReady_',
  200. ''); // pretend it's not ready to connect yet
  201. // Second tick
  202. mockChannel3
  203. .send(
  204. goog.messaging.BufferedChannel.CONTROL_CHANNEL_NAME_ +
  205. ':setPeerReady_',
  206. '')
  207. .$does(function() { bufferedChannel1.setPeerReady_(''); });
  208. // Third tick
  209. mockChannel1
  210. .send(
  211. goog.messaging.BufferedChannel.CONTROL_CHANNEL_NAME_ +
  212. ':setPeerReady_',
  213. '1')
  214. .$does(function() { bufferedChannel3.setPeerReady_('1'); });
  215. mockChannel3
  216. .send(
  217. goog.messaging.BufferedChannel.CONTROL_CHANNEL_NAME_ +
  218. ':setPeerReady_',
  219. '1')
  220. .$does(function() { bufferedChannel1.setPeerReady_('1'); });
  221. mockChannel1.send(
  222. goog.messaging.BufferedChannel.USER_CHANNEL_NAME_ + ':' +
  223. messages[0].serviceName,
  224. messages[0].payload);
  225. mockChannel3.send(
  226. goog.messaging.BufferedChannel.USER_CHANNEL_NAME_ + ':' +
  227. messages[1].serviceName,
  228. messages[1].payload);
  229. mockControl.$replayAll();
  230. // First tick causes setPeerReady_ to fire, which sets up the connection
  231. // between channels 1 and 2.
  232. clock.tick(goog.messaging.BufferedChannel.DEFAULT_INTERVAL_MILLIS_);
  233. assertTrue(bufferedChannel1.peerReady_);
  234. assertTrue(bufferedChannel2.peerReady_);
  235. // Now pretend that channel 2 went down and was replaced by channel 3, which
  236. // is trying to connect with channel 1.
  237. clock.tick(goog.messaging.BufferedChannel.DEFAULT_INTERVAL_MILLIS_);
  238. assertTrue(bufferedChannel1.peerReady_);
  239. clock.tick(goog.messaging.BufferedChannel.DEFAULT_INTERVAL_MILLIS_);
  240. assertTrue(bufferedChannel3.peerReady_);
  241. bufferedChannel1.send(messages[0].serviceName, messages[0].payload);
  242. bufferedChannel3.send(messages[1].serviceName, messages[1].payload);
  243. // All timers stopped, nothing happens on the fourth tick.
  244. clock.tick(goog.messaging.BufferedChannel.DEFAULT_INTERVAL_MILLIS_);
  245. mockControl.$verifyAll();
  246. }