~ubuntu-branches/ubuntu/precise/enigmail/precise-security

« back to all changes in this revision

Viewing changes to build/automationutils.py

  • Committer: Package Import Robot
  • Author(s): Chris Coulson
  • Date: 2012-11-12 16:36:01 UTC
  • mfrom: (0.12.15)
  • Revision ID: package-import@ubuntu.com-20121112163601-t8e8skdfi3ni9iqp
Tags: 2:1.4.6-0ubuntu0.12.04.1
* New upstream release v1.4.6
  - see LP: #1080212 for USN information
* Drop unneeded patches
  - remove debian/patches/correct-version-number.diff
  - remove debian/patches/dont_register_cids_multiple_times.diff
  - update debian/patches/series
* Support building in an objdir
  - update debian/rules

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
#
2
 
# ***** BEGIN LICENSE BLOCK *****
3
 
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
4
 
#
5
 
# The contents of this file are subject to the Mozilla Public License Version
6
 
# 1.1 (the "License"); you may not use this file except in compliance with
7
 
# the License. You may obtain a copy of the License at
8
 
# http://www.mozilla.org/MPL/
9
 
#
10
 
# Software distributed under the License is distributed on an "AS IS" basis,
11
 
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12
 
# for the specific language governing rights and limitations under the
13
 
# License.
14
 
#
15
 
# The Original Code is mozilla.org code.
16
 
#
17
 
# The Initial Developer of the Original Code is The Mozilla Foundation
18
 
# Portions created by the Initial Developer are Copyright (C) 2009
19
 
# the Initial Developer. All Rights Reserved.
20
 
#
21
 
# Contributor(s):
22
 
#   Serge Gautherie <sgautherie.bz@free.fr>
23
 
#   Ted Mielczarek <ted.mielczarek@gmail.com>
24
 
#
25
 
# Alternatively, the contents of this file may be used under the terms of
26
 
# either the GNU General Public License Version 2 or later (the "GPL"), or
27
 
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28
 
# in which case the provisions of the GPL or the LGPL are applicable instead
29
 
# of those above. If you wish to allow use of your version of this file only
30
 
# under the terms of either the GPL or the LGPL, and not to allow others to
31
 
# use your version of this file under the terms of the MPL, indicate your
32
 
# decision by deleting the provisions above and replace them with the notice
33
 
# and other provisions required by the GPL or the LGPL. If you do not delete
34
 
# the provisions above, a recipient may use your version of this file under
35
 
# the terms of any one of the MPL, the GPL or the LGPL.
36
 
#
37
 
# ***** END LICENSE BLOCK ***** */
 
2
# This Source Code Form is subject to the terms of the Mozilla Public
 
3
# License, v. 2.0. If a copy of the MPL was not distributed with this
 
4
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
38
5
 
39
6
from __future__ import with_statement
40
7
import glob, logging, os, platform, shutil, subprocess, sys, tempfile, urllib2, zipfile
41
8
import re
42
9
from urlparse import urlparse
43
 
from operator import itemgetter
44
10
 
45
11
__all__ = [
46
12
  "ZipFileReader",
53
19
  "DEBUGGER_INFO",
54
20
  "replaceBackSlashes",
55
21
  "wrapCommand",
56
 
  "ShutdownLeakLogger"
57
22
  ]
58
23
 
59
24
# Map of debugging programs to information about them, like default arguments
452
417
    return ["arch", "-arch", "i386"] + cmd
453
418
  # otherwise just execute the command normally
454
419
  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
 
    # log line has invalid format
511
 
    if not id:
512
 
      return
513
 
 
514
 
    if self.currentTest:
515
 
      windows = self.currentTest["windows"]
516
 
      if created:
517
 
        windows.add(id)
518
 
      else:
519
 
        windows.discard(id)
520
 
    elif self.seenShutdown and not created:
521
 
      self.leakedWindows[id] = self._parseValue(line, "url")
522
 
 
523
 
  def _logDocShell(self, line):
524
 
    created = line[:2] == "++"
525
 
    id = self._parseValue(line, "id")
526
 
 
527
 
    # log line has invalid format
528
 
    if not id:
529
 
      return
530
 
 
531
 
    if self.currentTest:
532
 
      docShells = self.currentTest["docShells"]
533
 
      if created:
534
 
        docShells.add(id)
535
 
      else:
536
 
        docShells.discard(id)
537
 
    elif self.seenShutdown and not created:
538
 
      self.leakedDocShells.add(id)
539
 
 
540
 
  def _parseValue(self, line, name):
541
 
    match = re.search("\[%s = (.+?)\]" % name, line)
542
 
    if match:
543
 
      return match.group(1)
544
 
 
545
 
  def _parseLeakingTests(self):
546
 
    leakingTests = []
547
 
 
548
 
    for test in self.tests:
549
 
      test["leakedWindows"] = [self.leakedWindows[id] for id in test["windows"] if id in self.leakedWindows]
550
 
      test["leakedDocShells"] = [id for id in test["docShells"] if id in self.leakedDocShells]
551
 
      test["leakCount"] = len(test["leakedWindows"]) + len(test["leakedDocShells"])
552
 
 
553
 
      if test["leakCount"]:
554
 
        leakingTests.append(test)
555
 
 
556
 
    return sorted(leakingTests, key=itemgetter("leakCount"), reverse=True)
557
 
 
558
 
  def _zipLeakedWindows(self, leakedWindows):
559
 
    counts = []
560
 
    counted = set()
561
 
 
562
 
    for url in leakedWindows:
563
 
      if not url in counted:
564
 
        counts.append((url, leakedWindows.count(url)))
565
 
        counted.add(url)
566
 
 
567
 
    return sorted(counts, key=itemgetter(1), reverse=True)