gossip_tests.lua 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. -- Gossip protocol implementation tests
  2. -- https://github.com/alexandruantochi/
  3. local gossipSubmodules = loadfile('gossip.lua')('test');
  4. local gossip = gossipSubmodules._gossip;
  5. local constants = gossipSubmodules._constants;
  6. local utils = gossipSubmodules._utils;
  7. local network = gossipSubmodules._network;
  8. local state = gossipSubmodules._state;
  9. -- test constants and mocks
  10. local function dummy() return nil; end
  11. -- luacheck: push allow defined
  12. tmr = {};
  13. tmr.time = function() return 200; end
  14. sjson = {};
  15. sjson.decode = function(data) return data; end
  16. file = {};
  17. file.exists = dummy
  18. file.putcontents = dummy
  19. -- luacheck: pop
  20. local Ip_1 = '192.168.0.1';
  21. local Ip_2 = '192.168.0.2';
  22. -- test runner
  23. local Test = {};
  24. local RunTests = function()
  25. local failures = {};
  26. print('\nRunning tests...\n');
  27. for testName, test in pairs(Test) do
  28. if type(test) == 'function' then
  29. local result = testName .. ': ';
  30. local passed, res = pcall(test);
  31. if passed then
  32. result = result .. ' Passed.';
  33. else
  34. result = result .. ' Failed ->';
  35. result = '>>>' .. result .. res;
  36. table.insert(failures, testName);
  37. end
  38. print(result);
  39. end
  40. end
  41. if (#failures ~= 0) then
  42. print('\n\n');
  43. print('Failed tests (' .. #failures .. '): \n');
  44. for k in pairs(failures) do print(failures[k]); end
  45. print('\n');
  46. end
  47. end
  48. -- utils
  49. function Test.utils_contains()
  50. local seedList = {};
  51. assert(not utils.contains(seedList, Ip_1));
  52. table.insert(seedList, Ip_1);
  53. assert(utils.contains(seedList, Ip_1));
  54. table.insert(seedList, Ip_2);
  55. assert(utils.contains(seedList, Ip_1) and utils.contains(seedList, Ip_2));
  56. end
  57. function Test.utils_setConfig()
  58. local config = {
  59. seedList = {Ip_1},
  60. roundInterval = 1500,
  61. comPort = 8000,
  62. junk = 'junk'
  63. };
  64. gossip.config = constants.defaultConfig;
  65. utils.setConfig(config);
  66. assert(#gossip.config.seedList == 1, 'Config failed when adding seedList');
  67. assert(gossip.config.seedList[1] == Ip_1,
  68. 'Config failed to add ip to seedList');
  69. assert(gossip.config.roundInterval == 1500,
  70. 'Config failed to add round interval.');
  71. assert(gossip.config.comPort == 8000, 'Config failed to add comPort.');
  72. assert(gossip.config.debug == false, 'Debug should be false.');
  73. assert(gossip.config.junk == nil, 'Junk data inserted in config.');
  74. gossip.config = constants.defaultConfig;
  75. end
  76. function Test.utils_compare()
  77. assert(utils.compare(1, 2) == 1);
  78. assert(utils.compare(2, 1) == -1);
  79. assert(utils.compare(0, 0) == 0);
  80. end
  81. function Test.utils_compareNodeData_on_revision()
  82. local networkData_1 = {
  83. revision = 1,
  84. heartbeat = 500,
  85. state = constants.nodeState.UP
  86. };
  87. local networkData_2 = {
  88. revision = 2,
  89. heartbeat = 500,
  90. state = constants.nodeState.UP
  91. };
  92. assert(utils.compareNodeData(networkData_1, networkData_2) == 1);
  93. assert(utils.compareNodeData(networkData_2, networkData_1) == -1);
  94. networkData_1.revision = networkData_2.revision;
  95. assert(utils.compareNodeData(networkData_1, networkData_2) == 0);
  96. end
  97. function Test.utils_compareNodeData_on_heartbeat()
  98. local networkData_1 = {
  99. revision = 1,
  100. heartbeat = 500,
  101. state = constants.nodeState.UP
  102. };
  103. local networkData_2 = {
  104. revision = 1,
  105. heartbeat = 600,
  106. state = constants.nodeState.UP
  107. };
  108. assert(utils.compareNodeData(networkData_1, networkData_2) == 1);
  109. assert(utils.compareNodeData(networkData_2, networkData_1) == -1);
  110. networkData_1.heartbeat = networkData_2.heartbeat;
  111. assert(utils.compareNodeData(networkData_1, networkData_2) == 0);
  112. end
  113. function Test.utils_compareNodeData_on_state()
  114. local networkData_1 = {
  115. revision = 1,
  116. heartbeat = 500,
  117. state = constants.nodeState.UP
  118. };
  119. local networkData_2 = {
  120. revision = 1,
  121. heartbeat = 500,
  122. state = constants.nodeState.SUSPECT
  123. };
  124. assert(utils.compareNodeData(networkData_1, networkData_2) == 1);
  125. assert(utils.compareNodeData(networkData_2, networkData_1) == -1);
  126. networkData_1.state = networkData_2.state;
  127. assert(utils.compareNodeData(networkData_1, networkData_2) == 0);
  128. end
  129. function Test.utils_compareNodeData_on_bad_data()
  130. local networkData_1 = {
  131. revision = 1,
  132. heartbeat = nil,
  133. state = constants.nodeState.UP
  134. };
  135. local networkData_2 = {
  136. revision = 1,
  137. heartbeat = 600,
  138. state = constants.nodeState.UP
  139. };
  140. assert(utils.compareNodeData(networkData_1, networkData_2) == 1);
  141. assert(utils.compareNodeData(networkData_2, networkData_1) == -1);
  142. networkData_2.state = nil;
  143. assert(utils.compareNodeData(networkData_1, networkData_2) == 0);
  144. end
  145. function Test.utils_getMinus()
  146. local data1 = {};
  147. local data2 = {};
  148. data1[Ip_1] = {
  149. revision = 1,
  150. heartbeat = 500,
  151. state = constants.nodeState.UP
  152. };
  153. data1[Ip_2] = {
  154. revision = 1,
  155. heartbeat = 400,
  156. state = constants.nodeState.UP
  157. };
  158. data2[Ip_1] = {
  159. revision = 1,
  160. heartbeat = 400,
  161. state = constants.nodeState.UP
  162. };
  163. data2[Ip_2] = {
  164. revision = 1,
  165. heartbeat = 400,
  166. state = constants.nodeState.SUSPECT;
  167. };
  168. --local diff1 = utils.getMinus(data1, data2);
  169. local diff2 = utils.getMinus(data2, data1);
  170. --assert(diff1[Ip_1] ~= nil and diff1[Ip_2] == nil);
  171. assert(diff2[Ip_1] == nil and diff2[Ip_2] ~= nil);
  172. end
  173. -- state
  174. function Test.state_setRev()
  175. gossip.ip = Ip_1;
  176. gossip.networkState[Ip_1] = {};
  177. gossip.networkState[Ip_1].revision = -1;
  178. assert(state.setRev() == 0, 'Revision not initialized to 0.');
  179. end
  180. function Test.state_tickNodeState()
  181. local ip_1 = Ip_1;
  182. local ip_2 = Ip_2;
  183. gossip.networkState[ip_1] = {};
  184. gossip.networkState[ip_2] = {};
  185. gossip.networkState[ip_1].state = constants.nodeState.UP;
  186. gossip.networkState[ip_2].state = constants.nodeState.DOWN;
  187. state.tickNodeState(ip_1);
  188. state.tickNodeState(ip_2);
  189. assert(gossip.networkState[ip_1].state == constants.nodeState.UP +
  190. constants.nodeState.TICK);
  191. assert(gossip.networkState[ip_2].state == constants.nodeState.REMOVE);
  192. state.tickNodeState(ip_1);
  193. assert(gossip.networkState[ip_1].state == constants.nodeState.SUSPECT);
  194. gossip.networkState = {};
  195. end
  196. -- network
  197. function Test.network_updateNetworkState_no_callback()
  198. local updateData = {}
  199. updateData[Ip_1] = {
  200. revision = 1,
  201. heartbeat = 400,
  202. state = constants.nodeState.UP
  203. };
  204. updateData[Ip_2] = {
  205. revision = 1,
  206. heartbeat = 700,
  207. state = constants.nodeState.UP
  208. };
  209. network.updateNetworkState(updateData);
  210. -- send duplicate data
  211. network.updateNetworkState(updateData);
  212. assert(#gossip.config.seedList == 2);
  213. assert(gossip.config.seedList[1] == Ip_1);
  214. assert(gossip.config.seedList[2] == Ip_2);
  215. assert(gossip.networkState[Ip_1] ~= nil and gossip.networkState[Ip_2] ~= nil);
  216. gossip.networkState = {};
  217. gossip.config = constants.defaultConfig;
  218. end
  219. function Test.network_updateNetworkState_with_callback()
  220. local callbackTriggered = false;
  221. local function updateCallback() callbackTriggered = true; end
  222. gossip.updateCallback = updateCallback;
  223. Test.network_updateNetworkState_no_callback();
  224. assert(callbackTriggered);
  225. gossip.updateCallback = nil;
  226. end
  227. function Test.network_receiveData_when_receive_syn()
  228. local originalReceiveSyn = network.receiveSyn;
  229. local receiveSynCalled = false;
  230. network.receiveSyn = function() receiveSynCalled = true; end
  231. network.receiveData('socket', {type = constants.updateType.SYN});
  232. network.receiveSyn = originalReceiveSyn;
  233. assert(receiveSynCalled);
  234. end
  235. function Test.network_receiveData_when_receive_ack()
  236. local originalReceiveAck = network.receiveAck;
  237. local receiveAckCalled = false;
  238. network.receiveAck = function() receiveAckCalled = true; end
  239. network.receiveData('socket', {type = constants.updateType.ACK});
  240. network.receiveAck = originalReceiveAck;
  241. assert(receiveAckCalled);
  242. end
  243. -- run tests
  244. RunTests();