зеркало из https://github.com/mozilla/gecko-dev.git
553 строки
15 KiB
JavaScript
553 строки
15 KiB
JavaScript
/* Any copyright is dedicated to the Public Domain.
|
|
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
|
|
let Promise = SpecialPowers.Cu.import("resource://gre/modules/Promise.jsm").Promise;
|
|
|
|
const ETHERNET_MANAGER_CONTRACT_ID = "@mozilla.org/ethernetManager;1";
|
|
|
|
const INTERFACE_UP = "UP";
|
|
const INTERFACE_DOWN = "DOWN";
|
|
|
|
let gTestSuite = (function() {
|
|
let suite = {};
|
|
|
|
// Private member variables of the returned object |suite|.
|
|
let ethernetManager = SpecialPowers.Cc[ETHERNET_MANAGER_CONTRACT_ID]
|
|
.getService(SpecialPowers.Ci.nsIEthernetManager);
|
|
let pendingEmulatorShellCount = 0;
|
|
|
|
/**
|
|
* Send emulator shell command with safe guard.
|
|
*
|
|
* We should only call |finish()| after all emulator command transactions
|
|
* end, so here comes with the pending counter. Resolve when the emulator
|
|
* gives positive response, and reject otherwise.
|
|
*
|
|
* Fulfill params: an array of emulator response lines.
|
|
* Reject params: an array of emulator response lines.
|
|
*
|
|
* @param command
|
|
* A string command to be passed to emulator through its telnet console.
|
|
*
|
|
* @return A deferred promise.
|
|
*/
|
|
function runEmulatorShellSafe(command) {
|
|
let deferred = Promise.defer();
|
|
|
|
++pendingEmulatorShellCount;
|
|
runEmulatorShell(command, function(aResult) {
|
|
--pendingEmulatorShellCount;
|
|
|
|
ok(true, "Emulator shell response: " + JSON.stringify(aResult));
|
|
if (Array.isArray(aResult)) {
|
|
deferred.resolve(aResult);
|
|
} else {
|
|
deferred.reject(aResult);
|
|
}
|
|
});
|
|
|
|
return deferred.promise;
|
|
}
|
|
|
|
/**
|
|
* Get the system network conifg by the given interface name.
|
|
*
|
|
* Use shell command 'netcfg' to get the list of network cofig.
|
|
*
|
|
* Fulfill params: An object of { name, flag, ip }
|
|
*
|
|
* @parm ifname
|
|
* Interface name.
|
|
*
|
|
* @return A deferred promise.
|
|
*/
|
|
function getNetworkConfig(ifname) {
|
|
return runEmulatorShellSafe(['netcfg'])
|
|
.then(result => {
|
|
// Sample 'netcfg' output:
|
|
//
|
|
// lo UP 127.0.0.1/8 0x00000049 00:00:00:00:00:00
|
|
// eth0 UP 10.0.2.15/24 0x00001043 52:54:00:12:34:56
|
|
// eth1 DOWN 0.0.0.0/0 0x00001002 52:54:00:12:34:57
|
|
// rmnet1 DOWN 0.0.0.0/0 0x00001002 52:54:00:12:34:59
|
|
|
|
let config;
|
|
|
|
for (let i = 0; i < result.length; i++) {
|
|
let tokens = result[i].split(/\s+/);
|
|
let name = tokens[0];
|
|
let flag = tokens[1];
|
|
let ip = tokens[2].split(/\/+/)[0];
|
|
if (name == ifname) {
|
|
config = { name: name, flag: flag, ip: ip };
|
|
break;
|
|
}
|
|
}
|
|
|
|
return config;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Get the ip assigned by dhcp server of a given interface name.
|
|
*
|
|
* Get the ip from android property 'dhcp.[ifname].ipaddress'.
|
|
*
|
|
* Fulfill params: A string of ip address.
|
|
*
|
|
* @parm ifname
|
|
* Interface name.
|
|
*
|
|
* @return A deferred promise.
|
|
*/
|
|
function getDhcpIpAddr(ifname) {
|
|
return runEmulatorShellSafe(['getprop', 'dhcp.' + ifname + '.ipaddress'])
|
|
.then(function(ipAddr) {
|
|
return ipAddr[0];
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Get the gateway assigned by dhcp server of a given interface name.
|
|
*
|
|
* Get the ip from android property 'dhcp.[ifname].gateway'.
|
|
*
|
|
* Fulfill params: A string of gateway.
|
|
*
|
|
* @parm ifname
|
|
* Interface name.
|
|
*
|
|
* @return A deferred promise.
|
|
*/
|
|
function getDhcpGateway(ifname) {
|
|
return runEmulatorShellSafe(['getprop', 'dhcp.' + ifname + '.gateway'])
|
|
.then(function(gateway) {
|
|
return gateway[0];
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Get the default route.
|
|
*
|
|
* Use shell command 'ip route' to get the default of device.
|
|
*
|
|
* Fulfill params: An array of { name, gateway }
|
|
*
|
|
* @return A deferred promise.
|
|
*/
|
|
function getDefaultRoute() {
|
|
return runEmulatorShellSafe(['ip', 'route'])
|
|
.then(result => {
|
|
// Sample 'ip route' output:
|
|
//
|
|
// 10.0.2.0/24 dev eth0 proto kernel scope link src 10.0.2.15
|
|
// default via 10.0.2.2 dev eth0 metric 2
|
|
|
|
let routeInfo = [];
|
|
|
|
for (let i = 0; i < result.length; i++) {
|
|
if (!result[i].match('default')) {
|
|
continue;
|
|
}
|
|
|
|
let tokens = result[i].split(/\s+/);
|
|
let name = tokens[4];
|
|
let gateway = tokens[2];
|
|
routeInfo.push({ name: name, gateway: gateway });
|
|
}
|
|
|
|
return routeInfo;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Check a specific interface is enabled or not.
|
|
*
|
|
* @parm ifname
|
|
* Interface name.
|
|
* @parm enabled
|
|
* A boolean value used to check interface is disable or not.
|
|
*
|
|
* @return A deferred promise.
|
|
*/
|
|
function checkInterfaceIsEnabled(ifname, enabled) {
|
|
return getNetworkConfig(ifname)
|
|
.then(function(config) {
|
|
if (enabled) {
|
|
is(config.flag, INTERFACE_UP, "Interface is enabled as expected.");
|
|
} else {
|
|
is(config.flag, INTERFACE_DOWN, "Interface is disabled as expected.");
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Check the ip of a specific interface is equal to given ip or not.
|
|
*
|
|
* @parm ifname
|
|
* Interface name.
|
|
* @parm ip
|
|
* Given ip address.
|
|
*
|
|
* @return A deferred promise.
|
|
*/
|
|
function checkInterfaceIpAddr(ifname, ip) {
|
|
return getNetworkConfig(ifname)
|
|
.then(function(config) {
|
|
is(config.ip, ip, "IP is right as expected.");
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Check the default gateway of a specific interface is equal to given gateway
|
|
* or not.
|
|
*
|
|
* @parm ifname
|
|
* Interface name.
|
|
* @parm gateway
|
|
* Given gateway.
|
|
*
|
|
* @return A deferred promise.
|
|
*/
|
|
function checkDefaultRoute(ifname, gateway) {
|
|
return getDefaultRoute()
|
|
.then(function(routeInfo) {
|
|
for (let i = 0; i < routeInfo.length; i++) {
|
|
if (routeInfo[i].name == ifname) {
|
|
is(routeInfo[i].gateway, gateway,
|
|
"Default gateway is right as expected.");
|
|
return true;
|
|
}
|
|
}
|
|
|
|
if (!gateway) {
|
|
ok(true, "Default route is cleared.");
|
|
return true;
|
|
}
|
|
|
|
// TODO: should we ok(false, ......) here?
|
|
return false;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Check the length of interface list in EthernetManager is equal to given
|
|
* length or not.
|
|
*
|
|
* @parm length
|
|
* Given length.
|
|
*/
|
|
function checkInterfaceListLength(length) {
|
|
let list = ethernetManager.interfaceList;
|
|
is(length, list.length, "List length is equal as expected.");
|
|
}
|
|
|
|
/**
|
|
* Check the given interface exists on device or not.
|
|
*
|
|
* @parm ifname
|
|
* Interface name.
|
|
*
|
|
* @return A deferred promise.
|
|
*/
|
|
function checkInterfaceExist(ifname) {
|
|
return scanInterfaces()
|
|
.then(list => {
|
|
let index = list.indexOf(ifname);
|
|
if (index < 0) {
|
|
throw "Interface " + ifname + " not found.";
|
|
}
|
|
|
|
ok(true, ifname + " exists.");
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Scan for available ethernet interfaces.
|
|
*
|
|
* Fulfill params: A list of available interfaces found in device.
|
|
*
|
|
* @return A deferred promise.
|
|
*/
|
|
function scanInterfaces() {
|
|
let deferred = Promise.defer();
|
|
|
|
ethernetManager.scan(function onScan(list) {
|
|
deferred.resolve(list);
|
|
});
|
|
|
|
return deferred.promise;
|
|
}
|
|
|
|
/**
|
|
* Add an interface into interface list.
|
|
*
|
|
* Fulfill params: A boolean value indicates success or not.
|
|
*
|
|
* @param ifname
|
|
* Interface name.
|
|
*
|
|
* @return A deferred promise.
|
|
*/
|
|
function addInterface(ifname) {
|
|
let deferred = Promise.defer();
|
|
|
|
ethernetManager.addInterface(ifname, function onAdd(success, message) {
|
|
ok(success, "Add interface " + ifname + " succeeded.");
|
|
is(message, "ok", "Message is as expected.");
|
|
|
|
deferred.resolve(success);
|
|
});
|
|
|
|
return deferred.promise;
|
|
}
|
|
|
|
/**
|
|
* Remove an interface form the interface list.
|
|
*
|
|
* Fulfill params: A boolean value indicates success or not.
|
|
*
|
|
* @param ifname
|
|
* Interface name.
|
|
*
|
|
* @return A deferred promise.
|
|
*/
|
|
function removeInterface(ifname) {
|
|
let deferred = Promise.defer();
|
|
|
|
ethernetManager.removeInterface(ifname, function onRemove(success, message) {
|
|
ok(success, "Remove interface " + ifname + " succeeded.");
|
|
is(message, "ok", "Message is as expected.");
|
|
|
|
deferred.resolve(success);
|
|
});
|
|
|
|
return deferred.promise;
|
|
}
|
|
|
|
/**
|
|
* Enable networking of an interface in the interface list.
|
|
*
|
|
* Fulfill params: A boolean value indicates success or not.
|
|
*
|
|
* @param ifname
|
|
* Interface name.
|
|
*
|
|
* @return A deferred promise.
|
|
*/
|
|
function enableInterface(ifname) {
|
|
let deferred = Promise.defer();
|
|
|
|
ethernetManager.enable(ifname, function onEnable(success, message) {
|
|
ok(success, "Enable interface " + ifname + " succeeded.");
|
|
is(message, "ok", "Message is as expected.");
|
|
|
|
deferred.resolve(success);
|
|
});
|
|
|
|
return deferred.promise;
|
|
}
|
|
|
|
/**
|
|
* Disable networking of an interface in the interface list.
|
|
*
|
|
* Fulfill params: A boolean value indicates success or not.
|
|
*
|
|
* @param ifname
|
|
* Interface name.
|
|
*
|
|
* @return A deferred promise.
|
|
*/
|
|
function disableInterface(ifname) {
|
|
let deferred = Promise.defer();
|
|
|
|
ethernetManager.disable(ifname, function onDisable(success, message) {
|
|
ok(success, "Disable interface " + ifname + " succeeded.");
|
|
is(message, "ok", "Message is as expected.");
|
|
|
|
deferred.resolve(success);
|
|
});
|
|
|
|
return deferred.promise;
|
|
}
|
|
|
|
/**
|
|
* Make an interface connect to network.
|
|
*
|
|
* Fulfill params: A boolean value indicates success or not.
|
|
*
|
|
* @param ifname
|
|
* Interface name.
|
|
*
|
|
* @return A deferred promise.
|
|
*/
|
|
function makeInterfaceConnect(ifname) {
|
|
let deferred = Promise.defer();
|
|
|
|
ethernetManager.connect(ifname, function onConnect(success, message) {
|
|
ok(success, "Interface " + ifname + " is connected successfully.");
|
|
is(message, "ok", "Message is as expected.");
|
|
|
|
deferred.resolve(success);
|
|
});
|
|
|
|
return deferred.promise;
|
|
}
|
|
|
|
/**
|
|
* Make an interface disconnect to network.
|
|
*
|
|
* Fulfill params: A boolean value indicates success or not.
|
|
*
|
|
* @param ifname
|
|
* Interface name.
|
|
*
|
|
* @return A deferred promise.
|
|
*/
|
|
function makeInterfaceDisconnect(ifname) {
|
|
let deferred = Promise.defer();
|
|
|
|
ethernetManager.disconnect(ifname, function onDisconnect(success, message) {
|
|
ok(success, "Interface " + ifname + " is disconnected successfully.");
|
|
is(message, "ok", "Message is as expected.");
|
|
|
|
deferred.resolve(success);
|
|
});
|
|
|
|
return deferred.promise;
|
|
}
|
|
|
|
/**
|
|
* Update the config the an interface in the interface list.
|
|
*
|
|
* @param ifname
|
|
* Interface name.
|
|
* @param config
|
|
* .ip: ip address.
|
|
* .prefixLength: mask length.
|
|
* .gateway: gateway.
|
|
* .dnses: dnses.
|
|
* .httpProxyHost: http proxy host.
|
|
* .httpProxyPort: http porxy port.
|
|
* .usingDhcp: an boolean value indicates using dhcp or not.
|
|
*
|
|
* @return A deferred promise.
|
|
*/
|
|
function updateInterfaceConfig(ifname, config) {
|
|
let deferred = Promise.defer();
|
|
|
|
ethernetManager.updateInterfaceConfig(ifname, config,
|
|
function onUpdated(success, message) {
|
|
ok(success, "Interface " + ifname + " config is updated successfully " +
|
|
"with " + JSON.stringify(config));
|
|
is(message, "ok", "Message is as expected.");
|
|
|
|
deferred.resolve(success);
|
|
});
|
|
|
|
return deferred.promise;
|
|
}
|
|
|
|
/**
|
|
* Wait for timeout.
|
|
*
|
|
* @param timeout
|
|
* Time in ms.
|
|
*
|
|
* @return A deferred promise.
|
|
*/
|
|
function waitForTimeout(timeout) {
|
|
let deferred = Promise.defer();
|
|
|
|
setTimeout(function() {
|
|
ok(true, "waitForTimeout " + timeout);
|
|
deferred.resolve();
|
|
}, timeout);
|
|
|
|
return deferred.promise;
|
|
}
|
|
|
|
/**
|
|
* Wait for default route of a specific interface being set and
|
|
* check.
|
|
*
|
|
* @param ifname
|
|
* Interface name.
|
|
* @param gateway
|
|
* Target gateway.
|
|
*
|
|
* @return A deferred promise.
|
|
*/
|
|
function waitForDefaultRouteSet(ifname, gateway) {
|
|
return gTestSuite.waitForTimeout(500)
|
|
.then(() => gTestSuite.checkDefaultRoute(ifname, gateway))
|
|
.then(success => {
|
|
if (success) {
|
|
ok(true, "Default route is set as expected." + gateway);
|
|
return;
|
|
}
|
|
|
|
ok(true, "Default route is not set yet, check again. " + success);
|
|
return waitForDefaultRouteSet(ifname, gateway);
|
|
});
|
|
}
|
|
|
|
//---------------------------------------------------
|
|
// Public test suite functions
|
|
//---------------------------------------------------
|
|
suite.scanInterfaces = scanInterfaces;
|
|
suite.addInterface = addInterface;
|
|
suite.removeInterface = removeInterface;
|
|
suite.enableInterface = enableInterface;
|
|
suite.disableInterface = disableInterface;
|
|
suite.makeInterfaceConnect = makeInterfaceConnect;
|
|
suite.makeInterfaceDisconnect = makeInterfaceDisconnect;
|
|
suite.updateInterfaceConfig = updateInterfaceConfig;
|
|
suite.getDhcpIpAddr = getDhcpIpAddr;
|
|
suite.getDhcpGateway = getDhcpGateway;
|
|
suite.checkInterfaceExist = checkInterfaceExist;
|
|
suite.checkInterfaceIsEnabled = checkInterfaceIsEnabled;
|
|
suite.checkInterfaceIpAddr = checkInterfaceIpAddr;
|
|
suite.checkDefaultRoute = checkDefaultRoute;
|
|
suite.checkInterfaceListLength = checkInterfaceListLength;
|
|
suite.waitForTimeout = waitForTimeout;
|
|
suite.waitForDefaultRouteSet = waitForDefaultRouteSet;
|
|
|
|
/**
|
|
* End up the test run.
|
|
*
|
|
* Wait until all pending emulator shell commands are done and then |finish|
|
|
* will be called in the end.
|
|
*/
|
|
function cleanUp() {
|
|
waitFor(finish, function() {
|
|
return pendingEmulatorShellCount === 0;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Common test routine.
|
|
*
|
|
* Start a test with the given test case chain. The test environment will be
|
|
* settled down before the test. After the test, all the affected things will
|
|
* be restored.
|
|
*
|
|
* @param aTestCaseChain
|
|
* The test case entry point, which can be a function or a promise.
|
|
*
|
|
* @return A deferred promise.
|
|
*/
|
|
suite.doTest = function(aTestCaseChain) {
|
|
return Promise.resolve()
|
|
.then(aTestCaseChain)
|
|
.then(function onresolve() {
|
|
cleanUp();
|
|
}, function onreject(aReason) {
|
|
ok(false, 'Promise rejects during test' + (aReason ? '(' + aReason + ')' : ''));
|
|
cleanUp();
|
|
});
|
|
};
|
|
|
|
return suite;
|
|
})();
|