Beispiel #1
0
class S1S2Test(PhoneTest):

    def __init__(self, phone_cfg, config_file=None, status_cb=None):
        PhoneTest.__init__(self, phone_cfg, config_file, status_cb)
        
    def runjob(self, job):
        if 'buildurl' not in job or 'androidprocname' not in job or \
                'revision' not in job or 'blddate' not in job or \
                'bldtype' not in job or 'version' not in job:
            self.logger.error('Invalid job configuration: %s' % job)
            raise NameError('ERROR: Invalid job configuration: %s' % job)

        if not androidutils.install_build_adb(phoneid=self.phone_cfg['phoneid'],
                                              url=job['buildurl'],
                                              procname=job['androidprocname'],
                                              serial=self.phone_cfg['serial']):
            return

        # Read our config file which gives us our number of
        # iterations and urls that we will be testing
        self.prepare_phone(job)

        self.dm = DeviceManagerSUT(self.phone_cfg['ip'],
                                   self.phone_cfg['sutcmdport'])

        intent = job['androidprocname'] + '/.App'

        for testname,url in self._urls.iteritems():
            self.logger.info('%s: Running test %s for %s iterations' %
                             (self.phone_cfg['phoneid'], testname,
                              self._iterations))
            for i in range(self._iterations):
                # Set status
                self.set_status(msg='Run %s for url %s' % (i,url))

                # Clear logcat
                androidutils.run_adb('logcat', ['-c'], self.phone_cfg['serial'])

                # Get start time
                try:
                    starttime = self.dm.getInfo('uptimemillis')['uptimemillis'][0]
                except IndexError:
                    starttime = 0

                # Run test
                androidutils.run_adb('shell',
                                     ['sh', '/mnt/sdcard/s1test/runbrowser.sh', intent,
                                      url], self.phone_cfg['serial'])

                # Let browser stabilize - this was 5s but that wasn't long
                # enough for the device to stabilize on slow devices
                sleep(10)

                # Get results
                throbberstart, throbberstop, drawtime = self.analyze_logcat()

                # Publish results
                self.publish_results(starttime=int(starttime),
                                     tstrt=throbberstart,
                                     tstop=throbberstop,
                                     drawing=drawtime,
                                     job=job,
                                     testname=testname)
                androidutils.kill_proc_sut(self.phone_cfg['ip'],
                                           self.phone_cfg['sutcmdport'],
                                           job['androidprocname'])
                androidutils.remove_sessionstore_files_adb(
                    self.phone_cfg['serial'],
                    procname=job['androidprocname'])

    def prepare_phone(self, job):
        androidutils.run_adb('shell', ['mkdir', '/mnt/sdcard/s1test'],
                             self.phone_cfg['serial'])
        androidutils.run_adb('push', ['runbrowser.sh', '/mnt/sdcard/s1test/'],
                             self.phone_cfg['serial'])

        testroot = '/mnt/sdcard/s1test'
        
        if not os.path.exists(self.config_file):
            self.logger.error('Cannot find config file: %s' % self.config_file)
            raise NameError('Cannot find config file: %s' % self.config_file)
        
        cfg = ConfigParser.RawConfigParser()
        cfg.read(self.config_file)
        
        # 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' % 
                                          os.path.basename(h[1])],
                                 self.phone_cfg['serial'])
        
        self._iterations = cfg.getint('settings', 'iterations')
        self._resulturl = cfg.get('settings', 'resulturl')
 
    def analyze_logcat(self):
        buf = androidutils.run_adb('logcat', ['-d'], self.phone_cfg['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, testname = ''):
        msg = 'Start Time: %s Throbber Start: %s Throbber Stop: %s EndDraw: %s' % (starttime, tstrt, tstop, drawing)
        print 'RESULTS %s:%s' % (self.phone_cfg['phoneid'], msg)
        self.logger.info('RESULTS: %s:%s' % (self.phone_cfg['phoneid'], msg))
        
        # Create JSON to send to webserver
        resultdata = {}
        resultdata['phoneid'] = self.phone_cfg['phoneid']
        resultdata['testname'] = testname
        resultdata['starttime'] = starttime
        resultdata['throbberstart'] = tstrt
        resultdata['throbberstop'] = tstop
        resultdata['enddrawing'] = drawing
        resultdata['blddate'] = job['blddate']
        
        resultdata['revision'] = job['revision']
        resultdata['productname'] = job['androidprocname']
        resultdata['productversion'] = job['version']
        resultdata['osver'] = self.phone_cfg['osver']
        resultdata['bldtype'] = job['bldtype']
        resultdata['machineid'] = self.phone_cfg['machinetype']
        
        # 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()
Beispiel #2
0
class S1S2Test(PhoneTest):
    def __init__(self,
                 phoneid=None,
                 serial=None,
                 ip=None,
                 sutcmdport=None,
                 sutdataport=None,
                 machinetype=None,
                 osver=None):
        PhoneTest.__init__(self, phoneid, serial, ip, sutcmdport, sutdataport, machinetype, osver)

    def add_job(self, job):
        self._logger.info("%s: s1s2test adding job: %s" % (self._phoneid,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
                "bldtype" 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 testname,url in self._urls.iteritems():
                self._logger.info("%s: Running test %s for %s iterations" %
                        (self._phoneid, testname, self._iterations))
                for i in range(self._iterations):
                    # Set status
                    self._set_status(msg="Run %s for url %s" % (i,url))

                    # 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,
                                url], 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,
                                         testname = testname)
                    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, testname = ''):
        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"] = testname
        resultdata["starttime"] = starttime
        resultdata["throbberstart"] = tstrt
        resultdata["throbberstop"] = tstop
        resultdata["enddrawing"] = drawing
        resultdata["blddate"] = job["blddate"]
        
        resultdata["revision"] = job["revision"]
        resultdata["productname"] = job["androidprocname"]
        resultdata["productversion"] = job["version"]
        resultdata["osver"] = self._osver
        resultdata["bldtype"] = job["bldtype"]
        resultdata["machineid"] = self._machinetype
        
        # 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()