summaryrefslogtreecommitdiffstats
path: root/dom/network/tests/unit_stats
diff options
context:
space:
mode:
Diffstat (limited to 'dom/network/tests/unit_stats')
-rw-r--r--dom/network/tests/unit_stats/test_networkstats_db.js1093
-rw-r--r--dom/network/tests/unit_stats/test_networkstats_service.js290
-rw-r--r--dom/network/tests/unit_stats/test_networkstats_service_proxy.js233
-rw-r--r--dom/network/tests/unit_stats/xpcshell.ini7
4 files changed, 1623 insertions, 0 deletions
diff --git a/dom/network/tests/unit_stats/test_networkstats_db.js b/dom/network/tests/unit_stats/test_networkstats_db.js
new file mode 100644
index 000000000..50a5dc186
--- /dev/null
+++ b/dom/network/tests/unit_stats/test_networkstats_db.js
@@ -0,0 +1,1093 @@
+/* Any: copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+
+Cu.import("resource://gre/modules/NetworkStatsDB.jsm");
+
+const STATS_STORE_NAME = "net_stats_store_v3";
+const netStatsDb = new NetworkStatsDB();
+
+function clearStore(store, callback) {
+ netStatsDb.dbNewTxn(store, "readwrite", function(aTxn, aStore) {
+ aStore.openCursor().onsuccess = function (event) {
+ let cursor = event.target.result;
+ if (cursor){
+ cursor.delete();
+ cursor.continue();
+ }
+ };
+ }, callback);
+}
+
+function getNetworkId(aIccId, aNetworkType) {
+ return aIccId + '' + aNetworkType;
+}
+
+add_test(function prepareDatabase() {
+ // Clear whole database to avoid starting tests with unknown state
+ // due to the previous tests.
+ clearStore(STATS_STORE_NAME, function() {
+ clearStore('net_alarm', function() {
+ run_next_test();
+ });
+ });
+});
+
+function filterTimestamp(date) {
+ var sampleRate = netStatsDb.sampleRate;
+ var offset = date.getTimezoneOffset() * 60 * 1000;
+ return Math.floor((date.getTime() - offset) / sampleRate) * sampleRate;
+}
+
+function getNetworks() {
+ return [{ id: '0', type: Ci.nsINetworkInterface.NETWORK_TYPE_WIFI },
+ { id: '1234', type: Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE }];
+}
+
+function compareNetworks(networkA, networkB) {
+ return (networkA[0] == networkB[0] && networkA[1] == networkB[1]);
+}
+
+add_test(function test_sampleRate() {
+ var sampleRate = netStatsDb.sampleRate;
+ do_check_true(sampleRate > 0);
+ netStatsDb.sampleRate = 0;
+ sampleRate = netStatsDb.sampleRate;
+ do_check_true(sampleRate > 0);
+
+ run_next_test();
+});
+
+add_test(function test_maxStorageSamples() {
+ var maxStorageSamples = netStatsDb.maxStorageSamples;
+ do_check_true(maxStorageSamples > 0);
+ netStatsDb.maxStorageSamples = 0;
+ maxStorageSamples = netStatsDb.maxStorageSamples;
+ do_check_true(maxStorageSamples > 0);
+
+ run_next_test();
+});
+
+add_test(function test_fillResultSamples_emptyData() {
+ var samples = 3;
+ var data = [];
+ var start = filterTimestamp(new Date());
+ var sampleRate = netStatsDb.sampleRate;
+ var end = start + (sampleRate * samples);
+ netStatsDb.fillResultSamples(start, end, data);
+ do_check_eq(data.length, samples + 1);
+
+ var aux = start;
+ var success = true;
+ for (var i = 0; i <= samples; i++) {
+ if (data[i].date.getTime() != aux || data[i].rxBytes != undefined || data[i].txBytes != undefined) {
+ success = false;
+ break;
+ }
+ aux += sampleRate;
+ }
+ do_check_true(success);
+
+ run_next_test();
+});
+
+add_test(function test_fillResultSamples_noEmptyData() {
+ var samples = 3;
+ var sampleRate = netStatsDb.sampleRate;
+ var start = filterTimestamp(new Date());
+ var end = start + (sampleRate * samples);
+ var data = [{date: new Date(start + sampleRate),
+ rxBytes: 0,
+ txBytes: 0}];
+ netStatsDb.fillResultSamples(start, end, data);
+ do_check_eq(data.length, samples + 1);
+
+ var aux = start;
+ var success = true;
+ for (var i = 0; i <= samples; i++) {
+ if (i == 1) {
+ if (data[i].date.getTime() != aux || data[i].rxBytes != 0 || data[i].txBytes != 0) {
+ success = false;
+ break;
+ }
+ } else {
+ if (data[i].date.getTime() != aux || data[i].rxBytes != undefined || data[i].txBytes != undefined) {
+ success = false;
+ break;
+ }
+ }
+ aux += sampleRate;
+ }
+ do_check_true(success);
+
+ run_next_test();
+});
+
+add_test(function test_clear() {
+ var networks = getNetworks();
+ networks.forEach(function(network, index) {
+ networks[index] = {network: network, networkId: getNetworkId(network.id, network.type)};
+ }, this);
+
+ netStatsDb.clearStats(networks, function (error, result) {
+ do_check_eq(error, null);
+ run_next_test();
+ });
+});
+
+add_test(function test_clear_interface() {
+ var networks = getNetworks();
+ networks.forEach(function(network, index) {
+ networks[index] = {network: network, networkId: getNetworkId(network.id, network.type)};
+ }, this);
+
+ netStatsDb.clearInterfaceStats(networks[0], function (error, result) {
+ do_check_eq(error, null);
+ run_next_test();
+ });
+});
+
+add_test(function test_internalSaveStats_singleSample() {
+ var networks = getNetworks();
+
+ var stats = { appId: 0,
+ isInBrowser: 0,
+ serviceType: "",
+ network: [networks[0].id, networks[0].type],
+ timestamp: Date.now(),
+ rxBytes: 0,
+ txBytes: 0,
+ rxSystemBytes: 1234,
+ txSystemBytes: 1234,
+ rxTotalBytes: 1234,
+ txTotalBytes: 1234 };
+
+ netStatsDb.dbNewTxn(STATS_STORE_NAME, "readwrite", function(txn, store) {
+ netStatsDb._saveStats(txn, store, stats);
+ }, function(error, result) {
+ do_check_eq(error, null);
+
+ netStatsDb.logAllRecords(function(error, result) {
+ do_check_eq(error, null);
+ do_check_eq(result.length, 1);
+ do_check_eq(result[0].appId, stats.appId);
+ do_check_eq(result[0].isInBrowser, stats.isInBrowser);
+ do_check_eq(result[0].serviceType, stats.serviceType);
+ do_check_true(compareNetworks(result[0].network, stats.network));
+ do_check_eq(result[0].timestamp, stats.timestamp);
+ do_check_eq(result[0].rxBytes, stats.rxBytes);
+ do_check_eq(result[0].txBytes, stats.txBytes);
+ do_check_eq(result[0].rxSystemBytes, stats.rxSystemBytes);
+ do_check_eq(result[0].txSystemBytes, stats.txSystemBytes);
+ do_check_eq(result[0].rxTotalBytes, stats.rxTotalBytes);
+ do_check_eq(result[0].txTotalBytes, stats.txTotalBytes);
+ run_next_test();
+ });
+ });
+});
+
+add_test(function test_internalSaveStats_arraySamples() {
+ clearStore(STATS_STORE_NAME, function() {
+ var networks = getNetworks();
+ var network = [networks[0].id, networks[0].type];
+
+ var samples = 2;
+ var stats = [];
+ for (var i = 0; i < samples; i++) {
+ stats.push({ appId: 0,
+ isInBrowser: 0,
+ serviceType: "",
+ network: network,
+ timestamp: Date.now() + (10 * i),
+ rxBytes: 0,
+ txBytes: 0,
+ rxSystemBytes: 1234,
+ txSystemBytes: 1234,
+ rxTotalBytes: 1234,
+ txTotalBytes: 1234 });
+ }
+
+ netStatsDb.dbNewTxn(STATS_STORE_NAME, "readwrite", function(txn, store) {
+ netStatsDb._saveStats(txn, store, stats);
+ }, function(error, result) {
+ do_check_eq(error, null);
+
+ netStatsDb.logAllRecords(function(error, result) {
+ do_check_eq(error, null);
+
+ do_check_eq(result.length, samples);
+ var success = true;
+ for (var i = 0; i < samples; i++) {
+ if (result[i].appId != stats[i].appId ||
+ result[i].isInBrowser != stats[i].isInBrowser ||
+ result[i].serviceType != stats[i].serviceType ||
+ !compareNetworks(result[i].network, stats[i].network) ||
+ result[i].timestamp != stats[i].timestamp ||
+ result[i].rxBytes != stats[i].rxBytes ||
+ result[i].txBytes != stats[i].txBytes ||
+ result[i].rxSystemBytes != stats[i].rxSystemBytes ||
+ result[i].txSystemBytes != stats[i].txSystemBytes ||
+ result[i].rxTotalBytes != stats[i].rxTotalBytes ||
+ result[i].txTotalBytes != stats[i].txTotalBytes) {
+ success = false;
+ break;
+ }
+ }
+ do_check_true(success);
+ run_next_test();
+ });
+ });
+ });
+});
+
+add_test(function test_internalRemoveOldStats() {
+ clearStore(STATS_STORE_NAME, function() {
+ var networks = getNetworks();
+ var network = [networks[0].id, networks[0].type];
+ var samples = 10;
+ var stats = [];
+ for (var i = 0; i < samples - 1; i++) {
+ stats.push({ appId: 0, isInBrowser: 0,
+ serviceType: "",
+ network: network, timestamp: Date.now() + (10 * i),
+ rxBytes: 0, txBytes: 0,
+ rxSystemBytes: 1234, txSystemBytes: 1234,
+ rxTotalBytes: 1234, txTotalBytes: 1234 });
+ }
+
+ stats.push({ appId: 0, isInBrowser: 0,
+ serviceType: "",
+ network: network, timestamp: Date.now() + (10 * samples),
+ rxBytes: 0, txBytes: 0,
+ rxSystemBytes: 1234, txSystemBytes: 1234,
+ rxTotalBytes: 1234, txTotalBytes: 1234 });
+
+ netStatsDb.dbNewTxn(STATS_STORE_NAME, "readwrite", function(txn, store) {
+ netStatsDb._saveStats(txn, store, stats);
+ var date = stats[stats.length - 1].timestamp
+ + (netStatsDb.sampleRate * netStatsDb.maxStorageSamples - 1) - 1;
+ netStatsDb._removeOldStats(txn, store, 0, 0, "", network, date);
+ }, function(error, result) {
+ do_check_eq(error, null);
+
+ netStatsDb.logAllRecords(function(error, result) {
+ do_check_eq(error, null);
+ do_check_eq(result.length, 1);
+
+ run_next_test();
+ });
+ });
+ });
+});
+
+function processSamplesDiff(networks, lastStat, newStat, callback) {
+ clearStore(STATS_STORE_NAME, function() {
+ netStatsDb.dbNewTxn(STATS_STORE_NAME, "readwrite", function(txn, store) {
+ netStatsDb._saveStats(txn, store, lastStat);
+ }, function(error, result) {
+ netStatsDb.dbNewTxn(STATS_STORE_NAME, "readwrite", function(txn, store) {
+ let request = store.index("network").openCursor(newStat.network, "prev");
+ request.onsuccess = function onsuccess(event) {
+ let cursor = event.target.result;
+ do_check_neq(cursor, null);
+ netStatsDb._processSamplesDiff(txn, store, cursor, newStat, true);
+ };
+ }, function(error, result) {
+ do_check_eq(error, null);
+ netStatsDb.logAllRecords(function(error, result) {
+ do_check_eq(error, null);
+ callback(result);
+ });
+ });
+ });
+ });
+}
+
+add_test(function test_processSamplesDiffSameSample() {
+ var networks = getNetworks();
+ var network = [networks[0].id, networks[0].type];
+
+ var sampleRate = netStatsDb.sampleRate;
+ var date = filterTimestamp(new Date());
+
+ var lastStat = { appId: 0, isInBrowser: 0,
+ serviceType: "",
+ network: network, timestamp: date,
+ rxBytes: 0, txBytes: 0,
+ rxSystemBytes: 1234, txSystemBytes: 1234,
+ rxTotalBytes: 2234, txTotalBytes: 2234 };
+
+ var newStat = { appId: 0, isInBrowser: 0,
+ serviceType: "",
+ network: network, timestamp: date,
+ rxBytes: 0, txBytes: 0,
+ rxSystemBytes: 2234, txSystemBytes: 2234,
+ rxTotalBytes: 2234, txTotalBytes: 2234 };
+
+ processSamplesDiff(networks, lastStat, newStat, function(result) {
+ do_check_eq(result.length, 1);
+ do_check_eq(result[0].appId, newStat.appId);
+ do_check_eq(result[0].isInBrowser, newStat.isInBrowser);
+ do_check_eq(result[0].serviceType, newStat.serviceType);
+ do_check_true(compareNetworks(result[0].network, newStat.network));
+ do_check_eq(result[0].timestamp, newStat.timestamp);
+ do_check_eq(result[0].rxBytes, newStat.rxSystemBytes - lastStat.rxSystemBytes);
+ do_check_eq(result[0].txBytes, newStat.txSystemBytes - lastStat.txSystemBytes);
+ do_check_eq(result[0].rxTotalBytes, lastStat.rxTotalBytes + newStat.rxSystemBytes - lastStat.rxSystemBytes);
+ do_check_eq(result[0].txTotalBytes, lastStat.txTotalBytes + newStat.txSystemBytes - lastStat.txSystemBytes);
+ do_check_eq(result[0].rxSystemBytes, newStat.rxSystemBytes);
+ do_check_eq(result[0].txSystemBytes, newStat.txSystemBytes);
+ run_next_test();
+ });
+});
+
+add_test(function test_processSamplesDiffNextSample() {
+ var networks = getNetworks();
+ var network = [networks[0].id, networks[0].type];
+
+ var sampleRate = netStatsDb.sampleRate;
+ var date = filterTimestamp(new Date());
+
+ var lastStat = { appId: 0, isInBrowser: 0,
+ serviceType: "",
+ network: network, timestamp: date,
+ rxBytes: 0, txBytes: 0,
+ rxSystemBytes: 1234, txSystemBytes: 1234,
+ rxTotalBytes: 2234, txTotalBytes: 2234 };
+
+ var newStat = { appId: 0, isInBrowser: 0,
+ serviceType: "",
+ network: network, timestamp: date + sampleRate,
+ rxBytes: 0, txBytes: 0,
+ rxSystemBytes: 1734, txSystemBytes: 1734,
+ rxTotalBytes: 0, txTotalBytes: 0 };
+
+ processSamplesDiff(networks, lastStat, newStat, function(result) {
+ do_check_eq(result.length, 2);
+ do_check_eq(result[1].appId, newStat.appId);
+ do_check_eq(result[1].isInBrowser, newStat.isInBrowser);
+ do_check_eq(result[1].serviceType, newStat.serviceType);
+ do_check_true(compareNetworks(result[1].network, newStat.network));
+ do_check_eq(result[1].timestamp, newStat.timestamp);
+ do_check_eq(result[1].rxBytes, newStat.rxSystemBytes - lastStat.rxSystemBytes);
+ do_check_eq(result[1].txBytes, newStat.txSystemBytes - lastStat.txSystemBytes);
+ do_check_eq(result[1].rxSystemBytes, newStat.rxSystemBytes);
+ do_check_eq(result[1].txSystemBytes, newStat.txSystemBytes);
+ do_check_eq(result[1].rxTotalBytes, lastStat.rxTotalBytes + newStat.rxSystemBytes - lastStat.rxSystemBytes);
+ do_check_eq(result[1].txTotalBytes, lastStat.txTotalBytes + newStat.txSystemBytes - lastStat.txSystemBytes);
+ run_next_test();
+ });
+});
+
+add_test(function test_processSamplesDiffSamplesLost() {
+ var networks = getNetworks();
+ var network = [networks[0].id, networks[0].type];
+ var samples = 5;
+ var sampleRate = netStatsDb.sampleRate;
+ var date = filterTimestamp(new Date());
+ var lastStat = { appId: 0, isInBrowser: 0,
+ serviceType: "",
+ network: network, timestamp: date,
+ rxBytes: 0, txBytes: 0,
+ rxSystemBytes: 1234, txSystemBytes: 1234,
+ rxTotalBytes: 2234, txTotalBytes: 2234};
+
+ var newStat = { appId: 0, isInBrowser: 0,
+ serviceType: "",
+ network: network, timestamp: date + (sampleRate * samples),
+ rxBytes: 0, txBytes: 0,
+ rxSystemBytes: 2234, txSystemBytes: 2234,
+ rxTotalBytes: 0, txTotalBytes: 0 };
+
+ processSamplesDiff(networks, lastStat, newStat, function(result) {
+ do_check_eq(result.length, samples + 1);
+ do_check_eq(result[0].appId, newStat.appId);
+ do_check_eq(result[0].isInBrowser, newStat.isInBrowser);
+ do_check_eq(result[0].serviceType, newStat.serviceType);
+ do_check_true(compareNetworks(result[samples].network, newStat.network));
+ do_check_eq(result[samples].timestamp, newStat.timestamp);
+ do_check_eq(result[samples].rxBytes, newStat.rxTotalBytes - lastStat.rxTotalBytes);
+ do_check_eq(result[samples].txBytes, newStat.txTotalBytes - lastStat.txTotalBytes);
+ do_check_eq(result[samples].rxSystemBytes, newStat.rxSystemBytes);
+ do_check_eq(result[samples].txSystemBytes, newStat.txSystemBytes);
+ do_check_eq(result[samples].rxTotalBytes, lastStat.rxTotalBytes + newStat.rxSystemBytes - lastStat.rxSystemBytes);
+ do_check_eq(result[samples].txTotalBytes, lastStat.txTotalBytes + newStat.txSystemBytes - lastStat.txSystemBytes);
+ run_next_test();
+ });
+});
+
+add_test(function test_saveStats() {
+ var networks = getNetworks();
+ var network = [networks[0].id, networks[0].type];
+
+ var stats = { appId: 0,
+ isInBrowser: false,
+ serviceType: "",
+ networkId: networks[0].id,
+ networkType: networks[0].type,
+ date: new Date(),
+ rxBytes: 2234,
+ txBytes: 2234,
+ isAccumulative: true };
+
+ clearStore(STATS_STORE_NAME, function() {
+ netStatsDb.saveStats(stats, function(error, result) {
+ do_check_eq(error, null);
+ netStatsDb.logAllRecords(function(error, result) {
+ do_check_eq(error, null);
+ do_check_eq(result.length, 1);
+ do_check_eq(result[0].appId, stats.appId);
+ do_check_eq(result[0].isInBrowser, stats.isInBrowser);
+ do_check_eq(result[0].serviceType, stats.serviceType);
+ do_check_true(compareNetworks(result[0].network, network));
+ let timestamp = filterTimestamp(stats.date);
+ do_check_eq(result[0].timestamp, timestamp);
+ do_check_eq(result[0].rxBytes, stats.rxBytes);
+ do_check_eq(result[0].txBytes, stats.txBytes);
+ do_check_eq(result[0].rxSystemBytes, stats.rxBytes);
+ do_check_eq(result[0].txSystemBytes, stats.txBytes);
+ do_check_eq(result[0].rxTotalBytes, stats.rxBytes);
+ do_check_eq(result[0].txTotalBytes, stats.txBytes);
+ run_next_test();
+ });
+ });
+ });
+});
+
+add_test(function test_saveAppStats() {
+ var networks = getNetworks();
+ var network = [networks[0].id, networks[0].type];
+
+ var stats = { appId: 1,
+ isInBrowser: false,
+ serviceType: "",
+ networkId: networks[0].id,
+ networkType: networks[0].type,
+ date: new Date(),
+ rxBytes: 2234,
+ txBytes: 2234,
+ isAccumulative: false };
+
+ clearStore(STATS_STORE_NAME, function() {
+ netStatsDb.saveStats(stats, function(error, result) {
+ do_check_eq(error, null);
+ netStatsDb.logAllRecords(function(error, result) {
+ do_check_eq(error, null);
+ do_check_eq(result.length, 1);
+ do_check_eq(result[0].appId, stats.appId);
+ do_check_eq(result[0].isInBrowser, 0);
+ do_check_eq(result[0].serviceType, stats.serviceType);
+ do_check_true(compareNetworks(result[0].network, network));
+ let timestamp = filterTimestamp(stats.date);
+ do_check_eq(result[0].timestamp, timestamp);
+ do_check_eq(result[0].rxBytes, stats.rxBytes);
+ do_check_eq(result[0].txBytes, stats.txBytes);
+ do_check_eq(result[0].rxSystemBytes, 0);
+ do_check_eq(result[0].txSystemBytes, 0);
+ do_check_eq(result[0].rxTotalBytes, 0);
+ do_check_eq(result[0].txTotalBytes, 0);
+ run_next_test();
+ });
+ });
+ });
+});
+
+add_test(function test_saveServiceStats() {
+ var networks = getNetworks();
+ var network = [networks[0].id, networks[0].type];
+
+ var stats = { appId: 0,
+ isInBrowser: false,
+ serviceType: "FakeType",
+ networkId: networks[0].id,
+ networkType: networks[0].type,
+ date: new Date(),
+ rxBytes: 2234,
+ txBytes: 2234,
+ isAccumulative: false };
+
+ clearStore(STATS_STORE_NAME, function() {
+ netStatsDb.saveStats(stats, function(error, result) {
+ do_check_eq(error, null);
+ netStatsDb.logAllRecords(function(error, result) {
+ do_check_eq(error, null);
+ do_check_eq(result.length, 1);
+ do_check_eq(result[0].appId, stats.appId);
+ do_check_eq(result[0].isInBrowser, 0);
+ do_check_eq(result[0].serviceType, stats.serviceType);
+ do_check_true(compareNetworks(result[0].network, network));
+ let timestamp = filterTimestamp(stats.date);
+ do_check_eq(result[0].timestamp, timestamp);
+ do_check_eq(result[0].rxBytes, stats.rxBytes);
+ do_check_eq(result[0].txBytes, stats.txBytes);
+ do_check_eq(result[0].rxSystemBytes, 0);
+ do_check_eq(result[0].txSystemBytes, 0);
+ do_check_eq(result[0].rxTotalBytes, 0);
+ do_check_eq(result[0].txTotalBytes, 0);
+ run_next_test();
+ });
+ });
+ });
+});
+
+function prepareFind(stats, callback) {
+ clearStore(STATS_STORE_NAME, function() {
+ netStatsDb.dbNewTxn(STATS_STORE_NAME, "readwrite", function(txn, store) {
+ netStatsDb._saveStats(txn, store, stats);
+ }, function(error, result) {
+ callback(error, result);
+ });
+ });
+}
+
+add_test(function test_find () {
+ var networks = getNetworks();
+ var networkWifi = [networks[0].id, networks[0].type];
+ var networkMobile = [networks[1].id, networks[1].type]; // Fake mobile interface
+ var appId = 0;
+ var isInBrowser = 0;
+ var serviceType = "";
+
+ var samples = 5;
+ var sampleRate = netStatsDb.sampleRate;
+ var start = Date.now();
+ var saveDate = filterTimestamp(new Date());
+ var end = new Date(start + (sampleRate * (samples - 1)));
+ start = new Date(start - sampleRate);
+ var stats = [];
+ for (var i = 0; i < samples; i++) {
+ stats.push({ appId: appId, isInBrowser: isInBrowser,
+ serviceType: serviceType,
+ network: networkWifi, timestamp: saveDate + (sampleRate * i),
+ rxBytes: 0, txBytes: 10,
+ rxSystemBytes: 0, txSystemBytes: 0,
+ rxTotalBytes: 0, txTotalBytes: 0 });
+
+
+ stats.push({ appId: appId, isInBrowser: isInBrowser,
+ serviceType: serviceType,
+ network: networkMobile, timestamp: saveDate + (sampleRate * i),
+ rxBytes: 0, txBytes: 10,
+ rxSystemBytes: 0, txSystemBytes: 0,
+ rxTotalBytes: 0, txTotalBytes: 0 });
+ }
+
+ prepareFind(stats, function(error, result) {
+ do_check_eq(error, null);
+ netStatsDb.find(function (error, result) {
+ do_check_eq(error, null);
+ do_check_eq(result.browsingTrafficOnly, false);
+ do_check_eq(result.serviceType, serviceType);
+ do_check_eq(result.network.id, networks[0].id);
+ do_check_eq(result.network.type, networks[0].type);
+ do_check_eq(result.start.getTime(), start.getTime());
+ do_check_eq(result.end.getTime(), end.getTime());
+ do_check_eq(result.data.length, samples + 1);
+ do_check_eq(result.data[0].rxBytes, null);
+ do_check_eq(result.data[1].rxBytes, 0);
+ do_check_eq(result.data[samples].rxBytes, 0);
+ run_next_test();
+ }, appId, false, serviceType, networks[0], start, end);
+ });
+});
+
+add_test(function test_findAppStats () {
+ var networks = getNetworks();
+ var networkWifi = [networks[0].id, networks[0].type];
+ var networkMobile = [networks[1].id, networks[1].type]; // Fake mobile interface
+ var appId = 1;
+ var isInBrowser = 0;
+ var serviceType = "";
+
+ var samples = 5;
+ var sampleRate = netStatsDb.sampleRate;
+ var start = Date.now();
+ var saveDate = filterTimestamp(new Date());
+ var end = new Date(start + (sampleRate * (samples - 1)));
+ start = new Date(start - sampleRate);
+ var stats = [];
+ for (var i = 0; i < samples; i++) {
+ stats.push({ appId: appId, isInBrowser: isInBrowser,
+ serviceType: serviceType,
+ network: networkWifi, timestamp: saveDate + (sampleRate * i),
+ rxBytes: 0, txBytes: 10,
+ rxTotalBytes: 0, txTotalBytes: 0 });
+
+ stats.push({ appId: appId, isInBrowser: isInBrowser,
+ serviceType: serviceType,
+ network: networkMobile, timestamp: saveDate + (sampleRate * i),
+ rxBytes: 0, txBytes: 10,
+ rxTotalBytes: 0, txTotalBytes: 0 });
+ }
+
+ prepareFind(stats, function(error, result) {
+ do_check_eq(error, null);
+ netStatsDb.find(function (error, result) {
+ do_check_eq(error, null);
+ do_check_eq(result.browsingTrafficOnly, false);
+ do_check_eq(result.serviceType, serviceType);
+ do_check_eq(result.network.id, networks[0].id);
+ do_check_eq(result.network.type, networks[0].type);
+ do_check_eq(result.start.getTime(), start.getTime());
+ do_check_eq(result.end.getTime(), end.getTime());
+ do_check_eq(result.data.length, samples + 1);
+ do_check_eq(result.data[0].rxBytes, null);
+ do_check_eq(result.data[1].rxBytes, 0);
+ do_check_eq(result.data[samples].rxBytes, 0);
+ run_next_test();
+ }, appId, false, serviceType, networks[0], start, end);
+ });
+});
+
+add_test(function test_findServiceStats () {
+ var networks = getNetworks();
+ var networkWifi = [networks[0].id, networks[0].type];
+ var networkMobile = [networks[1].id, networks[1].type]; // Fake mobile interface
+ var appId = 0;
+ var isInBrowser = 0;
+ var serviceType = "FakeType";
+
+ var samples = 5;
+ var sampleRate = netStatsDb.sampleRate;
+ var start = Date.now();
+ var saveDate = filterTimestamp(new Date());
+ var end = new Date(start + (sampleRate * (samples - 1)));
+ start = new Date(start - sampleRate);
+ var stats = [];
+ for (var i = 0; i < samples; i++) {
+ stats.push({ appId: appId, isInBrowser: isInBrowser,
+ serviceType: serviceType,
+ network: networkWifi, timestamp: saveDate + (sampleRate * i),
+ rxBytes: 0, txBytes: 10,
+ rxTotalBytes: 0, txTotalBytes: 0 });
+
+ stats.push({ appId: appId, isInBrowser: isInBrowser,
+ serviceType: serviceType,
+ network: networkMobile, timestamp: saveDate + (sampleRate * i),
+ rxBytes: 0, txBytes: 10,
+ rxTotalBytes: 0, txTotalBytes: 0 });
+ }
+
+ prepareFind(stats, function(error, result) {
+ do_check_eq(error, null);
+ netStatsDb.find(function (error, result) {
+ do_check_eq(error, null);
+ do_check_eq(result.browsingTrafficOnly, false);
+ do_check_eq(result.serviceType, serviceType);
+ do_check_eq(result.network.id, networks[0].id);
+ do_check_eq(result.network.type, networks[0].type);
+ do_check_eq(result.start.getTime(), start.getTime());
+ do_check_eq(result.end.getTime(), end.getTime());
+ do_check_eq(result.data.length, samples + 1);
+ do_check_eq(result.data[0].rxBytes, null);
+ do_check_eq(result.data[1].rxBytes, 0);
+ do_check_eq(result.data[samples].rxBytes, 0);
+ run_next_test();
+ }, appId, false, serviceType, networks[0], start, end);
+ });
+});
+
+add_test(function test_saveMultipleAppStats () {
+ var networks = getNetworks();
+ var networkWifi = networks[0];
+ var networkMobile = networks[1]; // Fake mobile interface
+
+ var saveDate = filterTimestamp(new Date());
+ var cached = Object.create(null);
+ var serviceType = "FakeType";
+ var wifiNetId = networkWifi.id + '' + networkWifi.type;
+ var mobileNetId = networkMobile.id + '' + networkMobile.type;
+
+ cached[0 + '' + serviceType + wifiNetId] = {
+ appId: 0, date: new Date(),
+ networkId: networkWifi.id, networkType: networkWifi.type,
+ rxBytes: 0, txBytes: 10,
+ serviceType: serviceType, isAccumulative: false,
+ isInBrowser: false
+ };
+
+ cached[0 + '' + serviceType + mobileNetId] = {
+ appId: 0, date: new Date(),
+ networkId: networkMobile.id, networkType: networkMobile.type,
+ rxBytes: 0, txBytes: 10,
+ serviceType: serviceType, isAccumulative: false,
+ isInBrowser: false
+ };
+
+ cached[1 + '' + wifiNetId] = {
+ appId: 1, date: new Date(),
+ networkId: networkWifi.id, networkType: networkWifi.type,
+ rxBytes: 0, txBytes: 10,
+ serviceType: "", isAccumulative: false,
+ isInBrowser: false
+ };
+
+ cached[1 + '' + mobileNetId] = {
+ appId: 1, date: new Date(),
+ networkId: networkMobile.id, networkType: networkMobile.type,
+ rxBytes: 0, txBytes: 10,
+ serviceType: "", isAccumulative: false,
+ isInBrowser: false
+ };
+
+ cached[2 + '' + wifiNetId] = {
+ appId: 2, date: new Date(),
+ networkId: networkWifi.id, networkType: networkWifi.type,
+ rxBytes: 0, txBytes: 10,
+ serviceType: "", isAccumulative: false,
+ isInBrowser: false
+ };
+
+ cached[2 + '' + mobileNetId] = {
+ appId: 2, date: new Date(),
+ networkId: networkMobile.id, networkType: networkMobile.type,
+ rxBytes: 0, txBytes: 10,
+ serviceType: "", isAccumulative: false,
+ isInBrowser: false
+ };
+
+ let keys = Object.keys(cached);
+ let index = 0;
+
+ networks.push(networkMobile);
+
+ clearStore(STATS_STORE_NAME, function() {
+ netStatsDb.saveStats(cached[keys[index]],
+ function callback(error, result) {
+ do_check_eq(error, null);
+
+ if (index == keys.length - 1) {
+ netStatsDb.logAllRecords(function(error, result) {
+ do_check_eq(error, null);
+ do_check_eq(result.length, 6);
+ do_check_eq(result[0].isInBrowser, 0);
+ do_check_eq(result[0].serviceType, serviceType);
+ do_check_eq(result[3].appId, 1);
+ do_check_true(compareNetworks(result[0].network, [networkWifi.id, networkWifi.type]));
+ do_check_eq(result[0].rxBytes, 0);
+ do_check_eq(result[0].txBytes, 10);
+ run_next_test();
+ });
+ return;
+ }
+
+ index += 1;
+ netStatsDb.saveStats(cached[keys[index]], callback);
+ });
+ });
+});
+
+// Test case for find samples with browsingTrafficOnly option.
+add_test(function test_findBrowsingTrafficStats() {
+ var networks = getNetworks();
+ var networkWifi = [networks[0].id, networks[0].type];
+ var networkMobile = [networks[1].id, networks[1].type];
+ var serviceType = "";
+ var samples = 5;
+ var sampleRate = netStatsDb.sampleRate;
+ var start = Date.now();
+ var end = new Date(start + (sampleRate * (samples - 1)));
+ var saveDate = filterTimestamp(new Date());
+ start = new Date(start - sampleRate);
+ var stats = [];
+
+ for (var i = 0; i < samples; i++) {
+ // System app.
+ stats.push({ appId: 1008, isInBrowser: 0,
+ serviceType: serviceType, network: networkMobile,
+ timestamp: saveDate + (sampleRate * i),
+ rxBytes: 200, txBytes: 100,
+ rxTotalBytes: 200, txTotalBytes: 100});
+ // Browser of system app.
+ stats.push({ appId: 1008, isInBrowser: 1,
+ serviceType: serviceType, network: networkMobile,
+ timestamp: saveDate + (sampleRate * i),
+ rxBytes: 1000, txBytes: 500,
+ rxTotalBytes: 1000, txTotalBytes: 500});
+ // Another app.
+ stats.push({ appId: 1021, isInBrowser: 0,
+ serviceType: serviceType, network: networkMobile,
+ timestamp: saveDate + (sampleRate * i),
+ rxBytes: 300, txBytes: 150,
+ rxTotalBytes: 300, txTotalBytes: 150});
+ // Browser of another app.
+ stats.push({ appId: 1021, isInBrowser: 1,
+ serviceType: serviceType, network: networkMobile,
+ timestamp: saveDate + (sampleRate * i),
+ rxBytes: 600, txBytes: 300,
+ rxTotalBytes: 600, txTotalBytes: 300});
+ }
+
+ prepareFind(stats, function(error, result) {
+ do_check_eq(error, null);
+ netStatsDb.find(function(error, result) {
+ do_check_eq(error, null);
+ do_check_eq(result.browsingTrafficOnly, true);
+ do_check_eq(result.serviceType, serviceType);
+ do_check_eq(result.network.id, networks[1].id);
+ do_check_eq(result.network.type, networks[1].type);
+ do_check_eq(result.start.getTime(), start.getTime());
+ do_check_eq(result.end.getTime(), end.getTime());
+ do_check_eq(result.data.length, samples + 1);
+ do_check_eq(result.data[0].rxBytes, null);
+ do_check_eq(result.data[1].txBytes, 500);
+ do_check_eq(result.data[2].rxBytes, 1000);
+ run_next_test();
+ }, 1008, true, serviceType, networks[1], start, end);
+ });
+});
+
+// Test case for find samples with browsingTrafficOnly option.
+add_test(function test_findAppTrafficStats() {
+ var networks = getNetworks();
+ var networkWifi = [networks[0].id, networks[0].type];
+ var networkMobile = [networks[1].id, networks[1].type];
+ var serviceType = "";
+ var samples = 5;
+ var sampleRate = netStatsDb.sampleRate;
+ var start = Date.now();
+ var end = new Date(start + (sampleRate * (samples - 1)));
+ var saveDate = filterTimestamp(new Date());
+ start = new Date(start - sampleRate);
+ var stats = [];
+
+ for (var i = 0; i < samples; i++) {
+ // System app.
+ stats.push({ appId: 1008, isInBrowser: 0,
+ serviceType: serviceType, network: networkMobile,
+ timestamp: saveDate + (sampleRate * i),
+ rxBytes: 200, txBytes: 100,
+ rxTotalBytes: 200, txTotalBytes: 100});
+ // Browser of system app.
+ stats.push({ appId: 1008, isInBrowser: 1,
+ serviceType: serviceType, network: networkMobile,
+ timestamp: saveDate + (sampleRate * i),
+ rxBytes: 1000, txBytes: 500,
+ rxTotalBytes: 1000, txTotalBytes: 500});
+ // Another app.
+ stats.push({ appId: 1021, isInBrowser: 0,
+ serviceType: serviceType, network: networkMobile,
+ timestamp: saveDate + (sampleRate * i),
+ rxBytes: 300, txBytes: 150,
+ rxTotalBytes: 300, txTotalBytes: 150});
+ // Browser of another app.
+ stats.push({ appId: 1021, isInBrowser: 1,
+ serviceType: serviceType, network: networkMobile,
+ timestamp: saveDate + (sampleRate * i),
+ rxBytes: 600, txBytes: 300,
+ rxTotalBytes: 600, txTotalBytes: 300});
+ }
+
+ prepareFind(stats, function(error, result) {
+ do_check_eq(error, null);
+ netStatsDb.find(function(error, result) {
+ do_check_eq(error, null);
+ do_check_eq(result.browsingTrafficOnly, false);
+ do_check_eq(result.serviceType, serviceType);
+ do_check_eq(result.network.id, networks[1].id);
+ do_check_eq(result.network.type, networks[1].type);
+ do_check_eq(result.start.getTime(), start.getTime());
+ do_check_eq(result.end.getTime(), end.getTime());
+ do_check_eq(result.data.length, samples + 1);
+ do_check_eq(result.data[0].rxBytes, null);
+ do_check_eq(result.data[1].txBytes, 600);
+ do_check_eq(result.data[2].rxBytes, 1200);
+ run_next_test();
+ }, 1008, false, serviceType, networks[1], start, end);
+ });
+});
+
+var networkWifi = '00';
+var networkMobile = '11';
+
+var examplePageURL = "http://example.com/index.html";
+var exampleManifestURL = "http://example.com/manifest.webapp";
+
+var testPageURL = "http://test.com/index.html";
+var testManifestURL = "http://test.com/manifest.webapp";
+
+var alarms = [{ id: null,
+ networkId: networkWifi,
+ absoluteThreshold: 10000,
+ relativeThreshold: 10000,
+ data: {foo: "something"},
+ pageURL: examplePageURL,
+ manifestURL: exampleManifestURL },
+ { id: null,
+ networkId: networkWifi,
+ absoluteThreshold: 1000,
+ relativeThreshold: 1000,
+ data: {foo: "else"},
+ pageURL: examplePageURL,
+ manifestURL: exampleManifestURL },
+ { id: null,
+ networkId: networkMobile,
+ absoluteThreshold: 100,
+ relativeThreshold: 100,
+ data: {foo: "to"},
+ pageURL: examplePageURL,
+ manifestURL: exampleManifestURL },
+ { id: null,
+ networkId: networkMobile,
+ absoluteThreshold: 10,
+ relativeThreshold: 10,
+ data: {foo: "test"},
+ pageURL: testPageURL,
+ manifestURL: testManifestURL }];
+
+var alarmsDbId = 1;
+
+add_test(function test_addAlarm() {
+ // Add alarms[0] -> DB: [ alarms[0] (id: 1) ]
+ // Check the insertion is OK.
+ netStatsDb.addAlarm(alarms[0], function(error, result) {
+ do_check_eq(error, null);
+ alarmsDbId = result;
+ netStatsDb.getAlarms(Ci.nsINetworkInfo.NETWORK_TYPE_WIFI, exampleManifestURL, function(error, result) {
+ do_check_eq(error, null);
+ do_check_eq(result.length, 1);
+ do_check_eq(result[0].id, alarmsDbId);
+ do_check_eq(result[0].networkId, alarms[0].networkId);
+ do_check_eq(result[0].absoluteThreshold, alarms[0].absoluteThreshold);
+ do_check_eq(result[0].relativeThreshold, alarms[0].relativeThreshold);
+ do_check_eq(result[0].data.foo, alarms[0].data.foo);
+ run_next_test();
+ });
+ });
+});
+
+add_test(function test_getFirstAlarm() {
+ // Add alarms[1] -> DB: [ alarms[0] (id: 1), alarms[1] (id: 2) ]
+ // Check first alarm is alarms[1] because threshold is lower.
+ alarmsDbId += 1;
+ netStatsDb.addAlarm(alarms[1], function (error, result) {
+ do_check_eq(error, null);
+ do_check_eq(result, alarmsDbId);
+ netStatsDb.getFirstAlarm(networkWifi, function(error, result) {
+ do_check_eq(error, null);
+ do_check_eq(result.id, alarmsDbId);
+ do_check_eq(result.networkId, alarms[1].networkId);
+ do_check_eq(result.absoluteThreshold, alarms[1].absoluteThreshold);
+ do_check_eq(result.relativeThreshold, alarms[1].relativeThreshold);
+ do_check_eq(result.data.foo, alarms[1].data.foo);
+ do_check_eq(result.pageURL, alarms[1].pageURL);
+ do_check_eq(result.manifestURL, alarms[1].manifestURL);
+ run_next_test();
+ });
+ });
+});
+
+add_test(function test_removeAlarm() {
+ // Remove alarms[1] (id: 2) -> DB: [ alarms[0] (id: 1) ]
+ // Check get first return alarms[0].
+ netStatsDb.removeAlarm(alarmsDbId, alarms[0].manifestURL, function (error, result) {
+ do_check_eq(error, null);
+ netStatsDb.getFirstAlarm(networkWifi, function(error, result) {
+ do_check_eq(error, null);
+ do_check_eq(result.id, alarmsDbId - 1);
+ do_check_eq(result.networkId, alarms[0].networkId);
+ do_check_eq(result.absoluteThreshold, alarms[0].absoluteThreshold);
+ do_check_eq(result.relativeThreshold, alarms[0].relativeThreshold);
+ do_check_eq(result.data.foo, alarms[0].data.foo);
+ do_check_eq(result.pageURL, alarms[0].pageURL);
+ do_check_eq(result.manifestURL, alarms[0].manifestURL);
+ run_next_test();
+ });
+ });
+});
+
+add_test(function test_removeAppAlarm() {
+ // Remove alarms[0] (id: 1) -> DB: [ ]
+ netStatsDb.removeAlarm(alarmsDbId - 1, alarms[0].manifestURL, function (error, result) {
+ do_check_eq(error, null);
+ netStatsDb.getAlarms(networkWifi, exampleManifestURL, function(error, result) {
+ do_check_eq(error, null);
+ do_check_eq(result.length, 0);
+ run_next_test();
+ });
+ });
+});
+
+add_test(function test_getAlarms() {
+ // Add all alarms -> DB: [ alarms[0] (id: 3),
+ // alarms[1] (id: 4),
+ // alarms[2] (id: 5),
+ // alarms[3] (id: 6) ]
+ // Check that getAlarms for wifi returns 2 alarms.
+ // Check that getAlarms for all connections returns 3 alarms.
+
+ var callback = function () {
+ netStatsDb.getAlarms(networkWifi, exampleManifestURL, function(error, result) {
+ do_check_eq(error, null);
+ do_check_eq(result.length, 2);
+ netStatsDb.getAlarms(null, exampleManifestURL, function(error, result) {
+ do_check_eq(error, null);
+ do_check_eq(result.length, 3);
+ run_next_test();
+ });
+ });
+ };
+
+ var index = 0;
+
+ var addFunction = function () {
+ alarmsDbId += 1;
+ netStatsDb.addAlarm(alarms[index], function (error, result) {
+ do_check_eq(error, null);
+ index += 1;
+ do_check_eq(result, alarmsDbId);
+ if (index >= alarms.length) {
+ callback();
+ return;
+ }
+ addFunction();
+ });
+ };
+
+ addFunction();
+});
+
+add_test(function test_removeAppAllAlarms() {
+ // Remove all alarms for exampleManifestURL -> DB: [ alarms[3] (id: 6) ]
+ netStatsDb.removeAlarms(exampleManifestURL, function (error, result) {
+ do_check_eq(error, null);
+ netStatsDb.getAlarms(null, exampleManifestURL, function(error, result) {
+ do_check_eq(error, null);
+ do_check_eq(result.length, 0);
+ netStatsDb.getAlarms(null, testManifestURL, function(error, result) {
+ do_check_eq(error, null);
+ do_check_eq(result.length, 1);
+ run_next_test();
+ });
+ });
+ });
+});
+
+add_test(function test_updateAlarm() {
+ // Update alarms[3] (id: 6) -> DB: [ alarms[3]* (id: 6) ]
+
+ var updatedAlarm = alarms[1];
+ updatedAlarm.id = alarmsDbId;
+ updatedAlarm.threshold = 10;
+
+ netStatsDb.updateAlarm(updatedAlarm, function (error, result) {
+ do_check_eq(error, null);
+ netStatsDb.getFirstAlarm(networkWifi, function(error, result) {
+ do_check_eq(error, null);
+ do_check_eq(result.id, updatedAlarm.id);
+ do_check_eq(result.networkId, updatedAlarm.networkId);
+ do_check_eq(result.absoluteThreshold, updatedAlarm.absoluteThreshold);
+ do_check_eq(result.relativeThreshold, updatedAlarm.relativeThreshold);
+ do_check_eq(result.data.foo, updatedAlarm.data.foo);
+ do_check_eq(result.pageURL, updatedAlarm.pageURL);
+ do_check_eq(result.manifestURL, updatedAlarm.manifestURL);
+ run_next_test();
+ });
+ });
+});
+
+function run_test() {
+ do_get_profile();
+ run_next_test();
+}
diff --git a/dom/network/tests/unit_stats/test_networkstats_service.js b/dom/network/tests/unit_stats/test_networkstats_service.js
new file mode 100644
index 000000000..8c43a9b54
--- /dev/null
+++ b/dom/network/tests/unit_stats/test_networkstats_service.js
@@ -0,0 +1,290 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+
+const NETWORK_STATUS_READY = 0;
+const NETWORK_STATUS_STANDBY = 1;
+const NETWORK_STATUS_AWAY = 2;
+
+const QUEUE_TYPE_UPDATE_STATS = 0;
+
+var wifiId = '00';
+
+function getNetworks(callback) {
+ NetworkStatsService._db.getAvailableNetworks(function onGetNetworks(aError, aResult) {
+ callback(aError, aResult);
+ });
+}
+
+add_test(function test_clearDB() {
+ getNetworks(function onGetNetworks(error, result) {
+ do_check_eq(error, null);
+ var networks = result;
+ networks.forEach(function(network, index) {
+ networks[index] = {network: network, networkId: NetworkStatsService.getNetworkId(network.id, network.type)};
+ }, this);
+
+ NetworkStatsService._db.clearStats(networks, function onDBCleared(error, result) {
+ do_check_eq(error, null);
+ run_next_test();
+ });
+ });
+});
+
+function getNetworkId(callback) {
+ getNetworks(function onGetNetworks(error, result) {
+ do_check_eq(error, null);
+ var netId = NetworkStatsService.getNetworkId(result[0].id, result[0].type);
+ callback(null, netId);
+ });
+}
+
+add_test(function test_networkStatsAvailable_ok() {
+ getNetworkId(function onGetId(error, result) {
+ do_check_eq(error, null);
+ var netId = result;
+ NetworkStatsService.networkStatsAvailable(function (success, msg) {
+ do_check_eq(success, true);
+ run_next_test();
+ }, netId, true, 1234, 4321, Date.now());
+ });
+});
+
+add_test(function test_networkStatsAvailable_failure() {
+ getNetworkId(function onGetId(error, result) {
+ do_check_eq(error, null);
+ var netId = result;
+ NetworkStatsService.networkStatsAvailable(function (success, msg) {
+ do_check_eq(success, false);
+ run_next_test();
+ }, netId, false, 1234, 4321, Date.now());
+ });
+});
+
+add_test(function test_update_invalidNetwork() {
+ NetworkStatsService.update(-1, function (success, msg) {
+ do_check_eq(success, false);
+ do_check_eq(msg, "Invalid network -1");
+ run_next_test();
+ });
+});
+
+add_test(function test_update() {
+ getNetworkId(function onGetId(error, result) {
+ do_check_eq(error, null);
+ var netId = result;
+ NetworkStatsService.update(netId, function (success, msg) {
+ do_check_eq(success, true);
+ run_next_test();
+ });
+ });
+});
+
+add_test(function test_updateQueueIndex() {
+ NetworkStatsService.updateQueue = [{netId: 0, callbacks: null, queueType: QUEUE_TYPE_UPDATE_STATS},
+ {netId: 1, callbacks: null, queueType: QUEUE_TYPE_UPDATE_STATS},
+ {netId: 2, callbacks: null, queueType: QUEUE_TYPE_UPDATE_STATS},
+ {netId: 3, callbacks: null, queueType: QUEUE_TYPE_UPDATE_STATS},
+ {netId: 4, callbacks: null, queueType: QUEUE_TYPE_UPDATE_STATS}];
+ var index = NetworkStatsService.updateQueueIndex(3);
+ do_check_eq(index, 3);
+ index = NetworkStatsService.updateQueueIndex(10);
+ do_check_eq(index, -1);
+
+ NetworkStatsService.updateQueue = [];
+ run_next_test();
+});
+
+add_test(function test_updateAllStats() {
+ NetworkStatsService._networks[wifiId].status = NETWORK_STATUS_READY;
+ NetworkStatsService.updateAllStats(function(success, msg) {
+ do_check_eq(success, true);
+ NetworkStatsService._networks[wifiId].status = NETWORK_STATUS_STANDBY;
+ NetworkStatsService.updateAllStats(function(success, msg) {
+ do_check_eq(success, true);
+ NetworkStatsService._networks[wifiId].status = NETWORK_STATUS_AWAY;
+ NetworkStatsService.updateAllStats(function(success, msg) {
+ do_check_eq(success, true);
+ run_next_test();
+ });
+ });
+ });
+});
+
+add_test(function test_updateStats_ok() {
+ getNetworkId(function onGetId(error, result) {
+ do_check_eq(error, null);
+ var netId = result;
+ NetworkStatsService.updateStats(netId, function(success, msg){
+ do_check_eq(success, true);
+ run_next_test();
+ });
+ });
+});
+
+add_test(function test_updateStats_failure() {
+ NetworkStatsService.updateStats(-1, function(success, msg){
+ do_check_eq(success, false);
+ run_next_test();
+ });
+});
+
+// Define Mockup function to simulate a request to netd
+function MockNetdRequest(aCallback) {
+ var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+ var event = {
+ notify: function (timer) {
+ aCallback();
+ }
+ };
+
+ timer.initWithCallback(event, 100, Ci.nsITimer.TYPE_ONE_SHOT);
+}
+
+add_test(function test_queue() {
+
+ // Overwrite update function of NetworkStatsService to avoid netd errors due to use
+ // fake interfaces. First, original function is stored to restore it at the end of the
+ // test.
+ var updateFunctionBackup = NetworkStatsService.update;
+
+ NetworkStatsService.update = function update(aNetId, aCallback) {
+ MockNetdRequest(function () {
+ if (aCallback) {
+ aCallback(true, "ok");
+ }
+ });
+ };
+
+ // Fill networks with fake network interfaces to enable netd async requests.
+ var network = {id: "1234", type: Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE};
+ var netId1 = NetworkStatsService.getNetworkId(network.id, network.type);
+ NetworkStatsService._networks[netId1] = { network: network,
+ interfaceName: "net1" };
+
+ network = {id: "5678", type: Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE};
+ var netId2 = NetworkStatsService.getNetworkId(network.id, network.type);
+ NetworkStatsService._networks[netId2] = { network: network,
+ interfaceName: "net2" };
+
+ NetworkStatsService.updateStats(netId1);
+ NetworkStatsService.updateStats(netId2);
+ do_check_eq(NetworkStatsService.updateQueue.length, 2);
+ do_check_eq(NetworkStatsService.updateQueue[0].callbacks.length, 1);
+
+ var i = 0;
+ var updateCount = 0;
+ var callback = function(success, msg) {
+ i++;
+ if (i >= updateCount) {
+ NetworkStatsService.update = updateFunctionBackup;
+ run_next_test();
+ }
+ };
+
+ NetworkStatsService.updateStats(netId1, callback);
+ updateCount++;
+ NetworkStatsService.updateStats(netId2, callback);
+ updateCount++;
+
+ do_check_eq(NetworkStatsService.updateQueue.length, 2);
+ do_check_eq(NetworkStatsService.updateQueue[0].callbacks.length, 2);
+ do_check_eq(NetworkStatsService.updateQueue[0].callbacks[0], null);
+ do_check_neq(NetworkStatsService.updateQueue[0].callbacks[1], null);
+});
+
+add_test(function test_getAlarmQuota() {
+ let alarm = { networkId: wifiId, absoluteThreshold: 10000 };
+
+ NetworkStatsService._getAlarmQuota(alarm, function onSet(error, quota){
+ do_check_eq(error, null);
+ do_check_neq(quota, undefined);
+ do_check_eq(alarm.absoluteThreshold, alarm.relativeThreshold);
+ run_next_test();
+ });
+});
+
+var testPageURL = "http://test.com";
+var testManifestURL = "http://test.com/manifest.webapp";
+
+add_test(function test_setAlarm() {
+ let alarm = { id: null,
+ networkId: wifiId,
+ threshold: 10000,
+ absoluteThreshold: null,
+ alarmStart: null,
+ alarmEnd: null,
+ data: null,
+ pageURL: testPageURL,
+ manifestURL: testManifestURL };
+
+ NetworkStatsService._setAlarm(alarm, function onSet(error, result) {
+ do_check_eq(result, 1);
+ run_next_test();
+ });
+});
+
+add_test(function test_setAlarm_invalid_threshold() {
+ let alarm = { id: null,
+ networkId: wifiId,
+ threshold: -10000,
+ absoluteThreshold: null,
+ alarmStart: null,
+ alarmEnd: null,
+ data: null,
+ pageURL: testPageURL,
+ manifestURL: testManifestURL };
+
+ NetworkStatsService._networks[wifiId].status = NETWORK_STATUS_READY;
+
+ NetworkStatsService._setAlarm(alarm, function onSet(error, result) {
+ do_check_eq(error, "InvalidStateError");
+ run_next_test();
+ });
+});
+
+add_test(function test_fireAlarm() {
+ // Add a fake alarm into database.
+ let alarm = { id: null,
+ networkId: wifiId,
+ threshold: 10000,
+ absoluteThreshold: null,
+ alarmStart: null,
+ alarmEnd: null,
+ data: null,
+ pageURL: testPageURL,
+ manifestURL: testManifestURL };
+
+ // Set wifi status to standby to avoid connecting to netd when adding an alarm.
+ NetworkStatsService._networks[wifiId].status = NETWORK_STATUS_STANDBY;
+
+ NetworkStatsService._db.addAlarm(alarm, function addSuccessCb(error, newId) {
+ NetworkStatsService._db.getAlarms(Ci.nsINetworkInfo.NETWORK_TYPE_WIFI,
+ testManifestURL, function onGet(error, result) {
+ do_check_eq(error, null);
+ do_check_eq(result.length, 1);
+
+ // Result of getAlarms is based on expected child's data format, so
+ // some changes are needed to be able to use it.
+ result[0].networkId = wifiId;
+ result[0].pageURL = testPageURL;
+ result[0].manifestURL = testManifestURL;
+
+ NetworkStatsService._fireAlarm(result[0], false);
+ NetworkStatsService._db.getAlarms(Ci.nsINetworkInfo.NETWORK_TYPE_WIFI,
+ testManifestURL, function onGet(error, result) {
+ do_check_eq(error, undefined);
+ do_check_eq(result.length, 0);
+ run_next_test();
+ });
+ });
+ });
+});
+
+function run_test() {
+ do_get_profile();
+
+ Cu.import("resource://gre/modules/NetworkStatsService.jsm");
+ run_next_test();
+}
diff --git a/dom/network/tests/unit_stats/test_networkstats_service_proxy.js b/dom/network/tests/unit_stats/test_networkstats_service_proxy.js
new file mode 100644
index 000000000..131b886d0
--- /dev/null
+++ b/dom/network/tests/unit_stats/test_networkstats_service_proxy.js
@@ -0,0 +1,233 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+XPCOMUtils.defineLazyServiceGetter(this, "nssProxy",
+ "@mozilla.org/networkstatsServiceProxy;1",
+ "nsINetworkStatsServiceProxy");
+
+function mokConvertNetworkInfo() {
+ NetworkStatsService.convertNetworkInfo = function(aNetworkInfo) {
+ if (aNetworkInfo.type != Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE &&
+ aNetworkInfo.type != Ci.nsINetworkInfo.NETWORK_TYPE_WIFI) {
+ return null;
+ }
+
+ let id = '0';
+ if (aNetworkInfo.type == Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE) {
+ id = '1234'
+ }
+
+ let netId = this.getNetworkId(id, aNetworkInfo.type);
+
+ if (!this._networks[netId]) {
+ this._networks[netId] = Object.create(null);
+ this._networks[netId].network = { id: id,
+ type: aNetworkInfo.type };
+ }
+
+ return netId;
+ };
+}
+
+add_test(function test_saveAppStats() {
+ var cachedStats = NetworkStatsService.cachedStats;
+ var timestamp = NetworkStatsService.cachedStatsDate.getTime();
+
+ // Create to fake nsINetworkInfos. As nsINetworkInfo can not be instantiated,
+ // these two vars will emulate it by filling the properties that will be used.
+ var wifi = {type: Ci.nsINetworkInfo.NETWORK_TYPE_WIFI, id: "0"};
+ var mobile = {type: Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE, id: "1234"};
+
+ // Insert fake mobile network info in NetworkStatsService
+ var mobileNetId = NetworkStatsService.getNetworkId(mobile.id, mobile.type);
+
+ do_check_eq(Object.keys(cachedStats).length, 0);
+
+ nssProxy.saveAppStats(1, false, wifi, timestamp, 10, 20, false,
+ function (success, message) {
+ do_check_eq(success, true);
+ nssProxy.saveAppStats(1, false, mobile, timestamp, 10, 20, false,
+ function (success, message) {
+ var key1 = 1 + "" + false + "" + NetworkStatsService.getNetworkId(wifi.id, wifi.type);
+ var key2 = 1 + "" + false + "" + mobileNetId + "";
+
+ do_check_eq(Object.keys(cachedStats).length, 2);
+ do_check_eq(cachedStats[key1].appId, 1);
+ do_check_eq(cachedStats[key1].isInBrowser, false);
+ do_check_eq(cachedStats[key1].serviceType.length, 0);
+ do_check_eq(cachedStats[key1].networkId, wifi.id);
+ do_check_eq(cachedStats[key1].networkType, wifi.type);
+ do_check_eq(cachedStats[key1].date.getTime(), timestamp);
+ do_check_eq(cachedStats[key1].rxBytes, 10);
+ do_check_eq(cachedStats[key1].txBytes, 20);
+ do_check_eq(cachedStats[key2].appId, 1);
+ do_check_eq(cachedStats[key1].serviceType.length, 0);
+ do_check_eq(cachedStats[key2].networkId, mobile.id);
+ do_check_eq(cachedStats[key2].networkType, mobile.type);
+ do_check_eq(cachedStats[key2].date.getTime(), timestamp);
+ do_check_eq(cachedStats[key2].rxBytes, 10);
+ do_check_eq(cachedStats[key2].txBytes, 20);
+
+ run_next_test();
+ });
+ });
+});
+
+add_test(function test_saveServiceStats() {
+ var timestamp = NetworkStatsService.cachedStatsDate.getTime();
+
+ // Create to fake nsINetworkInfos. As nsINetworkInfo can not be instantiated,
+ // these two vars will emulate it by filling the properties that will be used.
+ var wifi = {type: Ci.nsINetworkInfo.NETWORK_TYPE_WIFI, id: "0"};
+ var mobile = {type: Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE, id: "1234"};
+
+ // Insert fake mobile network info in NetworkStatsService
+ var mobileNetId = NetworkStatsService.getNetworkId(mobile.id, mobile.type);
+
+ NetworkStatsService.updateCachedStats(function (success, msg) {
+ do_check_eq(success, true);
+
+ var cachedStats = NetworkStatsService.cachedStats;
+ do_check_eq(Object.keys(cachedStats).length, 0);
+
+ var serviceType = 'FakeType';
+ nssProxy.saveServiceStats(serviceType, wifi, timestamp, 10, 20, false,
+ function (success, message) {
+ do_check_eq(success, true);
+ nssProxy.saveServiceStats(serviceType, mobile, timestamp, 10, 20, false,
+ function (success, message) {
+ do_check_eq(success, true);
+ var key1 = 0 + "" + false + "" + serviceType +
+ NetworkStatsService.getNetworkId(wifi.id, wifi.type);
+ var key2 = 0 + "" + false + "" + serviceType + mobileNetId + "";
+
+ do_check_eq(Object.keys(cachedStats).length, 2);
+ do_check_eq(cachedStats[key1].appId, 0);
+ do_check_eq(cachedStats[key1].isInBrowser, false);
+ do_check_eq(cachedStats[key1].serviceType, serviceType);
+ do_check_eq(cachedStats[key1].networkId, wifi.id);
+ do_check_eq(cachedStats[key1].networkType, wifi.type);
+ do_check_eq(cachedStats[key1].date.getTime(), timestamp);
+ do_check_eq(cachedStats[key1].rxBytes, 10);
+ do_check_eq(cachedStats[key1].txBytes, 20);
+ do_check_eq(cachedStats[key2].appId, 0);
+ do_check_eq(cachedStats[key1].serviceType, serviceType);
+ do_check_eq(cachedStats[key2].networkId, mobile.id);
+ do_check_eq(cachedStats[key2].networkType, mobile.type);
+ do_check_eq(cachedStats[key2].date.getTime(), timestamp);
+ do_check_eq(cachedStats[key2].rxBytes, 10);
+ do_check_eq(cachedStats[key2].txBytes, 20);
+
+ run_next_test();
+ });
+ });
+ });
+});
+
+add_test(function test_saveStatsWithDifferentDates() {
+ var today = NetworkStatsService.cachedStatsDate;
+ var tomorrow = new Date(today.getTime() + (24 * 60 * 60 * 1000));
+
+ var mobile = {type: Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE, id: "1234"};
+
+ NetworkStatsService.updateCachedStats(function (success, message) {
+ do_check_eq(success, true);
+
+ do_check_eq(Object.keys(NetworkStatsService.cachedStats).length, 0);
+ nssProxy.saveAppStats(1, false, mobile, today.getTime(), 10, 20, false,
+ function (success, message) {
+ do_check_eq(success, true);
+ nssProxy.saveAppStats(2, false, mobile, tomorrow.getTime(), 30, 40, false,
+ function (success, message) {
+ do_check_eq(success, true);
+
+ var cachedStats = NetworkStatsService.cachedStats;
+ var key = 2 + "" + false + "" +
+ NetworkStatsService.getNetworkId(mobile.id, mobile.type);
+ do_check_eq(Object.keys(cachedStats).length, 1);
+ do_check_eq(cachedStats[key].appId, 2);
+ do_check_eq(cachedStats[key].isInBrowser, false);
+ do_check_eq(cachedStats[key].networkId, mobile.id);
+ do_check_eq(cachedStats[key].networkType, mobile.type);
+ do_check_eq(cachedStats[key].date.getTime(), tomorrow.getTime());
+ do_check_eq(cachedStats[key].rxBytes, 30);
+ do_check_eq(cachedStats[key].txBytes, 40);
+
+ run_next_test();
+ });
+ });
+ });
+});
+
+add_test(function test_saveStatsWithMaxCachedTraffic() {
+ var timestamp = NetworkStatsService.cachedStatsDate.getTime();
+ var maxtraffic = NetworkStatsService.maxCachedTraffic;
+ var wifi = {type: Ci.nsINetworkInfo.NETWORK_TYPE_WIFI, id: "0"};
+
+ NetworkStatsService.updateCachedStats(function (success, message) {
+ do_check_eq(success, true);
+
+ var cachedStats = NetworkStatsService.cachedStats;
+ do_check_eq(Object.keys(cachedStats).length, 0);
+ nssProxy.saveAppStats(1, false, wifi, timestamp, 10, 20, false,
+ function (success, message) {
+ do_check_eq(success, true);
+ do_check_eq(Object.keys(cachedStats).length, 1);
+ nssProxy.saveAppStats(1, false, wifi, timestamp, maxtraffic, 20, false,
+ function (success, message) {
+ do_check_eq(success, true);
+ do_check_eq(Object.keys(cachedStats).length, 0);
+
+ run_next_test();
+ });
+ });
+ });
+});
+
+add_test(function test_saveAppStats() {
+ var cachedStats = NetworkStatsService.cachedStats;
+ var timestamp = NetworkStatsService.cachedStatsDate.getTime();
+
+ // Create to fake nsINetworkInfo. As nsINetworkInfo can not
+ // be instantiated, these two vars will emulate it by filling the properties
+ // that will be used.
+ var wifi = {type: Ci.nsINetworkInfo.NETWORK_TYPE_WIFI, id: "0"};
+ var mobile = {type: Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE, id: "1234"};
+
+ // Insert fake mobile network interface in NetworkStatsService
+ var mobileNetId = NetworkStatsService.getNetworkId(mobile.id, mobile.type);
+
+ do_check_eq(Object.keys(cachedStats).length, 0);
+
+ nssProxy.saveAppStats(1, false, wifi, timestamp, 10, 20, false, { notify:
+ function (success, message) {
+ do_check_eq(success, true);
+ var iterations = 10;
+ var counter = 0;
+ var callback = function (success, message) {
+ if (counter == iterations - 1)
+ run_next_test();
+ counter++;
+ };
+
+ for (var i = 0; i < iterations; i++) {
+ nssProxy.saveAppStats(1, false, mobile, timestamp, 10, 20, false, callback);
+ }
+ }});
+});
+
+function run_test() {
+ do_get_profile();
+
+ Cu.import("resource://gre/modules/NetworkStatsService.jsm");
+
+ // Function convertNetworkInfo of NetworkStatsService causes errors when dealing
+ // with RIL to get the iccid, so overwrite it.
+ mokConvertNetworkInfo();
+
+ run_next_test();
+}
diff --git a/dom/network/tests/unit_stats/xpcshell.ini b/dom/network/tests/unit_stats/xpcshell.ini
new file mode 100644
index 000000000..9b69ab755
--- /dev/null
+++ b/dom/network/tests/unit_stats/xpcshell.ini
@@ -0,0 +1,7 @@
+[DEFAULT]
+head =
+tail =
+
+[test_networkstats_service.js]
+[test_networkstats_service_proxy.js]
+[test_networkstats_db.js]