Beispiel #1
0
    def __init__(self, filename=None, results_raw=None, counter_results=None, global_counters=None):
        """
        - shutdown : whether to record shutdown results or not
        """

        self.counter_results = counter_results
        self.global_counters = global_counters

        if not (results_raw or filename):
            raise utils.talosError("Must specify filename or results_raw")

        self.filename = filename
        if results_raw is None:
            # read the file

            if not os.path.isfile(filename):
                raise utils.talosError("File '%s' does not exist" % filename)
            f = file(filename)
            exception = None
            try:
                results_raw = f.read()
            except Exception, exception:
                pass
            try:
                f.close()
            except:
                pass
            if exception:
                raise exception
Beispiel #2
0
def initializeProfile(profile_dir, browser_config):
  if browser_config["profile_path"] != {}:
      if not (ffsetup.InitializeNewProfile(browser_config['firefox'], profile_dir, browser_config['init_url'])):
         raise talosError("failed to initialize browser")
      time.sleep(10)
      if checkAllProcesses():
         raise talosError("browser failed to close after being initialized") 
Beispiel #3
0
def buildCommandLine(test):
  """build firefox command line options for tp tests"""

  # sanity check pageloader values
  # mandatory options: tpmanifest, tpcycles
  if test['tpcycles'] not in range(1, 1000):
    raise talosError('pageloader cycles must be int 1 to 1,000')
  if test.get('tpdelay') and test['tpdelay'] not in range(1, 10000):
    raise talosError('pageloader delay must be int 1 to 10,000')
  if 'tpmanifest' not in test:
    raise talosError("tpmanifest not found in test: %s" % test)
    # TODO: should probably check if the tpmanifest exists

  # build pageloader command from options
  url = ['-tp', test['tpmanifest']]
  CLI_bool_options = ['tpchrome', 'tpmozafterpaint', 'tpnoisy', 'rss', 'tprender']
  CLI_options = ['tpcycles', 'tppagecycles', 'tpdelay']
  for key in CLI_bool_options:
      if test.get(key):
          url.append('-%s' % key)
  for key in CLI_options:
      value = test.get(key)
      if value:
          url.extend(['-%s' % key, str(value)])

  # XXX we should actually return the list but since we abuse
  # the url as a command line flag to pass to firefox all over the place
  # will just make a string for now
  return ' '.join(url)
Beispiel #4
0
 def initializeProfile(self, profile_dir, browser_config):
     if not (self._ffsetup.InitializeNewProfile(browser_config['browser_path'], 
                                                 browser_config['process'],
                                                 browser_config['child_process'],
                                                 browser_config['browser_wait'],
                                                 browser_config['extra_args'], 
                                                 profile_dir, 
                                                 browser_config['init_url'],
                                                 browser_config['browser_log'])):
         raise talosError("failed to initialize browser")
     time.sleep(browser_config['browser_wait'])
     if self._ffprocess.checkAllProcesses(browser_config['process'], browser_config['child_process']):
         raise talosError("browser failed to close after being initialized") 
Beispiel #5
0
    def InitializeNewProfile(self, browser_path, process, child_process, browser_wait, extra_args, profile_dir, init_url, log):
        """Runs browser with the new profile directory, to negate any performance
            hit that could occur as a result of starting up with a new profile.  
            Also kills the "extra" browser that gets spawned the first time browser
            is run with a new profile.

        Args:
            browser_path: String containing the path to the browser exe
            profile_dir: The full path to the profile directory to load
        """
        PROFILE_REGEX = re.compile('__metrics(.*)__metrics', re.DOTALL|re.MULTILINE)
        command_line = self.ffprocess.GenerateBrowserCommandLine(browser_path, extra_args, profile_dir, init_url)

        b_cmd = 'python bcontroller.py --command "%s"' % (command_line)
        b_cmd += " --name %s" % (process)
        b_cmd += " --child_process %s" % (child_process)
        b_cmd += " --timeout %d" % (browser_wait)
        b_cmd += " --log %s" % (log)

        if (self._remoteWebServer <> 'localhost'):
            b_cmd += ' --host %s' % (self._host)
            b_cmd += ' --port %s' % (self._port)
            b_cmd += ' --deviceRoot %s' % (self._deviceroot)

        process = subprocess.Popen(b_cmd, universal_newlines=True, shell=True, bufsize=0, env=os.environ)

        timeout = True
        total_time = 0
        while total_time < 1200: #20 minutes
            time.sleep(1)
            if process.poll() != None: #browser_controller completed, file now full
                timeout = False
                break
            total_time += 1

        res = 0
        if (timeout == False):
            if not os.path.isfile(log):
                raise talosError("initalization has no output from browser")
            results_file = open(log, "r")
            results_raw = results_file.read()
            results_file.close()
            match = PROFILE_REGEX.search(results_raw)
            if match:
                res = 1
                print match.group(1)
        else:
            raise talosError("initialization timed out")

        return res
Beispiel #6
0
    def checkForCrashes(self, browser_config, profile_dir):
        if platform.system() in ('Windows', 'Microsoft'):
            stackwalkpaths = ['win32', 'minidump_stackwalk.exe']
        elif platform.system() == 'Linux':
            if platform.machine() == 'armv6l':
                stackwalkpaths = ['maemo', 'minidump_stackwalk']
            elif '64' in platform.architecture()[0]: #are we 64 bit?
                stackwalkpaths = ['linux64', 'minidump_stackwalk']
            else:
                stackwalkpaths = ['linux', 'minidump_stackwalk']
        elif platform.system() == 'Darwin':
            stackwalkpaths = ['osx', 'minidump_stackwalk']
        else:
            return
        stackwalkbin = os.path.join(os.path.dirname(__file__), 'breakpad', *stackwalkpaths)

        found = False
        for dump in glob.glob(os.path.join(profile_dir, 'minidumps', '*.dmp')):
            utils.noisy("Found crashdump: " + dump)
            if browser_config['symbols_path']:
                nullfd = open(os.devnull, 'w')
                subprocess.call([stackwalkbin, dump, browser_config['symbols_path']], stderr=nullfd)
                nullfd.close()
            os.remove(dump)
            found = True

        if found:
            raise talosError("crash during run (stack found)")
Beispiel #7
0
    def add(self, results, counter_results=None):
        """
        accumulate one cycle of results
        - results : TalosResults instance or path to browser log
        - counter_results : counters accumulated for this cycle
        """

        if isinstance(results, basestring):
            # ensure the browser log exists
            if not os.path.isfile(results):
                raise talosError("no output from browser [%s]" % results)

            # convert to a results class via parsing the browser log
            browserLog = BrowserLogResults(filename=results, counter_results=counter_results, global_counters=self.global_counters)
            results = browserLog.results()

        self.using_xperf = browserLog.using_xperf
        # ensure the results format matches previous results
        if self.results:
            if not results.format == self.results[0].format:
                raise utils.talosError("Conflicting formats for results")
        else:
            self.format = results.format

        self.results.append(results)

        if counter_results:
            self.all_counter_results.append(counter_results)
Beispiel #8
0
    def getPlatformType(self, remote):

        _ffprocess = None
        if remote == True:
            platform_type = 'remote_'
            import cmanager
            CounterManager = cmanager.CounterManager
        elif platform.system() == "Linux":
            import cmanager_linux
            CounterManager = cmanager_linux.LinuxCounterManager
            platform_type = 'linux_'
            _ffprocess = LinuxProcess()
        elif platform.system() in ("Windows", "Microsoft"):
            if '5.1' in platform.version(): #winxp
                platform_type = 'win_'
            elif '6.1' in platform.version(): #w7
                platform_type = 'w7_'
            elif '6.2' in platform.version(): #w8
                platform_type = 'w8_'
            else:
                raise talosError('unsupported windows version')
            import cmanager_win32
            CounterManager = cmanager_win32.WinCounterManager
            _ffprocess = Win32Process()
        elif platform.system() == "Darwin":
            import cmanager_mac
            CounterManager = cmanager_mac.MacCounterManager
            platform_type = 'mac_'
            _ffprocess = MacProcess()
        return CounterManager, platform_type, _ffprocess
Beispiel #9
0
    def cleanupProcesses(self, process_name, child_process, browser_wait):
        #kill any remaining browser processes
        #returns string of which process_names were terminated and with what signal

        # if we are running this against the metro browser, we currently use
        # metrotestharness.exe as a way to launch the metro browser process.
        # Talos thinks this harness is the browser, see:
        # http://hg.mozilla.org/build/talos/file/8c5f2725fbdd/talos/run_tests.py#l249
        # We must inform talos about the sub process, the metro browser itself,
        # that is spawned from metrotestharness. The metro browser proc is
        # given the same name as the non metro equivalent: 'firefox.exe'
        if process_name == "metrotestharness" and \
                "firefox" not in self.extra_prog:
            self.extra_prog.append("firefox")

        processes_to_kill = filter(lambda n: n, ([process_name, child_process] +
                                                 self.extra_prog))
        utils.debug("Terminating: %s", ", ".join(str(p) for p in processes_to_kill))
        terminate_result = self.TerminateAllProcesses(browser_wait, *processes_to_kill)
        #check if anything is left behind
        if self.checkAllProcesses(process_name, child_process):
            #this is for windows machines.  when attempting to send kill messages to win processes the OS
            # always gives the process a chance to close cleanly before terminating it, this takes longer
            # and we need to give it a little extra time to complete
            time.sleep(browser_wait)
            processes = self.checkAllProcesses(process_name, child_process)
            if processes:
                raise talosError("failed to cleanup processes: %s" % processes)

        return terminate_result
Beispiel #10
0
    def run(self):
        self.bwaiter = BrowserWaiter(self.remoteProcess, **self.options)
        noise = 0
        prev_size = 0
        while not self.bwaiter.hasTime():
            if noise > self.test_timeout:  # check for frozen browser
                try:
                    if os.path.isfile(self.browser_log):
                        os.chmod(self.browser_log, 0777)
                    results_file = open(self.browser_log, "a")
                    results_file.write("\n__FAILbrowser frozen__FAIL\n")
                    results_file.close()
                except IOError, e:
                    raise talosError(str(e))
                return
            time.sleep(1)
            try:
                open(self.browser_log, "r").close(
                )  #HACK FOR WINDOWS: refresh the file information
                size = os.path.getsize(self.browser_log)
            except:
                size = 0

            if size > prev_size:
                prev_size = size
                noise = 0
            else:
                noise += 1
Beispiel #11
0
    def addRemoteServerPref(self, profile_dir, server):
        """
          edit the user.js in the profile (on the host machine) and
          add the xpconnect priviledges for the remote server
        """
        import urlparse
        user_js_filename = os.path.join(profile_dir, 'user.js')
        user_js_file = open(user_js_filename, 'a+')

        #NOTE: this should be sufficient for defining a docroot
        scheme = "http://"
        if (server.startswith('http://') or
            server.startswith('chrome://') or
            server.startswith('file:///')):
          scheme = ""
        elif (server.find('://') >= 0):
          raise talosError("Unable to parse user defined webserver: '%s'" % (server))

        url = urlparse.urlparse('%s%s' % (scheme, server))

        port = url.port
        if not url.port or port < 0:
          port = 80

        #TODO: p2 is hardcoded, how do we determine what prefs.js has hardcoded?
        remoteCode = """
user_pref("capability.principal.codebase.p2.granted", "UniversalPreferencesWrite UniversalXPConnect UniversalPreferencesRead");
user_pref("capability.principal.codebase.p2.id", "http://%(server)s");
user_pref("capability.principal.codebase.p2.subjectName", "");
""" % { "server": server, "host": url.hostname, "port": int(port) }
        user_js_file.write(remoteCode)
        user_js_file.close()
Beispiel #12
0
    def results(self):
        """return results instance appropriate to the format detected"""

        if self.format not in self.classes:
            raise utils.talosError("Unable to find a results class for format: %s" % repr(self.format))

        return self.classes[self.format](self.browser_results)
Beispiel #13
0
def InitializeNewProfile(browser_path, process, browser_wait, extra_args, profile_dir, init_url, log):
  """Runs browser with the new profile directory, to negate any performance
     hit that could occur as a result of starting up with a new profile.  
     Also kills the "extra" browser that gets spawned the first time browser
     is run with a new profile.

  Args:
    browser_path: String containing the path to the browser exe
    profile_dir: The full path to the profile directory to load
  """
  PROFILE_REGEX = re.compile('__metrics(.*)__metrics', re.DOTALL|re.MULTILINE)
  command_line = ffprocess.GenerateBrowserCommandLine(browser_path, extra_args, profile_dir, init_url)
  bcontroller = path('talos/bcontroller.py')
  process = subprocess.Popen('python %s --command "%s" --name %s --timeout %d --log %s' % (bcontroller, command_line, process, browser_wait, log), universal_newlines=True, shell=True, bufsize=0, env=os.environ)
  res = 0
  total_time = 0
  while total_time < 600: #10 minutes
    time.sleep(1)
    if process.poll() != None: #browser_controller completed, file now full
      if not os.path.isfile(log):
        raise talosError("no output from browser")
      results_file = open(log, "r")
      results_raw = results_file.read()
      results_file.close()
      match = PROFILE_REGEX.search(results_raw)
      if match:
        res = 1
        print match.group(1)
        break
    total_time += 1

  return res
Beispiel #14
0
  def _updateCounterPathsForChildProcesses(self, counter):
    # Create a counter path for each instance of the child process that
    # is running.  If any of these paths are not in our counter list,
    # add them to our counter query and append them to the counter list,
    # so that we'll begin tracking their statistics.  We don't need to
    # worry about removing invalid paths from the list, as getCounterValue()
    # will generate a value of 0 for those.
    hq = self.registeredCounters[counter][0]
    oldCounterListLength = len(self.registeredCounters[counter][1])

    pdh.PdhEnumObjectsA(None, None, 0, 1, 0, True)

    expandedPaths = _getExpandedCounterPaths(self.childProcess, counter)
    if not expandedPaths:
      return
    for expandedPath in expandedPaths:
      alreadyInCounterList = False
      for singleCounter in self.registeredCounters[counter][1]:
        if expandedPath == singleCounter[1]:
          alreadyInCounterList = True
      if not alreadyInCounterList:
        try:
          newhc = HANDLE()
          if pdh.PdhAddCounterA(hq, expandedPath, 0, byref(newhc)) != 0:
            raise talosError("Could not add expanded win32 counter %s" %
                             expandedPath)
          self.registeredCounters[counter][1].append((newhc, expandedPath))
        except:
          continue

    if oldCounterListLength != len(self.registeredCounters[counter][1]):
      pdh.PdhCollectQueryData(hq)
Beispiel #15
0
    def copyDirToDevice(self, localDir):
        head, tail = os.path.split(localDir)

        remoteDir = self.rootdir + self.dirSlash + tail
        if (self.testAgent.pushDir(localDir, remoteDir) is None):
            raise talosError("Unable to copy '%s' to remote device '%s'" % (localDir, remoteDir))
        return remoteDir
Beispiel #16
0
  def run(self):
    self.bwaiter = BrowserWaiter(self.remoteProcess, **self.options)
    noise = 0
    prev_size = 0
    while not self.bwaiter.hasTime():
      if noise > self.test_timeout: # check for frozen browser
        try:
          if os.path.isfile(self.browser_log):
            os.chmod(self.browser_log, 0777)
          results_file = open(self.browser_log, "a")
          results_file.write("\n__FAILbrowser frozen__FAIL\n")
          results_file.close()
        except IOError, e:
          raise talosError(str(e))
        return
      time.sleep(1)
      try:
        open(self.browser_log, "r").close() #HACK FOR WINDOWS: refresh the file information
        size = os.path.getsize(self.browser_log)
      except:
        size = 0

      if size > prev_size:
        prev_size = size
        noise = 0
      else:
        noise += 1
    def runProgram(self, browser_config, command_args, timeout=1200):
        remoteLog = os.path.join(self.getDeviceRoot() + '/' + browser_config['browser_log'])
        self.removeFile(remoteLog)
        # bug 816719, remove sessionstore.js so we don't interfere with talos
        self.removeFile(os.path.join(self.getDeviceRoot(), "profile/sessionstore.js"))

        env = ""
        for key, value in browser_config['env'].items():
            env = "%s %s=%s" % (env, key, value)
        command_line = "%s %s" % (env, ' '.join(command_args))

        self.recordLogcat()
        firstTime = time.time()
        retVal = self.launchProcess(' '.join(command_args), outputFile=remoteLog, timeout=timeout)
        logcat = self.getLogcat()
        if logcat:
            with open('logcat.log', 'w') as f:
                f.write(''.join(logcat[-500:-1]))

        data = self.getFile(remoteLog, browser_config['browser_log'])
        with open(browser_config['browser_log'], 'a') as logfile:
            logfile.write("__startBeforeLaunchTimestamp%d__endBeforeLaunchTimestamp\n" % (firstTime * 1000))
            logfile.write("__startAfterTerminationTimestamp%d__endAfterTerminationTimestamp\n" % int(time.time() * 1000))
        if not retVal and data == '':
            raise talosError("missing data from remote log file")

        # Wait out the browser closing
        time.sleep(browser_config['browser_wait'])
Beispiel #18
0
    def InitializeNewProfile(self, profile_dir, browser_config):
        """Runs browser with the new profile directory, to negate any performance
            hit that could occur as a result of starting up with a new profile.  
            Also kills the "extra" browser that gets spawned the first time browser
            is run with a new profile.

        Args:
            browser_config: object containing all the browser_config options
            profile_dir: The full path to the profile directory to load
        """
        PROFILE_REGEX = re.compile('__metrics(.*)__metrics', re.DOTALL|re.MULTILINE)
        command_line = self.ffprocess.GenerateBrowserCommandLine(browser_config["browser_path"], 
                                                                 browser_config["extra_args"], 
                                                                 profile_dir, 
                                                                 browser_config["init_url"])

        log = browser_config['browser_log']
        if (browser_config['webserver'] != 'localhost'):
            b_log = browser_config['deviceroot'] + '/' + browser_config['browser_log']

        b_cmd = self.ffprocess.GenerateBControllerCommandLine(command_line, browser_config, {})
        process = subprocess.Popen(b_cmd, universal_newlines=True, shell=True, bufsize=0, env=os.environ)

        timeout = True
        total_time = 0
        while total_time < 1200: #20 minutes
            time.sleep(1)
            if process.poll() != None: #browser_controller completed, file now full
                timeout = False
                break
            total_time += 1

        res = 0
        if (timeout == False):
            if not os.path.isfile(log):
                raise talosError("initalization has no output from browser")
            results_file = open(log, "r")
            results_raw = results_file.read()
            results_file.close()
            match = PROFILE_REGEX.search(results_raw)
            if match:
                res = 1
                print match.group(1)
        else:
            raise talosError("initialization timed out")

        return res
Beispiel #19
0
 def onTimeout(self):
     """
     When we timeout, dictate this in the log file.
     """
     if os.path.isfile(self.logfile):
         os.chmod(self.logfile, 0777)
     self.logToFile("\n__FAILbrowser frozen__FAIL\n")
     self.closeLogFile()
     raise talosError("timeout")
Beispiel #20
0
    def InitializeNewProfile(self, profile_dir, browser_config):
        """Runs browser with the new profile directory, to negate any performance
            hit that could occur as a result of starting up with a new profile.  
            Also kills the "extra" browser that gets spawned the first time browser
            is run with a new profile.
            Returns 1 (success) if PROFILE_REGEX is found,
            and 0 (failure) otherwise

        Args:
            browser_config: object containing all the browser_config options
            profile_dir: The full path to the profile directory to load
        """
        INFO_REGEX = re.compile('__browserInfo(.*)__browserInfo', re.DOTALL|re.MULTILINE)
        PROFILE_REGEX = re.compile('__metrics(.*)__metrics', re.DOTALL|re.MULTILINE)

        command_args = utils.GenerateBrowserCommandLine(browser_config["browser_path"], 
                                                        browser_config["extra_args"], 
                                                        browser_config["deviceroot"],
                                                        profile_dir, 
                                                        browser_config["init_url"])

        if not browser_config['remote']:
            browser = talosProcess.talosProcess(command_args, env=os.environ.copy(), logfile=browser_config['browser_log'])
            browser.run()
            browser.wait()
            browser = None
            time.sleep(5)
        else:
            self.ffprocess.runProgram(browser_config, command_args, timeout=1200)

        res = 0
        if not os.path.isfile(browser_config['browser_log']):
            raise talosError("initalization has no output from browser")
        results_file = open(browser_config['browser_log'], "r")
        results_raw = results_file.read()
        results_file.close()
        match = PROFILE_REGEX.search(results_raw)
        if match:
            res = 1
        else:
            utils.info("Could not find %s in browser_log: %s", PROFILE_REGEX.pattern, browser_config['browser_log'])
            utils.info("Raw results:%s", results_raw)
            utils.info("Initialization of new profile failed")
        match = INFO_REGEX.search(results_raw)
        if match:
            binfo = match.group(1)
            print binfo
            for line in binfo.split('\n'):
                if line.strip().startswith('browser_name'):
                    browser_config['browser_name'] = line.split(':')[1]
                if line.strip().startswith('browser_version'):
                    browser_config['browser_version'] = line.split(':')[1]
                if line.strip().startswith('buildID'):
                    browser_config['buildid'] = line.split(':')[1]

        return res
Beispiel #21
0
def process_Request(post):
  links = ""
  lines = post.split('\n')
  for line in lines:
    if line.find("RETURN\t") > -1:
        links += line.replace("RETURN\t", "") + '\n'
    utils.debug("process_Request line: " + line.replace("RETURN\t", ""))
  if not links:
    raise talosError("send failed, graph server says:\n" + post)
  return links
Beispiel #22
0
    def cleanupAndCheckForCrashes(self, browser_config, profile_dir):
        cleanup_result = self._ffprocess.cleanupProcesses(browser_config['process'], 
                                                          browser_config['child_process'], 
                                                          browser_config['browser_wait']) 
        if platform.system() in ('Windows', 'Microsoft'):
            stackwalkpaths = ['win32', 'minidump_stackwalk.exe']
        elif platform.system() == 'Linux':
            if platform.machine() == 'armv6l':
                stackwalkpaths = ['maemo', 'minidump_stackwalk']
            elif '64' in platform.architecture()[0]: #are we 64 bit?
                stackwalkpaths = ['linux64', 'minidump_stackwalk']
            else:
                stackwalkpaths = ['linux', 'minidump_stackwalk']
        elif platform.system() == 'Darwin':
            stackwalkpaths = ['osx', 'minidump_stackwalk']
        else:
            return
        stackwalkbin = os.path.join(os.path.dirname(__file__), 'breakpad', *stackwalkpaths)

        found = False
        minidumpdir = os.path.join(profile_dir, 'minidumps')
        if browser_config['remote'] == True:
            minidumpdir = tempfile.mkdtemp()
            self._ffprocess.testAgent.getDirectory(profile_dir + '/minidumps/', minidumpdir)
        
        for dump in glob.glob(os.path.join(minidumpdir, '*.dmp')):
            utils.noisy("Found crashdump: " + dump)
            if browser_config['symbols_path']:
                nullfd = open(os.devnull, 'w')
                subprocess.call([stackwalkbin, dump, browser_config['symbols_path']], stderr=nullfd)
                nullfd.close()
            os.remove(dump)
            found = True

        if browser_config['remote'] == True:
            self._hostproc.removeDirectory(minidumpdir)
   
        if found:
            if cleanup_result:
                raise talosError("stack found after process termination (" + cleanup_result+ ")")
            else:
                raise talosError("crash during run (stack found)")
Beispiel #23
0
def cleanupProcesses():
  #kill any remaining firefox processes
  ffprocess.TerminateAllProcesses("firefox", "crashreporter", "dwwin", "talkback")
  #check if anything is left behind
  if checkAllProcesses(): 
    #this is for windows machines.  when attempting to send kill messages to win processes the OS
    # always gives the process a chance to close cleanly before terminating it, this takes longer
    # and we need to give it a little extra time to complete
    time.sleep(10)
    if checkAllProcesses():
      raise talosError("failed to cleanup")
Beispiel #24
0
 def process_Request(self, post):
     """get links from the graphserver response"""
     links = ""
     for line in post.splitlines():
         if line.find("RETURN\t") > -1:
             line = line.replace("RETURN\t", "")
             links += line + '\n'
         utils.debug("process_Request line: %s", line)
     if not links:
         raise utils.talosError("send failed, graph server says:\n%s" % post)
     return links
Beispiel #25
0
 def cleanupProcesses(self, process_name, child_process, browser_wait):
     #kill any remaining browser processes
     self.TerminateAllProcesses(browser_wait, process_name, child_process, "crashreporter", "dwwin", "talkback")
     #check if anything is left behind
     if self.checkAllProcesses(process_name, child_process):
         #this is for windows machines.  when attempting to send kill messages to win processes the OS
         # always gives the process a chance to close cleanly before terminating it, this takes longer
         # and we need to give it a little extra time to complete
         time.sleep(browser_wait)
         if self.checkAllProcesses(process_name, child_process):
             raise talosError("failed to cleanup")
Beispiel #26
0
def run_tests(configurator):
  """Runs the talos tests on the given configuration and generates a report.

  Args:
    config: dictionary of configuration, as generated by PerfConfigurator
  """
  config=configurator.config
  # data filters
  filters = config['filters']
  try:
      filters = filter.filters_args(filters)
  except AssertionError, e:
      raise talosError(str(e))
Beispiel #27
0
    def check_output_formats(self, output_formats, **output_options):
        """check output formats"""

        # ensure formats are available
        formats = output_formats.keys()
        missing = self.check_formats_exist(formats)
        if missing:
            raise utils.talosError("Output format(s) unknown: %s" % ','.join(missing))

        # perform per-format check
        for format, urls in output_formats.items():
            cls = output.formats[format]
            cls.check(urls, **(output_options.get(format, {})))
Beispiel #28
0
  def _addCounter(self, processName, counterType, counterName):
    pCounterPathElements = _PDH_COUNTER_PATH_ELEMENTS_A(
      LPSTR(None),
      LPSTR(counterType),
      LPSTR(processName),
      LPSTR(None),
      DWORD(-1),
      LPSTR(counterName))

    pcchbufferSize = DWORD(0)

    # First run we just try to get the buffer size so we can allocate a string
    # big enough to fill it
    if pdh.PdhMakeCounterPathA(pointer(pCounterPathElements),
                               LPCSTR(0), pointer(pcchbufferSize),
                               DWORD(0)) != _PDH_MORE_DATA:
      raise talosError("Could not create counter path for counter %s for %s" %
                       (counterName, processName))

    szFullPathBuffer = LPCSTR('\0'*pcchbufferSize.value)
    # Then we run to get the actual value
    if pdh.PdhMakeCounterPathA(pointer(pCounterPathElements),
                               szFullPathBuffer, pointer(pcchbufferSize),
                               DWORD(0)) != 0:
      raise talosError("Could not create counter path for counter %s for %s" %
                       (counterName, processName))

    path = szFullPathBuffer.value

    hq = HANDLE()
    if pdh.PdhOpenQuery(None, None, byref(hq)) != 0:
      raise talosError("Could not open win32 counter query")

    hc = HANDLE()
    if pdh.PdhAddCounterA(hq, path, 0, byref(hc)) != 0:
      raise talosError("Could not add win32 counter %s" % path)

    self.registeredCounters[counterName] = [hq, [(hc, path)]]
Beispiel #29
0
    def install_addon(self, profile_path, addon):
        """Installs the given addon in the profile.
           most of this borrowed from mozrunner, except downgraded to work on python 2.4
           # Contributor(s) for mozrunner:
           # Mikeal Rogers <*****@*****.**>
           # Clint Talbert <*****@*****.**>
           # Henrik Skupin <*****@*****.**>
        """
        def find_id(desc):
            addon_id = None
            for elem in desc:
                apps = elem.getElementsByTagName('em:targetApplication')
                if apps:
                    for app in apps:
                        #remove targetApplication nodes, they contain id's we aren't interested in
                        elem.removeChild(app)
                    if elem.getElementsByTagName('em:id'):
                        addon_id = str(elem.getElementsByTagName('em:id')[0].firstChild.data)
                    elif elem.hasAttribute('em:id'):
                        addon_id = str(elem.getAttribute('em:id'))
            return addon_id

        tmpdir = None
        addon_id = None
        tmpdir = tempfile.mkdtemp(suffix = "." + os.path.split(addon)[-1])
        zip_extractall(zipfile.ZipFile(addon), tmpdir)
        addon = tmpdir

        doc = minidom.parse(os.path.join(addon, 'install.rdf')) 
        # description_element =
        # tree.find('.//{http://www.w3.org/1999/02/22-rdf-syntax-ns#}Description/')

        desc = doc.getElementsByTagName('Description')
        addon_id = find_id(desc)
        if not addon_id:
          desc = doc.getElementsByTagName('RDF:Description')
          addon_id = find_id(desc)
        
        if not addon_id: #bail out, we don't have an addon id
            raise talosError("no addon_id found for extension")
                 
        addon_path = os.path.join(profile_path, 'extensions', addon_id)
        #if an old copy is already installed, remove it 
        if os.path.isdir(addon_path): 
            shutil.rmtree(addon_path, ignore_errors=True) 
        shutil.move(addon, addon_path) 
Beispiel #30
0
    def construct_results(self, vals, testname, **info):
        """
        return results string appropriate to graphserver
        - vals: list of 2-tuples: [(val, page)
        - kwargs: info necessary for self.info_format interpolation
        see https://wiki.mozilla.org/Buildbot/Talos/DataFormat
        """

        info['testname'] = testname
        info_format = self.info_format
        responsiveness = self.responsiveness_test(testname)
        _type = 'VALUES'
        average = None
        if responsiveness:
            _type = 'AVERAGE'
            average = self.responsiveness_Metric([val for (val, page) in vals])
        elif testname.startswith('v8_7'):
            _type = 'AVERAGE'
            average = self.v8_Metric(vals)
        elif testname.startswith('kraken'):
            _type = 'AVERAGE'
            average = self.JS_Metric(vals)
        elif testname.startswith('tcanvasmark'):
            _type = 'AVERAGE'
            average = self.CanvasMark_Metric(vals)

        # ensure that we have all of the info data available
        missing = [i for i in info_format if i not in info]
        if missing:
            raise utils.talosError("Missing keys: %s" % missing)
        info = ','.join([str(info[key]) for key in info_format])

        # write the data
        buffer = StringIO()
        buffer.write("START\n")
        buffer.write("%s\n" % _type)
        buffer.write('%s\n' % info)
        if average is not None:
            # write some kind of average
            buffer.write("%s\n" % average)
        else:
            for i, (val, page) in enumerate(vals):
                buffer.write("%d,%.2f,%s\n" % (i,float(val), page))
        buffer.write("END")
        return buffer.getvalue()
Beispiel #31
0
    def cleanupProcesses(self, process_name, child_process, browser_wait):
        #kill any remaining browser processes
        #returns string of which process_names were terminated and with what signal
        processes_to_kill = filter(lambda n: n, ([process_name, child_process] +
                                                 self.extra_prog))
        utils.debug("Terminating: %s", ", ".join(str(p) for p in processes_to_kill))
        terminate_result = self.TerminateAllProcesses(browser_wait, *processes_to_kill)
        #check if anything is left behind
        if self.checkAllProcesses(process_name, child_process):
            #this is for windows machines.  when attempting to send kill messages to win processes the OS
            # always gives the process a chance to close cleanly before terminating it, this takes longer
            # and we need to give it a little extra time to complete
            time.sleep(browser_wait)
            processes = self.checkAllProcesses(process_name, child_process)
            if processes:
                raise talosError("failed to cleanup processes: %s" % processes)

        return terminate_result
Beispiel #32
0
def InitializeNewProfile(browser_path, process, browser_wait, extra_args,
                         profile_dir, init_url, log):
    """Runs browser with the new profile directory, to negate any performance
     hit that could occur as a result of starting up with a new profile.  
     Also kills the "extra" browser that gets spawned the first time browser
     is run with a new profile.

  Args:
    browser_path: String containing the path to the browser exe
    profile_dir: The full path to the profile directory to load
  """
    PROFILE_REGEX = re.compile('__metrics(.*)__metrics',
                               re.DOTALL | re.MULTILINE)
    command_line = ffprocess.GenerateBrowserCommandLine(
        browser_path, extra_args, profile_dir, init_url)
    process = subprocess.Popen(
        'python bcontroller.py --command "%s" --name %s --timeout %d --log %s'
        % (command_line, process, browser_wait, log),
        universal_newlines=True,
        shell=True,
        bufsize=0,
        env=os.environ)
    res = 0
    total_time = 0
    while total_time < 600:  #10 minutes
        time.sleep(1)
        if process.poll(
        ) != None:  #browser_controller completed, file now full
            if not os.path.isfile(log):
                raise talosError("no output from browser")
            results_file = open(log, "r")
            results_raw = results_file.read()
            results_file.close()
            match = PROFILE_REGEX.search(results_raw)
            if match:
                res = 1
                print match.group(1)
                break
        total_time += 1

    return res