keepalive_spec.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. #include "PubSubClient.h"
  2. #include "ShimClient.h"
  3. #include "Buffer.h"
  4. #include "BDDTest.h"
  5. #include "trace.h"
  6. #include <unistd.h>
  7. byte server[] = { 172, 16, 0, 2 };
  8. void callback(char* topic, byte* payload, unsigned int length) {
  9. // handle message arrived
  10. }
  11. int test_keepalive_pings_idle() {
  12. IT("keeps an idle connection alive (takes 1 minute)");
  13. ShimClient shimClient;
  14. shimClient.setAllowConnect(true);
  15. byte connack[] = { 0x20, 0x02, 0x00, 0x00 };
  16. shimClient.respond(connack,4);
  17. PubSubClient client(server, 1883, callback, shimClient);
  18. int rc = client.connect((char*)"client_test1");
  19. IS_TRUE(rc);
  20. byte pingreq[] = { 0xC0,0x0 };
  21. shimClient.expect(pingreq,2);
  22. byte pingresp[] = { 0xD0,0x0 };
  23. shimClient.respond(pingresp,2);
  24. for (int i = 0; i < 50; i++) {
  25. sleep(1);
  26. if ( i == 15 || i == 31 || i == 47) {
  27. shimClient.expect(pingreq,2);
  28. shimClient.respond(pingresp,2);
  29. }
  30. rc = client.loop();
  31. IS_TRUE(rc);
  32. }
  33. IS_FALSE(shimClient.error());
  34. END_IT
  35. }
  36. int test_keepalive_pings_with_outbound_qos0() {
  37. IT("keeps a connection alive that only sends qos0 (takes 1 minute)");
  38. ShimClient shimClient;
  39. shimClient.setAllowConnect(true);
  40. byte connack[] = { 0x20, 0x02, 0x00, 0x00 };
  41. shimClient.respond(connack,4);
  42. PubSubClient client(server, 1883, callback, shimClient);
  43. int rc = client.connect((char*)"client_test1");
  44. IS_TRUE(rc);
  45. byte publish[] = {0x30,0xe,0x0,0x5,0x74,0x6f,0x70,0x69,0x63,0x70,0x61,0x79,0x6c,0x6f,0x61,0x64};
  46. for (int i = 0; i < 50; i++) {
  47. TRACE(i<<":");
  48. shimClient.expect(publish,16);
  49. rc = client.publish((char*)"topic",(char*)"payload");
  50. IS_TRUE(rc);
  51. IS_FALSE(shimClient.error());
  52. sleep(1);
  53. if ( i == 15 || i == 31 || i == 47) {
  54. byte pingreq[] = { 0xC0,0x0 };
  55. shimClient.expect(pingreq,2);
  56. byte pingresp[] = { 0xD0,0x0 };
  57. shimClient.respond(pingresp,2);
  58. }
  59. rc = client.loop();
  60. IS_TRUE(rc);
  61. IS_FALSE(shimClient.error());
  62. }
  63. END_IT
  64. }
  65. int test_keepalive_pings_with_inbound_qos0() {
  66. IT("keeps a connection alive that only receives qos0 (takes 1 minute)");
  67. ShimClient shimClient;
  68. shimClient.setAllowConnect(true);
  69. byte connack[] = { 0x20, 0x02, 0x00, 0x00 };
  70. shimClient.respond(connack,4);
  71. PubSubClient client(server, 1883, callback, shimClient);
  72. int rc = client.connect((char*)"client_test1");
  73. IS_TRUE(rc);
  74. byte publish[] = {0x30,0xe,0x0,0x5,0x74,0x6f,0x70,0x69,0x63,0x70,0x61,0x79,0x6c,0x6f,0x61,0x64};
  75. for (int i = 0; i < 50; i++) {
  76. TRACE(i<<":");
  77. sleep(1);
  78. if ( i == 15 || i == 31 || i == 47) {
  79. byte pingreq[] = { 0xC0,0x0 };
  80. shimClient.expect(pingreq,2);
  81. byte pingresp[] = { 0xD0,0x0 };
  82. shimClient.respond(pingresp,2);
  83. }
  84. shimClient.respond(publish,16);
  85. rc = client.loop();
  86. IS_TRUE(rc);
  87. IS_FALSE(shimClient.error());
  88. }
  89. END_IT
  90. }
  91. int test_keepalive_no_pings_inbound_qos1() {
  92. IT("does not send pings for connections with inbound qos1 (takes 1 minute)");
  93. ShimClient shimClient;
  94. shimClient.setAllowConnect(true);
  95. byte connack[] = { 0x20, 0x02, 0x00, 0x00 };
  96. shimClient.respond(connack,4);
  97. PubSubClient client(server, 1883, callback, shimClient);
  98. int rc = client.connect((char*)"client_test1");
  99. IS_TRUE(rc);
  100. byte publish[] = {0x32,0x10,0x0,0x5,0x74,0x6f,0x70,0x69,0x63,0x12,0x34,0x70,0x61,0x79,0x6c,0x6f,0x61,0x64};
  101. byte puback[] = {0x40,0x2,0x12,0x34};
  102. for (int i = 0; i < 50; i++) {
  103. shimClient.respond(publish,18);
  104. shimClient.expect(puback,4);
  105. sleep(1);
  106. rc = client.loop();
  107. IS_TRUE(rc);
  108. IS_FALSE(shimClient.error());
  109. }
  110. END_IT
  111. }
  112. int test_keepalive_disconnects_hung() {
  113. IT("disconnects a hung connection (takes 30 seconds)");
  114. ShimClient shimClient;
  115. shimClient.setAllowConnect(true);
  116. byte connack[] = { 0x20, 0x02, 0x00, 0x00 };
  117. shimClient.respond(connack,4);
  118. PubSubClient client(server, 1883, callback, shimClient);
  119. int rc = client.connect((char*)"client_test1");
  120. IS_TRUE(rc);
  121. byte pingreq[] = { 0xC0,0x0 };
  122. shimClient.expect(pingreq,2);
  123. for (int i = 0; i < 32; i++) {
  124. sleep(1);
  125. rc = client.loop();
  126. }
  127. IS_FALSE(rc);
  128. int state = client.state();
  129. IS_TRUE(state == MQTT_CONNECTION_TIMEOUT);
  130. IS_FALSE(shimClient.error());
  131. END_IT
  132. }
  133. int main()
  134. {
  135. SUITE("Keep-alive");
  136. test_keepalive_pings_idle();
  137. test_keepalive_pings_with_outbound_qos0();
  138. test_keepalive_pings_with_inbound_qos0();
  139. test_keepalive_no_pings_inbound_qos1();
  140. test_keepalive_disconnects_hung();
  141. FINISH
  142. }