~ubuntu-branches/ubuntu/quantal/lightning-extension/quantal-security

« back to all changes in this revision

Viewing changes to mozilla/build/automationutils.py

  • Committer: Package Import Robot
  • Author(s): Chris Coulson
  • Date: 2012-05-21 16:09:39 UTC
  • mfrom: (1.3.1) (25.1.1 precise-security)
  • Revision ID: package-import@ubuntu.com-20120521160939-0702473a46xfq3tl
Tags: 1.5~b2+build1-0ubuntu1
New upstream release from the beta channel (CALENDAR_1_5b2_BUILD1)

Show diffs side-by-side

added added

removed removed

Lines of Context:
40
40
import glob, logging, os, platform, shutil, subprocess, sys, tempfile, urllib2, zipfile
41
41
import re
42
42
from urlparse import urlparse
 
43
from operator import itemgetter
43
44
 
44
45
__all__ = [
45
46
  "ZipFileReader",
52
53
  "DEBUGGER_INFO",
53
54
  "replaceBackSlashes",
54
55
  "wrapCommand",
 
56
  "ShutdownLeakLogger"
55
57
  ]
56
58
 
57
59
# Map of debugging programs to information about them, like default arguments
450
452
    return ["arch", "-arch", "i386"] + cmd
451
453
  # otherwise just execute the command normally
452
454
  return cmd
 
455
 
 
456
class ShutdownLeakLogger(object):
 
457
  """
 
458
  Parses the mochitest run log when running a debug build, assigns all leaked
 
459
  DOM windows (that are still around after test suite shutdown, despite running
 
460
  the GC) to the tests that created them and prints leak statistics.
 
461
  """
 
462
  MAX_LEAK_COUNT = 121
 
463
 
 
464
  def __init__(self, logger):
 
465
    self.logger = logger
 
466
    self.tests = []
 
467
    self.leakedWindows = {}
 
468
    self.leakedDocShells = set()
 
469
    self.currentTest = None
 
470
    self.seenShutdown = False
 
471
 
 
472
  def log(self, line):
 
473
    if line[2:11] == "DOMWINDOW":
 
474
      self._logWindow(line)
 
475
    elif line[2:10] == "DOCSHELL":
 
476
      self._logDocShell(line)
 
477
    elif line.startswith("TEST-START"):
 
478
      fileName = line.split(" ")[-1].strip().replace("chrome://mochitests/content/browser/", "")
 
479
      self.currentTest = {"fileName": fileName, "windows": set(), "docShells": set()}
 
480
    elif line.startswith("INFO TEST-END"):
 
481
      # don't track a test if no windows or docShells leaked
 
482
      if self.currentTest["windows"] or self.currentTest["docShells"]:
 
483
        self.tests.append(self.currentTest)
 
484
      self.currentTest = None
 
485
    elif line.startswith("INFO TEST-START | Shutdown"):
 
486
      self.seenShutdown = True
 
487
 
 
488
  def parse(self):
 
489
    leakingTests = self._parseLeakingTests()
 
490
 
 
491
    if leakingTests:
 
492
      totalWindows = sum(len(test["leakedWindows"]) for test in leakingTests)
 
493
      totalDocShells = sum(len(test["leakedDocShells"]) for test in leakingTests)
 
494
      msgType = "INFO" if totalWindows + totalDocShells <= self.MAX_LEAK_COUNT else "UNEXPECTED-FAIL"
 
495
      self.logger.info("TEST-%s | ShutdownLeaks | leaked %d DOMWindow(s) and %d DocShell(s) until shutdown", msgType, totalWindows, totalDocShells)
 
496
 
 
497
    for test in leakingTests:
 
498
      self.logger.info("\n[%s]", test["fileName"])
 
499
 
 
500
      for url, count in self._zipLeakedWindows(test["leakedWindows"]):
 
501
        self.logger.info("  %d window(s) [url = %s]", count, url)
 
502
 
 
503
      if test["leakedDocShells"]:
 
504
        self.logger.info("  %d docShell(s)", len(test["leakedDocShells"]))
 
505
 
 
506
  def _logWindow(self, line):
 
507
    created = line[:2] == "++"
 
508
    id = self._parseValue(line, "serial")
 
509
 
 
510
    if self.currentTest:
 
511
      windows = self.currentTest["windows"]
 
512
      if created:
 
513
        windows.add(id)
 
514
      else:
 
515
        windows.discard(id)
 
516
    elif self.seenShutdown and not created:
 
517
      self.leakedWindows[id] = self._parseValue(line, "url")
 
518
 
 
519
  def _logDocShell(self, line):
 
520
    created = line[:2] == "++"
 
521
    id = self._parseValue(line, "id")
 
522
 
 
523
    if self.currentTest:
 
524
      docShells = self.currentTest["docShells"]
 
525
      if created:
 
526
        docShells.add(id)
 
527
      else:
 
528
        docShells.discard(id)
 
529
    elif self.seenShutdown and not created:
 
530
      self.leakedDocShells.add(id)
 
531
 
 
532
  def _parseValue(self, line, name):
 
533
    return re.search("\[%s = (.+?)\]" % name, line).group(1)
 
534
 
 
535
  def _parseLeakingTests(self):
 
536
    leakingTests = []
 
537
 
 
538
    for test in self.tests:
 
539
      test["leakedWindows"] = [self.leakedWindows[id] for id in test["windows"] if id in self.leakedWindows]
 
540
      test["leakedDocShells"] = [id for id in test["docShells"] if id in self.leakedDocShells]
 
541
      test["leakCount"] = len(test["leakedWindows"]) + len(test["leakedDocShells"])
 
542
 
 
543
      if test["leakCount"]:
 
544
        leakingTests.append(test)
 
545
 
 
546
    return sorted(leakingTests, key=itemgetter("leakCount"), reverse=True)
 
547
 
 
548
  def _zipLeakedWindows(self, leakedWindows):
 
549
    counts = []
 
550
    counted = set()
 
551
 
 
552
    for url in leakedWindows:
 
553
      if not url in counted:
 
554
        counts.append((url, leakedWindows.count(url)))
 
555
        counted.add(url)
 
556
 
 
557
    return sorted(counts, key=itemgetter(1), reverse=True)