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
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'
def grant_runtime_permissions(build_obj, app): """ Grant required runtime permissions to the specified app (typically org.mozilla.fennec_$USER). """ adb_path = _find_sdk_exe(build_obj.substs, 'adb', False) if not adb_path: adb_path = 'adb' dm = DeviceManagerADB(autoconnect=False, adbPath=adb_path, retryLimit=1) dm.default_timeout = 10 try: sdk_level = dm.shellCheckOutput(['getprop', 'ro.build.version.sdk']) if sdk_level and int(sdk_level) >= 23: _log_info("Granting important runtime permissions to %s" % app) dm.shellCheckOutput([ 'pm', 'grant', app, 'android.permission.WRITE_EXTERNAL_STORAGE' ]) dm.shellCheckOutput([ 'pm', 'grant', app, 'android.permission.ACCESS_FINE_LOCATION' ]) dm.shellCheckOutput( ['pm', 'grant', app, 'android.permission.CAMERA']) dm.shellCheckOutput( ['pm', 'grant', app, 'android.permission.WRITE_CONTACTS']) except DMError: _log_warning("Unable to grant runtime permissions to %s" % app)
def __init__(self, adb="adb", serial=None): self.test_results = {} self.test_results_file = None self.m = None self.gaia_apps = None self.screenshot_path = None self.logcat_path = None self.app_name = None self.attempt = None self.num_apps = None self.device = None self.serial = serial self.port = None self.run_log = logging.getLogger('marketplace-test') if self.serial: self.dm = DeviceManagerADB(adbPath=adb, deviceSerial=serial) else: self.dm = DeviceManagerADB(adbPath=adb)
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."
def __init__(self, avd_type='4.3', verbose=False, substs=None, device_serial=None): global verbose_logging self.emulator_log = None self.emulator_path = 'emulator' verbose_logging = verbose self.substs = substs self.avd_type = self._get_avd_type(avd_type) self.avd_info = AVD_DICT[self.avd_type] adb_path = _find_sdk_exe(substs, 'adb', False) if not adb_path: adb_path = 'adb' self.dm = DeviceManagerADB(autoconnect=False, adbPath=adb_path, retryLimit=1, deviceSerial=device_serial) self.dm.default_timeout = 10 _log_debug("Emulator created with type %s" % self.avd_type)
def check_marionette_exists(adb="adb"): dm = DeviceManagerADB(adbPath=adb) if dm.dirExists(INSTALL_DIR): return True else: dm.forward("tcp:2828", "tcp:2828") try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(('localhost', 2828)) data = sock.recv(16) sock.close() if 'root' in data: return True except socket.error: return False return False
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
def test_run_adb_as_root_parameter(self): dm = DeviceManagerADB() self.assertTrue(dm.processInfo("adbd")[2] != "root") dm = DeviceManagerADB(runAdbAsRoot=True) self.assertTrue(dm.processInfo("adbd")[2] == "root")
def uninstall(adb="adb"): dm = DeviceManagerADB(adbPath=adb) dm.remount() if dm.dirExists(INSTALL_DIR): dm.removeDir(INSTALL_DIR)
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
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)
def dm(self): if not self._dm: from mozdevice import DeviceManagerADB self._dm = DeviceManagerADB(adbPath=self.adb_path) return self._dm
def setUp(self): dm = DeviceManagerADB() dm.reboot(wait=True)
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 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
def tearDown(self): dm = DeviceManagerADB() dm.reboot()
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
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)
def dm(self): if not self._dm: self._dm = DeviceManagerADB(adbPath=self.adb_path) return self._dm
def dm(self): if not self._dm: self._dm = DeviceManagerADB(adbPath=self.adb, autoconnect=False, deviceRoot=self.remote_test_root) return self._dm
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()