PageRenderTime 46ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/org.eclipse.paho.client.mqttv3.test/src/test/java/org/eclipse/paho/client/mqttv3/test/connectionLoss/ConnectionLossTest.java

http://github.com/eclipse/paho.mqtt.java
Java | 491 lines | 364 code | 70 blank | 57 comment | 39 complexity | fb9c22f4ce7761ef6c8879d30ee0a1ea MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception
  1. /*******************************************************************************
  2. * Copyright (c) 2009, 2019 IBM Corp.
  3. *
  4. * All rights reserved. This program and the accompanying materials
  5. * are made available under the terms of the Eclipse Public License v2.0
  6. * and Eclipse Distribution License v1.0 which accompany this distribution.
  7. *
  8. * The Eclipse Public License is available at
  9. * https://www.eclipse.org/legal/epl-2.0
  10. * and the Eclipse Distribution License is available at
  11. * https://www.eclipse.org/org/documents/edl-v10.php
  12. *
  13. *******************************************************************************/
  14. package org.eclipse.paho.client.mqttv3.test.connectionLoss;
  15. import java.net.URI;
  16. import java.util.Date;
  17. import java.util.Timer;
  18. import java.util.TimerTask;
  19. import java.util.logging.Level;
  20. import java.util.logging.Logger;
  21. import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
  22. import org.eclipse.paho.client.mqttv3.MqttAsyncClient;
  23. import org.eclipse.paho.client.mqttv3.MqttCallback;
  24. import org.eclipse.paho.client.mqttv3.MqttClient;
  25. import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
  26. import org.eclipse.paho.client.mqttv3.MqttException;
  27. import org.eclipse.paho.client.mqttv3.MqttMessage;
  28. import org.eclipse.paho.client.mqttv3.persist.MqttDefaultFilePersistence;
  29. import org.eclipse.paho.client.mqttv3.test.logging.LoggingUtilities;
  30. import org.eclipse.paho.client.mqttv3.test.properties.TestProperties;
  31. import org.eclipse.paho.client.mqttv3.test.utilities.ConnectionManipulationProxyServer;
  32. import org.eclipse.paho.client.mqttv3.test.utilities.Utility;
  33. import org.junit.After;
  34. import org.junit.AfterClass;
  35. import org.junit.Assert;
  36. import org.junit.BeforeClass;
  37. import org.junit.Test;
  38. /**
  39. * These tests verify whether paho can successfully detect a loss of connection with a broker.
  40. *
  41. * >> The tests MUST BE run manually and they WILL FAIL in an automated test environment. <<
  42. * The pom.xml of the test project, all tests categorized as ManualTests are excluded from the execution.
  43. *
  44. * The tests will print a messages in the console notifying the operator when to "unplug" the internet connection of the test machine.
  45. *
  46. * @author mcarrer
  47. */
  48. public class ConnectionLossTest implements MqttCallback
  49. {
  50. static final Class<?> cclass = ConnectionLossTest.class;
  51. private static final String className = cclass.getName();
  52. private static final Logger log = Logger.getLogger(className);
  53. private static final MqttDefaultFilePersistence DATA_STORE = new MqttDefaultFilePersistence("/tmp");
  54. private String username = "username";
  55. private char[] password = "password".toCharArray();
  56. private String clientId = "device-client-id";
  57. private String message = "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890";
  58. static ConnectionManipulationProxyServer proxy;
  59. private static URI serverURI;
  60. @BeforeClass
  61. public static void setUpBeforeClass() throws Exception{
  62. try {
  63. String methodName = Utility.getMethodName();
  64. LoggingUtilities.banner(log, cclass, methodName);
  65. serverURI = TestProperties.getServerURI();
  66. // Use 0 for the first time.
  67. proxy = new ConnectionManipulationProxyServer(serverURI.getHost(), serverURI.getPort(), 0);
  68. proxy.startProxy();
  69. while(!proxy.isPortSet()){
  70. Thread.sleep(0);
  71. }
  72. log.log(Level.INFO, "Proxy Started, port set to: " + proxy.getLocalPort());
  73. } catch (Exception exception) {
  74. log.log(Level.SEVERE, "caught exception:", exception);
  75. throw exception;
  76. }
  77. }
  78. @AfterClass
  79. public static void tearDownAfterClass() throws Exception {
  80. log.info("Tests finished, stopping proxy");
  81. proxy.stopProxy();
  82. }
  83. @After
  84. public void afterTest() {
  85. log.info("Disabling Proxy");
  86. proxy.disableProxy();
  87. }
  88. /**
  89. * Tests whether paho can detect a connection loss with the server even if it has outbound activity by publishing messages with QoS 0.
  90. * @throws Exception
  91. */
  92. @Test
  93. public void testConnectionLossWhilePublishingQos0()
  94. throws Exception
  95. {
  96. String methodName = Utility.getMethodName();
  97. LoggingUtilities.banner(log, cclass, methodName);
  98. final int keepAlive = 15;
  99. MqttConnectOptions options = new MqttConnectOptions();
  100. options.setCleanSession(true);
  101. options.setUserName(username);
  102. options.setPassword(password);
  103. options.setKeepAliveInterval(keepAlive);
  104. MqttClient client = new MqttClient("tcp://localhost:" + proxy.getLocalPort(), clientId, DATA_STORE);
  105. client.setCallback(this);
  106. proxy.enableProxy();
  107. client.connect(options);
  108. log.info((new Date())+" - Connected.");
  109. for (int i=0; i<10; i++) {
  110. log.info("Disconnect your network in "+(10-i)+" sec...");
  111. client.publish(username+"/"+clientId+"/abc", message.getBytes(), 0, false);
  112. Thread.sleep(1000);
  113. }
  114. proxy.disableProxy();
  115. final int[] res = new int[1];
  116. new Timer().schedule( new TimerTask() {
  117. @Override
  118. public void run() {
  119. res[0]++;
  120. if (res[0] == keepAlive + 1) {
  121. log.info((new Date())+" - Connection should be lost...");
  122. }
  123. }
  124. }, 0, 1000);
  125. while (client.isConnected() && res[0] < 2*keepAlive) {
  126. try {
  127. client.publish(username+"/"+clientId+"/abc", message.getBytes(), 0, false);
  128. Thread.sleep(1000);
  129. }
  130. catch (MqttException e) {
  131. // ignore
  132. }
  133. }
  134. Assert.assertFalse("Disconected", client.isConnected());
  135. if (client.isConnected()) client.disconnect(0);
  136. client.close();
  137. }
  138. /**
  139. * Tests whether paho can detect a connection loss with the server even if it has outbound activity by publishing messages with QoS 1.
  140. * @throws Exception
  141. */
  142. @Test
  143. public void testConnectionLossWhilePublishingQos1() throws Exception {
  144. String methodName = Utility.getMethodName();
  145. LoggingUtilities.banner(log, cclass, methodName);
  146. final int keepAlive = 15;
  147. MqttConnectOptions options = new MqttConnectOptions();
  148. options.setCleanSession(true);
  149. options.setUserName(username);
  150. options.setPassword(password);
  151. options.setKeepAliveInterval(keepAlive);
  152. MqttClient client = new MqttClient("tcp://localhost:" + proxy.getLocalPort(), clientId, DATA_STORE);
  153. client.setCallback(this);
  154. proxy.enableProxy();
  155. client.connect(options);
  156. log.info((new Date()) + " - Connected.");
  157. for (int i = 0; i < 10; i++) {
  158. log.info("Disconnect your network in " + (10 - i) + " sec...");
  159. client.publish(username + "/" + clientId + "/abc", message.getBytes(), 1, false);
  160. Thread.sleep(1000);
  161. }
  162. proxy.disableProxy();
  163. final int[] res = new int[1];
  164. new Timer().schedule(new TimerTask() {
  165. @Override
  166. public void run() {
  167. res[0]++;
  168. if (res[0] == keepAlive + 1) {
  169. log.info((new Date()) + " - Connection should be lost...");
  170. }
  171. }
  172. }, 0, 1000);
  173. while (client.isConnected() && res[0] < 2 * keepAlive) {
  174. try {
  175. client.publish(username + "/" + clientId + "/abc", message.getBytes(), 1, false);
  176. Thread.sleep(1000);
  177. } catch (MqttException e) {
  178. // ignore
  179. }
  180. }
  181. log.info("Finished publishing...");
  182. Assert.assertFalse("Disconected", client.isConnected());
  183. if (client.isConnected())
  184. client.disconnect(0);
  185. client.close();
  186. }
  187. /**
  188. * Tests whether paho can detect a connection loss with the server even if it has outbound activity by publishing messages with QoS 2.
  189. * @throws Exception
  190. */
  191. @Test
  192. public void testConnectionLossWhilePublishingQos2()
  193. throws Exception
  194. {
  195. String methodName = Utility.getMethodName();
  196. LoggingUtilities.banner(log, cclass, methodName);
  197. final int keepAlive = 15;
  198. MqttConnectOptions options = new MqttConnectOptions();
  199. options.setCleanSession(true);
  200. options.setUserName(username);
  201. options.setPassword(password);
  202. options.setKeepAliveInterval(keepAlive);
  203. MqttClient client = new MqttClient("tcp://localhost:" + proxy.getLocalPort(), clientId, DATA_STORE);
  204. client.setCallback(this);
  205. proxy.enableProxy();
  206. client.connect(options);
  207. log.info((new Date())+" - Connected.");
  208. for (int i=0; i<10; i++) {
  209. log.info("Disconnect your network in "+(10-i)+" sec...");
  210. client.publish(username+"/"+clientId+"/abc", message.getBytes(), 2, false);
  211. Thread.sleep(1000);
  212. }
  213. proxy.disableProxy();
  214. final int[] res = new int[1];
  215. new Timer().schedule( new TimerTask() {
  216. @Override
  217. public void run() {
  218. res[0]++;
  219. if (res[0] == keepAlive + 1) {
  220. log.info((new Date())+" - Connection should be lost...");
  221. }
  222. }
  223. }, 0, 1000);
  224. while (client.isConnected() && res[0] < 2*keepAlive) {
  225. try {
  226. client.publish(username+"/"+clientId+"/abc", message.getBytes(), 2, false);
  227. Thread.sleep(1000);
  228. }
  229. catch (MqttException e) {
  230. // ignore
  231. }
  232. }
  233. Assert.assertFalse("Disconected", client.isConnected());
  234. if (client.isConnected()) client.disconnect(0);
  235. client.close();
  236. }
  237. /**
  238. * Tests whether async paho can detect a connection loss with the server even if it has outbound activity by publishing messages with QoS 1.
  239. * @throws Exception
  240. */
  241. @Test
  242. public void testConnectionLossWhilePublishingQos1Async()
  243. throws Exception
  244. {
  245. String methodName = Utility.getMethodName();
  246. LoggingUtilities.banner(log, cclass, methodName);
  247. final int keepAlive = 15;
  248. MqttConnectOptions options = new MqttConnectOptions();
  249. options.setCleanSession(true);
  250. options.setUserName(username);
  251. options.setPassword(password);
  252. options.setKeepAliveInterval(keepAlive);
  253. MqttAsyncClient client = new MqttAsyncClient("tcp://localhost:" + proxy.getLocalPort(), clientId, DATA_STORE);
  254. client.setCallback(this);
  255. proxy.enableProxy();
  256. log.info((new Date())+" - Connecting...");
  257. client.connect(options);
  258. while (!client.isConnected()) {
  259. Thread.sleep(1000);
  260. }
  261. log.info((new Date())+" - Connected.");
  262. for (int i=0; i<10; i++) {
  263. log.info("Disconnect your network in "+(10-i)+" sec...");
  264. client.publish(username+"/"+clientId+"/abc", message.getBytes(), 1, false);
  265. Thread.sleep(1000);
  266. }
  267. proxy.disableProxy();
  268. final int[] res = new int[1];
  269. new Timer().schedule( new TimerTask() {
  270. @Override
  271. public void run() {
  272. res[0]++;
  273. if (res[0] == keepAlive + 1) {
  274. log.info((new Date())+" - Connection should be lost...");
  275. }
  276. }
  277. }, 0, 1000);
  278. boolean stopPublishing = false;
  279. while (client.isConnected() && res[0] < 10*keepAlive) {
  280. if (!stopPublishing) {
  281. try {
  282. client.publish(username+"/"+clientId+"/abc", message.getBytes(), 1, false);
  283. log.info((new Date())+" - Published...");
  284. Thread.sleep(1000);
  285. }
  286. catch (MqttException e) {
  287. stopPublishing = true;
  288. }
  289. }
  290. }
  291. Assert.assertFalse("Disconected", client.isConnected());
  292. if (client.isConnected()) client.disconnect(0);
  293. client.close();
  294. }
  295. /**
  296. * Tests whether paho keeps the connection alive for 10 keep alive intervals while publishing messages with QoS 0.
  297. * @throws Exception
  298. */
  299. @Test
  300. public void testKeepConnectionOpenWhilePublishingQos0()
  301. throws Exception
  302. {
  303. String methodName = Utility.getMethodName();
  304. LoggingUtilities.banner(log, cclass, methodName);
  305. final int keepAlive = 15;
  306. MqttConnectOptions options = new MqttConnectOptions();
  307. options.setCleanSession(true);
  308. options.setUserName(username);
  309. options.setPassword(password);
  310. options.setKeepAliveInterval(keepAlive);
  311. MqttClient client = new MqttClient("tcp://localhost:" + proxy.getLocalPort(), clientId, DATA_STORE);
  312. client.setCallback(this);
  313. proxy.enableProxy();
  314. client.connect(options);
  315. log.info((new Date())+" - Connected.");
  316. final int[] res = new int[1];
  317. new Timer().schedule( new TimerTask() {
  318. @Override
  319. public void run() {
  320. res[0]++;
  321. if (res[0] % keepAlive == 0) {
  322. log.info((new Date())+" - Still running keep alive count: "+res[0]+"...");
  323. }
  324. }
  325. }, 0, 1000);
  326. while (client.isConnected() && res[0] < 10*keepAlive) {
  327. client.publish(username+"/"+clientId+"/abc", message.getBytes(), 0, false);
  328. Thread.sleep(1000);
  329. }
  330. Assert.assertTrue("Connected", client.isConnected());
  331. if (client.isConnected()) client.disconnect(0);
  332. client.close();
  333. }
  334. /**
  335. * Tests whether paho keeps the connection alive for 10 keep alive in idle state.
  336. * @throws Exception
  337. */
  338. @Test
  339. public void testKeepConnectionOpenIdle()
  340. throws Exception
  341. {
  342. String methodName = Utility.getMethodName();
  343. LoggingUtilities.banner(log, cclass, methodName);
  344. final int keepAlive = 15;
  345. MqttConnectOptions options = new MqttConnectOptions();
  346. options.setCleanSession(true);
  347. options.setUserName(username);
  348. options.setPassword(password);
  349. options.setKeepAliveInterval(keepAlive);
  350. MqttClient client = new MqttClient("tcp://localhost:" + proxy.getLocalPort(), clientId, DATA_STORE);
  351. client.setCallback(this);
  352. proxy.enableProxy();
  353. client.connect(options);
  354. log.info((new Date())+" - Connected.");
  355. final int[] res = new int[1];
  356. new Timer().schedule( new TimerTask() {
  357. @Override
  358. public void run() {
  359. res[0]++;
  360. if (res[0] % keepAlive == 0) {
  361. log.info((new Date())+" - Still running keep alive count: "+res[0]+"...");
  362. }
  363. }
  364. }, 0, 1000);
  365. while (client.isConnected() && res[0] < 10*keepAlive) {
  366. Thread.sleep(1000);
  367. }
  368. Assert.assertTrue("Connected", client.isConnected());
  369. if (client.isConnected()) client.disconnect(0);
  370. client.close();
  371. }
  372. private boolean connectionLostCalled = false;
  373. public void connectionLost(Throwable cause) {
  374. log.info((new Date())+" - Connection Lost");
  375. connectionLostCalled = true;
  376. }
  377. public void messageArrived(String topic, MqttMessage message) throws Exception {
  378. log.info("Message Arrived on " + topic + " with " + new String(message.getPayload()));
  379. }
  380. public void deliveryComplete(IMqttDeliveryToken token) {
  381. // log.info("Delivery Complete: " + token.getMessageId());
  382. }
  383. /**
  384. * Tests whether paho can detect a connection loss with the server with no publishing - using ping only
  385. * @throws Exception
  386. */
  387. @Test
  388. public void testConnectionLossUsingPing()
  389. throws Exception
  390. {
  391. String methodName = Utility.getMethodName();
  392. LoggingUtilities.banner(log, cclass, methodName);
  393. final int keepAlive = 15;
  394. MqttConnectOptions options = new MqttConnectOptions();
  395. options.setCleanSession(true);
  396. options.setUserName(username);
  397. options.setPassword(password);
  398. options.setKeepAliveInterval(keepAlive);
  399. connectionLostCalled = false;
  400. MqttClient client = new MqttClient("tcp://localhost:" + proxy.getLocalPort(), clientId, DATA_STORE);
  401. client.setCallback(this);
  402. proxy.enableProxy();
  403. client.connect(options);
  404. log.info((new Date())+" - Connected.");
  405. Thread.sleep(1000);
  406. proxy.disableProxy();
  407. int count = 0;
  408. while (client.isConnected() && ++count < 2*keepAlive) {
  409. try {
  410. Thread.sleep(1000);
  411. }
  412. catch (Exception e) {
  413. // ignore
  414. }
  415. }
  416. Assert.assertTrue("Connection lost was not called", connectionLostCalled);
  417. Assert.assertFalse("Disconnected", client.isConnected());
  418. if (client.isConnected()) client.disconnect(0);
  419. client.close();
  420. }
  421. }