Example #1
0
def run_firefox_for_android(build_obj, params):
    """
       Launch Firefox for Android on the connected device.
       Optional 'params' allow parameters to be passed to Firefox.
    """
    adb_path = _find_sdk_exe(build_obj.substs, 'adb', False)
    if not adb_path:
        adb_path = 'adb'
    dm = DeviceManagerADB(autoconnect=False, adbPath=adb_path, retryLimit=1)
    try:
        #
        # Construct an adb command similar to:
        #
        #   adb shell am start -a android.activity.MAIN -n org.mozilla.fennec_$USER -d <url param> --es args "<params>"
        #
        app = "%s/.App" % build_obj.substs['ANDROID_PACKAGE_NAME']
        cmd = ['am', 'start', '-a', 'android.activity.MAIN', '-n', app]
        if params:
            for p in params:
                if urlparse.urlparse(p).scheme != "":
                    cmd.extend(['-d', p])
                    params.remove(p)
                    break
        if params:
            cmd.extend(['--es', 'args', '"%s"' % ' '.join(params)])
        _log_debug(cmd)
        output = dm.shellCheckOutput(cmd, timeout=10)
        _log_info(output)
    except DMError:
        _log_warning("unable to launch Firefox for Android")
        return 1
    return 0
    def remoteInit(self):
        if (self.remoteInitialized != None):
            return

        self.dm = DeviceManagerADB(self.config.remoteAddr, 5555)
        self.appName = self.dm.packageName
        self.appRoot = self.dm.getAppRoot(self.appName)
        self.profileBase = self.appRoot + "/files/mozilla"
        self.profiles = self.getProfiles()

        # Install a signal handler that shuts down our external programs on SIGINT
        signal.signal(signal.SIGINT, self.signal_handler)

        if (len(self.profiles) == 0):
            print "Failed to detect any valid profile, aborting..."
            return 1

        self.defaultProfile = self.profiles[0]

        if (len(self.profiles) > 1):
            print "Multiple profiles detected, using the first: " + self.defaultProfile

        # Workaround for bug 754575. Avoid using DeviceManagerADB's "removeDir" because
        # that calls "rm" on every single entry which takes a lot of additional time.
        print "Purging possible cache leftover directories..."
        self.dm.runCmd([
            'shell', 'rm', '-r',
            self.profileBase + "/" + self.defaultProfile + "/Cache.Trash*"
        ]).communicate()

        self.remoteInitialized = True
Example #3
0
def _get_device_platform(substs):
    # PIE executables are required when SDK level >= 21 - important for gdbserver
    adb_path = _find_sdk_exe(substs, 'adb', False)
    if not adb_path:
        adb_path = 'adb'
    dm = DeviceManagerADB(autoconnect=False, adbPath=adb_path, retryLimit=1)
    sdk_level = None
    try:
        cmd = ['getprop', 'ro.build.version.sdk']
        _log_debug(cmd)
        output = dm.shellCheckOutput(cmd, timeout=10)
        if output:
            sdk_level = int(output)
    except:
        _log_warning("unable to determine Android sdk level")
    pie = ''
    if sdk_level and sdk_level >= 21:
        pie = '-pie'
    if substs['TARGET_CPU'].startswith('arm'):
        return 'arm%s' % pie
    if sdk_level and sdk_level >= 21:
        _log_warning(
            "PIE gdbserver is not yet available for x86: you may not be able to debug on this platform"
        )
    return 'x86'
Example #4
0
def grant_runtime_permissions(build_obj, app):
    """
       Grant required runtime permissions to the specified app (typically org.mozilla.fennec_$USER).
    """
    adb_path = _find_sdk_exe(build_obj.substs, 'adb', False)
    if not adb_path:
        adb_path = 'adb'
    dm = DeviceManagerADB(autoconnect=False, adbPath=adb_path, retryLimit=1)
    dm.default_timeout = 10
    try:
        sdk_level = dm.shellCheckOutput(['getprop', 'ro.build.version.sdk'])
        if sdk_level and int(sdk_level) >= 23:
            _log_info("Granting important runtime permissions to %s" % app)
            dm.shellCheckOutput([
                'pm', 'grant', app, 'android.permission.WRITE_EXTERNAL_STORAGE'
            ])
            dm.shellCheckOutput([
                'pm', 'grant', app, 'android.permission.ACCESS_FINE_LOCATION'
            ])
            dm.shellCheckOutput(
                ['pm', 'grant', app, 'android.permission.CAMERA'])
            dm.shellCheckOutput(
                ['pm', 'grant', app, 'android.permission.WRITE_CONTACTS'])
    except DMError:
        _log_warning("Unable to grant runtime permissions to %s" % app)
 def __init__(self, adb="adb", serial=None):
     self.test_results = {}
     self.test_results_file = None
     self.m = None
     self.gaia_apps = None
     self.screenshot_path = None
     self.logcat_path = None
     self.app_name = None
     self.attempt = None
     self.num_apps = None
     self.device = None
     self.serial = serial
     self.port = None
     self.run_log = logging.getLogger('marketplace-test')
     if self.serial:
         self.dm = DeviceManagerADB(adbPath=adb, deviceSerial=serial)
     else:
         self.dm = DeviceManagerADB(adbPath=adb)
Example #6
0
 def setUp(self):
     self.dm = DeviceManagerADB()
     if not os.path.exists(self.tempLocalDir):
         os.mkdir(self.tempLocalDir)
     if not os.path.exists(self.tempLocalFile):
         # Create empty file
         open(self.tempLocalFile, 'w').close()
     self.tempRemoteDir = self.dm.getTempDir()
     self.tempRemoteFile = os.path.join(
         self.tempRemoteDir, os.path.basename(self.tempLocalFile))
    def reset(self, prefFile):
        self.dm = DeviceManagerADB(self.config.remoteAddr, 5555)

        # Install a signal handler that shuts down our external programs on SIGINT
        signal.signal(signal.SIGINT, self.signal_handler)

        # Standard init stuff
        self.appName = self.dm.packageName
        self.appRoot = self.dm.getAppRoot(self.appName)
        self.profileBase = self.appRoot + "/files/mozilla"

        # Ensure no Fennec instance is running
        self.stopFennec()

        # Now try to get the old profile(s)
        self.profiles = self.getProfiles()

        for profile in self.profiles:
            self.dm.removeDir(self.profileBase + "/" + profile)

        self.dm.removeFile(self.profileBase + "/profiles.ini")

        # Start Fennec, so a new profile is created
        self.startFennec(blank=True)

        # Grant some time to create profile
        time.sleep(self.config.runTimeout * 2)

        # Stop Fennec again
        self.stopFennec()

        # Now try to get the profile(s) again
        self.profiles = self.getProfiles()

        if (len(self.profiles) == 0):
            print "Failed to detect any valid profile, aborting..."
            return 1

        self.defaultProfile = self.profiles[0]

        if (len(self.profiles) > 1):
            print "Multiple profiles detected, using the first: " + self.defaultProfile

        # Push prefs.js to profile
        self.dm.pushFile(
            prefFile,
            self.profileBase + "/" + self.defaultProfile + "/prefs.js")

        # Try to install addon if requested by configuration
        if self.config.addon != None:
            self.ensureExtensionInstalled(self.config.addon)

        print "Successfully resetted profile."
Example #8
0
 def __init__(self, avd_type='4.3', verbose=False, substs=None, device_serial=None):
     global verbose_logging
     self.emulator_log = None
     self.emulator_path = 'emulator'
     verbose_logging = verbose
     self.substs = substs
     self.avd_type = self._get_avd_type(avd_type)
     self.avd_info = AVD_DICT[self.avd_type]
     adb_path = _find_sdk_exe(substs, 'adb', False)
     if not adb_path:
         adb_path = 'adb'
     self.dm = DeviceManagerADB(autoconnect=False, adbPath=adb_path, retryLimit=1,
         deviceSerial=device_serial)
     self.dm.default_timeout = 10
     _log_debug("Emulator created with type %s" % self.avd_type)
def check_marionette_exists(adb="adb"):
    dm = DeviceManagerADB(adbPath=adb)
    if dm.dirExists(INSTALL_DIR):
        return True
    else:
        dm.forward("tcp:2828", "tcp:2828")
        try:
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.connect(('localhost', 2828))
            data = sock.recv(16)
            sock.close()
            if 'root' in data:
                return True
        except socket.error:
            return False
    return False
Example #10
0
 def verify_device(self, adb_path, device):
     """
        Check that the specified device is available and rooted.
     """
     try:
         dm = DeviceManagerADB(adbPath=adb_path,
                               retryLimit=1,
                               deviceSerial=device)
         if dm._haveSu or dm._haveRootShell:
             return True
     except:
         self.build_obj.log(logging.WARN, "autophone", {},
                            "Unable to verify root on device.")
         if self.verbose:
             self.build_obj.log(logging.ERROR, "autophone", {},
                                str(sys.exc_info()[0]))
     return False
Example #11
0
 def test_run_adb_as_root_parameter(self):
     dm = DeviceManagerADB()
     self.assertTrue(dm.processInfo("adbd")[2] != "root")
     dm = DeviceManagerADB(runAdbAsRoot=True)
     self.assertTrue(dm.processInfo("adbd")[2] == "root")
def uninstall(adb="adb"):
    dm = DeviceManagerADB(adbPath=adb)
    dm.remount()
    if dm.dirExists(INSTALL_DIR):
        dm.removeDir(INSTALL_DIR)
Example #13
0
def run_remote_reftests(parser, options):
    auto = B2GRemoteAutomation(None, "fennec", context_chrome=True)

    # create our Marionette instance
    kwargs = {}
    if options.emulator:
        kwargs['emulator'] = options.emulator
        auto.setEmulator(True)
        if options.noWindow:
            kwargs['noWindow'] = True
        if options.geckoPath:
            kwargs['gecko_path'] = options.geckoPath
        if options.logdir:
            kwargs['logdir'] = options.logdir
        if options.busybox:
            kwargs['busybox'] = options.busybox
        if options.symbolsPath:
            kwargs['symbols_path'] = options.symbolsPath
    if options.emulator_res:
        kwargs['emulator_res'] = options.emulator_res
    if options.b2gPath:
        kwargs['homedir'] = options.b2gPath
    if options.marionette:
        host,port = options.marionette.split(':')
        kwargs['host'] = host
        kwargs['port'] = int(port)
    if options.adb_path:
        kwargs['adb_path'] = options.adb_path
    marionette = Marionette(**kwargs)
    auto.marionette = marionette

    if options.emulator:
        dm = marionette.emulator.dm
    else:
        # create the DeviceManager
        kwargs = {'adbPath': options.adb_path,
                  'deviceRoot': options.remoteTestRoot}
        if options.deviceIP:
            kwargs.update({'host': options.deviceIP,
                           'port': options.devicePort})
        dm = DeviceManagerADB(**kwargs)
    auto.setDeviceManager(dm)

    parser.validate_remote(options, auto)

    # TODO fix exception
    if not options.ignoreWindowSize:
        parts = dm.getInfo('screen')['screen'][0].split()
        width = int(parts[0].split(':')[1])
        height = int(parts[1].split(':')[1])
        if (width < 1366 or height < 1050):
            print "ERROR: Invalid screen resolution %sx%s, please adjust to 1366x1050 or higher" % (width, height)
            return 1

    auto.setProduct("b2g")
    auto.test_script = os.path.join(here, 'b2g_start_script.js')
    auto.test_script_args = [options.remoteWebServer, options.httpPort]
    auto.logFinish = "REFTEST TEST-START | Shutdown"

    reftest = B2GRemoteReftest(auto, dm, options, here)
    parser.validate(options, reftest)

    logParent = os.path.dirname(options.remoteLogFile)
    dm.mkDir(logParent);
    auto.setRemoteLog(options.remoteLogFile)
    auto.setServerInfo(options.webServer, options.httpPort, options.sslPort)

    # Hack in a symbolic link for jsreftest
    os.system("ln -s %s %s" % (os.path.join('..', 'jsreftest'), os.path.join(here, 'jsreftest')))


    # Start the webserver
    retVal = 1
    try:
        retVal = reftest.startWebServer(options)
        if retVal:
            return retVal
        procName = options.app.split('/')[-1]
        if (dm.processExist(procName)):
            dm.killProcess(procName)

        retVal = reftest.runTests(options.tests, options)
    except:
        print "Automation Error: Exception caught while running tests"
        traceback.print_exc()
        reftest.stopWebServer(options)
        try:
            reftest.cleanup(None)
        except:
            pass
        return 1

    reftest.stopWebServer(options)
    return retVal
Example #14
0
def run_remote_mochitests(parser, options):
    # create our Marionette instance
    kwargs = {}
    if options.emulator:
        kwargs['emulator'] = options.emulator
        if options.noWindow:
            kwargs['noWindow'] = True
        if options.geckoPath:
            kwargs['gecko_path'] = options.geckoPath
        if options.logcat_dir:
            kwargs['logcat_dir'] = options.logcat_dir
        if options.busybox:
            kwargs['busybox'] = options.busybox
        if options.symbolsPath:
            kwargs['symbols_path'] = options.symbolsPath
    # needless to say sdcard is only valid if using an emulator
    if options.sdcard:
        kwargs['sdcard'] = options.sdcard
    if options.b2gPath:
        kwargs['homedir'] = options.b2gPath
    if options.marionette:
        host, port = options.marionette.split(':')
        kwargs['host'] = host
        kwargs['port'] = int(port)

    marionette = Marionette.getMarionetteOrExit(**kwargs)

    if options.emulator:
        dm = marionette.emulator.dm
    else:
        # create the DeviceManager
        kwargs = {'adbPath': options.adbPath,
                  'deviceRoot': options.remoteTestRoot}
        if options.deviceIP:
            kwargs.update({'host': options.deviceIP,
                           'port': options.devicePort})
        dm = DeviceManagerADB(**kwargs)

    options = parser.verifyRemoteOptions(options)
    if (options == None):
        print "ERROR: Invalid options specified, use --help for a list of valid options"
        sys.exit(1)

    mochitest = B2GDeviceMochitest(marionette, dm, options.profile_data_dir, options.xrePath,
                                   remote_test_root=options.remoteTestRoot,
                                   remote_log_file=options.remoteLogFile)

    options = parser.verifyOptions(options, mochitest)
    if (options == None):
        sys.exit(1)

    retVal = 1
    try:
        mochitest.cleanup(None, options)
        retVal = mochitest.run_tests(options)
    except:
        print "Automation Error: Exception caught while running tests"
        traceback.print_exc()
        mochitest.stopWebServer(options)
        mochitest.stopWebSocketServer(options)
        try:
            mochitest.cleanup(None, options)
        except:
            pass
        retVal = 1

    sys.exit(retVal)
Example #15
0
 def dm(self):
     if not self._dm:
         from mozdevice import DeviceManagerADB
         self._dm = DeviceManagerADB(adbPath=self.adb_path)
     return self._dm
Example #16
0
 def setUp(self):
     dm = DeviceManagerADB()
     dm.reboot(wait=True)
Example #17
0
 def test_after_reboot_adb_runs_as_root(self):
     dm = DeviceManagerADB(runAdbAsRoot=True)
     self.assertTrue(dm.processInfo("adbd")[2] == "root")
     dm.reboot(wait=True)
     self.assertTrue(dm.processInfo("adbd")[2] == "root")
Example #18
0
 def configure_devices(self):
     """
        Ensure devices.ini is set up.
     """
     keep_going = True
     device_ini = os.path.join(self.config['base-dir'], 'devices.ini')
     if os.path.exists(device_ini):
         response = raw_input(
             "Use existing device configuration at %s? (Y/n) " %
             device_ini).strip()
         if 'n' not in response.lower():
             self.build_obj.log(
                 logging.INFO, "autophone", {},
                 "Using device configuration at %s" % device_ini)
             return keep_going
     keep_going = False
     self.build_obj.log(
         logging.INFO, "autophone", {},
         "You must configure at least one Android device "
         "before running autophone.")
     response = raw_input("Configure devices now? (Y/n) ").strip()
     if response.lower().startswith('y') or response == '':
         response = raw_input(
             "Connect your rooted Android test device(s) with usb and press Enter "
         )
         adb_path = 'adb'
         try:
             if os.path.exists(self.build_obj.substs["ADB"]):
                 adb_path = self.build_obj.substs["ADB"]
         except:
             if self.verbose:
                 self.build_obj.log(logging.ERROR, "autophone", {},
                                    str(sys.exc_info()[0]))
             # No build environment?
             try:
                 adb_path = which.which('adb')
             except which.WhichError:
                 adb_path = raw_input(
                     "adb not found. Enter path to adb: ").strip()
         if self.verbose:
             print("Using adb at %s" % adb_path)
         dm = DeviceManagerADB(autoconnect=False,
                               adbPath=adb_path,
                               retryLimit=1)
         device_index = 1
         try:
             with open(os.path.join(self.config['base-dir'], 'devices.ini'),
                       'w') as f:
                 for device in dm.devices():
                     serial = device[0]
                     if self.verify_device(adb_path, serial):
                         f.write("[device-%d]\nserialno=%s\n" %
                                 (device_index, serial))
                         device_index += 1
                         self.build_obj.log(
                             logging.INFO, "autophone", {},
                             "Added '%s' to device configuration." % serial)
                         keep_going = True
                     else:
                         self.build_obj.log(
                             logging.WARNING, "autophone", {},
                             "Device '%s' is not rooted - skipping" %
                             serial)
         except:
             self.build_obj.log(
                 logging.ERROR, "autophone", {},
                 "Failed to get list of connected Android devices.")
             if self.verbose:
                 self.build_obj.log(logging.ERROR, "autophone", {},
                                    str(sys.exc_info()[0]))
             keep_going = False
         if device_index <= 1:
             self.build_obj.log(
                 logging.ERROR, "autophone", {},
                 "No devices configured! (Can you see your rooted test device(s)"
                 " in 'adb devices'?")
             keep_going = False
         if keep_going:
             self.config['devices-configured'] = True
     return keep_going
Example #19
0
 def tearDown(self):
     dm = DeviceManagerADB()
     dm.reboot()
Example #20
0
def run_remote_reftests(parser, options, args):
    auto = B2GRemoteAutomation(None, "fennec", context_chrome=True)

    # create our Marionette instance
    kwargs = {}
    if options.emulator:
        kwargs['emulator'] = options.emulator
        auto.setEmulator(True)
        if options.noWindow:
            kwargs['noWindow'] = True
        if options.geckoPath:
            kwargs['gecko_path'] = options.geckoPath
        if options.logdir:
            kwargs['logdir'] = options.logdir
        if options.busybox:
            kwargs['busybox'] = options.busybox
        if options.symbolsPath:
            kwargs['symbols_path'] = options.symbolsPath
    if options.emulator_res:
        kwargs['emulator_res'] = options.emulator_res
    if options.b2gPath:
        kwargs['homedir'] = options.b2gPath
    if options.marionette:
        host, port = options.marionette.split(':')
        kwargs['host'] = host
        kwargs['port'] = int(port)
    if options.adb_path:
        kwargs['adb_path'] = options.adb_path
    marionette = Marionette(**kwargs)
    auto.marionette = marionette

    if options.emulator:
        dm = marionette.emulator.dm
    else:
        # create the DeviceManager
        kwargs = {
            'adbPath': options.adb_path,
            'deviceRoot': options.remoteTestRoot
        }
        if options.deviceIP:
            kwargs.update({
                'host': options.deviceIP,
                'port': options.devicePort
            })
        dm = DeviceManagerADB(**kwargs)
    auto.setDeviceManager(dm)

    options = parser.verifyRemoteOptions(options, auto)

    if (options == None):
        print "ERROR: Invalid options specified, use --help for a list of valid options"
        sys.exit(1)

    # TODO fix exception
    if not options.ignoreWindowSize:
        parts = dm.getInfo('screen')['screen'][0].split()
        width = int(parts[0].split(':')[1])
        height = int(parts[1].split(':')[1])
        if (width < 1366 or height < 1050):
            print "ERROR: Invalid screen resolution %sx%s, please adjust to 1366x1050 or higher" % (
                width, height)
            return 1

    auto.setProduct("b2g")
    auto.test_script = os.path.join(here, 'b2g_start_script.js')
    auto.test_script_args = [options.remoteWebServer, options.httpPort]
    auto.logFinish = "REFTEST TEST-START | Shutdown"

    reftest = B2GRemoteReftest(auto, dm, options, here)
    options = parser.verifyCommonOptions(options, reftest)

    logParent = os.path.dirname(options.remoteLogFile)
    dm.mkDir(logParent)
    auto.setRemoteLog(options.remoteLogFile)
    auto.setServerInfo(options.webServer, options.httpPort, options.sslPort)

    # Hack in a symbolic link for jsreftest
    os.system(
        "ln -s %s %s" %
        (os.path.join('..', 'jsreftest'), os.path.join(here, 'jsreftest')))

    # Dynamically build the reftest URL if possible, beware that args[0] should exist 'inside' the webroot
    manifest = args[0]
    if os.path.exists(os.path.join(here, args[0])):
        manifest = "http://%s:%s/%s" % (options.remoteWebServer,
                                        options.httpPort, args[0])
    elif os.path.exists(args[0]):
        manifestPath = os.path.abspath(args[0]).split(here)[1].strip('/')
        manifest = "http://%s:%s/%s" % (options.remoteWebServer,
                                        options.httpPort, manifestPath)
    else:
        print "ERROR: Could not find test manifest '%s'" % manifest
        return 1

    # Start the webserver
    retVal = 1
    try:
        retVal = reftest.startWebServer(options)
        if retVal:
            return retVal
        procName = options.app.split('/')[-1]
        if (dm.processExist(procName)):
            dm.killProcess(procName)

        cmdlineArgs = ["-reftest", manifest]
        if getattr(options, 'bootstrap', False):
            cmdlineArgs = []

        retVal = reftest.runTests(manifest, options, cmdlineArgs)
    except:
        print "Automation Error: Exception caught while running tests"
        traceback.print_exc()
        reftest.stopWebServer(options)
        try:
            reftest.cleanup(None)
        except:
            pass
        return 1

    reftest.stopWebServer(options)
    return retVal
Example #21
0
def run_remote_mochitests(automation, parser, options):
    # create our Marionette instance
    kwargs = {}
    if options.emulator:
        kwargs['emulator'] = options.emulator
        automation.setEmulator(True)
        if options.noWindow:
            kwargs['noWindow'] = True
        if options.geckoPath:
            kwargs['gecko_path'] = options.geckoPath
        if options.logcat_dir:
            kwargs['logcat_dir'] = options.logcat_dir
        if options.busybox:
            kwargs['busybox'] = options.busybox
        if options.symbolsPath:
            kwargs['symbols_path'] = options.symbolsPath
    # needless to say sdcard is only valid if using an emulator
    if options.sdcard:
        kwargs['sdcard'] = options.sdcard
    if options.b2gPath:
        kwargs['homedir'] = options.b2gPath
    if options.marionette:
        host, port = options.marionette.split(':')
        kwargs['host'] = host
        kwargs['port'] = int(port)

    marionette = Marionette.getMarionetteOrExit(**kwargs)

    automation.marionette = marionette

    # create the DeviceManager
    kwargs = {'adbPath': options.adbPath, 'deviceRoot': options.remoteTestRoot}
    if options.deviceIP:
        kwargs.update({'host': options.deviceIP, 'port': options.devicePort})
    dm = DeviceManagerADB(**kwargs)
    automation.setDeviceManager(dm)
    options = parser.verifyRemoteOptions(options, automation)
    if (options == None):
        print "ERROR: Invalid options specified, use --help for a list of valid options"
        sys.exit(1)

    automation.setProduct("b2g")

    mochitest = B2GDeviceMochitest(automation, dm, options)

    options = parser.verifyOptions(options, mochitest)
    if (options == None):
        sys.exit(1)

    logParent = os.path.dirname(options.remoteLogFile)
    dm.mkDir(logParent)
    automation.setRemoteLog(options.remoteLogFile)
    automation.setServerInfo(options.webServer, options.httpPort,
                             options.sslPort)
    retVal = 1
    try:
        mochitest.cleanup(None, options)
        retVal = mochitest.runTests(options)
    except:
        print "Automation Error: Exception caught while running tests"
        traceback.print_exc()
        mochitest.stopWebServer(options)
        mochitest.stopWebSocketServer(options)
        try:
            mochitest.cleanup(None, options)
        except:
            pass
        retVal = 1

    sys.exit(retVal)
Example #22
0
 def dm(self):
     if not self._dm:
         self._dm = DeviceManagerADB(adbPath=self.adb_path)
     return self._dm
Example #23
0
 def dm(self):
     if not self._dm:
         self._dm = DeviceManagerADB(adbPath=self.adb,
                                     autoconnect=False,
                                     deviceRoot=self.remote_test_root)
     return self._dm
Example #24
0
                      root=True)
        output = str(out.getvalue()).rstrip().splitlines()
        out.close()
        self.assertEquals(output, ['Mozilla', '/'])

    def test_port_forwarding(self):
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.bind(("", 0))
        port = s.getsockname()[1]
        s.close()
        # If successful then no exception is raised
        self.dm.forward("tcp:%s" % port, "tcp:2828")

    def test_port_forwarding_error(self):
        self.assertRaises(DMError, self.dm.forward, "", "")


if __name__ == '__main__':
    dm = DeviceManagerADB()
    if not dm.devices():
        print "There are no connected adb devices"
        sys.exit(1)

    if find_mount_permissions(dm, "/system") == "rw":
        print "We've found out that /system is mounted as 'rw'. This is because the command " \
            "'adb remount' has been run before running this test case. Please reboot the device " \
            "and try again."
        sys.exit(1)

    unittest.main()