Bug 951976 - Part 2: Test cases. r=gene

This commit is contained in:
Borting Chen 2014-05-12 18:55:49 +08:00
parent 256f322650
commit 0192073286
14 changed files with 2581 additions and 1 deletions

View File

@ -22,5 +22,6 @@ EXTRA_JS_MODULES += [
'ResourceStatsService.jsm',
]
FINAL_LIBRARY = 'gklayout'
TEST_DIRS += ['tests']
FINAL_LIBRARY = 'gklayout'

View File

@ -0,0 +1,16 @@
[test_basic.html]
skip-if = toolkit != "gonk"
[test_network_stats.html]
skip-if = toolkit != "gonk"
[test_power_stats.html]
skip-if = toolkit != "gonk"
[test_network_alarm.html]
skip-if = toolkit != "gonk"
[test_power_alarm.html]
skip-if = toolkit != "gonk"
[test_disabled_pref.html]
skip-if = toolkit != "gonk"
[test_no_perm.html]
skip-if = toolkit != "gonk"
[test_not_supported_type.html]
skip-if = toolkit != "gonk"

View File

@ -0,0 +1,41 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test accessibility of interfaces</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
SimpleTest.waitForExplicitFinish();
// Test accessibility of interfaces.
SpecialPowers.addPermission("resourcestats-manage", true, document);
SpecialPowers.pushPrefEnv({ 'set': [
["dom.resource_stats.enabled", true],
["dom.ignore_webidl_scope_checks", true]
]}, function() {
ok(SpecialPowers.hasPermission("resourcestats-manage", document),
"Has permission 'resourcestats-manage'.");
ok(SpecialPowers.getBoolPref("dom.resource_stats.enabled"),
"Preference 'dom.resource_stats.enabled' is true.");
// Check all interfaces are accessible.
ok('ResourceStatsManager' in window, "ResourceStatsManager exist.");
ok('ResourceStatsAlarm' in window, "ResourceStatsAlarm exist.");
ok('ResourceStats' in window, "ResourceStats exist.");
ok('NetworkStatsData' in window, "NetworkStatsData exist.");
ok('PowerStatsData' in window, "PowerStatsData exist.");
SimpleTest.finish();
});
</script>
</pre>
</body>
</html>

View File

@ -0,0 +1,41 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test to ensure interface is not accessible when preference is disabled</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
SimpleTest.waitForExplicitFinish();
// Test to ensure interface is not accessible when preference is disabled.
SpecialPowers.addPermission("resourcestats-manage", true, document);
SpecialPowers.pushPrefEnv({ 'set': [
["dom.resource_stats.enabled", false],
["dom.ignore_webidl_scope_checks", true]
]}, function() {
ok(SpecialPowers.hasPermission("resourcestats-manage", document),
"Has permission 'resourcestats-manage'.");
ok(!(SpecialPowers.getBoolPref("dom.resource_stats.enabled")),
"Preference 'dom.resource_stats.enabled' is false.");
// Check accessibility.
is('ResourceStatsManager' in window, false, "ResourceStatsManager should not exist.");
is('ResourceStatsAlarm' in window, false, "ResourceStatsAlarm should not exist.");
is('ResourceStats' in window, false, "ResourceStats should not exist.");
is('NetworkStatsData' in window, false, "NetworkStatsData should not exist.");
is('PowerStatsData' in window, false, "PowerStatsData should not exist.");
SimpleTest.finish();
});
</script>
</pre>
</body>
</html>

View File

@ -0,0 +1,356 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for ResourceStats methods realted to network resource control</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
const invalidManifestURL = "app://invalid.gaiamobile.org/manifest.webapp";
const wifiComponent = "wifi:0";
const mobileComponent = "mobile:1";
var networkStatsMgr = null; // ResourceStatsManager for network statistics.
function errorCb(reason) {
ok(false, reason);
}
// Check the content returned by getAlarms.
function checkAlarmsArray(alarms) {
// Check if data is an array.
if (!Array.isArray(alarms)) {
throw "getAlarms does not return an array.";
} else {
ok(true, "getAlarms returns an array.")
}
// Iterate the array and check the type of each element.
var obj = null;
var message = null; // Message for exception
for (var i = 0; i < alarms.length; i++) {
obj = alarms[i];
// Check if obj is an instance os ResourceStatsAlarm.
if (!(obj instanceof ResourceStatsAlarm)) {
message = "The array contains a non-ResourceStatsAlarm object.";
break;
}
// Check if obj.type is network.
if (obj.type != "network") {
message = "The type of a ResourceStatsAlarm object is not network.";
break;
}
}
if (message) {
throw message;
}
ok(true, "The return is an array of ResourceStatsAlarm objects.");
}
// Test Cases for testing WebIDL methods related to resource control.
var testCases = [
function() {
// Test removeAllAlarms.
var promise = networkStatsMgr.removeAllAlarms();
promise.then(function() {
ok(true, "removeAllAlarms deleted all network alarms.");
testMethods();
}, function() {
ok(false, "removeAllAlarms failed to delete network alarms.");
});
},
function() {
// Test addAlarm.
var threshold = Math.floor(Math.random() * 1000);
var promise = networkStatsMgr.addAlarm(threshold,
{ 'component': wifiComponent },
{ 'startTime': Date.now() });
promise.then(function(value) {
// Check the value (alarmId).
if (value < 0) {
ok(false, "addAlarm failed to create an alarm.");
} else {
ok(true, "addAlarm created an alarm.");
testMethods();
}
}, function() {
ok(false, "addAlarm failed to create an alarm.");
});
},
function() {
// Test addAlarm with negative threshold.
var threshold = -1;
var promise = networkStatsMgr.addAlarm(threshold,
{ 'component': wifiComponent },
{ 'startTime': Date.now() });
promise.then(function() {
// Check the value.
ok(false,
"addAlarm did not throw an exception when negative threshold is set.");
}, function() {
ok(true, "addAlarm threw an exception when negative threshold is set.");
testMethods();
});
},
function() {
// Test addAlarm with no threshold.
var promise = networkStatsMgr.addAlarm();
promise.then(function() {
// Check the value.
ok(false, "addAlarm did not throw an exception when no threshold.");
}, function() {
ok(true, "addAlarm threw an exception when no threshold.");
testMethods();
});
},
function() {
// Test addAlarm with negative startTime.
var threshold = Math.floor(Math.random() * 1000);
var promise = networkStatsMgr.addAlarm(threshold,
{ 'component': wifiComponent },
{ 'startTime': -1 });
promise.then(function() {
// Check the value.
ok(false,
"addAlarm did not throw an exception when negative startTime is set.");
}, function() {
ok(true, "addAlarm threw an exception when negative startTime is set.");
testMethods();
});
},
function() {
// Test addAlarm when manifestURL is invalid.
var threshold = Math.floor(Math.random() * 1000);
var promise = networkStatsMgr.addAlarm(threshold,
{ 'component': wifiComponent,
'manifestURL': invalidManifestURL },
{ 'startTime': Date.now() });
promise.then(function() {
// Check the value.
ok(false, "addAlarm did not throw an exception when manifestURL is invalid.");
}, function() {
ok(true, "addAlarm threw an exception when manifestURL is invalid.");
testMethods();
});
},
function() {
// Test getAlarms.
var alarmId;
var alarms;
var threshold = Math.floor(Math.random() * 1000);
// Execution steps:
// 1. Add a new alarm.
var promise = networkStatsMgr.addAlarm(threshold,
{ 'component': wifiComponent },
{ 'startTime': Date.now() });
// 2. Test getAlarms if new alarm is added.
var runGetAlarms = function(value) {
alarmId = value;
return networkStatsMgr.getAlarms({ 'component': wifiComponent });
};
// 3. Check the content returned by getAlarms.
var checkGetAlarmsReturn = function(value) {
alarms = value;
checkAlarmsArray(value);
};
// 4. Check the alarm added in step 1 is inside the return of getAlarms.
var checkAlarm = function (value) {
// Find the alarm.
var index = alarms.map(function(e) { return e.alarmId; })
.indexOf(alarmId);
if (index < 0) {
throw "getAlarms does not get the alarm added in previous step.";
}
var alarm = alarms[index];
// Evaluate the alarm.
ok(alarm.threshold == threshold, "threshold is equal.");
ok(alarm.component == wifiComponent, "component is equal.");
ok(alarm.serviceType == null, "serviceType should be null.");
ok(alarm.manifestURL == null, "manifestURL should be null.");
};
// Create promise chaining.
promise.then(runGetAlarms)
.then(checkGetAlarmsReturn)
.then(checkAlarm)
.then(testMethods, errorCb); // Execute next test case.
},
function() {
// Test getAlarms with invalid manifestURL.
var threshold = Math.floor(Math.random() * 1000);
var promise = networkStatsMgr.addAlarm(threshold,
{ 'component': wifiComponent,
'manifestURL': invalidManifestURL },
{ 'startTime': Date.now() });
promise.then(function() {
// Check the value.
ok(false, "getAlarms did not throw an exception when manifestURL is invalid.");
}, function() {
ok(true, "getAlarms threw an exception when manifestURL is invalid.");
testMethods();
});
},
function() {
// Test getAlarms with incorrect parameter.
var threshold = Math.floor(Math.random() * 1000);
// Execution steps:
// 1. Add a new alarm.
var promise = networkStatsMgr.addAlarm(threshold,
{ 'component': wifiComponent },
{ 'startTime': Date.now() });
// 2. Call getAlarms with incorrect parameter.
var runGetAlarms = function() {
return networkStatsMgr.getAlarms({ 'component': mobileComponent });
};
// 3. check the content returned by getAlarms.
var checkGetAlarmsReturn = function(value) {
// Check array length
if (value.length) {
throw "getAlarms gets an alarm when using incorrect parameter.";
} else {
ok(true,
"getAlarms returns an empty array when using incorrect parameter.");
}
};
// Create pomise chaining.
promise.then(runGetAlarms)
.then(checkGetAlarmsReturn)
.then(testMethods, errorCb); // Execute next test case.
},
function() {
// Test removeAlarm
var alarmId;
var threshold = Math.floor(Math.random() * 1000);
// Execution steps:
// 1. Add a new alarm.
var promise = networkStatsMgr.addAlarm(threshold,
{ 'component': wifiComponent },
{ 'startTime': Date.now() });
// 2. Try to remove the new alarm.
var runRemoveAlarm = function(value) {
alarmId = value;
return networkStatsMgr.removeAlarm(alarmId);
}
// Create promise chaining.
promise.then(runRemoveAlarm)
.then(function() {
ok(true, "removeAlarm deleted the alarm.");
testMethods();
}, errorCb);
},
function() {
// Test removeAlarm with negative alarmId
var alarmId = -1;
var promise = networkStatsMgr.removeAlarm(alarmId);
promise.then(function() {
ok(false,
"removeAlarm did not throw an exception when negative alarmId is set.");
}, function() {
ok(true, "removeAlarm threw an exception when negative alarmId is set.");
testMethods();
});
},
function() {
// Test removeAlarm with invalid alarmId
var alarmId;
var threshold = Math.floor(Math.random() * 1000);
// Execution steps:
// 1. Add a new alarm.
var promise = networkStatsMgr.addAlarm(threshold,
{ 'component': wifiComponent },
{ 'startTime': Date.now() });
// 2. Try to remove an invalid alarm.
var runRemoveAlarm = function(value) {
alarmId = value;
// Because alarmId is auto-increment, any alarmId larger than the
// latest alarmId should be invalid.
return networkStatsMgr.removeAlarm(alarmId + 10);
}
// Create promise chaining.
promise.then(runRemoveAlarm)
.then(function() {
// Input with incorrect alarmId should not be resolved.
throw "removeAlarm should fail with invalid alarmId.";
}, function(reason) {
if (reason == "alarm not existed") {
ok(true, "removeAlarm with invalid alarmId should fail.")
} else {
throw reason;
}
})
.then(testMethods, errorCb);
}
];
// Test WebIDL methods related stats operation.
function testMethods() {
if (!testCases.length) {
ok(true, "Done.");
SpecialPowers.removePermission("resourcestats-manage", document);
SimpleTest.finish();
return;
}
var testCase = testCases.shift();
testCase();
}
function startTest() {
// Create an instance of ResourceStatsManager for network.
networkStatsMgr = new ResourceStatsManager("network");
ok(networkStatsMgr, "Create networkStatsMgr.");
// Test WebIDL methods related to resource control.
testMethods();
}
SimpleTest.waitForExplicitFinish();
// Enable permission and preference.
SpecialPowers.addPermission("resourcestats-manage", true, document);
SpecialPowers.pushPrefEnv({ 'set': [
["dom.resource_stats.enabled", true],
["dom.ignore_webidl_scope_checks", true]
]}, startTest);
</script>
</pre>
</body>
</html>

View File

@ -0,0 +1,345 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for ResourceStats methods realted to network statistics</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
const invalidManifestURL = "app://invalid.gaiamobile.org/manifest.webapp";
var networkStatsMgr = null; // ResourceStatsManager for network statistics.
var sampleRate = 0;
// Test WebIDL attributes.
function testAttributes() {
// Test sampleRate.
ok('sampleRate' in networkStatsMgr,
"sampleRate should be a ResourceStatsManager attribute.");
sampleRate = networkStatsMgr.sampleRate;
ok(sampleRate > 0, "sampleRate is greater than 0.");
// Test maxStorageAge.
ok('maxStorageAge' in networkStatsMgr,
"maxStorageAge should be a ResourceStatsManager attribute.");
ok(networkStatsMgr.maxStorageAge > 0,
"maxStorageAge is greater than 0.");
// Test whether "network" in resourceTypes array.
ok('resourceTypes' in networkStatsMgr,
"resourceTypes should be a ResourceStatsManager attribute.");
ok(Array.isArray(networkStatsMgr.resourceTypes),
"networkStatsMgr.resourceTypes is an array.");
ok(networkStatsMgr.resourceTypes.indexOf("network") > -1,
"'network' is an element of networkStatsMgr.resourceTypes.");
}
// Check the content returned by ResourceStats.getData().
function checkData(data, start, end) {
// Check if data is an array.
if (!Array.isArray(data)) {
ok(false, "getData does not return an array.")
return;
} else {
ok(true, "getData returns an array.")
}
// Iterate the array and check the timestamp and type of each element.
var success = true;
var obj = null;
var timestamp = start;
var i = 0;
var length = data.length;
do {
obj = data[i++];
// Check object type.
if (!(obj instanceof NetworkStatsData)) {
success = false;
ok(false, "The array contains a non-NetworkStatsData object.");
break;
}
// Check if the timestamp is continuous.
if (obj.timestamp !== timestamp) {
success = false;
ok(false, "The timestamp of NetworkStatsData object is correct.");
break;
}
timestamp += sampleRate;
} while (i < length);
if (!success) {
return;
}
// Check the timestamp of the last element is equal to end.
if (obj.timestamp != end) {
ok(false,
"The timestamp of the last element of the array is equal to end.");
return;
}
// Execute next test case.
ok(true, "The return of getData is an array of NetworkStatsData objects.");
testMethods();
}
// Test Cases for testing WebIDL methods.
var testCases = [
function() {
// Test clearAllStats.
var promise = networkStatsMgr.clearAllStats();
promise.then(function() {
ok(true, "clearAllStats clears the network store.");
testMethods();
}, function() {
ok(false, "clearAllStats fails to clear the network store.");
});
},
function() {
// Test clearStats.
var promise = networkStatsMgr.clearStats();
promise.then(function() {
ok(true, "clearStats clears the network store.");
testMethods();
}, function() {
ok(false, "clearStats fails to clear the network store.");
});
},
function() {
// Check if clearStats throw exception when start is great than end.
var end = Date.now();
var start = end + 1000;
var promise = networkStatsMgr.clearStats(null, start, end);
promise.then(function() {
ok(false,
"clearStats does not throw exception when start is great than end.");
}, function() {
ok(true, "clearStats throw exception when start is great than end.");
testMethods();
});
},
function() {
// Check if clearStats throw exception when start is less than 0.
var end = Date.now();
var start = -1;
var promise = networkStatsMgr.clearStats(null, start, end);
promise.then(function() {
ok(false,
"clearStats dose not throw exception when start is less than 0.");
}, function() {
ok(true, "clearStats throw exception when start is less than 0.");
testMethods();
});
},
function() {
// Check if clearStats throw exception when manifestURL is invalid.
var options = {manifestURL: invalidManifestURL};
var promise = networkStatsMgr.clearStats(options);
promise.then(function() {
ok(false,
"clearStats does not throw exception when manifestURL is invalid.");
}, function() {
ok(true, "clearStats throw exception when manifestURL is invalid.");
testMethods();
});
},
function() {
// Test getAvailableComponents.
var promise = networkStatsMgr.getAvailableComponents();
promise.then(function(value) {
if (Array.isArray(value)) {
ok(true, "getAvailableComponents returns an array.");
testMethods();
} else {
ok(false, "getAvailableComponents does not return an array.");
}
}, function() {
ok(false, "Fail to execute getAvailableComponents.");
});
},
function() {
// Test getStats.
ok(true, "Get system stats when start and end are adapted to sampleRate.");
// Prepare start and end.
var offset = (new Date()).getTimezoneOffset() * 60 * 1000;
var end = Math.floor((Date.now() - offset) / sampleRate) * sampleRate + offset;
var start = end - sampleRate * 10;
// Launch request.
var promise = networkStatsMgr.getStats(null, start, end);
promise.then(function(value) {
// Check the object type.
if (value instanceof ResourceStats) {
ok(true, "Get a ResourceStats object.");
} else {
ok(false, "Fail to get a ResourceStats object.");
return;
}
// Check attributes of ResourceStats.
ok(value.type == "network", "type should be network.");
ok(value.component == null, "component should be null.");
ok(value.serviceType == null, "serviceType should be null.");
ok(value.manifestURL == null, "manifestURL should be null.");
// Check if the time range of ResourceStats is equal to the request.
ok(value.start == start, "start timestamp should be equal.");
ok(value.end == end, "end timestamp should be equal.");
// Check stats stored inside ResourceStats.
if ('getData' in value) {
checkData(value.getData(), start, end);
} else {
ok(false, "getData is not a method of ResourceStats.");
return;
}
}, function() {
ok(false, "Get network stats failed.");
});
},
function() {
// Test getStats when start and end are not adapted to sampleRate.
ok(true,
"Get system stats when start and end are not adapted to sampleRate.");
// Prepare start and end.
var end = Date.now();
var start = end - sampleRate * 10;
// Normalize start and end.
var offset = (new Date()).getTimezoneOffset() * 60 * 1000;
var normEnd = Math.floor((end - offset) / sampleRate)
* sampleRate + offset;
var normStart = Math.floor((start - offset) / sampleRate)
* sampleRate + offset;
// Launch request.
var promise = networkStatsMgr.getStats(null, start, end);
promise.then(function(value) {
// Check the object type.
if (value instanceof ResourceStats) {
ok(true, "Get a ResourceStats object.");
} else {
ok(false, "Fail to get a ResourceStats object.");
return;
}
// Check attributes of ResourceStats.
ok(value.type == "network", "type should be network.");
ok(value.component == null, "component should be null.");
ok(value.serviceType == null, "serviceType should be null.");
ok(value.manifestURL == null, "manifestURL should be null.");
// Check if time range of ResourceStats are normalized.
ok(value.start == normStart, "start timestamp should be normalized.");
ok(value.end == normEnd, "end timestamp should be normalized.");
// Check stats stored inside ResourceStats.
if ('getData' in value) {
checkData(value.getData(), normStart, normEnd);
} else {
ok(false, "getData is not a method of ResourceStats.");
return;
}
}, function() {
ok(false, "Get network stats failed.");
});
},
function () {
// Check if getStats throw exception when start is greater than end.
var end = Date.now();
var start = end + 1000;
var promise = networkStatsMgr.getStats(null, start, end);
promise.then(function() {
ok(false,
"getStats dose not throw exception when start is great than end.");
}, function() {
ok(true, "getStats throw exception when start is great than end.");
testMethods();
});
},
function() {
// Check if getStats throw exception when start is less than 0.
var end = Date.now();
var start = -1;
var promise = networkStatsMgr.getStats(null, start, end);
promise.then(function() {
ok(false,
"getStats dose not throw exception when start is less than 0.");
}, function() {
ok(true, "getStats throw exception when start is less than 0.");
testMethods();
});
},
function() {
// Check if getStats throw exception when manifestURL is invalid.
var options = {manifestURL: invalidManifestURL};
var promise = networkStatsMgr.getStats(options);
promise.then(function(value) {
ok(false,
"getStats does not throw exception when manifestURL is invalid.");
}, function() {
ok(true, "getStats throw exception when manifestURL is invalid.");
testMethods();
});
}
];
// Test WebIDL methods related stats operation.
function testMethods() {
if (!testCases.length) {
ok(true, "Done.");
SpecialPowers.removePermission("resourcestats-manage", document);
SimpleTest.finish();
return;
}
var testCase = testCases.shift();
testCase();
}
function startTest() {
// Create an instance of ResourceStatsManager for network stats.
networkStatsMgr = new window.ResourceStatsManager("network");
ok(networkStatsMgr, "Create networkStatsMgr.");
// Test WebIDL attributes.
testAttributes();
// Test WebIDL methods related to stats operation.
testMethods();
}
SimpleTest.waitForExplicitFinish();
// Enable permission and preference.
SpecialPowers.addPermission("resourcestats-manage", true, document);
SpecialPowers.pushPrefEnv({ 'set': [
["dom.resource_stats.enabled", true],
["dom.ignore_webidl_scope_checks", true]
]}, startTest);
</script>
</pre>
</body>
</html>

View File

@ -0,0 +1,38 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test to ensure ResourceStatsManager is not accessible without permission</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
SimpleTest.waitForExplicitFinish();
// Test to ensure ResourceStatsManager is not accessible without permission.
SpecialPowers.removePermission("resourcestats-manage", document);
SpecialPowers.pushPrefEnv({ 'set': [
["dom.resource_stats.enabled", true],
["dom.ignore_webidl_scope_checks", true]
]}, function() {
ok(!(SpecialPowers.hasPermission("resourcestats-manage", document)),
"Do not have permission 'resourcestats-manage'.");
ok(SpecialPowers.getBoolPref("dom.resource_stats.enabled"),
"Preference 'dom.resource_stats.enabled' is true.");
// Check ResourceStatsManager exist.
ok(!('ResourceStatsManager' in window),
"Cannot access window.ResourceStatsManager when have no permission");
SimpleTest.finish();
});
</script>
</pre>
</body>
</html>

View File

@ -0,0 +1,41 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test to ensure ResourceStatsManager does not create an instance for non-supported type</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
const type = "non-supported";
SimpleTest.waitForExplicitFinish();
// Test to ensure ResourceStatsManager does not create an instance for
// non-supported type.
SpecialPowers.addPermission("resourcestats-manage", true, document);
SpecialPowers.pushPrefEnv({ 'set': [
["dom.resource_stats.enabled", true],
["dom.ignore_webidl_scope_checks", true]
]}, function() {
try {
var mgr = ResourceStatsManager(type);
ok(false,
"Creating an instance for non-supported type should throw an exeception.");
} catch (ex) {
ok(ex,
"Got an exception when creating an instance for non-supported type.");
}
SimpleTest.finish();
});
</script>
</pre>
</body>
</html>

View File

@ -0,0 +1,355 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for ResourceStats methods realted to power resource control</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
const invalidManifestURL = "app://invalid.gaiamobile.org/manifest.webapp";
const cpuComponent = "cpu:0";
const gpsComponent = "gps:0";
var powerStatsMgr = null; // ResourceStatsManager for power statistics.
function errorCb(reason) {
ok(false, reason);
}
// Check the content returned by getAlarms.
function checkAlarmsArray(alarms) {
// Check if data is an array.
if (!Array.isArray(alarms)) {
throw "getAlarms does not return an array.";
} else {
ok(true, "getAlarms returns an array.")
}
// Iterate the array and check the type of each element.
var obj = null;
var message = null; // Message for exception
for (var i = 0; i < alarms.length; i++) {
obj = alarms[i];
// Check if obj is an instance os ResourceStatsAlarm.
if (!(obj instanceof ResourceStatsAlarm)) {
message = "The array contains a non-ResourceStatsAlarm object.";
break;
}
// Check if obj.type is power.
if (obj.type != "power") {
message = "The type of a ResourceStatsAlarm object is not power.";
break;
}
}
if (message) {
throw message;
}
ok(true, "The return is an array of ResourceStatsAlarm objects.");
}
// Test Cases for testing WebIDL methods related to resource control.
var testCases = [
function() {
// Test removeAllAlarms.
var promise = powerStatsMgr.removeAllAlarms();
promise.then(function() {
ok(true, "removeAllAlarms deleted all power alarms.");
testMethods();
}, function() {
ok(false, "removeAllAlarms failed to delete power alarms.");
});
},
function() {
// Test addAlarm.
var threshold = Math.floor(Math.random() * 1000);
var promise = powerStatsMgr.addAlarm(threshold,
{ 'component': cpuComponent },
{ 'startTime': Date.now() });
promise.then(function(value) {
// Check the value (alarmId).
if (value < 0) {
ok(false, "addAlarm failed to create an alarm.");
} else {
ok(true, "addAlarm created an alarm.");
testMethods();
}
}, function() {
ok(false, "addAlarm failed to create an alarm.");
});
},
function() {
// Test addAlarm with negative threshold.
var threshold = -1;
var promise = powerStatsMgr.addAlarm(threshold,
{ 'component': cpuComponent },
{ 'startTime': Date.now() });
promise.then(function() {
// Check the value.
ok(false,
"addAlarm did not throw an exception when negative threshold is set.");
}, function() {
ok(true, "addAlarm threw an exception when negative threshold is set.");
testMethods();
});
},
function() {
// Test addAlarm with no threshold.
var promise = powerStatsMgr.addAlarm();
promise.then(function() {
// Check the value.
ok(false, "addAlarm did not throw an exception when no threshold.");
}, function() {
ok(true, "addAlarm threw an exception when no threshold.");
testMethods();
});
},
function() {
// Test addAlarm with negative startTime.
var threshold = Math.floor(Math.random() * 1000);
var promise = powerStatsMgr.addAlarm(threshold,
{ 'component': cpuComponent },
{ 'startTime': -1 });
promise.then(function() {
// Check the value.
ok(false,
"addAlarm did not throw an exception when negative startTime is set.");
}, function() {
ok(true, "addAlarm threw an exception when negative startTime is set.");
testMethods();
});
},
function() {
// Test addAlarm when manifestURL is invalid.
var threshold = Math.floor(Math.random() * 1000);
var promise = powerStatsMgr.addAlarm(threshold,
{ 'component': cpuComponent,
'manifestURL': invalidManifestURL },
{ 'startTime': Date.now() });
promise.then(function() {
// Check the value.
ok(false, "addAlarm did not throw an exception when manifestURL is invalid.");
}, function() {
ok(true, "addAlarm threw an exception when manifestURL is invalid.");
testMethods();
});
},
function() {
// Test getAlarms.
var alarmId;
var alarms;
var threshold = Math.floor(Math.random() * 1000);
// Execution steps:
// 1. Add a new alarm.
var promise = powerStatsMgr.addAlarm(threshold,
{ 'component': cpuComponent },
{ 'startTime': Date.now() });
// 2. Test getAlarms if new alarm is added.
var runGetAlarms = function(value) {
alarmId = value;
return powerStatsMgr.getAlarms({ 'component': cpuComponent });
};
// 3. Check the content returned by getAlarms.
var checkGetAlarmsReturn = function(value) {
alarms = value;
checkAlarmsArray(value);
};
// 4. Check the alarm added in step 1 is inside the return of getAlarms.
var checkAlarm = function (value) {
// Find the alarm.
var index = alarms.map(function(e) { return e.alarmId; })
.indexOf(alarmId);
if (index < 0) {
throw "getAlarms does not get the alarm added in previous step.";
}
var alarm = alarms[index];
// Evaluate the alarm.
ok(alarm.threshold == threshold, "threshold is equal.");
ok(alarm.component == cpuComponent, "component is equal.");
ok(alarm.serviceType == null, "serviceType should be null.");
ok(alarm.manifestURL == null, "manifestURL should be null.");
};
// Create promise chaining.
promise.then(runGetAlarms)
.then(checkGetAlarmsReturn)
.then(checkAlarm)
.then(testMethods, errorCb); // Execute next test case.
},
function() {
// Test getAlarms with invalid manifestURL.
var threshold = Math.floor(Math.random() * 1000);
var promise = powerStatsMgr.addAlarm(threshold,
{ 'component': cpuComponent,
'manifestURL': invalidManifestURL },
{ 'startTime': Date.now() });
promise.then(function() {
// Check the value.
ok(false, "getAlarms did not throw an exception when manifestURL is invalid.");
}, function() {
ok(true, "getAlarms threw an exception when manifestURL is invalid.");
testMethods();
});
},
function() {
// Test getAlarms with incorrect parameter.
var threshold = Math.floor(Math.random() * 1000);
// Execution steps:
// 1. Add a new alarm.
var promise = powerStatsMgr.addAlarm(threshold,
{ 'component': cpuComponent },
{ 'startTime': Date.now() });
// 2. Call getAlarms with incorrect parameter.
var runGetAlarms = function() {
return powerStatsMgr.getAlarms({ 'component': gpsComponent });
};
// 3. check the content returned by getAlarms.
var checkGetAlarmsReturn = function(value) {
// Check array length
if (value.length) {
throw "getAlarms gets an alarm when using incorrect parameter.";
} else {
ok(true,
"getAlarms returns an empty array when using incorrect parameter.");
}
};
// Create pomise chaining.
promise.then(runGetAlarms)
.then(checkGetAlarmsReturn)
.then(testMethods, errorCb); // Execute next test case.
},
function() {
// Test removeAlarm
var alarmId;
var threshold = Math.floor(Math.random() * 1000);
// Execution steps:
// 1. Add a new alarm.
var promise = powerStatsMgr.addAlarm(threshold,
{ 'component': cpuComponent },
{ 'startTime': Date.now() });
// 2. Try to remove the new alarm.
var runRemoveAlarm = function(value) {
alarmId = value;
return powerStatsMgr.removeAlarm(alarmId);
}
// Create promise chaining.
promise.then(runRemoveAlarm)
.then(function() {
ok(true, "removeAlarm deleted the alarm.");
testMethods();
}, errorCb);
},
function() {
// Test removeAlarm with negative alarmId
var alarmId = -1;
var promise = powerStatsMgr.removeAlarm(alarmId);
promise.then(function() {
ok(false,
"removeAlarm did not throw an exception when negative alarmId is set.");
}, function() {
ok(true, "removeAlarm threw an exception when negative alarmId is set.");
testMethods();
});
},
function() {
// Test removeAlarm with invalid alarmId
var alarmId;
var threshold = Math.floor(Math.random() * 1000);
// Execution steps:
// 1. Add a new alarm.
var promise = powerStatsMgr.addAlarm(threshold,
{ 'component': cpuComponent },
{ 'startTime': Date.now() });
// 2. Try to remove an invalid alarm.
var runRemoveAlarm = function(value) {
alarmId = value;
// Because alarmId is auto-increment, any alarmId larger than the
// latest alarmId should be invalid.
return powerStatsMgr.removeAlarm(alarmId + 10);
}
// Create promise chaining.
promise.then(runRemoveAlarm)
.then(function() {
// Input with incorrect alarmId should not be resolved.
throw "removeAlarm should fail with invalid alarmId.";
}, function(reason) {
if (reason == "alarm not existed") {
ok(true, "removeAlarm with invalid alarmId should fail.")
} else {
throw reason;
}
})
.then(testMethods, errorCb);
}
];
// Test WebIDL methods related stats operation.
function testMethods() {
if (!testCases.length) {
ok(true, "Done.");
SpecialPowers.removePermission("resourcestats-manage", document);
SimpleTest.finish();
return;
}
var testCase = testCases.shift();
testCase();
}
function startTest() {
// Create an instance of ResourceStatsManager for power.
powerStatsMgr = new ResourceStatsManager("power");
ok(powerStatsMgr, "Create powerStatsMgr.");
// Test WebIDL methods related to resource control.
testMethods();
}
SimpleTest.waitForExplicitFinish();
// Enable permission and preference.
SpecialPowers.addPermission("resourcestats-manage", true, document);
SpecialPowers.pushPrefEnv({ 'set': [
["dom.resource_stats.enabled", true],
["dom.ignore_webidl_scope_checks", true]
]}, startTest);
</script>
</pre>
</body>
</html>

View File

@ -0,0 +1,345 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for ResourceStats methods realted to power statistics</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
const invalidManifestURL = "app://invalid.gaiamobile.org/manifest.webapp";
var powerStatsMgr = null; // ResourceStatsManager for power statistics.
var sampleRate = 0;
// Test WebIDL attributes.
function testAttributes() {
// Test sampleRate.
ok('sampleRate' in powerStatsMgr,
"sampleRate should be a ResourceStatsManager attribute.");
sampleRate = powerStatsMgr.sampleRate;
ok(sampleRate > 0, "sampleRate is greater than 0.");
// Test maxStorageAge.
ok('maxStorageAge' in powerStatsMgr,
"maxStorageAge should be a ResourceStatsManager attribute.");
ok(powerStatsMgr.maxStorageAge > 0,
"maxStorageAge is greater than 0.");
// Test whether "power" in resourceTypes array.
ok('resourceTypes' in powerStatsMgr,
"resourceTypes should be a ResourceStatsManager attribute.");
ok(Array.isArray(powerStatsMgr.resourceTypes),
"powerStatsMgr.resourceTypes is an array.");
ok(powerStatsMgr.resourceTypes.indexOf("power") > -1,
"'power' is an element of powerStatsMgr.resourceTypes.");
}
// Check the content returned by ResourceStats.getData().
function checkData(data, start, end) {
// Check if data is an array.
if (!Array.isArray(data)) {
ok(false, "getData does not return an array.")
return;
} else {
ok(true, "getData returns an array.")
}
// Iterate the array and check the timestamp and type of each element.
var success = true;
var obj = null;
var timestamp = start;
var i = 0;
var length = data.length;
do {
obj = data[i++];
// Check object type.
if (!(obj instanceof PowerStatsData)) {
success = false;
ok(false, "The array contains a non-PowerStatsData object.");
break;
}
// Check if the timestamp is continuous.
if (obj.timestamp != timestamp) {
success = false;
ok(false, "The timestamp of PowerStatsData object is correct.");
break;
}
timestamp += sampleRate;
} while (i < length);
if (!success) {
return;
}
// Check the timestamp of the last element is equal to end.
if (obj.timestamp != end) {
ok(false,
"The timestamp of the last element of the array is equal to end.");
return;
}
// Execute next test case.
ok(true, "The return of getData is an array of PowerStatsData objects.");
testMethods();
}
// Test Cases for testing WebIDL methods.
var testCases = [
function() {
// Test clearAllStats.
var promise = powerStatsMgr.clearAllStats();
promise.then(function() {
ok(true, "clearAllStats clears the power store.");
testMethods();
}, function() {
ok(false, "clearAllStats fails to clear the power store.");
});
},
function() {
// Test clearStats.
var promise = powerStatsMgr.clearStats();
promise.then(function() {
ok(true, "clearStats clears the power store.");
testMethods();
}, function() {
ok(false, "clearStats fails to clear the power store.");
});
},
function() {
// Check if clearStats throw exception when start is great than end.
var end = Date.now();
var start = end + 1000;
var promise = powerStatsMgr.clearStats(null, start, end);
promise.then(function() {
ok(false,
"clearStats does not throw exception when start is great than end.");
}, function() {
ok(true, "clearStats throw exception when start is great than end.");
testMethods();
});
},
function() {
// Check if clearStats throw exception when start is less than 0.
var end = Date.now();
var start = -1;
var promise = powerStatsMgr.clearStats(null, start, end);
promise.then(function() {
ok(false,
"clearStats dose not throw exception when start is less than 0.");
}, function() {
ok(true, "clearStats throw exception when start is less than 0.");
testMethods();
});
},
function() {
// Check if clearStats throw exception when manifestURL is invalid.
var options = {manifestURL: invalidManifestURL};
var promise = powerStatsMgr.clearStats(options);
promise.then(function() {
ok(false,
"clearStats does not throw exception when manifestURL is invalid.");
}, function() {
ok(true, "clearStats throw exception when manifestURL is invalid.");
testMethods();
});
},
function() {
// Test getAvailableComponents.
var promise = powerStatsMgr.getAvailableComponents();
promise.then(function(value) {
if (Array.isArray(value)) {
ok(true, "getAvailableComponents returns an array.");
testMethods();
} else {
ok(false, "getAvailableComponents does not return an array.");
}
}, function() {
ok(false, "Fail to execute getAvailableComponents.");
});
},
function() {
// Test getStats.
ok(true, "Get system stats when start and end are adapted to sampleRate.");
// Prepare start and end.
var offset = (new Date()).getTimezoneOffset() * 60 * 1000;
var end = Math.floor((Date.now() - offset) / sampleRate) * sampleRate + offset;
var start = end - sampleRate * 10;
// Launch request.
var promise = powerStatsMgr.getStats(null, start, end);
promise.then(function(value) {
// Check the object type.
if (value instanceof ResourceStats) {
ok(true, "Get a ResourceStats object.");
} else {
ok(false, "Fail to get a ResourceStats object.");
return;
}
// Check attributes of ResourceStats.
ok(value.type == "power", "type should be power.");
ok(value.component == null, "component should be null.");
ok(value.serviceType == null, "serviceType should be null.");
ok(value.manifestURL == null, "manifestURL should be null.");
// Check if the time range of ResourceStats is equal to the request.
ok(value.start == start, "start timestamp should be equal.");
ok(value.end == end, "end timestamp should be equal.");
// Check stats stored inside ResourceStats.
if ('getData' in value) {
checkData(value.getData(), start, end);
} else {
ok(false, "getData is not a method of ResourceStats.");
return;
}
}, function() {
ok(false, "Get power stats failed.");
});
},
function() {
// Test getStats when start and end are not adapted to sampleRate.
ok(true,
"Get system stats when start and end are not adapted to sampleRate.");
// Prepare start and end.
var end = Date.now();
var start = end - sampleRate * 10;
// Normalize start and end.
var offset = (new Date()).getTimezoneOffset() * 60 * 1000;
var normEnd = Math.floor((end - offset) / sampleRate)
* sampleRate + offset;
var normStart = Math.floor((start - offset) / sampleRate)
* sampleRate + offset;
// Launch request.
var promise = powerStatsMgr.getStats(null, start, end);
promise.then(function(value) {
// Check the object type.
if (value instanceof ResourceStats) {
ok(true, "Get a ResourceStats object.");
} else {
ok(false, "Fail to get a ResourceStats object.");
return;
}
// Check attributes of ResourceStats.
ok(value.type == "power", "type should be power.");
ok(value.component == null, "component should be null.");
ok(value.serviceType == null, "serviceType should be null.");
ok(value.manifestURL == null, "manifestURL should be null.");
// Check if time range of ResourceStats are normalized.
ok(value.start == normStart, "start timestamp should be normalized.");
ok(value.end == normEnd, "end timestamp should be normalized.");
// Check stats stored inside ResourceStats.
if ('getData' in value) {
checkData(value.getData(), normStart, normEnd);
} else {
ok(false, "getData is not a method of ResourceStats.");
return;
}
}, function() {
ok(false, "Get power stats failed.");
});
},
function() {
// Check if getStats throw exception when start is greater than end.
var end = Date.now();
var start = end + 1000;
var promise = powerStatsMgr.getStats(null, start, end);
promise.then(function() {
ok(false,
"getStats dose not throw exception when start is great than end.");
}, function() {
ok(true, "getStats throw exception when start is great than end.");
testMethods();
});
},
function() {
// Check if getStats throw exception when start is less than 0.
var end = Date.now();
var start = -1;
var promise = powerStatsMgr.getStats(null, start, end);
promise.then(function() {
ok(false,
"getStats dose not throw exception when start is less than 0.");
}, function() {
ok(true, "getStats throw exception when start is less than 0.");
testMethods();
});
},
function() {
// Check if getStats throw exception when manifestURL is invalid.
var options = {manifestURL: invalidManifestURL};
var promise = powerStatsMgr.getStats(options);
promise.then(function(value) {
ok(false,
"getStats does not throw exception when manifestURL is invalid.");
}, function() {
ok(true, "getStats throw exception when manifestURL is invalid.");
testMethods();
});
}
];
// Test WebIDL methods related stats operation.
function testMethods() {
if (!testCases.length) {
ok(true, "Done.");
SpecialPowers.removePermission("resourcestats-manage", document);
SimpleTest.finish();
return;
}
var testCase = testCases.shift();
testCase();
}
function startTest() {
// Create an instance of ResourceStatsManager for power stats.
powerStatsMgr = new ResourceStatsManager("power");
ok(powerStatsMgr, "Create powerStatsMgr.");
// Test WebIDL attributes.
testAttributes();
// Test WebIDL methods related to stats operation.
testMethods();
}
SimpleTest.waitForExplicitFinish();
// Enable permission and preference.
SpecialPowers.addPermission("resourcestats-manage", true, document);
SpecialPowers.pushPrefEnv({ 'set': [
["dom.resource_stats.enabled", true],
["dom.ignore_webidl_scope_checks", true]
]}, startTest);
</script>
</pre>
</body>
</html>

View File

@ -0,0 +1,10 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
if CONFIG['MOZ_B2G_RIL']:
XPCSHELL_TESTS_MANIFESTS += ['xpcshell/xpcshell.ini']
MOCHITEST_MANIFESTS += ['mochitest/mochitest.ini']

View File

@ -0,0 +1,985 @@
/* Any: copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
Cu.import("resource://gre/modules/ResourceStatsDB.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
const db = new ResourceStatsDB();
// Components.
const wifiComponent = "wifi:0";
const mobileComponent = "mobile:1";
const cpuComponent = "cpu:0";
const gpsComponent = "gps:0";
// List of available components.
const networkComponents = [wifiComponent, mobileComponent];
const powerComponents = [cpuComponent, gpsComponent];
const offset = (new Date()).getTimezoneOffset() * 60 * 1000;
// Clear store.
function clearStore(store, callback) {
db._dbNewTxn(store, "readwrite", function(aTxn, aStore) {
aStore.openCursor().onsuccess = function (event) {
let cursor = event.target.result;
if (cursor){
cursor.delete();
cursor.continue();
}
};
}, callback);
}
// Clear all stores to avoid starting tests with unknown state.
add_test(function prepareDatabase() {
clearStore('power_stats_store', function() {
clearStore('network_stats_store', function() {
clearStore('alarm_store', function() {
run_next_test();
});
});
});
});
// Dump data saved in a store.
function dumpStore(store, callback) {
db._dbNewTxn(store, "readonly", function(aTxn, aStore) {
aStore.mozGetAll().onsuccess = function onsuccess(event) {
aTxn.result = event.target.result;
};
}, callback);
}
// Check sampleRate is unchangeable.
add_test(function test_sampleRate() {
var sampleRate = db.sampleRate;
do_check_true(sampleRate > 0);
db.sampleRate = 0;
sampleRate = db.sampleRate;
do_check_true(sampleRate > 0);
run_next_test();
});
// Test maxStorageAge is unchangeable.
add_test(function test_maxStorageAge() {
var maxStorageAge = db.maxStorageAge;
do_check_true(maxStorageAge > 0);
db.maxStorageAge = 0;
maxStorageAge = db.maxStorageAge;
do_check_true(maxStorageAge > 0);
run_next_test();
});
// Normalize timestamp to sampleRate precision.
function normalizeTime(aTimeStamp) {
var sampleRate = db.sampleRate;
return Math.floor((aTimeStamp - offset) / sampleRate) * sampleRate;
}
// Generte record as input for saveNetworkStats() as well as the expected
// result when calling getStats().
function generateNetworkRecord(aAppId, aServiceType, aComponents) {
var result = [];
var componentStats = {};
var receivedBytes;
var sentBytes;
var totalReceivedBytes = 0;
var totalSentBytes = 0;
aComponents.forEach(function(comp) {
// Step 1: generate random value for receivedBytes and sentBytes.
receivedBytes = Math.floor(Math.random() * 1000);
sentBytes = Math.floor(Math.random() * 1000);
totalReceivedBytes += receivedBytes;
totalSentBytes += sentBytes;
// Step 2: add stats to record.componentStats.
componentStats[comp] = {
receivedBytes: receivedBytes,
sentBytes: sentBytes
};
// Step 3: generate expected results.
result.push({
appId: aAppId,
serviceType: aServiceType,
component: comp,
receivedBytes: receivedBytes,
sentBytes: sentBytes
});
});
// Step 4: generate expected total stats.
result.push({
appId: aAppId,
serviceType: aServiceType,
component: "",
receivedBytes: totalReceivedBytes,
sentBytes: totalSentBytes
});
// Step 5: get record.
var record = { appId: aAppId,
serviceType: aServiceType,
componentStats: componentStats };
return { record: record, result: result };
}
// Generte record as input for savePowerStats() as well as the expected
// result when calling getStats().
function generatePowerRecord(aAppId, aServiceType, aComponents) {
var result = [];
var componentStats = {};
var consumedPower;
var totalConsumedPower = 0;
aComponents.forEach(function(comp) {
// Step 1: generate random value for consumedPower.
consumedPower = Math.floor(Math.random() * 1000);
totalConsumedPower += consumedPower;
// Step 2: add stats to record.componentStats.
componentStats[comp] = consumedPower;
// Step 3: generate expected results.
result.push({
appId: aAppId,
serviceType: aServiceType,
component: comp,
consumedPower: consumedPower
});
});
// Step 4: generate expected total stats.
result.push({
appId: aAppId,
serviceType: aServiceType,
component: "",
consumedPower: totalConsumedPower
});
// Step 5: get record.
var record = { appId: aAppId,
serviceType: aServiceType,
componentStats: componentStats };
return { record: record, result: result };
}
// Compare stats saved in network store with expected results.
function checkNetworkStatsStore(aExpectedResult, aDumpResult, aTimestamp) {
// Step 1: a quick check for the length of arrays first.
do_check_eq(aExpectedResult.length, aDumpResult.length);
// Step 2: create a map array for search by receivedBytes.
var mapArray = aExpectedResult.map(function(e) {return e.receivedBytes;});
// Step 3: compare each element to make sure both array are equal.
var index;
var target;
aDumpResult.forEach(function(stats) {
index = 0;
// Find the first equal receivedBytes since index.
while ((index = mapArray.indexOf(stats.receivedBytes, index)) > -1) {
// Compare all attributes.
target = aExpectedResult[index];
if (target.appId != stats.appId ||
target.serviceType != stats.serviceType ||
target.component != stats.component ||
target.sentBytes != stats.sentBytes ||
aTimestamp != stats.timestamp) {
index += 1;
continue;
} else {
// If found, remove that element from aExpectedResult and mapArray.
aExpectedResult.splice(index, 1);
mapArray.splice(index, 1);
break;
}
}
do_check_neq(index, -1);
});
run_next_test();
}
// Compare stats saved in power store with expected results.
function checkPowerStatsStore(aExpectedResult, aDumpResult, aTimestamp) {
// Step 1: a quick check for the length of arrays first.
do_check_eq(aExpectedResult.length, aDumpResult.length);
// Step 2: create a map array for search by consumedPower.
var mapArray = aExpectedResult.map(function(e) {return e.consumedPower;});
// Step 3: compare each element to make sure both array are equal.
var index;
var target;
aDumpResult.forEach(function(stats) {
index = 0;
// Find the first equal consumedPower since index.
while ((index = mapArray.indexOf(stats.consumedPower, index)) > -1) {
// Compare all attributes.
target = aExpectedResult[index];
if (target.appId != stats.appId ||
target.serviceType != stats.serviceType ||
target.component != stats.component ||
aTimestamp != stats.timestamp) {
index += 1;
continue;
} else {
// If found, remove that element from aExpectedResult and mapArray.
aExpectedResult.splice(index, 1);
mapArray.splice(index, 1);
break;
}
}
do_check_neq(index, -1);
});
run_next_test();
}
// Prepare network store for testing.
function prepareNetworkStatsStore(recordArray, timestamp, callback) {
// Step 1: clear store.
clearStore("network_stats_store", function() {
// Step 2: save record to store.
db.saveNetworkStats(recordArray, timestamp, callback);
});
}
// Prepare power store for testing.
function preparePowerStatsStore(recordArray, timestamp, callback) {
// Step 1: clear store.
clearStore("power_stats_store", function() {
// Step 2: save record to store.
db.savePowerStats(recordArray, timestamp, callback);
});
}
// Test saveNetworkStats.
add_test(function test_saveNetworkStats() {
var appId = 1;
var serviceType = "";
// Step 1: generate data saved to store.
var { record: record, result: expectedResult } =
generateNetworkRecord(appId, serviceType, networkComponents);
var recordArray = [record];
var timestamp = Date.now();
// Step 2: save recordArray to network store.
prepareNetworkStatsStore(recordArray, timestamp, function(error, callback) {
// Step 3: check if the function call succeed.
do_check_eq(error, null);
// Step 4: dump store for comparison.
dumpStore("network_stats_store", function(error, result) {
do_check_eq(error, null);
checkNetworkStatsStore(expectedResult, result, normalizeTime(timestamp));
});
});
});
// Test savePowerStats.
add_test(function test_savePowerStats() {
var appId = 1;
var serviceType = "";
// Step 1: generate data saved to store.
var { record: record, result: expectedResult } =
generatePowerRecord(appId, serviceType, powerComponents);
var recordArray = [record];
var timestamp = Date.now();
// Step 2: save recordArray to power store.
preparePowerStatsStore(recordArray, timestamp, function(error, callback) {
// Step 3: check if the function call succeed.
do_check_eq(error, null);
// Step 4: dump store for comparison.
dumpStore("power_stats_store", function(error, result) {
do_check_eq(error, null);
checkPowerStatsStore(expectedResult, result, normalizeTime(timestamp));
});
});
});
// Test getting network stats via getStats.
add_test(function test_getNetworkStats() {
var appId = 0;
var manifestURL = "";
var serviceType = "";
var component = "";
// Step 1: generate data saved to store.
var { record: record, result: result } =
generateNetworkRecord(appId, serviceType, networkComponents);
var recordArray = [record];
var expectedStats = result[result.length - 1]; // Check total stats only.
var timestamp = Date.now();
var end = normalizeTime(timestamp) + offset;
var start = end;
// Step 2: save record and prepare network store.
prepareNetworkStatsStore(recordArray, timestamp, function(error, callback) {
// Step 3: get network stats.
db.getStats("network", manifestURL, serviceType, component, start, end,
function(error, result) {
do_check_eq(error, null);
// Step 4: verify result.
do_check_eq(result.type, "network");
do_check_eq(result.manifestURL, manifestURL);
do_check_eq(result.serviceType, serviceType);
do_check_eq(result.component, component);
do_check_eq(result.start, start);
do_check_eq(result.end, end);
do_check_eq(result.sampleRate, db.sampleRate);
do_check_true(Array.isArray(result.statsData));
do_check_eq(result.statsData.length, 1);
var stats = result.statsData[0];
do_check_eq(stats.receivedBytes, expectedStats.receivedBytes);
do_check_eq(stats.sentBytes, expectedStats.sentBytes);
run_next_test(); // If success, run next test.
});
});
});
// Test getting power stats via getStats.
add_test(function test_getPowerStats() {
var appId = 0;
var manifestURL = "";
var serviceType = "";
var component = "";
// Step 1: generate data saved to store.
var { record: record, result: result } =
generatePowerRecord(appId, serviceType, powerComponents);
var recordArray = [record];
var expectedStats = result[result.length - 1]; // Check total stats only.
var timestamp = Date.now();
var end = normalizeTime(timestamp) + offset;
var start = end;
// Step 2: save record and prepare power store.
preparePowerStatsStore(recordArray, timestamp, function(error, callback) {
// Step 3: get power stats.
db.getStats("power", manifestURL, serviceType, component, start, end,
function(error, result) {
do_check_eq(error, null);
// Step 4: verify result
do_check_eq(result.type, "power");
do_check_eq(result.manifestURL, manifestURL);
do_check_eq(result.serviceType, serviceType);
do_check_eq(result.component, component);
do_check_eq(result.start, start);
do_check_eq(result.end, end);
do_check_eq(result.sampleRate, db.sampleRate);
do_check_true(Array.isArray(result.statsData));
do_check_eq(result.statsData.length, 1);
var stats = result.statsData[0];
do_check_eq(stats.consumedPower, expectedStats.consumedPower);
run_next_test(); // If success, run next test.
});
});
});
// Test deleting network stats via clearStats.
add_test(function test_clearNetworkStats() {
var appId = 0;
var manifestURL = "";
var serviceType = "";
var component = "";
// Step 1: genrate data saved to network store.
var { record: record, result: result } =
generateNetworkRecord(appId, serviceType, networkComponents);
var recordArray = [record];
var timestamp = Date.now();
var end = normalizeTime(timestamp) + offset;
var start = end;
// Step 2: save record and prepare network store.
prepareNetworkStatsStore(recordArray, timestamp, function(error, callback) {
// Step 3: clear network stats.
db.clearStats("network", appId, serviceType, component, start, end,
function(error, result) {
do_check_eq(error, null);
// Step 4: check if the stats is deleted.
db.getStats("network", manifestURL, serviceType, component, start, end,
function(error, result) {
do_check_eq(result.statsData.length, 0);
run_next_test();
});
});
});
});
// Test deleting power stats via clearStats.
add_test(function test_clearPowerStats() {
var appId = 0;
var manifestURL = "";
var serviceType = "";
var component = "";
// Step 1: genrate data saved to power store.
var { record: record, result: result } =
generatePowerRecord(appId, serviceType, powerComponents);
var recordArray = [record];
var timestamp = Date.now();
var end = normalizeTime(timestamp) + offset;
var start = end;
// Step 2: save record and prepare power store.
preparePowerStatsStore(recordArray, timestamp, function(error, callback) {
// Step 3: clear power stats.
db.clearStats("power", appId, serviceType, component, start, end,
function(error, result) {
do_check_eq(error, null);
// Step 4: check if the stats is deleted.
db.getStats("power", manifestURL, serviceType, component, start, end,
function(error, result) {
do_check_eq(result.statsData.length, 0);
run_next_test();
});
});
});
});
// Test clearing all network stats.
add_test(function test_clearAllNetworkStats() {
db.clearAllStats("network", function(error, result) {
do_check_eq(error, null);
run_next_test();
});
});
// Test clearing all power stats.
add_test(function test_clearAllPowerStats() {
db.clearAllStats("power", function(error, result) {
do_check_eq(error, null);
run_next_test();
});
});
// Test getting network components.
add_test(function test_getNetworkComponents() {
var appId = 0;
var serviceType = "";
// Step 1: generate data saved to store.
var { record: record, result: expectedResult } =
generateNetworkRecord(appId, serviceType, networkComponents);
var recordArray = [record];
var timestamp = Date.now();
// Step 2: save recordArray to network store.
prepareNetworkStatsStore(recordArray, timestamp, function(error, callback) {
// Step 3: call getComponents.
db.getComponents("network", function(error, result) {
do_check_eq(error, null);
do_check_true(Array.isArray(result));
do_check_eq(result.length, networkComponents.length);
// Check each element in result array is an element of networkComponents.
result.forEach(function(component) {
do_check_true(networkComponents.indexOf(component) > -1);
});
run_next_test(); // If success, run next test.
});
});
});
// Test getting power components.
add_test(function test_getPowerComponents() {
var appId = 0;
var serviceType = "";
// Step 1: generate data saved to store.
var { record: record, result: expectedResult } =
generatePowerRecord(appId, serviceType, powerComponents);
var recordArray = [record];
var timestamp = Date.now();
// Step 2: save recordArray to power store.
preparePowerStatsStore(recordArray, timestamp, function(error, callback) {
// Step 3: call getComponents.
db.getComponents("power", function(error, result) {
do_check_eq(error, null);
do_check_true(Array.isArray(result));
do_check_eq(result.length, powerComponents.length);
// Check each element in result array is an element of powerComponents.
result.forEach(function(component) {
do_check_true(powerComponents.indexOf(component) > -1);
});
run_next_test(); // If success, run next test.
});
});
});
// Generate alarm object for addAlarm().
function generateAlarmObject(aType, aManifestURL, aServiceType, aComponent) {
let alarm = {
type: aType,
component: aComponent,
serviceType: aServiceType,
manifestURL: aManifestURL,
threshold: Math.floor(Math.random() * 1000),
startTime: Math.floor(Math.random() * 1000),
data: null
};
return alarm;
}
// Test adding a network alarm.
add_test(function test_addNetowrkAlarm() {
var manifestURL = "";
var serviceType = "";
// Step 1: generate a network alarm.
var alarm =
generateAlarmObject("network", manifestURL, serviceType, wifiComponent);
// Step 2: clear store.
clearStore("alarm_store", function() {
// Step 3: save the alarm to store.
db.addAlarm(alarm, function(error, result) {
// Step 4: check if the function call succeed.
do_check_eq(error, null);
do_check_true(result > -1);
let alarmId = result;
// Step 5: dump store for comparison.
dumpStore("alarm_store", function(error, result) {
do_check_eq(error, null);
do_check_true(Array.isArray(result));
do_check_true(result.length == 1);
do_check_eq(result[0].type, alarm.type);
do_check_eq(result[0].manifestURL, alarm.manifestURL);
do_check_eq(result[0].serviceType, alarm.serviceType);
do_check_eq(result[0].component, alarm.component);
do_check_eq(result[0].threshold, alarm.threshold);
do_check_eq(result[0].startTime, alarm.startTime);
do_check_eq(result[0].data, alarm.data);
do_check_eq(result[0].alarmId, alarmId);
run_next_test(); // If success, run next test.
});
});
});
});
// Test adding a power alarm.
add_test(function test_addPowerAlarm() {
var manifestURL = "";
var serviceType = "";
// Step 1: generate a power alarm.
var alarm =
generateAlarmObject("power", manifestURL, serviceType, cpuComponent);
// Step 2: clear store.
clearStore("alarm_store", function() {
// Step 3: save the alarm to store.
db.addAlarm(alarm, function(error, result) {
// Step 4: check if the function call succeed.
do_check_eq(error, null);
do_check_true(result > -1);
let alarmId = result;
// Step 5: dump store for comparison.
dumpStore("alarm_store", function(error, result) {
do_check_eq(error, null);
do_check_true(Array.isArray(result));
do_check_true(result.length == 1);
do_check_eq(result[0].type, alarm.type);
do_check_eq(result[0].manifestURL, alarm.manifestURL);
do_check_eq(result[0].serviceType, alarm.serviceType);
do_check_eq(result[0].component, alarm.component);
do_check_eq(result[0].threshold, alarm.threshold);
do_check_eq(result[0].startTime, alarm.startTime);
do_check_eq(result[0].data, alarm.data);
do_check_eq(result[0].alarmId, alarmId);
run_next_test(); // If success, run next test.
});
});
});
});
// Add multiple alarms to store and record the obtained alarmId in each
// alarm object.
function addAlarmsToStore(alarms, index, callback) {
var alarm = alarms[index++];
if (index < alarms.length) {
db.addAlarm(alarm, function(error, result) {
alarm.alarmId = result;
addAlarmsToStore(alarms, index, callback);
});
} else {
db.addAlarm(alarm, function(error, result) {
alarm.alarmId = result;
callback(error, result);
});
}
}
// Prepare alarm store for testging.
function prepareAlarmStore(alarms, callback) {
// Step 1: clear srore.
clearStore("alarm_store", function() {
// Step 2: save alarms to store one by one.
addAlarmsToStore(alarms, 0, callback);
});
}
// Compare alrams returned by getAlarms().
function compareAlarms(aExpectedResult, aResult) {
// Step 1: a quick check for the length of arrays first.
do_check_eq(aExpectedResult.length, aResult.length);
// Step 2: create a map array for search by threshold.
var mapArray = aExpectedResult.map(function(e) {return e.threshold;});
// Step 3: compare each element to make sure both array are equal.
var index;
var target;
aResult.forEach(function(alarm) {
index = 0;
// Find the first equal receivedBytes since index.
while ((index = mapArray.indexOf(alarm.threshold, index)) > -1) {
// Compare all attributes.
target = aExpectedResult[index];
if (target.alarmId != alarm.alarmId ||
target.type != alarm.type ||
target.manifestURL != alarm.manifestURL ||
target.serviceType != alarm.serviceType ||
target.component != alarm.component ||
target.data != alarm.data) {
index += 1;
continue;
} else {
// If found, remove that element from aExpectedResult and mapArray.
aExpectedResult.splice(index, 1);
mapArray.splice(index, 1);
break;
}
}
do_check_neq(index, -1);
});
run_next_test();
}
// Test getting designate network alarms from store.
add_test(function test_getNetworkAlarms() {
var manifestURL = "";
var serviceType = "";
var alarms = [];
// Step 1: generate two network alarms using same parameters.
alarms.push(generateAlarmObject("network", manifestURL, serviceType,
wifiComponent));
alarms.push(generateAlarmObject("network", manifestURL, serviceType,
wifiComponent));
// Step 2: generate another network alarm using different parameters.
alarms.push(generateAlarmObject("network", manifestURL, serviceType,
mobileComponent));
// Step 3: clear alarm store and save new alarms to store.
prepareAlarmStore(alarms, function(error, result) {
// Step 4: call getAlarms.
let options = {
manifestURL: manifestURL,
serviceType: serviceType,
component: wifiComponent
};
db.getAlarms("network", options, function(error, result) {
// Step 5: check if the function call succeed.
do_check_eq(error, null);
// Step 6: check results.
// The last element in alarms array is not our expected result,
// so pop that out first.
alarms.pop();
compareAlarms(alarms, result);
});
});
});
// Test getting designate power alarms from store.
add_test(function test_getPowerAlarms() {
var manifestURL = "";
var serviceType = "";
var alarms = [];
// Step 1: generate two power alarms using same parameters.
alarms.push(generateAlarmObject("power", manifestURL, serviceType,
cpuComponent));
alarms.push(generateAlarmObject("power", manifestURL, serviceType,
cpuComponent));
// Step 2: generate another power alarm using different parameters.
alarms.push(generateAlarmObject("power", manifestURL, serviceType,
gpsComponent));
// Step 3: clear alarm store and save new alarms to store.
prepareAlarmStore(alarms, function(error, result) {
// Step 4: call getAlarms.
let options = {
manifestURL: manifestURL,
serviceType: serviceType,
component: cpuComponent
};
db.getAlarms("power", options, function(error, result) {
// Step 5: check if the function call succeed.
do_check_eq(error, null);
// Step 6: check results.
// The last element in alarms array is not our expected result,
// so pop that out first.
alarms.pop();
compareAlarms(alarms, result);
});
});
});
// Test getting all network alarms from store.
add_test(function test_getAllNetworkAlarms() {
var manifestURL = "";
var serviceType = "";
var alarms = [];
// Step 1: generate two network alarms.
alarms.push(generateAlarmObject("network", manifestURL, serviceType,
wifiComponent));
alarms.push(generateAlarmObject("network", manifestURL, serviceType,
mobileComponent));
// Step 2: generate another power alarm.
alarms.push(generateAlarmObject("power", manifestURL, serviceType,
cpuComponent));
// Step 3: clear alarm store and save new alarms to store.
prepareAlarmStore(alarms, function(error, result) {
// Step 4: call getAlarms.
let options = null;
db.getAlarms("network", options, function(error, result) {
// Step 5: check if the function call succeed.
do_check_eq(error, null);
// Step 6: check results.
// The last element in alarms array is not our expected result,
// so pop that out first.
alarms.pop();
compareAlarms(alarms, result);
});
});
});
// Test getting all power alarms from store.
add_test(function test_getAllPowerAlarms() {
var manifestURL = "";
var serviceType = "";
var alarms = [];
// Step 1: generate two power alarms.
alarms.push(generateAlarmObject("power", manifestURL, serviceType,
cpuComponent));
alarms.push(generateAlarmObject("power", manifestURL, serviceType,
gpsComponent));
// Step 2: generate another network alarm.
alarms.push(generateAlarmObject("network", manifestURL, serviceType,
wifiComponent));
// Step 3: clear alarm store and save new alarms to store.
prepareAlarmStore(alarms, function(error, result) {
// Step 4: call getAlarms.
let options = null;
db.getAlarms("power", options, function(error, result) {
// Step 5: check if the function call succeed.
do_check_eq(error, null);
// Step 6: check results.
// The last element in alarms array is not our expected result,
// so pop that out first.
alarms.pop();
compareAlarms(alarms, result);
});
});
});
// Test removing designate network alarm from store.
add_test(function test_removeNetworkAlarm() {
var manifestURL = "";
var serviceType = "";
var alarms = [];
// Step 1: generate one network alarm.
alarms.push(generateAlarmObject("network", manifestURL, serviceType,
wifiComponent));
// Step 2: clear alarm store and save new alarms to store.
prepareAlarmStore(alarms, function(error, result) {
var alarmId = result;
// Step 3: remove the alarm.
db.removeAlarm("network", alarmId, function(error, result) {
// Step 4: check if the function call succeed.
do_check_eq(result, true);
// Step 5: dump store to check if the alarm is removed.
dumpStore("alarm_store", function(error, result) {
do_check_eq(error, null);
do_check_true(Array.isArray(result));
do_check_true(result.length === 0);
run_next_test(); // If success, run next test.
});
});
});
});
// Test removing designate power alarm from store.
add_test(function test_removePowerAlarm() {
var manifestURL = "";
var serviceType = "";
var alarms = [];
// Step 1: generate one power alarm.
alarms.push(generateAlarmObject("power", manifestURL, serviceType,
cpuComponent));
// Step 2: clear alarm store and save new alarms to store.
prepareAlarmStore(alarms, function(error, result) {
var alarmId = result;
// Step 3: remove the alarm.
db.removeAlarm("power", alarmId, function(error, result) {
// Step 4: check if the function call succeed.
do_check_eq(result, true);
// Step 5: dump store to check if the alarm is removed.
dumpStore("alarm_store", function(error, result) {
do_check_eq(error, null);
do_check_true(Array.isArray(result));
do_check_true(result.length === 0);
run_next_test(); // If success, run next test.
});
});
});
});
// Test removing designate network alarm from store.
add_test(function test_removeAllNetworkAlarms() {
var manifestURL = "";
var serviceType = "";
var alarms = [];
// Step 1: generate two network alarms.
alarms.push(generateAlarmObject("network", manifestURL, serviceType,
wifiComponent));
alarms.push(generateAlarmObject("network", manifestURL, serviceType,
mobileComponent));
// Step 2: generate another power alarm.
alarms.push(generateAlarmObject("power", manifestURL, serviceType,
cpuComponent));
// Step 3: clear alarm store and save new alarms to store.
prepareAlarmStore(alarms, function(error, result) {
// Step 4: remove all network alarms.
db.removeAllAlarms("network", function(error, result) {
// Step 5: check if the function call succeed.
do_check_eq(error, null);
// Step 6: dump store for comparison.
// Because the power alarm should not be removed, so it would be the
// only result returned by dumpStore.
var alarm = alarms.pop(); // The expected result.
dumpStore("alarm_store", function(error, result) {
do_check_eq(error, null);
do_check_true(Array.isArray(result));
do_check_true(result.length == 1);
do_check_eq(result[0].type, alarm.type);
do_check_eq(result[0].manifestURL, alarm.manifestURL);
do_check_eq(result[0].serviceType, alarm.serviceType);
do_check_eq(result[0].component, alarm.component);
do_check_eq(result[0].threshold, alarm.threshold);
do_check_eq(result[0].startTime, alarm.startTime);
do_check_eq(result[0].data, alarm.data);
do_check_eq(result[0].alarmId, alarm.alarmId);
run_next_test(); // If success, run next test.
});
});
});
});
// Test removing designate power alarm from store.
add_test(function test_removeAllPowerAlarms() {
var manifestURL = "";
var serviceType = "";
var alarms = [];
// Step 1: generate two power alarms.
alarms.push(generateAlarmObject("power", manifestURL, serviceType,
cpuComponent));
alarms.push(generateAlarmObject("power", manifestURL, serviceType,
gpsComponent));
// Step 2: generate another network alarm.
alarms.push(generateAlarmObject("network", manifestURL, serviceType,
wifiComponent));
// Step 3: clear alarm store and save new alarms to store.
prepareAlarmStore(alarms, function(error, result) {
// Step 4: remove all power alarms.
db.removeAllAlarms("power", function(error, result) {
// Step 5: check if the function call succeed.
do_check_eq(error, null);
// Step 6: dump store for comparison.
// Because the network alarm should not be removed, so it would be the
// only result returned by dumpStore.
var alarm = alarms.pop(); // The expected result.
dumpStore("alarm_store", function(error, result) {
do_check_eq(error, null);
do_check_true(Array.isArray(result));
do_check_true(result.length == 1);
do_check_eq(result[0].type, alarm.type);
do_check_eq(result[0].manifestURL, alarm.manifestURL);
do_check_eq(result[0].serviceType, alarm.serviceType);
do_check_eq(result[0].component, alarm.component);
do_check_eq(result[0].threshold, alarm.threshold);
do_check_eq(result[0].startTime, alarm.startTime);
do_check_eq(result[0].data, alarm.data);
do_check_eq(result[0].alarmId, alarm.alarmId);
run_next_test(); // If success, run next test.
});
});
});
});
function run_test() {
do_get_profile();
run_next_test();
}

View File

@ -0,0 +1,5 @@
[DEFAULT]
head =
tail =
[test_resourcestats_db.js]

View File

@ -5,6 +5,7 @@
[include:dom/apps/tests/unit/xpcshell.ini]
[include:dom/mobilemessage/tests/xpcshell/xpcshell.ini]
[include:dom/network/tests/unit_stats/xpcshell.ini]
[include:dom/resourcestats/tests/xpcshell/xpcshell.ini]
[include:dom/system/gonk/tests/xpcshell.ini]
[include:dom/wappush/tests/xpcshell.ini]
[include:toolkit/components/osfile/tests/xpcshell/xpcshell.ini]