123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277 |
- -- Gossip protocol implementation tests
- -- https://github.com/alexandruantochi/
- local gossipSubmodules = loadfile('gossip.lua')('test');
- local gossip = gossipSubmodules._gossip;
- local constants = gossipSubmodules._constants;
- local utils = gossipSubmodules._utils;
- local network = gossipSubmodules._network;
- local state = gossipSubmodules._state;
- -- test constants and mocks
- local function dummy() return nil; end
- -- luacheck: push allow defined
- tmr = {};
- tmr.time = function() return 200; end
- sjson = {};
- sjson.decode = function(data) return data; end
- file = {};
- file.exists = dummy
- file.putcontents = dummy
- -- luacheck: pop
- local Ip_1 = '192.168.0.1';
- local Ip_2 = '192.168.0.2';
- -- test runner
- local Test = {};
- local RunTests = function()
- local failures = {};
- print('\nRunning tests...\n');
- for testName, test in pairs(Test) do
- if type(test) == 'function' then
- local result = testName .. ': ';
- local passed, res = pcall(test);
- if passed then
- result = result .. ' Passed.';
- else
- result = result .. ' Failed ->';
- result = '>>>' .. result .. res;
- table.insert(failures, testName);
- end
- print(result);
- end
- end
- if (#failures ~= 0) then
- print('\n\n');
- print('Failed tests (' .. #failures .. '): \n');
- for k in pairs(failures) do print(failures[k]); end
- print('\n');
- end
- end
- -- utils
- function Test.utils_contains()
- local seedList = {};
- assert(not utils.contains(seedList, Ip_1));
- table.insert(seedList, Ip_1);
- assert(utils.contains(seedList, Ip_1));
- table.insert(seedList, Ip_2);
- assert(utils.contains(seedList, Ip_1) and utils.contains(seedList, Ip_2));
- end
- function Test.utils_setConfig()
- local config = {
- seedList = {Ip_1},
- roundInterval = 1500,
- comPort = 8000,
- junk = 'junk'
- };
- gossip.config = constants.defaultConfig;
- utils.setConfig(config);
- assert(#gossip.config.seedList == 1, 'Config failed when adding seedList');
- assert(gossip.config.seedList[1] == Ip_1,
- 'Config failed to add ip to seedList');
- assert(gossip.config.roundInterval == 1500,
- 'Config failed to add round interval.');
- assert(gossip.config.comPort == 8000, 'Config failed to add comPort.');
- assert(gossip.config.debug == false, 'Debug should be false.');
- assert(gossip.config.junk == nil, 'Junk data inserted in config.');
- gossip.config = constants.defaultConfig;
- end
- function Test.utils_compare()
- assert(utils.compare(1, 2) == 1);
- assert(utils.compare(2, 1) == -1);
- assert(utils.compare(0, 0) == 0);
- end
- function Test.utils_compareNodeData_on_revision()
- local networkData_1 = {
- revision = 1,
- heartbeat = 500,
- state = constants.nodeState.UP
- };
- local networkData_2 = {
- revision = 2,
- heartbeat = 500,
- state = constants.nodeState.UP
- };
- assert(utils.compareNodeData(networkData_1, networkData_2) == 1);
- assert(utils.compareNodeData(networkData_2, networkData_1) == -1);
- networkData_1.revision = networkData_2.revision;
- assert(utils.compareNodeData(networkData_1, networkData_2) == 0);
- end
- function Test.utils_compareNodeData_on_heartbeat()
- local networkData_1 = {
- revision = 1,
- heartbeat = 500,
- state = constants.nodeState.UP
- };
- local networkData_2 = {
- revision = 1,
- heartbeat = 600,
- state = constants.nodeState.UP
- };
- assert(utils.compareNodeData(networkData_1, networkData_2) == 1);
- assert(utils.compareNodeData(networkData_2, networkData_1) == -1);
- networkData_1.heartbeat = networkData_2.heartbeat;
- assert(utils.compareNodeData(networkData_1, networkData_2) == 0);
- end
- function Test.utils_compareNodeData_on_state()
- local networkData_1 = {
- revision = 1,
- heartbeat = 500,
- state = constants.nodeState.UP
- };
- local networkData_2 = {
- revision = 1,
- heartbeat = 500,
- state = constants.nodeState.SUSPECT
- };
- assert(utils.compareNodeData(networkData_1, networkData_2) == 1);
- assert(utils.compareNodeData(networkData_2, networkData_1) == -1);
- networkData_1.state = networkData_2.state;
- assert(utils.compareNodeData(networkData_1, networkData_2) == 0);
- end
- function Test.utils_compareNodeData_on_bad_data()
- local networkData_1 = {
- revision = 1,
- heartbeat = nil,
- state = constants.nodeState.UP
- };
- local networkData_2 = {
- revision = 1,
- heartbeat = 600,
- state = constants.nodeState.UP
- };
- assert(utils.compareNodeData(networkData_1, networkData_2) == 1);
- assert(utils.compareNodeData(networkData_2, networkData_1) == -1);
- networkData_2.state = nil;
- assert(utils.compareNodeData(networkData_1, networkData_2) == 0);
- end
- function Test.utils_getMinus()
- local data1 = {};
- local data2 = {};
- data1[Ip_1] = {
- revision = 1,
- heartbeat = 500,
- state = constants.nodeState.UP
- };
- data1[Ip_2] = {
- revision = 1,
- heartbeat = 400,
- state = constants.nodeState.UP
- };
- data2[Ip_1] = {
- revision = 1,
- heartbeat = 400,
- state = constants.nodeState.UP
- };
- data2[Ip_2] = {
- revision = 1,
- heartbeat = 400,
- state = constants.nodeState.SUSPECT;
- };
- --local diff1 = utils.getMinus(data1, data2);
- local diff2 = utils.getMinus(data2, data1);
- --assert(diff1[Ip_1] ~= nil and diff1[Ip_2] == nil);
- assert(diff2[Ip_1] == nil and diff2[Ip_2] ~= nil);
- end
- -- state
- function Test.state_setRev()
- gossip.ip = Ip_1;
- gossip.networkState[Ip_1] = {};
- gossip.networkState[Ip_1].revision = -1;
- assert(state.setRev() == 0, 'Revision not initialized to 0.');
- end
- function Test.state_tickNodeState()
- local ip_1 = Ip_1;
- local ip_2 = Ip_2;
- gossip.networkState[ip_1] = {};
- gossip.networkState[ip_2] = {};
- gossip.networkState[ip_1].state = constants.nodeState.UP;
- gossip.networkState[ip_2].state = constants.nodeState.DOWN;
- state.tickNodeState(ip_1);
- state.tickNodeState(ip_2);
- assert(gossip.networkState[ip_1].state == constants.nodeState.UP +
- constants.nodeState.TICK);
- assert(gossip.networkState[ip_2].state == constants.nodeState.REMOVE);
- state.tickNodeState(ip_1);
- assert(gossip.networkState[ip_1].state == constants.nodeState.SUSPECT);
- gossip.networkState = {};
- end
- -- network
- function Test.network_updateNetworkState_no_callback()
- local updateData = {}
- updateData[Ip_1] = {
- revision = 1,
- heartbeat = 400,
- state = constants.nodeState.UP
- };
- updateData[Ip_2] = {
- revision = 1,
- heartbeat = 700,
- state = constants.nodeState.UP
- };
- network.updateNetworkState(updateData);
- -- send duplicate data
- network.updateNetworkState(updateData);
- assert(#gossip.config.seedList == 2);
- assert(gossip.config.seedList[1] == Ip_1);
- assert(gossip.config.seedList[2] == Ip_2);
- assert(gossip.networkState[Ip_1] ~= nil and gossip.networkState[Ip_2] ~= nil);
- gossip.networkState = {};
- gossip.config = constants.defaultConfig;
- end
- function Test.network_updateNetworkState_with_callback()
- local callbackTriggered = false;
- local function updateCallback() callbackTriggered = true; end
- gossip.updateCallback = updateCallback;
- Test.network_updateNetworkState_no_callback();
- assert(callbackTriggered);
- gossip.updateCallback = nil;
- end
- function Test.network_receiveData_when_receive_syn()
- local originalReceiveSyn = network.receiveSyn;
- local receiveSynCalled = false;
- network.receiveSyn = function() receiveSynCalled = true; end
- network.receiveData('socket', {type = constants.updateType.SYN});
- network.receiveSyn = originalReceiveSyn;
- assert(receiveSynCalled);
- end
- function Test.network_receiveData_when_receive_ack()
- local originalReceiveAck = network.receiveAck;
- local receiveAckCalled = false;
- network.receiveAck = function() receiveAckCalled = true; end
- network.receiveData('socket', {type = constants.updateType.ACK});
- network.receiveAck = originalReceiveAck;
- assert(receiveAckCalled);
- end
- -- run tests
- RunTests();
|