+
+Richard_Kadrey
+I give up. Ridley Scott or not, Prophets of Science
+ Fiction is embarrassingly awful. As if Look Around You didn't know it
+was a parody.
+
+
+
+Gabrielle_Faust
+Not sure why the NY Times magazine needed to make Viggo Mortenson look like Justin Beiber? ow.ly/i/mYJ4 Almost didn't recognize him.
+
+
+
+jaymgates
+Sitting at my desk, watching the painters try to
+set a ladder in front of the window in front of me. This is half
+hilarious, half scary.
+
+
+
+
+
+
diff --git a/androidutils.py b/androidutils.py
new file mode 100644
index 0000000..adba778
--- /dev/null
+++ b/androidutils.py
@@ -0,0 +1,214 @@
+import subprocess
+import os
+import logging
+from time import sleep
+import urllib
+import sys
+import ConfigParser
+import devicemanagerSUT
+
+# This code is meant to be used from threads, so make subprocess threadsafe in
+# a very hacky way, python: http://bugs.python.org/issue1731717
+subprocess._cleanup = lambda: None
+
+"""
+install_build_sut - installs build on phone via sutagent
+Params:
+* phoneID: phone id (for reporting)
+* url: url of build to download and install
+* procname: process name for uninstall of existing app
+* sutip: ip address of sutagent
+* sutport: port of sutagent on phone (cmdport)
+* callbackport: port to use as a callback on this machine
+"""
+def install_build_sut(phoneid=None, url=None, procname="org.mozilla.fennec",
+ sutip=None, sutport="20701", callbackport="30000"):
+ if not phoneid or not url or not sutip:
+ print "You must specify a phoneid, url, and sutip address"
+ return False
+
+ ret = True
+ # First, you download
+ os.mkdir(phoneid)
+ apkpath = os.path.abspath(os.path.join(phoneid, "bld.apk"))
+ try:
+ logging.debug("Installing build on phone: %s from url %s" % (phoneid, url))
+ urllib.urlretrieve(url, apkpath)
+ except:
+ logging.error("Could not download build due to: %s %s" % sys.exc_info()[:2])
+ ret = False
+
+ nt = NetworkTools()
+ myip = nt.getLanIp()
+
+ if ret:
+ try:
+ dm = devicemanagerSUT.DeviceManagerSUT(sutip, sutport)
+ devroot = dm.getDeviceRoot()
+ # If we get a real deviceroot, then we can connect to the phone
+ if devroot:
+ devpath = devroot + "/fennecbld.apk"
+ dm.pushFile(apkpath, devpath)
+ dm.updateApp(devpath, processName=procname, ipAddr=myip,
+ port=callbackport)
+ logging.debug("Completed update for phoneID: %s" % phoneid)
+ else:
+ logging.warn("Could not get devroot for phone: %s" % phoneid)
+ except:
+ logging.error("Could not install latest nightly on %s" % phoneid)
+ ret = False
+
+ # If the file exists, clean it up
+ if os.path.exists(apkpath):
+ os.remove(apkpath)
+ os.rmdir(phoneid)
+ return ret
+
+"""
+install build adb - downloads and installs build on phone via adb
+Params:
+* phoneid: id of phone for reporting
+* url: url to download build from
+* procname: process name to uninstall old build
+* serial: adb serial number for phone
+"""
+def install_build_adb(phoneid=None, url=None, procname="org.mozilla.fennec",
+ serial=None):
+ if not phoneid or not url or not serial:
+ print "You must specify a phoneid, url, and a serial number"
+ return False
+ #import pdb
+ #pdb.set_trace()
+ ret = True
+
+ os.mkdir(phoneid)
+ apkpath = os.path.abspath(os.path.join(phoneid, "bld.apk"))
+ try:
+ logging.debug("Installing build on phone: %s from url %s" % (phoneid, url))
+ urllib.urlretrieve(url, apkpath)
+ except:
+ logging.error("Could not download build due to: %s %s" % sys.exc_info()[:2])
+ ret = False
+
+ o = run_adb("uninstall", [procname], serial)
+ if o.lower().find('success') == -1:
+ logging.warn("Unable to uninstall application on phoneID: %s" %
+ phoneid)
+ ret = False
+
+ o = run_adb("install", [apkpath], serial)
+ print o
+ if o.lower().find('success') == -1:
+ logging.error("Unable to install application on phoneID: %s" % phoneid)
+ ret = False
+ else:
+ # It could be the case that the app wasn't installed so we might have
+ # failed to uninstall which would be ok
+ ret = True
+
+ if os.path.exists(apkpath):
+ os.remove(apkpath)
+ os.rmdir(phoneid)
+
+ return ret
+
+"""
+run_adb - runs an adb command
+Assumes that the android sdk location is specified by ANDROID_SDK environment
+variable or that adb is accessible from your path. If this is not the case this
+will throw
+Params:
+* adbcmd - the adb command to run install, logcat, shell etc
+* cmd - an ARRAY of command parameters, MUST BE AN ARRAY
+* serial - optional serial number if multiple adb devices are installed
+
+RETURNS:
+* The stdout of the adb command
+"""
+def run_adb(adbcmd, cmd, serial=None):
+ if os.environ["ANDROID_SDK"]:
+ adb = os.path.join(os.environ["ANDROID_SDK"], "platform-tools", "adb")
+ else:
+ logging.warn("Cannot find ANDROID_SDK in environment variables, assuming adb is on your path")
+ adb = "adb"
+
+
+ if serial:
+ logging.debug("adb cmd: %s" % subprocess.list2cmdline([adb, "-s", serial, adbcmd] + cmd))
+ p = subprocess.Popen([adb, "-s", serial, adbcmd] + cmd,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ else:
+ logging.debug("run adb cmd: %s" % subprocess.list2cmdline([adb,
+ adbcmd] + cmd))
+ p = subprocess.Popen([adb, adbcmd] + cmd,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ return p.communicate()[0]
+
+"""
+Use sutagent to kill an application
+Params:
+ ip of phone
+ port of cmd port for agent on phone
+ process name
+"""
+def kill_proc_sut(ip=None, port="20701", procname="org.mozilla.fennec"):
+ if not ip:
+ print "You must specify an IP address to the phone"
+ return False
+
+ dm = devicemanagerSUT.DeviceManagerSUT(ip, port)
+ dm.killProcess(procname)
+
+def get_fennec_profile_path_adb(serial=None, procname=None):
+ if not serial:
+ print "You must specify a serial number for adb"
+ return None
+ logging.debug("Getting Fennec Profile Path")
+ path = "/data/data/" + procname + "/files/mozilla/profiles.ini"
+ data = run_adb("shell", ["cat", path], serial=serial)
+
+ if data == '':
+ return None
+
+ pfile = open("profiles.ini", "w")
+ pfile.writelines(data.split("\r"))
+ pfile.flush()
+ path = None
+ if os.path.exists("profiles.ini"):
+ cfg = ConfigParser.RawConfigParser()
+ cfg.read("profiles.ini")
+
+ if cfg.has_section("Profile0"):
+ isrelative = cfg.get("Profile0", "IsRelative")
+ profname = cfg.get("Profile0", "Path")
+ else:
+ logging.error("Unknown profile")
+
+ if isrelative == "1":
+ path = "/data/data/%s/files/mozilla/%s" % (procname,profname)
+ else:
+ path = profname
+ os.remove("profiles.ini")
+ return path
+
+def remove_sessionstore_files_adb(serial=None,
+ procname = None):
+ if not serial or not procname:
+ print "You must specify a serial number for adb and the app name"
+ return None
+
+ # Get the profile
+ fennec_profile = get_fennec_profile_path_adb(serial=serial,
+ procname=procname)
+
+ if fennec_profile:
+ sessionstorepth = fennec_profile + "/sessionstore.js"
+ run_adb("shell", ["rm", sessionstorepth], serial=serial)
+ sessionstorepth = fennec_profile + "/sessionstore.bak"
+ run_adb("shell", ["rm", sessionstorepth], serial=serial)
+ else:
+ # The first run doesn't have a profile so that's ok
+ logging.warn("No profile exists")
+
diff --git a/daemon.py b/daemon.py
index 43ab0ed..15b2225 100644
--- a/daemon.py
+++ b/daemon.py
@@ -1,4 +1,5 @@
import socket
+import logging
import sys, os
import threading
from time import sleep
@@ -13,12 +14,11 @@
import traceback
import uuid
from pulsebuildmonitor import start_pulse_monitor
-import devicemanager, devicemanagerSUT
from devicemanager import NetworkTools
# Objects that conform to test object interface
-import runstartuptest
-
+# TODO: refactor this one: import runstartuptest
+from s1s2test import S1S2Test
gDaemon = None
@@ -44,19 +44,22 @@ def handle(self):
data = ''
class Daemon():
- def __init__(self, is_restarting=False, cachefile="daemon_cache.ini", testconfig="test_config.ini", port=28001):
+ def __init__(self, is_restarting=False, cachefile="daemon_cache.ini",
+ testconfig="test_config.ini", port=28001, logfile="daemon.log",
+ loglevel="DEBUG"):
self._stop = False
self._cache = cachefile
self._phonemap = {}
- self._lasttest = datetime(2011, 10, 22)
self._cachelock = threading.RLock()
- # TODO: Make this configurable
- self._logfilename = "daemon.log"
- self._logfile = open(self._logfilename, "w")
+ logging.basicConfig(filename=logfile,
+ filemode="w",
+ level=loglevel,
+ format='%(asctime)s|%(levelname)s|%(message)s')
- self.log("Starting Daemon")
+ logging.info("Starting Daemon")
# Start the queue
self._jobs = Queue.Queue()
+ self._phonesstarted = False
if not os.path.exists(self._cache):
# If we don't have a cache you aren't restarting
@@ -91,10 +94,9 @@ def __init__(self, is_restarting=False, cachefile="daemon_cache.ini", testconfig
def msg_loop(self):
try:
while (not self._stop):
+ self.disperse_jobs()
+ self.start_phones()
sleep(60)
- while not self._jobs.empty():
- self.lock_and_run_tests()
- #self.log("Done with jobs")
except KeyboardInterrupt:
self.server.shutdown()
@@ -102,45 +104,59 @@ def msg_loop(self):
# This runs the tests and resets the self._lasttest variable.
# It also can install a new build, to install, set build_url to the URL of the
# build to download and install
- def lock_and_run_tests(self, build_url=None):
+ def disperse_jobs(self):
try:
- self.log("Asking for jobs")
- job = self._jobs.get()
- self.log("Got job: %s" % job)
- if "buildurl" in job:
- res = self.install_build(job["phone"], job["buildurl"])
- if res:
- self.run_tests(job)
- else:
- self.log("Failed to install: Phone:%s Build%s" % (job["phone"], job["buildurl"]),
- isError=True)
- else:
- self.run_tests(job)
+ logging.debug("Asking for jobs")
+ while not self._jobs.empty():
+ job = self._jobs.get()
+ logging.debug("Got job: %s" % job)
+ for k,v in self._phonemap.iteritems():
+ # TODO: Refactor so that the job can specify the test so that
+ # then multiple types of test objects can be ran on one set of
+ # phones.
+ logging.debug("Adding job to phone: %s" % v["name"])
+ v["testobj"].add_job(job)
+ self._jobs.task_done()
except:
- self.log("Exception: %s %s" % sys.exc_info()[:2], isError=True)
- finally:
- self._jobs.task_done()
- self.log("Test Lock Released")
+ logging.error("Exception adding jobs: %s %s" % sys.exc_info()[:2])
+
+ # Start the phones for testing
+ def start_phones(self):
+ if not self._phonesstarted:
+ for k,v in self._phonemap.iteritems():
+ logging.info("Starting phone: %s" % v["name"])
+ v["testobj"].start_test()
+ self._phonesstarted = True
+
def route_cmd(self, conn, data):
regdeviceRE = re.compile('register.*')
data = data.lower()
if not conn:
- self.log("Lost Daemon connection!", isError=True)
+ logging.debug("Lost Daemon connection!", isError=True)
raise DaemonException("Lost Connection")
+ # TODO: Implement the get status command to get status for a particular
+ # phone
if data == 'stop':
self.stop()
elif regdeviceRE.match(data):
conn.send("OK\r\n")
self.register_device(data)
elif data == 'quit':
- self.log("Daemon received quit notification", isError=True)
+ logging.debug("Daemon received quit notification", isError=True)
return True
else:
conn.send("Unknown command, either stop or register device\n")
return False
+ def _create_test_object(self, macaddy, phonedict):
+ t = S1S2Test(phoneid=macaddy + "_" + phonedict['name'],
+ serial = phonedict['serial'],
+ ip = phonedict['ip'],
+ sutcmdport = phonedict['port'])
+ return t
+
def register_device(self, data):
# Eat register command
data = data.lstrip("register ")
@@ -150,39 +166,49 @@ def register_device(self, data):
# Lock down so we write to cache safely
self._cachelock.acquire()
- self.log("Obtained cachelock for registering: %s" % data)
+ logging.debug("Obtained cachelock for registering: %s" % data)
try:
# Map MAC Address to ip and user name for phone
- # Even if a known phone is re-registering, just overwrite its record
- # in case its IP changed
# The configparser does odd things with the :'s so remove them.
macaddy = data['name'][0].replace(':', '_')
- self._phonemap[macaddy] = {'ip': data['ipaddr'][0],
- 'name': data['hardware'][0],
- 'port': data['cmdport'][0]}
- cfg = ConfigParser.RawConfigParser()
- cfg.read(self._cache)
- if not cfg.has_section("phones"):
- cfg.add_section("phones")
-
- values = "%s,%s,%s" % (self._phonemap[macaddy]['ip'],
- self._phonemap[macaddy]['name'],
- self._phonemap[macaddy]['port'])
- cfg.set("phones", macaddy, values)
- cfg.write(open(self._cache, 'wb'))
+
+ if macaddy not in self._phonemap:
+ self._phonemap[macaddy] = {'ip': data['ipaddr'][0],
+ 'name': data['hardware'][0],
+ 'port': data['cmdport'][0],
+ 'serial': data['pool'][0]}
+ testobj = self._create_test_object(macaddy, self._phonemap[macaddy])
+ self._phonemap[macaddy]["testobj"] = testobj
+
+
+ cfg = ConfigParser.RawConfigParser()
+ cfg.read(self._cache)
+ if not cfg.has_section("phones"):
+ cfg.add_section("phones")
+
+ values = "%s,%s,%s,%s" % (self._phonemap[macaddy]['ip'],
+ self._phonemap[macaddy]['name'],
+ self._phonemap[macaddy]['port'],
+ self._phonemap[macaddy]['serial'])
+ logging.debug("Registering new phone: %s" % values)
+ cfg.set("phones", macaddy, values)
+ cfg.write(open(self._cache, 'wb'))
+ else:
+ logging.debug("Registering known phone: %s_%s" % (data['name'],
+ data['hardware']))
except:
print "ERROR: could not write cache file, exiting"
print "Exception: %s %s" % sys.exc_info()[:2]
self.stop()
finally:
self._cachelock.release()
- self.log("Released cachelock")
+ logging.debug("Released cachelock")
def read_cache(self):
# Being a little paranoid
self._cachelock.acquire()
- self.log("Read_cache::cachelock acquired: %s" % self._cache)
+ logging.debug("Read_cache::cachelock acquired: %s" % self._cache)
try:
self._phonemap.clear()
cfg = ConfigParser.RawConfigParser()
@@ -191,8 +217,11 @@ def read_cache(self):
vlist = i[1].split(',')
self._phonemap[i[0]] = {"ip": vlist[0],
"name": vlist[1],
- "port": vlist[2]}
-
+ "port": vlist[2],
+ "serial": vlist[3]}
+ testobj = self._create_test_object(i[0], self._phonemap[i[0]])
+ self._phonemap[i[0]]["testobj"] = testobj
+
# Jobs are a string of key/value pairs and have the following attributes:
# phone=,buildurl=,builddate=,revision=,
# test=,iterations=
@@ -206,10 +235,10 @@ def read_cache(self):
# Insert the key value pairs into the dict
job[k[0]] = k[1]
# Insert the full job dict into the queue for processing
- self.log("Adding job: %s" % job)
- self._jobs.put_nowait(job)
+ logging.info("Adding job: %s" % job)
+ self._jobs.put_nowait(job)
except:
- self.log("Unable to rebuild cache: %s %s" % sys.exc_info()[:2], isError=True)
+ logging.error("Unable to rebuild cache: %s %s" % sys.exc_info()[:2])
# We may not have started the server yet.
if self.server:
self.stop()
@@ -217,28 +246,25 @@ def read_cache(self):
sys.exit(1)
finally:
self._cachelock.release()
- self.log("Read_cache::cachelock released")
+ logging.debug("Read_cache::cachelock released")
def reset_phones(self):
nt = NetworkTools()
myip = nt.getLanIp()
for k,v in self._phonemap.iteritems():
- self.log("Rebooting %s:%s" % (k, v["name"]))
+ logging.info("Rebooting %s:%s" % (k, v["name"]))
try:
dm = devicemanagerSUT.DeviceManagerSUT(v["ip"],v["port"])
dm.reboot(myip)
except:
- self.log("COULD NOT REBOOT PHONE: %s:%s" % (k, v["name"]),
- isError=True)
- # TODO: SHould it get removed from the list? Think so.
- #del self._phonemap[k]
+ logging.error("COULD NOT REBOOT PHONE: %s:%s" % (k, v["name"]))
def on_build(self, msg):
# Use the msg to get the build and install it then kick off our tests
- self.log("---------- BUILD FOUND ----------")
- self.log("%s" % msg)
- self.log("---------------------------------")
+ logging.debug("---------- BUILD FOUND ----------")
+ logging.debug("%s" % msg)
+ logging.debug("---------------------------------")
# We will get a msg on busted builds with no URLs, so just ignore
# those, and only run the ones with real URLs
@@ -248,47 +274,6 @@ def on_build(self, msg):
job = {"phone":k, "buildurl":msg["buildurl"], "builddate":msg["builddate"],
"revision":msg["commit"]}
self._jobs.put_nowait(job)
-
- # Install a build on a phone
- # phoneID: phone mac address
- # url: url of build to download and install
- def install_build(self, phoneID, url):
- ret = True
- # First, you download
- try:
- self.log("Installing build on phone: %s from url %s" % (phoneID, url))
- buildfile = os.path.abspath("fennecbld.apk")
- urllib.urlretrieve(url, buildfile)
- except:
- self.log("Could not download nightly due to: %s %s" % sys.exc_info()[:2],
- isError=True)
- ret = False
-
- nt = NetworkTools()
- myip = nt.getLanIp()
-
- if ret:
- try:
- dm = devicemanagerSUT.DeviceManagerSUT(self._phonemap[phoneID]["ip"],
- self._phonemap[phoneID]["port"])
- devroot = dm.getDeviceRoot()
- # If we get a real deviceroot, then we can connect to the phone
- if devroot:
- devpath = devroot + "/fennecbld.apk"
- dm.pushFile("fennecbld.apk", devpath)
- dm.updateApp(devpath, processName="org.mozilla.fennec", ipAddr=myip)
- self.log("Completed update for phoneID: %s" % phoneID)
- else:
- self.log("Could not get devroot for phone: %s" % phoneID, isError=True)
- except:
- self.log("Could not install latest nightly on %s:%s" % (phoneID,self._phonemap[phoneID]["name"]), isError=True)
- self.log("Exception: %s %s" % sys.exc_info()[:2], isError=True)
- ret = False
-
- # If the file exists, clean it up
- if os.path.exists("fennecbld.apk"):
- os.remove("fennecbld.apk")
- return ret
def run_tests(self, job):
# TODO: We can make this configurable by reading in a list of
@@ -300,7 +285,7 @@ def run_tests(self, job):
import runstartuptest
phoneID = job["phone"]
phoneName = self._phonemap[phoneID]["name"]
- self.log("*!*!*! Beginning test run on %s:%s *!*!*!"% (phoneID, phoneName))
+ logging.debug("*!*!*! Beginning test run on %s:%s *!*!*!"% (phoneID, phoneName))
# Configure it
# Add in a revision ID into our config file for this test run
@@ -320,42 +305,25 @@ def run_tests(self, job):
# Run it
# TODO: At the moment, hack in support for allowing it to
# log to our logging method.
- t = runstartuptest.StartupTest(dm, opts, logcallback=self.log)
+ t = runstartuptest.StartupTest(dm, opts, logcallback=logging.debug)
t.prepare_phone()
t.run()
except:
t, v, tb = sys.exc_info()
- self.log("Test Run threw exception: %s %s" % (t,v), isError=True)
+ logging.debug("Test Run threw exception: %s %s" % (t,v), isError=True)
traceback.print_exception(t,v,tb)
- def log(self, msg, isError=False):
- timestamp = datetime.now().isoformat("T")
- if not self._logfile:
- self._logfile = open(self._logfilename, "w")
- m = "ERROR|Reopening Log File|%s\n" % timestamp
- print m
- self._logfile.write(m)
-
- if isError:
- m = "ERROR|%s|%s\n" % (msg, timestamp)
- else:
- m = "INFO|%s|%s\n" % (msg, timestamp)
-
- # TODO: Defaults to being very chatty
- print m
- self._logfile.write(m)
- self._logfile.flush()
-
def stop(self):
self._stop = True
- self._logfile.close()
self.server.shutdown()
-def main(is_restarting, cachefile, port):
+def main(is_restarting, cachefile, port, logfile, loglevel):
global gDaemon
gDaemon = Daemon(is_restarting=is_restarting,
cachefile = cachefile,
- port = port)
+ port = port,
+ logfile = logfile,
+ loglevel = loglevel)
gDaemon.msg_loop()
defaults = {}
@@ -372,8 +340,16 @@ def main(is_restarting, cachefile, port):
help="Cache file to use, defaults to daemon_cache.ini in local dir")
defaults["cachefile"] = "daemon_cache.ini"
+parser.add_option("--logfile", action="store", type="string", dest="logfile",
+ help="Log file to store logging from entire system, default: daemon.log")
+defaults["logfile"] = "daemon.log"
+
+parser.add_option("--loglevel", action="store", type="string", dest="loglevel",
+ help="Log level - ERROR, WARNING, DEBUG, or INFO, defaults to DEBUG")
+defaults["loglevel"] = "DEBUG"
parser.set_defaults(**defaults)
(options, args) = parser.parse_args()
if __name__ == "__main__":
- main(options.is_restarting, options.cachefile, options.port)
+ main(options.is_restarting, options.cachefile, options.port,
+ options.logfile, options.loglevel)
diff --git a/daemon_cache.ini b/daemon_cache.ini
index baa6fd6..1721f65 100644
--- a/daemon_cache.ini
+++ b/daemon_cache.ini
@@ -1,228 +1,5 @@
[phones]
-78_d6_f0_cf_d2_17 = 10.250.49.241,nexus_s,20701
-98_4b_4a_2c_e4_89 = 10.250.49.254,droid_pro,20701
-98_0c_82_33_ec_8d = 10.250.49.250,samsung_gs2,20701
-00_23_76_96_cc_6f = 10.250.49.240,nexus_one,20701
+a0_0b_ba_bf_3c_e9 = 192.168.1.105,galaxy_nexus,20701,014691061801b00b
[jobs]
-job82 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-04-04-04-06-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1320404640,revision=f3eea1384f14
-job83 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-04-04-04-06-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1320404640,revision=f3eea1384f14
-job104 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-11-04-03-25-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1321012980,revision=dce9246b76d7
-job105 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-11-04-03-25-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1321012980,revision=dce9246b76d7
-job106 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-11-04-03-25-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1321012980,revision=dce9246b76d7
-job107 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-11-04-03-25-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1321012980,revision=dce9246b76d7
-job100 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-10-04-09-27-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1320926940,revision=1cf9e4b19819
-job101 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-10-04-09-27-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1320926940,revision=1cf9e4b19819
-job102 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-10-04-09-27-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1320926940,revision=1cf9e4b19819
-job103 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-10-04-09-27-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1320926940,revision=1cf9e4b19819
-job200 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/12/2011-12-07-07-53-04-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1323273180,revision=8e9f9ed1358f
-job108 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-17-07-43-54-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1321544580,revision=04b6e59f4e82
-job109 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-17-07-43-54-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1321544580,revision=04b6e59f4e82
-job46 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-26-04-02-27-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319626920,revision=8fb012fa3613
-job225 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/12/2011-12-13-04-03-22-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1323777780,revision=8e9f9ed1358f
-job224 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/12/2011-12-13-04-03-22-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1323777780,revision=8e9f9ed1358f
-job99 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-09-04-05-05-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1320840300,revision=edd8921d5bb8
-job98 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-09-04-05-05-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1320840300,revision=edd8921d5bb8
-job221 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/12/2011-12-12-04-02-39-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1323691320,revision=8e9f9ed1358f
-job220 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/12/2011-12-12-04-02-39-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1323691320,revision=8e9f9ed1358f
-job223 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/12/2011-12-12-04-02-39-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1323691320,revision=8e9f9ed1358f
-job222 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/12/2011-12-12-04-02-39-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1323691320,revision=8e9f9ed1358f
-job93 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-08-04-03-46-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1320753780,revision=df8c264a45d9
-job92 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-08-04-03-46-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1320753780,revision=df8c264a45d9
-job91 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-07-04-03-37-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1320667380,revision=22f16ec4052a
-job90 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-07-04-03-37-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1320667380,revision=22f16ec4052a
-job97 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-09-04-05-05-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1320840300,revision=edd8921d5bb8
-job96 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-09-04-05-05-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1320840300,revision=edd8921d5bb8
-job95 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-08-04-03-46-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1320753780,revision=df8c264a45d9
-job94 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-08-04-03-46-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1320753780,revision=df8c264a45d9
-job13 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-21-04-02-22-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319194920,revision=6113f767a431
-job12 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-21-04-02-22-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319194920,revision=6113f767a431
-job11 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-20-04-02-12-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319108520,revision=653aa43e9643
-job10 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-20-04-02-12-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319108520,revision=653aa43e9643
-job17 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-22-04-02-30-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319281320,revision=f84cfff96eae
-job16 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-22-04-02-30-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319281320,revision=f84cfff96eae
-job15 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-21-04-02-22-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319194920,revision=6113f767a431
-job14 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-21-04-02-22-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319194920,revision=6113f767a431
-job19 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-22-04-02-30-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319281320,revision=f84cfff96eae
-job18 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-22-04-02-30-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319281320,revision=f84cfff96eae
-job199 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/12/2011-12-06-04-02-08-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1323172920,revision=a7fb88bd5148
-job198 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/12/2011-12-06-04-02-08-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1323172920,revision=a7fb88bd5148
-job197 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/12/2011-12-06-04-02-08-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1323172920,revision=a7fb88bd5148
-job196 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/12/2011-12-06-04-02-08-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1323172920,revision=a7fb88bd5148
-job113 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-18-04-02-20-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1321617720,revision=9999a423d8ab
-job112 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-18-04-02-20-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1321617720,revision=9999a423d8ab
-job86 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-05-04-03-32-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1320490980,revision=a43602eadb2d
-job110 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-17-07-43-54-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1321544580,revision=04b6e59f4e82
-job80 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-04-04-04-06-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1320404640,revision=f3eea1384f14
-job81 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-04-04-04-06-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1320404640,revision=f3eea1384f14
-job115 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-18-04-02-20-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1321617720,revision=9999a423d8ab
-job114 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-18-04-02-20-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1321617720,revision=9999a423d8ab
-job119 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-19-04-03-05-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1321704180,revision=bcab5ec25b5e
-job118 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-19-04-03-05-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1321704180,revision=bcab5ec25b5e
-job88 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-07-04-03-37-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1320667380,revision=22f16ec4052a
-job89 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-07-04-03-37-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1320667380,revision=22f16ec4052a
-job210 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/12/2011-12-09-04-03-22-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1323432180,revision=8e9f9ed1358f
-job211 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/12/2011-12-09-04-03-22-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1323432180,revision=8e9f9ed1358f
-job212 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/12/2011-12-10-04-03-43-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1323518580,revision=8e9f9ed1358f
-job213 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/12/2011-12-10-04-03-43-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1323518580,revision=8e9f9ed1358f
-job214 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/12/2011-12-10-04-03-43-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1323518580,revision=8e9f9ed1358f
-job215 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/12/2011-12-10-04-03-43-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1323518580,revision=8e9f9ed1358f
-job216 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/12/2011-12-11-04-03-10-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1323604980,revision=8e9f9ed1358f
-job217 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/12/2011-12-11-04-03-10-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1323604980,revision=8e9f9ed1358f
-job218 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/12/2011-12-11-04-03-10-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1323604980,revision=8e9f9ed1358f
-job219 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/12/2011-12-11-04-03-10-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1323604980,revision=8e9f9ed1358f
-job47 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-26-04-02-27-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319626920,revision=8fb012fa3613
-job48 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-26-10-19-37-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319649540,revision=0668a17050a3
-job111 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-17-07-43-54-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1321544580,revision=04b6e59f4e82
-job85 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-05-04-03-32-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1320490980,revision=a43602eadb2d
-job49 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-26-10-19-37-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319649540,revision=0668a17050a3
-job233 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/12/2011-12-15-04-03-21-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1323950580,revision=8e9f9ed1358f
-job7 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-19-04-02-13-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319022120,revision=f013c96028a7
-job6 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-19-04-02-13-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319022120,revision=f013c96028a7
-job5 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-19-04-02-13-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319022120,revision=f013c96028a7
-job4 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-19-04-02-13-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319022120,revision=f013c96028a7
-job3 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-18-04-02-42-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1318935720,revision=b35d89b7a705
-job2 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-18-04-02-42-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1318935720,revision=b35d89b7a705
-job1 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-18-04-02-42-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1318935720,revision=b35d89b7a705
-job0 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-18-04-02-42-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1318935720,revision=b35d89b7a705
-job9 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-20-04-02-12-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319108520,revision=653aa43e9643
-job8 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-20-04-02-12-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319108520,revision=653aa43e9643
-job166 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-29-04-02-52-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1322568120,revision=82f3392976b4
-job167 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-29-04-02-52-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1322568120,revision=82f3392976b4
-job164 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-29-04-02-52-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1322568120,revision=82f3392976b4
-job165 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-29-04-02-52-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1322568120,revision=82f3392976b4
-job162 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-28-04-02-11-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1322481720,revision=aa6ad7ab9b43
-job163 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-28-04-02-11-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1322481720,revision=aa6ad7ab9b43
-job160 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-28-04-02-11-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1322481720,revision=aa6ad7ab9b43
-job208 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/12/2011-12-09-04-03-22-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1323432180,revision=8e9f9ed1358f
-job207 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/12/2011-12-08-04-02-05-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1323345720,revision=8e9f9ed1358f
-job206 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/12/2011-12-08-04-02-05-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1323345720,revision=8e9f9ed1358f
-job205 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/12/2011-12-08-04-02-05-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1323345720,revision=8e9f9ed1358f
-job204 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/12/2011-12-08-04-02-05-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1323345720,revision=8e9f9ed1358f
-job203 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/12/2011-12-07-07-53-04-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1323273180,revision=8e9f9ed1358f
-job202 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/12/2011-12-07-07-53-04-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1323273180,revision=8e9f9ed1358f
-job201 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/12/2011-12-07-07-53-04-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1323273180,revision=8e9f9ed1358f
-job169 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-29-06-35-13-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1322577300,revision=86bc0eabb94d
-job79 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-03-04-03-34-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1320318180,revision=c09a52af4cd8
-job78 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-03-04-03-34-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1320318180,revision=c09a52af4cd8
-job144 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-24-04-02-07-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1322136120,revision=f8505fcb5808
-job71 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-01-04-02-11-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1320145320,revision=7203d86d5868
-job70 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-01-04-02-11-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1320145320,revision=7203d86d5868
-job73 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-02-04-02-57-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1320231720,revision=2b9de9749c1e
-job72 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-02-04-02-57-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1320231720,revision=2b9de9749c1e
-job75 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-02-04-02-57-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1320231720,revision=2b9de9749c1e
-job74 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-02-04-02-57-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1320231720,revision=2b9de9749c1e
-job77 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-03-04-03-34-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1320318180,revision=c09a52af4cd8
-job76 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-03-04-03-34-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1320318180,revision=c09a52af4cd8
-job57 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-28-04-04-27-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319799840,revision=cdb0a41ea68c
-job56 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-28-04-04-27-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319799840,revision=cdb0a41ea68c
-job142 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-23-04-02-07-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1322049720,revision=cd5725c23a13
-job54 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-27-04-03-21-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319713380,revision=c775f204ec05
-job145 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-24-04-02-07-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1322136120,revision=f8505fcb5808
-job175 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-30-04-02-40-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1322654520,revision=4e745f151abd
-job174 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-30-04-02-40-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1322654520,revision=4e745f151abd
-job177 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/12/2011-12-01-04-02-52-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1322740920,revision=d71c91775f9b
-job176 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/12/2011-12-01-04-02-52-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1322740920,revision=d71c91775f9b
-job171 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-29-06-35-13-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1322577300,revision=86bc0eabb94d
-job146 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-24-04-02-07-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1322136120,revision=f8505fcb5808
-job173 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-30-04-02-40-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1322654520,revision=4e745f151abd
-job172 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-30-04-02-40-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1322654520,revision=4e745f151abd
-job147 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-24-04-02-07-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1322136120,revision=f8505fcb5808
-job179 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/12/2011-12-01-04-02-52-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1322740920,revision=d71c91775f9b
-job178 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/12/2011-12-01-04-02-52-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1322740920,revision=d71c91775f9b
-job68 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-01-04-02-11-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1320145320,revision=7203d86d5868
-job69 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-01-04-02-11-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1320145320,revision=7203d86d5868
-job62 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-29-04-02-19-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319886120,revision=f853e2b1e753
-job63 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-29-04-02-19-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319886120,revision=f853e2b1e753
-job60 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-29-04-02-19-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319886120,revision=f853e2b1e753
-job61 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-29-04-02-19-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319886120,revision=f853e2b1e753
-job66 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-31-04-02-10-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1320058920,revision=b7bbb5708b42
-job67 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-31-04-02-10-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1320058920,revision=b7bbb5708b42
-job64 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-31-04-02-10-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1320058920,revision=b7bbb5708b42
-job65 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-31-04-02-10-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1320058920,revision=b7bbb5708b42
-job229 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/12/2011-12-14-04-03-13-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1323864180,revision=8e9f9ed1358f
-job228 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/12/2011-12-14-04-03-13-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1323864180,revision=8e9f9ed1358f
-job140 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-23-04-02-07-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1322049720,revision=cd5725c23a13
-job141 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-23-04-02-07-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1322049720,revision=cd5725c23a13
-job55 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-27-04-03-21-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319713380,revision=c775f204ec05
-job143 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-23-04-02-07-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1322049720,revision=cd5725c23a13
-job53 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-27-04-03-21-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319713380,revision=c775f204ec05
-job52 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-27-04-03-21-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319713380,revision=c775f204ec05
-job51 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-26-10-19-37-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319649540,revision=0668a17050a3
-job50 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-26-10-19-37-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319649540,revision=0668a17050a3
-job148 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-25-04-02-16-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1322222520,revision=2aec00aaf211
-job149 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-25-04-02-16-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1322222520,revision=2aec00aaf211
-job59 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-28-04-04-27-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319799840,revision=cdb0a41ea68c
-job58 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-28-04-04-27-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319799840,revision=cdb0a41ea68c
-job138 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-22-15-05-11-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1322003100,revision=522b28c81dfe
-job170 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-29-06-35-13-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1322577300,revision=86bc0eabb94d
-job40 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-25-20-14-55-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319598840,revision=8fb012fa3613
-job41 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-25-20-14-55-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319598840,revision=8fb012fa3613
-job42 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-25-20-14-55-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319598840,revision=8fb012fa3613
-job43 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-25-20-14-55-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319598840,revision=8fb012fa3613
-job44 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-26-04-02-27-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319626920,revision=8fb012fa3613
-job45 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-26-04-02-27-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319626920,revision=8fb012fa3613
-job159 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-27-04-03-20-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1322395380,revision=2aec00aaf211
-job158 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-27-04-03-20-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1322395380,revision=2aec00aaf211
-job157 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-27-04-03-20-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1322395380,revision=2aec00aaf211
-job156 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-27-04-03-20-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1322395380,revision=2aec00aaf211
-job155 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-26-04-03-16-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1322308980,revision=2aec00aaf211
-job154 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-26-04-03-16-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1322308980,revision=2aec00aaf211
-job153 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-26-04-03-16-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1322308980,revision=2aec00aaf211
-job152 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-26-04-03-16-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1322308980,revision=2aec00aaf211
-job151 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-25-04-02-16-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1322222520,revision=2aec00aaf211
-job150 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-25-04-02-16-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1322222520,revision=2aec00aaf211
-job25 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-23-04-02-53-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319367720,revision=d80bb047fca2
-job137 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-22-15-05-11-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1322003100,revision=522b28c81dfe
-job128 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-22-04-02-03-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1321963320,revision=8bb653dcddc9
-job129 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-22-04-02-03-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1321963320,revision=8bb653dcddc9
-job122 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-20-04-02-50-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1321790520,revision=9827c94661b4
-job123 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-20-04-02-50-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1321790520,revision=9827c94661b4
-job120 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-20-04-02-50-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1321790520,revision=9827c94661b4
-job121 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-20-04-02-50-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1321790520,revision=9827c94661b4
-job126 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-21-04-02-55-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1321876920,revision=41b63b2b6420
-job127 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-21-04-02-55-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1321876920,revision=41b63b2b6420
-job124 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-21-04-02-55-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1321876920,revision=41b63b2b6420
-job125 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-21-04-02-55-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1321876920,revision=41b63b2b6420
-job35 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-25-04-02-35-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319540520,revision=ca91054429b4
-job34 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-25-04-02-35-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319540520,revision=ca91054429b4
-job37 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-25-14-39-27-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319578740,revision=2f77b085a9d0
-job36 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-25-14-39-27-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319578740,revision=2f77b085a9d0
-job31 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-24-04-02-54-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319454120,revision=1b7748fbdf19
-job30 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-24-04-02-54-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319454120,revision=1b7748fbdf19
-job33 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-25-04-02-35-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319540520,revision=ca91054429b4
-job32 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-25-04-02-35-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319540520,revision=ca91054429b4
-job39 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-25-14-39-27-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319578740,revision=2f77b085a9d0
-job38 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-25-14-39-27-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319578740,revision=2f77b085a9d0
-job227 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/12/2011-12-13-04-03-22-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1323777780,revision=8e9f9ed1358f
-job226 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/12/2011-12-13-04-03-22-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1323777780,revision=8e9f9ed1358f
-job161 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-28-04-02-11-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1322481720,revision=aa6ad7ab9b43
-job139 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-22-15-05-11-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1322003100,revision=522b28c81dfe
-job84 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-05-04-03-32-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1320490980,revision=a43602eadb2d
-job234 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/12/2011-12-15-04-03-21-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1323950580,revision=8e9f9ed1358f
-job235 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/12/2011-12-15-04-03-21-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1323950580,revision=8e9f9ed1358f
-job232 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/12/2011-12-15-04-03-21-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1323950580,revision=8e9f9ed1358f
-job209 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/12/2011-12-09-04-03-22-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1323432180,revision=8e9f9ed1358f
-job230 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/12/2011-12-14-04-03-13-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1323864180,revision=8e9f9ed1358f
-job231 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/12/2011-12-14-04-03-13-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1323864180,revision=8e9f9ed1358f
-job131 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-22-04-02-03-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1321963320,revision=8bb653dcddc9
-job130 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-22-04-02-03-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1321963320,revision=8bb653dcddc9
-job133 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-22-13-24-18-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1321997040,revision=68ad2016a7d0
-job132 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-22-13-24-18-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1321997040,revision=68ad2016a7d0
-job135 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-22-13-24-18-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1321997040,revision=68ad2016a7d0
-job134 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-22-13-24-18-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1321997040,revision=68ad2016a7d0
-job168 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-29-06-35-13-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1322577300,revision=86bc0eabb94d
-job136 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-22-15-05-11-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1322003100,revision=522b28c81dfe
-job26 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-23-04-02-53-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319367720,revision=d80bb047fca2
-job27 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-23-04-02-53-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319367720,revision=d80bb047fca2
-job24 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-23-04-02-53-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319367720,revision=d80bb047fca2
-job87 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-05-04-03-32-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1320490980,revision=a43602eadb2d
-job22 = phone=98_0c_82_33_ec_8d,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-22-08-47-34-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319298420,revision=f84cfff96eae
-job23 = phone=00_23_76_96_cc_6f,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-22-08-47-34-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319298420,revision=f84cfff96eae
-job20 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-22-08-47-34-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319298420,revision=f84cfff96eae
-job21 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-22-08-47-34-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319298420,revision=f84cfff96eae
-job117 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-19-04-03-05-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1321704180,revision=bcab5ec25b5e
-job29 = phone=98_4b_4a_2c_e4_89,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-24-04-02-54-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319454120,revision=1b7748fbdf19
-job28 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/10/2011-10-24-04-02-54-birch-android/fennec-10.0a1.en-US.android-arm.apk,builddate=1319454120,revision=1b7748fbdf19
-job116 = phone=78_d6_f0_cf_d2_17,buildurl=ftp://ftp.mozilla.org/pub/mobile/nightly/2011/11/2011-11-19-04-03-05-birch-android/fennec-11.0a1.en-US.android-arm.apk,builddate=1321704180,revision=bcab5ec25b5e
-
+job1 = buildurl=http://people.mozilla.org/~ctalbert/mobile_perf/fennec-12.0a1.en-US.android-arm.apk,blddate=2012-01-26,revision=deadbeef,androidprocname=org.mozilla.fennec_ctalbert
diff --git a/devicemanagerSUT.py b/devicemanagerSUT.py
index e319cda..77eccd6 100644
--- a/devicemanagerSUT.py
+++ b/devicemanagerSUT.py
@@ -924,6 +924,7 @@ def reboot(self, ipAddr=None, port=30000):
# os - name of the os
# id - unique id of the device
# uptime - uptime of the device
+ # uptimemillis - uptime of device in milliseconds
# systime - system time of the device
# screen - screen resolution
# memory - memory stats
@@ -939,8 +940,7 @@ def getInfo(self, directive=None):
result = {}
collapseSpaces = re.compile(' +')
- directives = ['os', 'id','uptime','systime','screen','memory','process',
- 'disk','power']
+ directives = ['os', 'id','uptime','uptimemillis', 'systime','screen','memory','process', 'disk','power']
if (directive in directives):
directives = [directive]
diff --git a/favorites2.html b/favorites2.html
index 6e881b6..a8f436d 100644
--- a/favorites2.html
+++ b/favorites2.html
@@ -1085,6 +1085,7 @@
Footer
console.log("-----------\n");
console.log("KILL\n");
+ document.close();
}
/* If key not found returns 'notfound' which will fail in nice
diff --git a/master_test.py b/master_test.py
new file mode 100644
index 0000000..237d3e6
--- /dev/null
+++ b/master_test.py
@@ -0,0 +1,20 @@
+import logging
+from s1s2test import S1S2Test
+
+logging.basicConfig(filename="foo.log",
+ filemode="w",
+ level='DEBUG',
+ format='%(asctime)s|%(levelname)s|%(message)s')
+
+p1 = S1S2Test(phoneid='galaxy-nexus',
+ serial='014691061801b00b',
+ ip='10.250.5.62',
+ sutcmdport='20701')
+
+jobs = [{"buildurl":'http://people.mozilla.org/~ctalbert/mobile_perf/fennec-12.0a1.en-US.android-arm.apk','blddate':'2012-01-26','revision': 'deadbeef', 'androidprocname': 'org.mozilla.fennec_ctalbert', 'version':'12','buildtype':'opt'}]
+
+for j in jobs:
+ p1.add_job(j)
+p1.start_test(stop=True)
+print p1.get_status()
+
diff --git a/phonetest.py b/phonetest.py
new file mode 100644
index 0000000..70a08af
--- /dev/null
+++ b/phonetest.py
@@ -0,0 +1,95 @@
+import Queue
+import logging
+from datetime import datetime
+
+class PhoneTest:
+ """
+ The initialization function. It takes and stores all the information
+ related to contacting this phone.
+ Params:
+ phoneid = ID of phone, to be used in log messages and reporting
+ serial = serial number for adb style interfaces
+ ip = phone's IP address (where sutagent running if it is running)
+ sutcmdport = cmd port of sutagent if it is running
+ sutdataport = data port of sutagent if it is running
+ osver = version string of phone OS
+ TODO: Add in connection data here for programmable power so we can add a
+ powercycle method to this class.
+ """
+ def __init__(self,
+ phoneid=None,
+ serial=None,
+ ip=None,
+ sutcmdport=None,
+ sutdataport=None,
+ osver=None):
+ print "This is the initialization function"
+ self._jobs = Queue.Queue()
+ self._phoneid = phoneid
+ self._serial = serial
+ self._ip = ip
+ self._sutcmdport = sutcmdport
+ self._sutdataport = sutdataport
+ self._osver = osver
+ self._logger = logging.getLogger('phonetest')
+ self._status = {'timestamp': datetime.now().isoformat(),
+ 'online': True, 'msg': 'Initialized'}
+
+ """
+ add job - Add a job to the list of things the phone should do
+ Params:
+ job dict - the job is the main unit of communication with the test.
+ A job is a dict of the following information:
+ * buildurl - url of bundle to download and install before running test
+ * revisionID - changeset ID associated with that build
+ * branch - branch of build (for reporting)
+ * builddate - date of build (for reporting)
+
+ This can be called both once the phone has started testing as well as
+ prior to phone start.
+ """
+ def add_job(self, job=None):
+ # TODO: Enforce the abstract class?
+ self._logger.warning("Base class adding job %s" % job)
+ if job:
+ self._jobs.put_nowait(job)
+
+ """
+ start Test - starts the testing process.
+ This will walk the job queue and run all the jobs. If stop is True then it
+ will stop the message loop once it completes the list of jobs, otherwise
+ the phone will wait for more jobs to be added to the queue.
+ """
+ def start_test(self, stop=False):
+ # TODO: Enforce abstract class here
+ print "TODO: Enforce abstract class"
+
+ """
+ get status - will return some kind of status to the daemon master.
+ The child object is expected to set a status message, this function
+ will ensure that the master will obtain a properly formatted message.
+ The returned message will have the following form:
+ YYYYMMDDTHH:MM:SS.uuu||
+ where the timestamp is the stamp the last status message was set
+ the True/False is the phone's current belief as to its online state
+ and the message is the last message set in the status block
+ """
+ def get_status(self):
+ statusline = "%s|%s|%s" % (self._status["timestamp"],
+ self._status["online"], self._status["msg"])
+ self._logger.debug("Getting status: %s" % statusline)
+ return statusline
+
+ """
+ sets the status
+ Params:
+ online = boolean True of False
+ msg = the message of status
+ """
+ def _set_status(self, online=True, msg=None):
+ self._logger.debug("creating status")
+ self._status["timestamp"] = datetime.now().isoformat()
+ self._status["online"] = online
+ self._status["msg"] = msg
+
+
diff --git a/runbrowser.sh b/runbrowser.sh
new file mode 100644
index 0000000..40ffbcb
--- /dev/null
+++ b/runbrowser.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+# Parameter 1 is the application name
+# Parameter 2 is the URL
+am start -a android.intent.action.VIEW -n $1 -d $2
+
+
diff --git a/s1s2_settings.ini b/s1s2_settings.ini
new file mode 100644
index 0000000..b4910fe
--- /dev/null
+++ b/s1s2_settings.ini
@@ -0,0 +1,16 @@
+[htmlfiles]
+file3 = Twitter_files
+file1 = startup5.html
+file2 = Twitter.html
+
+[urls]
+# These must resolve, so ensure this matches what is in the code for
+# the testroot
+local-twitter = file://mnt/sdcard/s1test/Twitter2.html
+local-blank = file://mnt/sdcard/s1test/startup6.html
+remote-twitter = http://10.250.50.162/Twitter2.html
+remote-onload = http://10.250.50.162/startup6.html
+
+[settings]
+iterations = 20
+resulturl = http://10.250.2.223:8100/s1s2_add
diff --git a/s1s2test.py b/s1s2test.py
new file mode 100644
index 0000000..1dacc20
--- /dev/null
+++ b/s1s2test.py
@@ -0,0 +1,199 @@
+import re
+import os
+import threading
+import androidutils
+import ConfigParser
+import json
+import urllib2
+from time import sleep
+from phonetest import PhoneTest
+from devicemanagerSUT import DeviceManagerSUT
+
+CONFIG_FILE_PATH = os.path.join(os.getcwd(), "s1s2_settings.ini")
+
+class S1S2Test(PhoneTest):
+ def __init__(self,
+ phoneid=None,
+ serial=None,
+ ip=None,
+ sutcmdport=None,
+ sutdataport=None,
+ osver=None):
+ PhoneTest.__init__(self, phoneid, serial, ip, sutcmdport, sutdataport, osver)
+
+ def add_job(self, job):
+ self._logger.info("s1s2test adding job: %s" % job)
+ self._jobs.put_nowait(job)
+
+ def start_test(self, stop=False):
+ # For Android, adb expects our serial number to be in upper case
+ self._serial = self._serial.swapcase()
+ self.stop = stop
+ self._thread = threading.Thread(target=self.runtests,
+ name=self._phoneid)
+ self._thread.start()
+
+ def runtests(self):
+ # Ensure we have a connection to the device
+ self.dm = DeviceManagerSUT(self._ip, self._sutcmdport)
+ # Get our next job
+ while 1:
+ if self._jobs.empty() and self.stop:
+ # Then we are finished and we should end the thread
+ break
+
+ # This blocks until a job arrives
+ job = self._jobs.get()
+ self._logger.debug("Got job: %s" % job)
+ if ("buildurl" not in job or "androidprocname" not in job or
+ "revision" not in job or "blddate" not in job or
+ "buildtype" not in job or "version" not in job):
+ self._logger.error("Invalid job configuration: %s" % job)
+ raise NameError("ERROR: Invalid job configuration: %s" % job)
+
+ androidutils.install_build_adb(phoneid = self._phoneid,
+ url=job["buildurl"],
+ procname = job["androidprocname"],
+ serial=self._serial)
+
+ # Read our config file which gives us our number of
+ # iterations and urls that we will be testing
+ self.prepare_phone(job)
+
+ intent = job["androidprocname"] + "/.App"
+
+ for u in self._urls:
+ self._logger.info("Running url %s for %s iterations" %
+ (u, self._iterations))
+ for i in range(self._iterations):
+ # Set status
+ self._set_status(msg="Run %s for url %s" % (i,u))
+
+ # Clear logcat
+ androidutils.run_adb("logcat", ["-c"], self._serial)
+
+ # Get start time
+ starttime = self.dm.getInfo('uptimemillis')['uptimemillis'][0]
+
+ # Run test
+ androidutils.run_adb("shell",
+ ["sh", "/mnt/sdcard/s1test/runbrowser.sh", intent,
+ u], self._serial)
+
+ # Let browser stabilize
+ sleep(5)
+
+ # Get results
+ throbberstart, throbberstop, drawtime = self.analyze_logcat()
+
+ # Publish results
+ self.publish_results(starttime=int(starttime),
+ tstrt=throbberstart,
+ tstop=throbberstop,
+ drawing=drawtime,
+ job = job,
+ url = u)
+ androidutils.kill_proc_sut(self._ip, self._sutcmdport,
+ job["androidprocname"])
+ androidutils.remove_sessionstore_files_adb(self._serial,
+ procname=job["androidprocname"])
+
+ self._jobs.task_done()
+ self._logger.debug("Finished job: %s" % job)
+
+ def prepare_phone(self, job):
+ print "Preparing phone"
+ androidutils.run_adb("shell", ["mkdir", "/mnt/sdcard/s1test"],
+ self._serial)
+ androidutils.run_adb("push", ["runbrowser.sh",
+ "/mnt/sdcard/s1test/"], self._serial)
+
+ testroot = "/mnt/sdcard/s1test"
+
+ if not os.path.exists(CONFIG_FILE_PATH):
+ self._logger.error("Cannot find config file: %s" % CONFIG_FILE_PATH)
+ raise NameError("Cannot find config file: %s" % CONFIG_FILE_PATH)
+
+ cfg = ConfigParser.RawConfigParser()
+ cfg.read(CONFIG_FILE_PATH)
+
+ # Map URLS - {urlname: url} - urlname serves as testname
+ self._urls = {}
+ for u in cfg.items("urls"):
+ self._urls[u[0]] = u[1]
+
+ # Move the local html files in htmlfiles onto the phone's sdcard
+ # Copy our HTML files for local use into place
+ # TODO: Handle errors
+ for h in cfg.items("htmlfiles"):
+ androidutils.run_adb("push", [h[1], testroot + "/%s" % h[1]], self._serial)
+
+ self._iterations = cfg.getint("settings", "iterations")
+ self._resulturl = cfg.get("settings", "resulturl")
+
+
+
+ def analyze_logcat(self):
+ buf = androidutils.run_adb("logcat", ["-d"], self._serial)
+ buf = buf.split('\r\n')
+ throbberstartRE = re.compile(".*Throbber start$")
+ throbberstopRE = re.compile(".*Throbber stop$")
+ endDrawingRE = re.compile(".*endDrawing$")
+ throbstart = 0
+ throbstop = 0
+ enddraw = 0
+
+ for line in buf:
+ line = line.strip()
+ if throbberstartRE.match(line):
+ throbstart = line.split(' ')[-4]
+ elif throbberstopRE.match(line):
+ throbstop = line.split(' ')[-4]
+ elif endDrawingRE.match(line):
+ enddraw = line.split(' ')[-3]
+ return (int(throbstart), int(throbstop), int(enddraw))
+
+ def publish_results(self, starttime=0, tstrt=0, tstop=0, drawing=0, job=None, url = ''):
+ msg = "Start Time: %s Throbber Start: %s Throbber Stop: %s EndDraw: %s" % (starttime, tstrt, tstop, drawing)
+ print "RESULTS %s:%s" % (self._phoneid, msg)
+ self._logger.info("RESULTS: %s:%s" % (self._phoneid, msg))
+
+ # Create JSON to send to webserver
+ resultdata = {}
+ resultdata["phoneid"] = self._phoneid
+ resultdata["testname"] = url
+ resultdata["throbberstart"] = tstrt
+ resultdata["throbberstop"] = tstop
+ resultdata["enddrawing"] = drawing
+
+ # Accept either YYYY-mm-dd or YYYY-mm-ddTHH:MM:SS for blddate stamps
+ # TODO: Enforce these formats and throw errors if not found
+ dt = job["blddate"].split("T")
+ if len(dt) == 1:
+ # YYYY-mm-dd format
+ resultdata["blddate"] = "%sT%s", (job["blddate"], "00:00:00")
+ else:
+ resultdata["blddate"] = job["blddate"]
+
+ resultdata["revision"] = job["revision"]
+ resultdata["productname"] = job["androidprocname"]
+ resultdata["productversion"] = job["version"]
+ resultdata["osver"] = self._osver
+
+ # Upload
+ result = json.dumps({"data": resultdata})
+ req = urllib2.Request(self._resulturl, result, {'Content-Type': 'application/json'})
+ f = urllib2.urlopen(req)
+ response = f.read()
+ f.close()
+
+
+
+
+
+
+
+
+
+
+
diff --git a/startup5.html b/startup5.html
index ea9b2b1..0940526 100644
--- a/startup5.html
+++ b/startup5.html
@@ -19,6 +19,7 @@
console.log("-----------\n");
console.log("KILL\n");
+ document.close();
}
/* If key not found returns 'notfound' which will fail in nice
diff --git a/startup6.html b/startup6.html
new file mode 100644
index 0000000..8f3a869
--- /dev/null
+++ b/startup6.html
@@ -0,0 +1,14 @@
+
+
+
+
+
+