コード例 #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/org.mozilla.gecko.BrowserApp" % 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
コード例 #2
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
コード例 #4
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'
コード例 #5
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."
コード例 #7
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)
コード例 #8
0
ファイル: adbfuzz.py プロジェクト: 0xr0ot/ADBFuzz
  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
コード例 #9
0
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
コード例 #10
0
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
コード例 #11
0
 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)
コード例 #12
0
 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)
コード例 #13
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))
コード例 #14
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
    return 'x86%s' % pie
コード例 #15
0
ファイル: android_device.py プロジェクト: nwgh/gecko-dev
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
    return "x86%s" % pie
コード例 #16
0
class DeviceManagerADBTestCase(unittest.TestCase):
    tempLocalDir = "tempDir"
    tempLocalFile = os.path.join(tempLocalDir, "tempfile.txt")
    tempRemoteDir = None
    tempRemoteFile = None

    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 tearDown(self):
        os.remove(self.tempLocalFile)
        os.rmdir(self.tempLocalDir)
        if self.dm.dirExists(self.tempRemoteDir):
            self.dm.removeDir(self.tempRemoteDir)
コード例 #17
0
class DeviceManagerADBTestCase(unittest.TestCase):
    tempLocalDir = "tempDir"
    tempLocalFile = os.path.join(tempLocalDir, "tempfile.txt")
    tempRemoteDir = None
    tempRemoteFile = None

    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 tearDown(self):
        os.remove(self.tempLocalFile)
        os.rmdir(self.tempLocalDir)
        if self.dm.dirExists(self.tempRemoteDir):
            self.dm.removeDir(self.tempRemoteDir)
コード例 #18
0
 def __init__(self, avd_type="4.3", verbose=False, substs=None):
     self.emulator_log = None
     self.emulator_path = "emulator"
     self.verbose = verbose
     self.substs = substs
     self.avd_type = self._get_avd_type(avd_type)
     self.avd_info = AVD_DICT[self.avd_type]
     adb_path = self._find_sdk_exe("adb", False)
     if not adb_path:
         adb_path = "adb"
     self.dm = DeviceManagerADB(autoconnect=False, adbPath=adb_path, retryLimit=1)
     self.dm.default_timeout = 10
     self._log_debug("Emulator created with type %s" % self.avd_type)
コード例 #19
0
ファイル: adbfuzz.py プロジェクト: 0xr0ot/ADBFuzz
  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."
コード例 #20
0
ファイル: android_device.py プロジェクト: nwgh/gecko-dev
 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)
コード例 #21
0
ファイル: android_device.py プロジェクト: DINKIN/Waterfox
 def __init__(self, avd_type='4.3', verbose=False, substs=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 = self._find_sdk_exe('adb', False)
     if not adb_path:
         adb_path = 'adb'
     self.dm = DeviceManagerADB(autoconnect=False, adbPath=adb_path, retryLimit=1)
     self.dm.default_timeout = 10
     _log_debug("Emulator created with type %s" % self.avd_type)
コード例 #22
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
コード例 #23
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]
     self.gpu = True
     self.restarted = False
     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("Running on %s" % platform.platform())
     _log_debug("Emulator created with type %s" % self.avd_type)
コード例 #24
0
class DeviceManagerADBTestCase(unittest.TestCase):
    tempLocalDir = "tempDir"
    tempLocalFile = os.path.join(tempLocalDir, "tempfile.txt")
    tempRemoteDir = None
    tempRemoteFile = None
    tempRemoteSystemFile = None

    def setUp(self):
        self.assertTrue(find_mount_permissions(self.dm, "/system"), "ro")

        self.assertTrue(os.path.exists(self.tempLocalDir))
        self.assertTrue(os.path.exists(self.tempLocalFile))

        if self.dm.fileExists(self.tempRemoteFile):
            self.dm.removeFile(self.tempRemoteFile)
        self.assertFalse(self.dm.fileExists(self.tempRemoteFile))

        if self.dm.fileExists(self.tempRemoteSystemFile):
            self.dm.removeFile(self.tempRemoteSystemFile)

        self.assertTrue(self.dm.dirExists(self.tempRemoteDir))

    @classmethod
    def setUpClass(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))
        self.tempRemoteSystemFile = \
            os.path.join("/system", os.path.basename(self.tempLocalFile))

    @classmethod
    def tearDownClass(self):
        os.remove(self.tempLocalFile)
        os.rmdir(self.tempLocalDir)
        if self.dm.dirExists(self.tempRemoteDir):
            # self.tempRemoteFile will get deleted with it
            self.dm.removeDir(self.tempRemoteDir)
        if self.dm.fileExists(self.tempRemoteSystemFile):
            self.dm.removeFile(self.tempRemoteSystemFile)
コード例 #25
0
class DeviceManagerADBTestCase(unittest.TestCase):
    tempLocalDir = "tempDir"
    tempLocalFile = os.path.join(tempLocalDir, "tempfile.txt")
    tempRemoteDir = None
    tempRemoteFile = None
    tempRemoteSystemFile = None

    def setUp(self):
        self.assertTrue(find_mount_permissions(self.dm, "/system"), "ro")

        self.assertTrue(os.path.exists(self.tempLocalDir))
        self.assertTrue(os.path.exists(self.tempLocalFile))

        if self.dm.fileExists(self.tempRemoteFile):
            self.dm.removeFile(self.tempRemoteFile)
        self.assertFalse(self.dm.fileExists(self.tempRemoteFile))

        if self.dm.fileExists(self.tempRemoteSystemFile):
            self.dm.removeFile(self.tempRemoteSystemFile)

        self.assertTrue(self.dm.dirExists(self.tempRemoteDir))

    @classmethod
    def setUpClass(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))
        self.tempRemoteSystemFile = \
            os.path.join("/system", os.path.basename(self.tempLocalFile))

    @classmethod
    def tearDownClass(self):
        os.remove(self.tempLocalFile)
        os.rmdir(self.tempLocalDir)
        if self.dm.dirExists(self.tempRemoteDir):
            # self.tempRemoteFile will get deleted with it
            self.dm.removeDir(self.tempRemoteDir)
        if self.dm.fileExists(self.tempRemoteSystemFile):
            self.dm.removeFile(self.tempRemoteSystemFile)
コード例 #26
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 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")

    def tearDown(self):
        dm = DeviceManagerADB()
        dm.reboot()


if __name__ == "__main__":
    dm = DeviceManagerADB()
    if not dm.devices():
        print "There are no connected adb devices"
        sys.exit(1)
    else:
        if not (int(dm._runCmd(["shell", "getprop", "ro.secure"]).output[0]) and
                int(dm._runCmd(["shell", "getprop", "ro.debuggable"]).output[0])):
            print "This test case is meant for devices with devices that start " \
                "adbd as non-root and allows for adbd to be restarted as root."
            sys.exit(1)

    unittest.main()
コード例 #27
0
 def setUp(self):
     dm = DeviceManagerADB()
     dm.reboot(wait=True)
コード例 #28
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")
コード例 #29
0
class AndroidEmulator(object):

    """
        Support running the Android emulator with an AVD from Mozilla
        test automation.

        Example usage:
            emulator = AndroidEmulator()
            if not emulator.is_running() and emulator.is_available():
                if not emulator.check_avd():
                    warn("this may take a while...")
                    emulator.update_avd()
                emulator.start()
                emulator.wait_for_start()
                emulator.wait()
    """

    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]
        self.gpu = True
        self.restarted = False
        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("Running on %s" % platform.platform())
        _log_debug("Emulator created with type %s" % self.avd_type)

    def __del__(self):
        if self.emulator_log:
            self.emulator_log.close()

    def is_running(self):
        """
           Returns True if the Android emulator is running.
        """
        for proc in psutil.process_iter():
            name = proc.name()
            # On some platforms, "emulator" may start an emulator with
            # process name "emulator64-arm" or similar.
            if name and name.startswith('emulator'):
                return True
        return False

    def is_available(self):
        """
           Returns True if an emulator executable is found.
        """
        found = False
        emulator_path = _find_sdk_exe(self.substs, 'emulator', True)
        if emulator_path:
            self.emulator_path = emulator_path
            found = True
        return found

    def check_avd(self, force=False):
        """
           Determine if the AVD is already installed locally.
           (This is usually used to determine if update_avd() is likely
           to require a download; it is a convenient way of determining
           whether a 'this may take a while' warning is warranted.)

           Returns True if the AVD is installed.
        """
        avd = os.path.join(
            EMULATOR_HOME_DIR, 'avd', self.avd_info.name + '.avd')
        if force and os.path.exists(avd):
            shutil.rmtree(avd)
        if os.path.exists(avd):
            _log_debug("AVD found at %s" % avd)
            return True
        return False

    def update_avd(self, force=False):
        """
           If required, update the AVD via tooltool.

           If the AVD directory is not found, or "force" is requested,
           download the tooltool manifest associated with the AVD and then
           invoke tooltool.py on the manifest. tooltool.py will download the
           required archive (unless already present in the local tooltool
           cache) and install the AVD.
        """
        avd = os.path.join(
            EMULATOR_HOME_DIR, 'avd', self.avd_info.name + '.avd')
        ini_file = os.path.join(
            EMULATOR_HOME_DIR, 'avd', self.avd_info.name + '.ini')
        if force and os.path.exists(avd):
            shutil.rmtree(avd)
        if not os.path.exists(avd):
            if os.path.exists(ini_file):
                os.remove(ini_file)
            path = self.avd_info.tooltool_manifest
            _get_tooltool_manifest(self.substs, path, EMULATOR_HOME_DIR, 'releng.manifest')
            _tooltool_fetch()
            self._update_avd_paths()

    def start(self):
        """
           Launch the emulator.
        """
        if os.path.exists(EMULATOR_AUTH_FILE):
            os.remove(EMULATOR_AUTH_FILE)
            _log_debug("deleted %s" % EMULATOR_AUTH_FILE)
        # create an empty auth file to disable emulator authentication
        auth_file = open(EMULATOR_AUTH_FILE, 'w')
        auth_file.close()

        def outputHandler(line):
            self.emulator_log.write("<%s>\n" % line)
            if "Invalid value for -gpu" in line or "Invalid GPU mode" in line:
                self.gpu = False
        env = os.environ
        env['ANDROID_AVD_HOME'] = os.path.join(EMULATOR_HOME_DIR, "avd")
        command = [self.emulator_path, "-avd",
                   self.avd_info.name, "-port", "5554"]
        if self.gpu:
            command += ['-gpu', 'swiftshader']
        if self.avd_info.extra_args:
            # -enable-kvm option is not valid on OSX
            if _get_host_platform() == 'macosx64' and '-enable-kvm' in self.avd_info.extra_args:
                self.avd_info.extra_args.remove('-enable-kvm')
            command += self.avd_info.extra_args
        log_path = os.path.join(EMULATOR_HOME_DIR, 'emulator.log')
        self.emulator_log = open(log_path, 'w')
        _log_debug("Starting the emulator with this command: %s" %
                   ' '.join(command))
        _log_debug("Emulator output will be written to '%s'" %
                   log_path)
        self.proc = ProcessHandler(
            command, storeOutput=False, processOutputLine=outputHandler,
            env=env)
        self.proc.run()
        _log_debug("Emulator started with pid %d" %
                   int(self.proc.proc.pid))

    def wait_for_start(self):
        """
           Verify that the emulator is running, the emulator device is visible
           to adb, and Android has booted.
        """
        if not self.proc:
            _log_warning("Emulator not started!")
            return False
        if self.check_completed():
            return False
        _log_debug("Waiting for device status...")
        while(('emulator-5554', 'device') not in self.dm.devices()):
            time.sleep(10)
            if self.check_completed():
                return False
        _log_debug("Device status verified.")

        _log_debug("Checking that Android has booted...")
        complete = False
        while(not complete):
            output = ''
            try:
                output = self.dm.shellCheckOutput(
                    ['getprop', 'sys.boot_completed'], timeout=5)
            except DMError:
                # adb not yet responding...keep trying
                pass
            if output.strip() == '1':
                complete = True
            else:
                time.sleep(10)
                if self.check_completed():
                    return False
        _log_debug("Android boot status verified.")

        if not self._verify_emulator():
            return False
        if self.avd_info.x86:
            _log_info("Running the x86 emulator; be sure to install an x86 APK!")
        else:
            _log_info("Running the arm emulator; be sure to install an arm APK!")
        return True

    def check_completed(self):
        if self.proc.proc.poll() is not None:
            if not self.gpu and not self.restarted:
                _log_warning("Emulator failed to start. Your emulator may be out of date.")
                _log_warning("Trying to restart the emulator without -gpu argument.")
                self.restarted = True
                self.start()
                return False
            _log_warning("Emulator has already completed!")
            log_path = os.path.join(EMULATOR_HOME_DIR, 'emulator.log')
            _log_warning("See log at %s and/or use --verbose for more information." % log_path)
            return True
        return False

    def wait(self):
        """
           Wait for the emulator to close. If interrupted, close the emulator.
        """
        try:
            self.proc.wait()
        except:
            if self.proc.poll() is None:
                self.cleanup()
        return self.proc.poll()

    def cleanup(self):
        """
           Close the emulator.
        """
        self.proc.kill(signal.SIGTERM)

    def get_avd_description(self):
        """
           Return the human-friendly description of this AVD.
        """
        return self.avd_info.description

    def _update_avd_paths(self):
        avd_path = os.path.join(EMULATOR_HOME_DIR, "avd")
        ini_file = os.path.join(avd_path, "test-1.ini")
        ini_file_new = os.path.join(avd_path, self.avd_info.name + ".ini")
        os.rename(ini_file, ini_file_new)
        avd_dir = os.path.join(avd_path, "test-1.avd")
        avd_dir_new = os.path.join(avd_path, self.avd_info.name + ".avd")
        os.rename(avd_dir, avd_dir_new)
        self._replace_ini_contents(ini_file_new)

    def _replace_ini_contents(self, path):
        with open(path, "r") as f:
            lines = f.readlines()
        with open(path, "w") as f:
            for line in lines:
                if line.startswith('path='):
                    avd_path = os.path.join(EMULATOR_HOME_DIR, "avd")
                    f.write('path=%s/%s.avd\n' %
                            (avd_path, self.avd_info.name))
                elif line.startswith('path.rel='):
                    f.write('path.rel=avd/%s.avd\n' % self.avd_info.name)
                else:
                    f.write(line)

    def _telnet_cmd(self, telnet, command):
        _log_debug(">>> " + command)
        telnet.write('%s\n' % command)
        result = telnet.read_until('OK', 10)
        _log_debug("<<< " + result)
        return result

    def _verify_emulator(self):
        telnet_ok = False
        tn = None
        while(not telnet_ok):
            try:
                tn = telnetlib.Telnet('localhost', 5554, 10)
                if tn is not None:
                    tn.read_until('OK', 10)
                    self._telnet_cmd(tn, 'avd status')
                    self._telnet_cmd(tn, 'redir list')
                    self._telnet_cmd(tn, 'network status')
                    tn.write('quit\n')
                    tn.read_all()
                    telnet_ok = True
                else:
                    _log_warning("Unable to connect to port 5554")
            except:
                _log_warning("Trying again after unexpected exception")
            finally:
                if tn is not None:
                    tn.close()
            if not telnet_ok:
                time.sleep(10)
                if self.proc.proc.poll() is not None:
                    _log_warning("Emulator has already completed!")
                    return False
        return telnet_ok

    def _get_avd_type(self, requested):
        if requested in AVD_DICT.keys():
            return requested
        if self.substs:
            if not self.substs['TARGET_CPU'].startswith('arm'):
                return 'x86'
        return '4.3'
コード例 #30
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")
コード例 #31
0
ファイル: runreftestb2g.py プロジェクト: msliu/gecko-dev
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
コード例 #32
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")
コード例 #33
0
ファイル: b2gmixin.py プロジェクト: sinemetu1/mozbase
 def __init__(self, **kwargs):
     DeviceManagerADB.__init__(self, **kwargs)
     B2GMixin.__init__(self, **kwargs)
コード例 #34
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()
class ADBFuzz:
    def __init__(self, cfgFile):
        self.config = ADBFuzzConfig(cfgFile)

        self.HTTPProcess = None
        self.logProcesses = []
        self.logThreads = []
        self.remoteInitialized = None

        self.triager = Triager(self.config)

        # Seed RNG with localtime
        random.seed()

    def deploy(self, packageFile, 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)

        self.dm.updateApp(packageFile)

        # 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()

        # Start Fennec, so a profile is created if this is the first install
        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)
        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 deployed package."

    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."

    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

    def signal_handler(self, signal, frame):
        self.cleanupProcesses()
        sys.exit(0)

    def cleanupProcesses(self):
        self.stopFennec()
        if (self.HTTPProcess != None):
            try:
                self.HTTPProcess.terminate()
            except:
                pass
        if (self.logProcesses != None):
            try:
                self.stopLoggers()
            except:
                pass

    def loopFuzz(self, maxIterations=None):
        try:
            iterations = 0
            while (maxIterations == None or maxIterations >= iterations):
                self.runFuzzer()
                iterations += 1
        except:
            self.cleanupProcesses()
            raise

    def runFuzzer(self):
        self.remoteInit()

        # Ensure Fennec isn't running
        if self.isFennecRunning():
            self.stopFennec()

        # Clean all existing minidumps
        if not self.clearMinidumps():
            raise Exception("Failed to clean existing minidumps")

        # Start our HTTP server for serving the fuzzer code
        self.HTTPProcess = self.startHTTPServer()

        # Start all loggers
        self.startLoggers()

        # Start Fennec
        self.startFennec()

        # Even though the program is already running, we should grant it
        # some extra time to load the fuzzer source and start running,
        # so it isn't directly diagnosed as hanging
        time.sleep(10)

        logSize = 0
        hangDetected = False
        forceRestart = False
        while (self.isFennecRunning() and not self.checkLoggingThreads()):
            time.sleep(self.config.runTimeout)

            if not os.path.exists(self.logFile):
                raise Exception(
                    "Logfile not present. If you are using websockets, this could indicate a network problem."
                )

            # Poor man's hang detection. Yes, this is a bad
            # idea, just for the sake of proof-of-concept
            newLogSize = os.path.getsize(self.logFile)
            if (logSize == newLogSize):
                hangDetected = True
                break
            else:
                logSize = newLogSize
                if newLogSize > self.config.maxLogSize:
                    forceRestart = True
                    break

        if hangDetected or forceRestart:
            self.stopFennec()
            self.stopLoggers()
            print "Hang detected or running too long, restarting..."
        else:
            try:
                # Fennec died or a logger found something
                checkCrashDump = True
                crashUUID = None
                minidump = None

                # If Fennec is still running, stop it now
                if self.isFennecRunning():
                    checkCrashDump = False
                    self.stopFennec()

                # Terminate our logging processes first
                self.stopLoggers()

                if checkCrashDump:
                    dumps = self.getMinidumps()
                    if (len(dumps) > 1):
                        raise Exception("Multiple dumps detected!")

                    if (len(dumps) < 1):
                        raise Exception("No crash dump detected!")

                    if not self.fetchMinidump(dumps[0]):
                        raise Exception("Failed to fetch minidump with UUID " +
                                        dumps[0])

                    crashUUID = dumps[0]

                    # Copy logfiles
                    shutil.copy2(self.syslogFile, dumps[0] + ".syslog")
                    shutil.copy2(self.logFile, dumps[0] + ".log")

                    minidump = Minidump(dumps[0] + ".dmp", self.config.libDir)
                else:
                    # We need to generate an arbitrary ID here
                    crashUUID = str(uuid.uuid4())

                    # Copy logfiles
                    shutil.copy2(self.syslogFile, crashUUID + ".syslog")
                    shutil.copy2(self.logFile, crashUUID + ".log")

                print "Crash detected. Reproduction logfile stored at: " + crashUUID + ".log"
                if checkCrashDump:
                    crashTrace = minidump.getCrashTrace()
                    crashType = minidump.getCrashType()
                    print "Crash type: " + crashType
                    print "Crash backtrace:"
                    print ""
                    print crashTrace
                else:
                    print "Crash type: Abnormal behavior (e.g. Assertion violation)"

                self.triager.process(crashUUID, minidump,
                                     crashUUID + ".syslog", crashUUID + ".log")
            except Exception, e:
                print "Error during crash processing: "
                print traceback.format_exc()

        self.HTTPProcess.terminate()
        return
コード例 #36
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
コード例 #37
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 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")

    def tearDown(self):
        dm = DeviceManagerADB()
        dm.reboot()


if __name__ == "__main__":
    dm = DeviceManagerADB()
    if not dm.devices():
        print("There are no connected adb devices")
        sys.exit(1)
    else:
        if not (int(dm._runCmd(["shell", "getprop", "ro.secure"]).output[0]) and
                int(dm._runCmd(["shell", "getprop", "ro.debuggable"]).output[0])):
            print("This test case is meant for devices with devices that start "
                  "adbd as non-root and allows for adbd to be restarted as root.")
            sys.exit(1)

    unittest.main()
コード例 #38
0
 def setUp(self):
     dm = DeviceManagerADB()
     dm.reboot(wait=True)
コード例 #39
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)
コード例 #40
0
ファイル: adbfuzz.py プロジェクト: 0xr0ot/ADBFuzz
class ADBFuzz:

  def __init__(self, cfgFile):
    self.config = ADBFuzzConfig(cfgFile)

    self.HTTPProcess = None
    self.logProcesses = []
    self.logThreads = []
    self.remoteInitialized = None

    self.triager = Triager(self.config)
    
    # Seed RNG with localtime
    random.seed()
    
  def deploy(self, packageFile, 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)
    
    self.dm.updateApp(packageFile)
    
    # 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()
    
    # Start Fennec, so a profile is created if this is the first install
    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)
    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 deployed package."
    
  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."

  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

  def signal_handler(self, signal, frame):
    self.cleanupProcesses()
    sys.exit(0)

  def cleanupProcesses(self):
    self.stopFennec()
    if (self.HTTPProcess != None):
      try:
        self.HTTPProcess.terminate()
      except:
        pass
    if (self.logProcesses != None):
      try:
        self.stopLoggers()
      except:
        pass

  def loopFuzz(self, maxIterations=None):
    try:
      iterations = 0
      while (maxIterations == None or maxIterations >= iterations):
        self.runFuzzer()
        iterations += 1
    except:
      self.cleanupProcesses()
      raise

  def runFuzzer(self):
    self.remoteInit()

    # Ensure Fennec isn't running
    if self.isFennecRunning():
      self.stopFennec()

    # Clean all existing minidumps
    if not self.clearMinidumps():
      raise Exception("Failed to clean existing minidumps")

    # Start our HTTP server for serving the fuzzer code
    self.HTTPProcess = self.startHTTPServer()

    # Start all loggers
    self.startLoggers()

    # Start Fennec
    self.startFennec()

    # Even though the program is already running, we should grant it
    # some extra time to load the fuzzer source and start running,
    # so it isn't directly diagnosed as hanging
    time.sleep(10);
    
    logSize = 0
    hangDetected = False
    forceRestart = False
    while(self.isFennecRunning() and not self.checkLoggingThreads()):
      time.sleep(self.config.runTimeout)

      if not os.path.exists(self.logFile):
        raise Exception("Logfile not present. If you are using websockets, this could indicate a network problem.")

      # Poor man's hang detection. Yes, this is a bad
      # idea, just for the sake of proof-of-concept
      newLogSize = os.path.getsize(self.logFile)
      if (logSize == newLogSize):
        hangDetected = True
        break
      else:
        logSize = newLogSize
        if newLogSize > self.config.maxLogSize:
          forceRestart = True
          break

    if hangDetected or forceRestart:
      self.stopFennec()
      self.stopLoggers()
      print "Hang detected or running too long, restarting..."
    else:
      try:
        # Fennec died or a logger found something
        checkCrashDump = True
        crashUUID = None
        minidump = None
        
        # If Fennec is still running, stop it now
        if self.isFennecRunning():
          checkCrashDump = False
          self.stopFennec()
        
        # Terminate our logging processes first
        self.stopLoggers()
        
        if checkCrashDump:
          dumps = self.getMinidumps()
          if (len(dumps) > 1):
            raise Exception("Multiple dumps detected!")
            
          if (len(dumps) < 1):
            raise Exception("No crash dump detected!")
    
          if not self.fetchMinidump(dumps[0]):
            raise Exception("Failed to fetch minidump with UUID " + dumps[0])
  
          crashUUID = dumps[0]
  
          # Copy logfiles
          shutil.copy2(self.syslogFile, dumps[0] + ".syslog")
          shutil.copy2(self.logFile, dumps[0] + ".log")
    
          minidump = Minidump(dumps[0] + ".dmp", self.config.libDir)
        else:
          # We need to generate an arbitrary ID here
          crashUUID = str(uuid.uuid4())
          
          # Copy logfiles
          shutil.copy2(self.syslogFile, crashUUID + ".syslog")
          shutil.copy2(self.logFile, crashUUID + ".log")
  
        print "Crash detected. Reproduction logfile stored at: " + crashUUID + ".log"
        if checkCrashDump:
          crashTrace = minidump.getCrashTrace()
          crashType = minidump.getCrashType()
          print "Crash type: " + crashType
          print "Crash backtrace:"
          print ""
          print crashTrace
        else:
          print "Crash type: Abnormal behavior (e.g. Assertion violation)"
  
        self.triager.process(crashUUID, minidump, crashUUID + ".syslog", crashUUID + ".log")
      except Exception, e:
        print "Error during crash processing: "
        print traceback.format_exc()

    self.HTTPProcess.terminate()
    return
コード例 #41
0
    def test_remount(self):
        self.assertEquals(self.dm.remount(), 0)

    def test_list_devices(self):
        self.assertEquals(len(list(self.dm.devices())), 1)

    def test_shell(self):
        out = StringIO()
        self.dm.shell(["echo", "$COMPANY", ";", "pwd"], out,
                env={"COMPANY":"Mozilla"}, cwd="/", timeout=4, root=True)
        output = str(out.getvalue()).rstrip().splitlines()
        out.close()
        self.assertEquals(output, ['Mozilla', '/'])

    def test_reboot(self):
        # We are not running the reboot function because it takes too long
        #self.dm.reboot(wait=True)
        pass

    def test_port_forwarding(self):
        # I don't really know how to test this properly
        self.assertEquals(self.dm.forward("tcp:2828", "tcp:2828"), 0)

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

    unittest.main()
コード例 #42
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")
コード例 #43
0
ファイル: android_device.py プロジェクト: DINKIN/Waterfox
class AndroidEmulator(object):

    """
        Support running the Android emulator with an AVD from Mozilla
        test automation.

        Example usage:
            emulator = AndroidEmulator()
            if not emulator.is_running() and emulator.is_available():
                if not emulator.check_avd():
                    warn("this may take a while...")
                    emulator.update_avd()
                emulator.start()
                emulator.wait_for_start()
                emulator.wait()
    """

    def __init__(self, avd_type='4.3', verbose=False, substs=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 = self._find_sdk_exe('adb', False)
        if not adb_path:
            adb_path = 'adb'
        self.dm = DeviceManagerADB(autoconnect=False, adbPath=adb_path, retryLimit=1)
        self.dm.default_timeout = 10
        _log_debug("Emulator created with type %s" % self.avd_type)

    def __del__(self):
        if self.emulator_log:
            self.emulator_log.close()

    def is_running(self):
        """
           Returns True if the Android emulator is running.
        """
        for proc in psutil.process_iter():
            name = proc.name()
            # On some platforms, "emulator" may start an emulator with
            # process name "emulator64-arm" or similar.
            if name and name.startswith('emulator'):
                return True
        return False

    def is_available(self):
        """
           Returns True if an emulator executable is found.
        """
        found = False
        emulator_path = self._find_sdk_exe('emulator', True)
        if emulator_path:
            self.emulator_path = emulator_path
            found = True
        return found

    def check_avd(self, force=False):
        """
           Determine if the AVD is already installed locally.
           (This is usually used to determine if update_avd() is likely
           to require a download; it is a convenient way of determining
           whether a 'this may take a while' warning is warranted.)

           Returns True if the AVD is installed.
        """
        avd = os.path.join(
            EMULATOR_HOME_DIR, 'avd', self.avd_info.name + '.avd')
        if force and os.path.exists(avd):
            shutil.rmtree(avd)
        if os.path.exists(avd):
            _log_debug("AVD found at %s" % avd)
            return True
        return False

    def update_avd(self, force=False):
        """
           If required, update the AVD via tooltool.

           If the AVD directory is not found, or "force" is requested,
           download the tooltool manifest associated with the AVD and then
           invoke tooltool.py on the manifest. tooltool.py will download the
           required archive (unless already present in the local tooltool
           cache) and install the AVD.
        """
        avd = os.path.join(
            EMULATOR_HOME_DIR, 'avd', self.avd_info.name + '.avd')
        if force and os.path.exists(avd):
            shutil.rmtree(avd)
        if not os.path.exists(avd):
            _download_file(TOOLTOOL_URL, 'tooltool.py', EMULATOR_HOME_DIR)
            url = '%s/%s' % (TRY_URL, self.avd_info.tooltool_manifest)
            _download_file(url, 'releng.manifest', EMULATOR_HOME_DIR)
            _tooltool_fetch()
            self._update_avd_paths()

    def start(self):
        """
           Launch the emulator.
        """
        def outputHandler(line):
            self.emulator_log.write("<%s>\n" % line)
        env = os.environ
        env['ANDROID_AVD_HOME'] = os.path.join(EMULATOR_HOME_DIR, "avd")
        command = [self.emulator_path, "-avd",
                   self.avd_info.name, "-port", "5554"]
        if self.avd_info.extra_args:
            command += self.avd_info.extra_args
        log_path = os.path.join(EMULATOR_HOME_DIR, 'emulator.log')
        self.emulator_log = open(log_path, 'w')
        _log_debug("Starting the emulator with this command: %s" %
                        ' '.join(command))
        _log_debug("Emulator output will be written to '%s'" %
                        log_path)
        self.proc = ProcessHandler(
            command, storeOutput=False, processOutputLine=outputHandler,
            env=env)
        self.proc.run()
        _log_debug("Emulator started with pid %d" %
                        int(self.proc.proc.pid))

    def wait_for_start(self):
        """
           Verify that the emulator is running, the emulator device is visible
           to adb, and Android has booted.
        """
        if not self.proc:
            _log_warning("Emulator not started!")
            return False
        if self.proc.proc.poll() is not None:
            _log_warning("Emulator has already completed!")
            return False
        _log_debug("Waiting for device status...")
        while(('emulator-5554', 'device') not in self.dm.devices()):
            time.sleep(10)
            if self.proc.proc.poll() is not None:
                _log_warning("Emulator has already completed!")
                return False
        _log_debug("Device status verified.")

        _log_debug("Checking that Android has booted...")
        complete = False
        while(not complete):
            output = ''
            try:
                output = self.dm.shellCheckOutput(
                    ['getprop', 'sys.boot_completed'], timeout=5)
            except DMError:
                # adb not yet responding...keep trying
                pass
            if output.strip() == '1':
                complete = True
            else:
                time.sleep(10)
                if self.proc.proc.poll() is not None:
                    _log_warning("Emulator has already completed!")
                    return False
        _log_debug("Android boot status verified.")

        if not self._verify_emulator():
            return False
        if self.avd_info.uses_sut:
            if not self._verify_sut():
                return False
        return True

    def wait(self):
        """
           Wait for the emulator to close. If interrupted, close the emulator.
        """
        try:
            self.proc.wait()
        except:
            if self.proc.poll() is None:
                self.cleanup()
        return self.proc.poll()

    def cleanup(self):
        """
           Close the emulator.
        """
        self.proc.kill(signal.SIGTERM)

    def get_avd_description(self):
        """
           Return the human-friendly description of this AVD.
        """
        return self.avd_info.description

    def _update_avd_paths(self):
        avd_path = os.path.join(EMULATOR_HOME_DIR, "avd")
        ini_file = os.path.join(avd_path, "test-1.ini")
        ini_file_new = os.path.join(avd_path, self.avd_info.name + ".ini")
        os.rename(ini_file, ini_file_new)
        avd_dir = os.path.join(avd_path, "test-1.avd")
        avd_dir_new = os.path.join(avd_path, self.avd_info.name + ".avd")
        os.rename(avd_dir, avd_dir_new)
        self._replace_ini_contents(ini_file_new)

    def _replace_ini_contents(self, path):
        with open(path, "r") as f:
            lines = f.readlines()
        with open(path, "w") as f:
            for line in lines:
                if line.startswith('path='):
                    avd_path = os.path.join(EMULATOR_HOME_DIR, "avd")
                    f.write('path=%s/%s.avd\n' %
                            (avd_path, self.avd_info.name))
                elif line.startswith('path.rel='):
                    f.write('path.rel=avd/%s.avd\n' % self.avd_info.name)
                else:
                    f.write(line)

    def _telnet_cmd(self, telnet, command):
        _log_debug(">>> " + command)
        telnet.write('%s\n' % command)
        result = telnet.read_until('OK', 10)
        _log_debug("<<< " + result)
        return result

    def _verify_emulator(self):
        telnet_ok = False
        tn = None
        while(not telnet_ok):
            try:
                tn = telnetlib.Telnet('localhost', self.avd_info.port, 10)
                if tn is not None:
                    res = tn.read_until('OK', 10)
                    self._telnet_cmd(tn, 'avd status')
                    if self.avd_info.uses_sut:
                        cmd = 'redir add tcp:%s:%s' % \
                           (str(self.avd_info.sut_port),
                            str(self.avd_info.sut_port))
                        self._telnet_cmd(tn, cmd)
                        cmd = 'redir add tcp:%s:%s' % \
                            (str(self.avd_info.sut_port2),
                             str(self.avd_info.sut_port2))
                        self._telnet_cmd(tn, cmd)
                    self._telnet_cmd(tn, 'redir list')
                    self._telnet_cmd(tn, 'network status')
                    tn.write('quit\n')
                    tn.read_all()
                    telnet_ok = True
                else:
                    _log_warning("Unable to connect to port %d" % port)
            except:
                _log_warning("Trying again after unexpected exception")
            finally:
                if tn is not None:
                    tn.close()
            if not telnet_ok:
                time.sleep(10)
                if self.proc.proc.poll() is not None:
                    _log_warning("Emulator has already completed!")
                    return False
        return telnet_ok

    def _verify_sut(self):
        sut_ok = False
        while(not sut_ok):
            try:
                tn = telnetlib.Telnet('localhost', self.avd_info.sut_port, 10)
                if tn is not None:
                    _log_debug(
                        "Connected to port %d" % self.avd_info.sut_port)
                    res = tn.read_until('$>', 10)
                    if res.find('$>') == -1:
                        _log_debug("Unexpected SUT response: %s" % res)
                    else:
                        _log_debug("SUT response: %s" % res)
                        sut_ok = True
                    tn.write('quit\n')
                    tn.read_all()
            except:
                _log_debug("Caught exception while verifying sutagent")
            finally:
                if tn is not None:
                    tn.close()
            if not sut_ok:
                time.sleep(10)
                if self.proc.proc.poll() is not None:
                    _log_warning("Emulator has already completed!")
                    return False
        return sut_ok

    def _get_avd_type(self, requested):
        if requested in AVD_DICT.keys():
            return requested
        if self.substs:
            if not self.substs['TARGET_CPU'].startswith('arm'):
                return 'x86'
            if self.substs['MOZ_ANDROID_MIN_SDK_VERSION'] == '9':
                return '2.3'
        return '4.3'

    def _find_sdk_exe(self, exe, tools):
        if tools:
            subdir = 'tools'
            var = 'ANDROID_TOOLS'
        else:
            subdir = 'platform-tools'
            var = 'ANDROID_PLATFORM_TOOLS'

        found = False

        # Can exe be found in the Android SDK?
        try:
            android_sdk_root = os.environ['ANDROID_SDK_ROOT']
            exe_path = os.path.join(
                android_sdk_root, subdir, exe)
            if os.path.exists(exe_path):
                found = True
            else:
                _log_debug(
                    "Unable to find executable at %s" % exe_path)
        except KeyError:
            _log_debug("ANDROID_SDK_ROOT not set")

        if not found and self.substs:
            # Can exe be found in ANDROID_TOOLS/ANDROID_PLATFORM_TOOLS?
            try:
                exe_path = os.path.join(
                    self.substs[var], exe)
                if os.path.exists(exe_path):
                    found = True
                else:
                    _log_debug(
                        "Unable to find executable at %s" % exe_path)
            except KeyError:
                _log_debug("%s not set" % var)

        if not found:
            # Can exe be found in the default bootstrap location?
            mozbuild_path = os.environ.get('MOZBUILD_STATE_PATH',
                os.path.expanduser(os.path.join('~', '.mozbuild')))
            exe_path = os.path.join(
                mozbuild_path, 'android-sdk-linux', subdir, exe)
            if os.path.exists(exe_path):
                found = True
            else:
                _log_debug(
                    "Unable to find executable at %s" % exe_path)

        if not found:
            # Is exe on PATH?
            exe_path = find_executable(exe)
            if exe_path:
                found = True
            else:
                _log_debug("Unable to find executable on PATH")

        if found:
            _log_debug("%s found at %s" % (exe, exe_path))
        else:
            exe_path = None
        return exe_path
コード例 #44
0
ファイル: runtestsb2g.py プロジェクト: memorais/TC2_impl
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)
コード例 #45
0
 def tearDown(self):
     dm = DeviceManagerADB()
     dm.reboot()
コード例 #46
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)
コード例 #47
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)
コード例 #48
0
class AndroidEmulator(object):

    """
        Support running the Android emulator with an AVD from Mozilla
        test automation.

        Example usage:
            emulator = AndroidEmulator()
            if not emulator.is_running() and emulator.is_available():
                if not emulator.check_avd():
                    warn("this may take a while...")
                    emulator.update_avd()
                emulator.start()
                emulator.wait_for_start()
                emulator.wait()
    """

    def __init__(self, avd_type="4.3", verbose=False, substs=None):
        self.emulator_log = None
        self.emulator_path = "emulator"
        self.verbose = verbose
        self.substs = substs
        self.avd_type = self._get_avd_type(avd_type)
        self.avd_info = AVD_DICT[self.avd_type]
        adb_path = self._find_sdk_exe("adb", False)
        if not adb_path:
            adb_path = "adb"
        self.dm = DeviceManagerADB(autoconnect=False, adbPath=adb_path, retryLimit=1)
        self.dm.default_timeout = 10
        self._log_debug("Emulator created with type %s" % self.avd_type)

    def __del__(self):
        if self.emulator_log:
            self.emulator_log.close()

    def is_running(self):
        """
           Returns True if the Android emulator is running.
        """
        for proc in psutil.process_iter():
            name = proc.name()
            # On some platforms, "emulator" may start an emulator with
            # process name "emulator64-arm" or similar.
            if name and name.startswith("emulator"):
                return True
        return False

    def is_available(self):
        """
           Returns True if an emulator executable is found.
        """
        found = False
        emulator_path = self._find_sdk_exe("emulator", True)
        if emulator_path:
            self.emulator_path = emulator_path
            found = True
        return found

    def check_avd(self, force=False):
        """
           Determine if the AVD is already installed locally.
           (This is usually used to determine if update_avd() is likely
           to require a download; it is a convenient way of determining
           whether a 'this may take a while' warning is warranted.)

           Returns True if the AVD is installed.
        """
        avd = os.path.join(EMULATOR_HOME_DIR, "avd", self.avd_info.name + ".avd")
        if force and os.path.exists(avd):
            shutil.rmtree(avd)
        if os.path.exists(avd):
            self._log_debug("AVD found at %s" % avd)
            return True
        return False

    def update_avd(self, force=False):
        """
           If required, update the AVD via tooltool.

           If the AVD directory is not found, or "force" is requested,
           download the tooltool manifest associated with the AVD and then
           invoke tooltool.py on the manifest. tooltool.py will download the
           required archive (unless already present in the local tooltool
           cache) and install the AVD.
        """
        avd = os.path.join(EMULATOR_HOME_DIR, "avd", self.avd_info.name + ".avd")
        if force and os.path.exists(avd):
            shutil.rmtree(avd)
        if not os.path.exists(avd):
            self._fetch_tooltool()
            self._fetch_tooltool_manifest()
            self._tooltool_fetch()
            self._update_avd_paths()

    def start(self):
        """
           Launch the emulator.
        """

        def outputHandler(line):
            self.emulator_log.write("<%s>\n" % line)

        env = os.environ
        env["ANDROID_AVD_HOME"] = os.path.join(EMULATOR_HOME_DIR, "avd")
        command = [self.emulator_path, "-avd", self.avd_info.name, "-port", "5554"]
        if self.avd_info.extra_args:
            command += self.avd_info.extra_args
        log_path = os.path.join(EMULATOR_HOME_DIR, "emulator.log")
        self.emulator_log = open(log_path, "w")
        self._log_debug("Starting the emulator with this command: %s" % " ".join(command))
        self._log_debug("Emulator output will be written to '%s'" % log_path)
        self.proc = ProcessHandler(command, storeOutput=False, processOutputLine=outputHandler, env=env)
        self.proc.run()
        self._log_debug("Emulator started with pid %d" % int(self.proc.proc.pid))

    def wait_for_start(self):
        """
           Verify that the emulator is running, the emulator device is visible
           to adb, and Android has booted.
        """
        if not self.proc:
            self._log_warning("Emulator not started!")
            return False
        if self.proc.proc.poll() is not None:
            self._log_warning("Emulator has already completed!")
            return False
        self._log_debug("Waiting for device status...")
        while ("emulator-5554", "device") not in self.dm.devices():
            time.sleep(10)
            if self.proc.proc.poll() is not None:
                self._log_warning("Emulator has already completed!")
                return False
        self._log_debug("Device status verified.")

        self._log_debug("Checking that Android has booted...")
        complete = False
        while not complete:
            output = ""
            try:
                output = self.dm.shellCheckOutput(["getprop", "sys.boot_completed"], timeout=5)
            except DMError:
                # adb not yet responding...keep trying
                pass
            if output.strip() == "1":
                complete = True
            else:
                time.sleep(10)
                if self.proc.proc.poll() is not None:
                    self._log_warning("Emulator has already completed!")
                    return False
        self._log_debug("Android boot status verified.")

        if not self._verify_emulator():
            return False
        if self.avd_info.uses_sut:
            if not self._verify_sut():
                return False
        return True

    def wait(self):
        """
           Wait for the emulator to close. If interrupted, close the emulator.
        """
        try:
            self.proc.wait()
        except:
            if self.proc.poll() is None:
                self.cleanup()
        return self.proc.poll()

    def cleanup(self):
        """
           Close the emulator.
        """
        self.proc.kill(signal.SIGTERM)

    def get_avd_description(self):
        """
           Return the human-friendly description of this AVD.
        """
        return self.avd_info.description

    def _log_debug(self, text):
        if self.verbose:
            print "DEBUG: %s" % text

    def _log_warning(self, text):
        print "WARNING: %s" % text

    def _fetch_tooltool(self):
        self._download_file(TOOLTOOL_URL, "tooltool.py", EMULATOR_HOME_DIR)

    def _fetch_tooltool_manifest(self):
        url = "https://hg.mozilla.org/%s/raw-file/%s/%s" % ("try", "default", self.avd_info.tooltool_manifest)
        self._download_file(url, "releng.manifest", EMULATOR_HOME_DIR)

    def _tooltool_fetch(self):
        def outputHandler(line):
            self._log_debug(line)

        command = ["python", "tooltool.py", "fetch", "-m", "releng.manifest"]
        proc = ProcessHandler(command, processOutputLine=outputHandler, storeOutput=False, cwd=EMULATOR_HOME_DIR)
        proc.run()
        try:
            proc.wait()
        except:
            if proc.poll() is None:
                proc.kill(signal.SIGTERM)

    def _update_avd_paths(self):
        avd_path = os.path.join(EMULATOR_HOME_DIR, "avd")
        ini_file = os.path.join(avd_path, "test-1.ini")
        ini_file_new = os.path.join(avd_path, self.avd_info.name + ".ini")
        os.rename(ini_file, ini_file_new)
        avd_dir = os.path.join(avd_path, "test-1.avd")
        avd_dir_new = os.path.join(avd_path, self.avd_info.name + ".avd")
        os.rename(avd_dir, avd_dir_new)
        self._replace_ini_contents(ini_file_new)

    def _download_file(self, url, filename, path):
        f = urllib2.urlopen(url)
        if not os.path.isdir(path):
            try:
                os.makedirs(path)
            except Exception, e:
                self._log_warning(str(e))
                return False
        local_file = open(os.path.join(path, filename), "wb")
        local_file.write(f.read())
        local_file.close()
        self._log_debug("Downloaded %s to %s/%s" % (url, path, filename))
        return True
コード例 #49
0
def grant_runtime_permissions(build_obj):
    """
    Grant required runtime permissions to the specified app
    (typically org.mozilla.fennec_$USER).
    """
    app = build_obj.substs['ANDROID_PACKAGE_NAME']
    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.READ_EXTERNAL_STORAGE'])
            dm.shellCheckOutput(['pm', 'grant', app, 'android.permission.ACCESS_FINE_LOCATION'])
            dm.shellCheckOutput(['pm', 'grant', app, 'android.permission.CAMERA'])
    except DMError:
        _log_warning("Unable to grant runtime permissions to %s" % app)
コード例 #50
0
 def __init__(self, **kwargs):
     DeviceManagerADB.__init__(self, **kwargs)
     B2GMixin.__init__(self, **kwargs)
コード例 #51
0
 def dm(self):
     if not self._dm:
         from mozdevice import DeviceManagerADB
         self._dm = DeviceManagerADB(adbPath=self.adb_path)
     return self._dm
コード例 #52
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
コード例 #53
0
ファイル: runreftestb2g.py プロジェクト: BrunoReX/palemoon
def main(args=sys.argv[1:]):
    auto = B2GRemoteAutomation(None, "fennec", context_chrome=True)
    parser = B2GOptions(auto)
    options, args = parser.parse_args(args)

    # 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.logcat_dir:
            kwargs['logcat_dir'] = options.logcat_dir
        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)
    marionette = Marionette.getMarionetteOrExit(**kwargs)
    auto.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)
    auto.setDeviceManager(dm)

    options = parser.verifyRemoteOptions(options)

    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(SCRIPT_DIRECTORY, 'b2g_start_script.js')
    auto.test_script_args = [options.remoteWebServer, options.httpPort]
    auto.logFinish = "REFTEST TEST-START | Shutdown"

    reftest = B2GReftest(auto, dm, options, SCRIPT_DIRECTORY)
    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)

    # 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(SCRIPT_DIRECTORY, 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(SCRIPT_DIRECTORY)[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
コード例 #54
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]

    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
コード例 #55
0
class AndroidEmulator(object):
    """
        Support running the Android emulator with an AVD from Mozilla
        test automation.

        Example usage:
            emulator = AndroidEmulator()
            if not emulator.is_running() and emulator.is_available():
                if not emulator.check_avd():
                    warn("this may take a while...")
                    emulator.update_avd()
                emulator.start()
                emulator.wait_for_start()
                emulator.wait()
    """
    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 __del__(self):
        if self.emulator_log:
            self.emulator_log.close()

    def is_running(self):
        """
           Returns True if the Android emulator is running.
        """
        for proc in psutil.process_iter():
            name = proc.name()
            # On some platforms, "emulator" may start an emulator with
            # process name "emulator64-arm" or similar.
            if name and name.startswith('emulator'):
                return True
        return False

    def is_available(self):
        """
           Returns True if an emulator executable is found.
        """
        found = False
        emulator_path = _find_sdk_exe(self.substs, 'emulator', True)
        if emulator_path:
            self.emulator_path = emulator_path
            found = True
        return found

    def check_avd(self, force=False):
        """
           Determine if the AVD is already installed locally.
           (This is usually used to determine if update_avd() is likely
           to require a download; it is a convenient way of determining
           whether a 'this may take a while' warning is warranted.)

           Returns True if the AVD is installed.
        """
        avd = os.path.join(EMULATOR_HOME_DIR, 'avd',
                           self.avd_info.name + '.avd')
        if force and os.path.exists(avd):
            shutil.rmtree(avd)
        if os.path.exists(avd):
            _log_debug("AVD found at %s" % avd)
            return True
        return False

    def update_avd(self, force=False):
        """
           If required, update the AVD via tooltool.

           If the AVD directory is not found, or "force" is requested,
           download the tooltool manifest associated with the AVD and then
           invoke tooltool.py on the manifest. tooltool.py will download the
           required archive (unless already present in the local tooltool
           cache) and install the AVD.
        """
        avd = os.path.join(EMULATOR_HOME_DIR, 'avd',
                           self.avd_info.name + '.avd')
        if force and os.path.exists(avd):
            shutil.rmtree(avd)
        if not os.path.exists(avd):
            _download_file(TOOLTOOL_URL, 'tooltool.py', EMULATOR_HOME_DIR)
            url = '%s/%s' % (TRY_URL, self.avd_info.tooltool_manifest)
            _download_file(url, 'releng.manifest', EMULATOR_HOME_DIR)
            _tooltool_fetch()
            self._update_avd_paths()

    def start(self):
        """
           Launch the emulator.
        """
        def outputHandler(line):
            self.emulator_log.write("<%s>\n" % line)

        env = os.environ
        env['ANDROID_AVD_HOME'] = os.path.join(EMULATOR_HOME_DIR, "avd")
        command = [
            self.emulator_path, "-avd", self.avd_info.name, "-port", "5554"
        ]
        if self.avd_info.extra_args:
            # -enable-kvm option is not valid on OSX
            if _get_host_platform(
            ) == 'macosx64' and '-enable-kvm' in self.avd_info.extra_args:
                self.avd_info.extra_args.remove('-enable-kvm')
            command += self.avd_info.extra_args
        log_path = os.path.join(EMULATOR_HOME_DIR, 'emulator.log')
        self.emulator_log = open(log_path, 'w')
        _log_debug("Starting the emulator with this command: %s" %
                   ' '.join(command))
        _log_debug("Emulator output will be written to '%s'" % log_path)
        self.proc = ProcessHandler(command,
                                   storeOutput=False,
                                   processOutputLine=outputHandler,
                                   env=env)
        self.proc.run()
        _log_debug("Emulator started with pid %d" % int(self.proc.proc.pid))

    def wait_for_start(self):
        """
           Verify that the emulator is running, the emulator device is visible
           to adb, and Android has booted.
        """
        if not self.proc:
            _log_warning("Emulator not started!")
            return False
        if self.proc.proc.poll() is not None:
            _log_warning("Emulator has already completed!")
            return False
        _log_debug("Waiting for device status...")
        while (('emulator-5554', 'device') not in self.dm.devices()):
            time.sleep(10)
            if self.proc.proc.poll() is not None:
                _log_warning("Emulator has already completed!")
                return False
        _log_debug("Device status verified.")

        _log_debug("Checking that Android has booted...")
        complete = False
        while (not complete):
            output = ''
            try:
                output = self.dm.shellCheckOutput(
                    ['getprop', 'sys.boot_completed'], timeout=5)
            except DMError:
                # adb not yet responding...keep trying
                pass
            if output.strip() == '1':
                complete = True
            else:
                time.sleep(10)
                if self.proc.proc.poll() is not None:
                    _log_warning("Emulator has already completed!")
                    return False
        _log_debug("Android boot status verified.")

        if not self._verify_emulator():
            return False
        if self.avd_info.uses_sut:
            if not self._verify_sut():
                return False
        return True

    def wait(self):
        """
           Wait for the emulator to close. If interrupted, close the emulator.
        """
        try:
            self.proc.wait()
        except:
            if self.proc.poll() is None:
                self.cleanup()
        return self.proc.poll()

    def cleanup(self):
        """
           Close the emulator.
        """
        self.proc.kill(signal.SIGTERM)

    def get_avd_description(self):
        """
           Return the human-friendly description of this AVD.
        """
        return self.avd_info.description

    def _update_avd_paths(self):
        avd_path = os.path.join(EMULATOR_HOME_DIR, "avd")
        ini_file = os.path.join(avd_path, "test-1.ini")
        ini_file_new = os.path.join(avd_path, self.avd_info.name + ".ini")
        os.rename(ini_file, ini_file_new)
        avd_dir = os.path.join(avd_path, "test-1.avd")
        avd_dir_new = os.path.join(avd_path, self.avd_info.name + ".avd")
        os.rename(avd_dir, avd_dir_new)
        self._replace_ini_contents(ini_file_new)

    def _replace_ini_contents(self, path):
        with open(path, "r") as f:
            lines = f.readlines()
        with open(path, "w") as f:
            for line in lines:
                if line.startswith('path='):
                    avd_path = os.path.join(EMULATOR_HOME_DIR, "avd")
                    f.write('path=%s/%s.avd\n' %
                            (avd_path, self.avd_info.name))
                elif line.startswith('path.rel='):
                    f.write('path.rel=avd/%s.avd\n' % self.avd_info.name)
                else:
                    f.write(line)

    def _telnet_cmd(self, telnet, command):
        _log_debug(">>> " + command)
        telnet.write('%s\n' % command)
        result = telnet.read_until('OK', 10)
        _log_debug("<<< " + result)
        return result

    def _verify_emulator(self):
        telnet_ok = False
        tn = None
        while (not telnet_ok):
            try:
                tn = telnetlib.Telnet('localhost', self.avd_info.port, 10)
                if tn is not None:
                    res = tn.read_until('OK', 10)
                    self._telnet_cmd(tn, 'avd status')
                    if self.avd_info.uses_sut:
                        cmd = 'redir add tcp:%s:%s' % \
                           (str(self.avd_info.sut_port),
                            str(self.avd_info.sut_port))
                        self._telnet_cmd(tn, cmd)
                        cmd = 'redir add tcp:%s:%s' % \
                            (str(self.avd_info.sut_port2),
                             str(self.avd_info.sut_port2))
                        self._telnet_cmd(tn, cmd)
                    self._telnet_cmd(tn, 'redir list')
                    self._telnet_cmd(tn, 'network status')
                    tn.write('quit\n')
                    tn.read_all()
                    telnet_ok = True
                else:
                    _log_warning("Unable to connect to port %d" % port)
            except:
                _log_warning("Trying again after unexpected exception")
            finally:
                if tn is not None:
                    tn.close()
            if not telnet_ok:
                time.sleep(10)
                if self.proc.proc.poll() is not None:
                    _log_warning("Emulator has already completed!")
                    return False
        return telnet_ok

    def _verify_sut(self):
        sut_ok = False
        while (not sut_ok):
            try:
                tn = telnetlib.Telnet('localhost', self.avd_info.sut_port, 10)
                if tn is not None:
                    _log_debug("Connected to port %d" % self.avd_info.sut_port)
                    res = tn.read_until('$>', 10)
                    if res.find('$>') == -1:
                        _log_debug("Unexpected SUT response: %s" % res)
                    else:
                        _log_debug("SUT response: %s" % res)
                        sut_ok = True
                    tn.write('quit\n')
                    tn.read_all()
            except:
                _log_debug("Caught exception while verifying sutagent")
            finally:
                if tn is not None:
                    tn.close()
            if not sut_ok:
                time.sleep(10)
                if self.proc.proc.poll() is not None:
                    _log_warning("Emulator has already completed!")
                    return False
        return sut_ok

    def _get_avd_type(self, requested):
        if requested in AVD_DICT.keys():
            return requested
        if self.substs:
            if not self.substs['TARGET_CPU'].startswith('arm'):
                return 'x86'
            if self.substs['MOZ_ANDROID_MIN_SDK_VERSION'] == '9':
                return '2.3'
        return '4.3'
コード例 #56
0
def uninstall(adb="adb"):
    dm = DeviceManagerADB(adbPath=adb)
    dm.remount()
    if dm.dirExists(INSTALL_DIR):
        dm.removeDir(INSTALL_DIR)
コード例 #57
0
ファイル: autophone.py プロジェクト: MekliCZ/positron
 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 not 'n' 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
コード例 #58
0
 def dm(self):
     if not self._dm:
         self._dm = DeviceManagerADB(adbPath=self.adb_path)
     return self._dm
コード例 #59
0
 def dm(self):
     if not self._dm:
         self._dm = DeviceManagerADB(adbPath=self.adb,
                                     autoconnect=False,
                                     deviceRoot=self.remote_test_root)
     return self._dm
コード例 #60
0
 def tearDown(self):
     dm = DeviceManagerADB()
     dm.reboot()