michael@0: /* Any copyright is dedicated to the Public Domain. michael@0: http://creativecommons.org/publicdomain/zero/1.0/ */ michael@0: michael@0: const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; michael@0: michael@0: const NETWORK_STATUS_READY = 0; michael@0: const NETWORK_STATUS_STANDBY = 1; michael@0: const NETWORK_STATUS_AWAY = 2; michael@0: michael@0: const QUEUE_TYPE_UPDATE_STATS = 0; michael@0: michael@0: var wifiId = '00'; michael@0: michael@0: function getNetworks(callback) { michael@0: NetworkStatsService._db.getAvailableNetworks(function onGetNetworks(aError, aResult) { michael@0: callback(aError, aResult); michael@0: }); michael@0: } michael@0: michael@0: add_test(function test_clearDB() { michael@0: getNetworks(function onGetNetworks(error, result) { michael@0: do_check_eq(error, null); michael@0: var networks = result; michael@0: networks.forEach(function(network, index) { michael@0: networks[index] = {network: network, networkId: NetworkStatsService.getNetworkId(network.id, network.type)}; michael@0: }, this); michael@0: michael@0: NetworkStatsService._db.clearStats(networks, function onDBCleared(error, result) { michael@0: do_check_eq(error, null); michael@0: run_next_test(); michael@0: }); michael@0: }); michael@0: }); michael@0: michael@0: function getNetworkId(callback) { michael@0: getNetworks(function onGetNetworks(error, result) { michael@0: do_check_eq(error, null); michael@0: var netId = NetworkStatsService.getNetworkId(result[0].id, result[0].type); michael@0: callback(null, netId); michael@0: }); michael@0: } michael@0: michael@0: add_test(function test_networkStatsAvailable_ok() { michael@0: getNetworkId(function onGetId(error, result) { michael@0: do_check_eq(error, null); michael@0: var netId = result; michael@0: NetworkStatsService.networkStatsAvailable(function (success, msg) { michael@0: do_check_eq(success, true); michael@0: run_next_test(); michael@0: }, netId, true, 1234, 4321, new Date()); michael@0: }); michael@0: }); michael@0: michael@0: add_test(function test_networkStatsAvailable_failure() { michael@0: getNetworkId(function onGetId(error, result) { michael@0: do_check_eq(error, null); michael@0: var netId = result; michael@0: NetworkStatsService.networkStatsAvailable(function (success, msg) { michael@0: do_check_eq(success, false); michael@0: run_next_test(); michael@0: }, netId, false, 1234, 4321, new Date()); michael@0: }); michael@0: }); michael@0: michael@0: add_test(function test_update_invalidNetwork() { michael@0: NetworkStatsService.update(-1, function (success, msg) { michael@0: do_check_eq(success, false); michael@0: do_check_eq(msg, "Invalid network -1"); michael@0: run_next_test(); michael@0: }); michael@0: }); michael@0: michael@0: add_test(function test_update() { michael@0: getNetworkId(function onGetId(error, result) { michael@0: do_check_eq(error, null); michael@0: var netId = result; michael@0: NetworkStatsService.update(netId, function (success, msg) { michael@0: do_check_eq(success, true); michael@0: run_next_test(); michael@0: }); michael@0: }); michael@0: }); michael@0: michael@0: add_test(function test_updateQueueIndex() { michael@0: NetworkStatsService.updateQueue = [{netId: 0, callbacks: null, queueType: QUEUE_TYPE_UPDATE_STATS}, michael@0: {netId: 1, callbacks: null, queueType: QUEUE_TYPE_UPDATE_STATS}, michael@0: {netId: 2, callbacks: null, queueType: QUEUE_TYPE_UPDATE_STATS}, michael@0: {netId: 3, callbacks: null, queueType: QUEUE_TYPE_UPDATE_STATS}, michael@0: {netId: 4, callbacks: null, queueType: QUEUE_TYPE_UPDATE_STATS}]; michael@0: var index = NetworkStatsService.updateQueueIndex(3); michael@0: do_check_eq(index, 3); michael@0: index = NetworkStatsService.updateQueueIndex(10); michael@0: do_check_eq(index, -1); michael@0: michael@0: NetworkStatsService.updateQueue = []; michael@0: run_next_test(); michael@0: }); michael@0: michael@0: add_test(function test_updateAllStats() { michael@0: NetworkStatsService._networks[wifiId].status = NETWORK_STATUS_READY; michael@0: NetworkStatsService.updateAllStats(function(success, msg) { michael@0: do_check_eq(success, true); michael@0: NetworkStatsService._networks[wifiId].status = NETWORK_STATUS_STANDBY; michael@0: NetworkStatsService.updateAllStats(function(success, msg) { michael@0: do_check_eq(success, true); michael@0: NetworkStatsService._networks[wifiId].status = NETWORK_STATUS_AWAY; michael@0: NetworkStatsService.updateAllStats(function(success, msg) { michael@0: do_check_eq(success, true); michael@0: run_next_test(); michael@0: }); michael@0: }); michael@0: }); michael@0: }); michael@0: michael@0: add_test(function test_updateStats_ok() { michael@0: getNetworkId(function onGetId(error, result) { michael@0: do_check_eq(error, null); michael@0: var netId = result; michael@0: NetworkStatsService.updateStats(netId, function(success, msg){ michael@0: do_check_eq(success, true); michael@0: run_next_test(); michael@0: }); michael@0: }); michael@0: }); michael@0: michael@0: add_test(function test_updateStats_failure() { michael@0: NetworkStatsService.updateStats(-1, function(success, msg){ michael@0: do_check_eq(success, false); michael@0: run_next_test(); michael@0: }); michael@0: }); michael@0: michael@0: // Define Mockup function to simulate a request to netd michael@0: function MockNetdRequest(aCallback) { michael@0: var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); michael@0: var event = { michael@0: notify: function (timer) { michael@0: aCallback(); michael@0: } michael@0: }; michael@0: michael@0: timer.initWithCallback(event, 100, Ci.nsITimer.TYPE_ONE_SHOT); michael@0: } michael@0: michael@0: add_test(function test_queue() { michael@0: michael@0: // Overwrite update function of NetworkStatsService to avoid netd errors due to use michael@0: // fake interfaces. First, original function is stored to restore it at the end of the michael@0: // test. michael@0: var updateFunctionBackup = NetworkStatsService.update; michael@0: michael@0: NetworkStatsService.update = function update(aNetId, aCallback) { michael@0: MockNetdRequest(function () { michael@0: if (aCallback) { michael@0: aCallback(true, "ok"); michael@0: } michael@0: }); michael@0: }; michael@0: michael@0: // Fill networks with fake network interfaces to enable netd async requests. michael@0: var network = {id: "1234", type: Ci.nsIDOMMozNetworkStatsManager.MOBILE}; michael@0: var netId1 = NetworkStatsService.getNetworkId(network.id, network.type); michael@0: NetworkStatsService._networks[netId1] = { network: network, michael@0: interfaceName: "net1" }; michael@0: michael@0: network = {id: "5678", type: Ci.nsIDOMMozNetworkStatsManager.MOBILE}; michael@0: var netId2 = NetworkStatsService.getNetworkId(network.id, network.type); michael@0: NetworkStatsService._networks[netId2] = { network: network, michael@0: interfaceName: "net2" }; michael@0: michael@0: NetworkStatsService.updateStats(netId1); michael@0: NetworkStatsService.updateStats(netId2); michael@0: do_check_eq(NetworkStatsService.updateQueue.length, 2); michael@0: do_check_eq(NetworkStatsService.updateQueue[0].callbacks.length, 1); michael@0: michael@0: var i = 0; michael@0: var updateCount = 0; michael@0: var callback = function(success, msg) { michael@0: i++; michael@0: if (i >= updateCount) { michael@0: NetworkStatsService.update = updateFunctionBackup; michael@0: run_next_test(); michael@0: } michael@0: }; michael@0: michael@0: NetworkStatsService.updateStats(netId1, callback); michael@0: updateCount++; michael@0: NetworkStatsService.updateStats(netId2, callback); michael@0: updateCount++; michael@0: michael@0: do_check_eq(NetworkStatsService.updateQueue.length, 2); michael@0: do_check_eq(NetworkStatsService.updateQueue[0].callbacks.length, 2); michael@0: do_check_eq(NetworkStatsService.updateQueue[0].callbacks[0], null); michael@0: do_check_neq(NetworkStatsService.updateQueue[0].callbacks[1], null); michael@0: }); michael@0: michael@0: add_test(function test_getAlarmQuota() { michael@0: let alarm = { networkId: wifiId, absoluteThreshold: 10000 }; michael@0: michael@0: NetworkStatsService._getAlarmQuota(alarm, function onSet(error, quota){ michael@0: do_check_eq(error, null); michael@0: do_check_neq(quota, undefined); michael@0: do_check_eq(alarm.absoluteThreshold, alarm.relativeThreshold); michael@0: run_next_test(); michael@0: }); michael@0: }); michael@0: michael@0: var testPageURL = "http://test.com"; michael@0: var testManifestURL = "http://test.com/manifest.webapp"; michael@0: michael@0: add_test(function test_setAlarm() { michael@0: let alarm = { id: null, michael@0: networkId: wifiId, michael@0: threshold: 10000, michael@0: absoluteThreshold: null, michael@0: alarmStart: null, michael@0: alarmEnd: null, michael@0: data: null, michael@0: pageURL: testPageURL, michael@0: manifestURL: testManifestURL }; michael@0: michael@0: NetworkStatsService._setAlarm(alarm, function onSet(error, result) { michael@0: do_check_eq(result, 1); michael@0: run_next_test(); michael@0: }); michael@0: }); michael@0: michael@0: add_test(function test_setAlarm_invalid_threshold() { michael@0: let alarm = { id: null, michael@0: networkId: wifiId, michael@0: threshold: -10000, michael@0: absoluteThreshold: null, michael@0: alarmStart: null, michael@0: alarmEnd: null, michael@0: data: null, michael@0: pageURL: testPageURL, michael@0: manifestURL: testManifestURL }; michael@0: michael@0: NetworkStatsService._networks[wifiId].status = NETWORK_STATUS_READY; michael@0: michael@0: NetworkStatsService._setAlarm(alarm, function onSet(error, result) { michael@0: do_check_eq(error, "InvalidStateError"); michael@0: run_next_test(); michael@0: }); michael@0: }); michael@0: michael@0: add_test(function test_fireAlarm() { michael@0: // Add a fake alarm into database. michael@0: let alarm = { id: null, michael@0: networkId: wifiId, michael@0: threshold: 10000, michael@0: absoluteThreshold: null, michael@0: alarmStart: null, michael@0: alarmEnd: null, michael@0: data: null, michael@0: pageURL: testPageURL, michael@0: manifestURL: testManifestURL }; michael@0: michael@0: // Set wifi status to standby to avoid connecting to netd when adding an alarm. michael@0: NetworkStatsService._networks[wifiId].status = NETWORK_STATUS_STANDBY; michael@0: michael@0: NetworkStatsService._db.addAlarm(alarm, function addSuccessCb(error, newId) { michael@0: NetworkStatsService._db.getAlarms(Ci.nsINetworkInterface.NETWORK_TYPE_WIFI, michael@0: testManifestURL, function onGet(error, result) { michael@0: do_check_eq(error, null); michael@0: do_check_eq(result.length, 1); michael@0: michael@0: // Result of getAlarms is based on expected child's data format, so michael@0: // some changes are needed to be able to use it. michael@0: result[0].networkId = wifiId; michael@0: result[0].pageURL = testPageURL; michael@0: result[0].manifestURL = testManifestURL; michael@0: michael@0: NetworkStatsService._fireAlarm(result[0], false); michael@0: NetworkStatsService._db.getAlarms(Ci.nsINetworkInterface.NETWORK_TYPE_WIFI, michael@0: testManifestURL, function onGet(error, result) { michael@0: do_check_eq(error, undefined); michael@0: do_check_eq(result.length, 0); michael@0: run_next_test(); michael@0: }); michael@0: }); michael@0: }); michael@0: }); michael@0: michael@0: function run_test() { michael@0: do_get_profile(); michael@0: michael@0: Cu.import("resource://gre/modules/NetworkStatsService.jsm"); michael@0: run_next_test(); michael@0: }