зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1325148 - Use "error" level in mozleak when logging leak failures, r=jgraham
This fixes a regression when switching to the StructuredOutputParser in mozharness. Previously, mozleak was relying on the string "TEST-UNEXPECTED-FAIL" to turn the jobs orange, but it was doing so at the "warning" level. The StructuredOutputParser requires the "error" level to set the appropriate tbpl_status. MozReview-Commit-ID: 9u9mwqrkA6E --HG-- extra : rebase_source : d31ece08232a87713702e713076071fa10fb8324
This commit is contained in:
Родитель
afb3ed504c
Коммит
148b884e2c
|
@ -48,12 +48,12 @@ class ShutdownLeaks(object):
|
|||
|
||||
def process(self):
|
||||
if not self.seenShutdown:
|
||||
self.logger.warning(
|
||||
self.logger.error(
|
||||
"TEST-UNEXPECTED-FAIL | ShutdownLeaks | process() called before end of test suite")
|
||||
|
||||
for test in self._parseLeakingTests():
|
||||
for url, count in self._zipLeakedWindows(test["leakedWindows"]):
|
||||
self.logger.warning(
|
||||
self.logger.error(
|
||||
"TEST-UNEXPECTED-FAIL | %s | leaked %d window(s) until shutdown "
|
||||
"[url = %s]" % (test["fileName"], count, url))
|
||||
|
||||
|
@ -62,9 +62,9 @@ class ShutdownLeaks(object):
|
|||
(test["fileName"], test["leakedWindowsString"]))
|
||||
|
||||
if test["leakedDocShells"]:
|
||||
self.logger.warning("TEST-UNEXPECTED-FAIL | %s | leaked %d docShell(s) until "
|
||||
"shutdown" %
|
||||
(test["fileName"], len(test["leakedDocShells"])))
|
||||
self.logger.error("TEST-UNEXPECTED-FAIL | %s | leaked %d docShell(s) until "
|
||||
"shutdown" %
|
||||
(test["fileName"], len(test["leakedDocShells"])))
|
||||
self.logger.info("TEST-INFO | %s | docShell(s) leaked: %s" %
|
||||
(test["fileName"], ', '.join(["[pid = %s] [id = %s]" %
|
||||
x for x in test["leakedDocShells"]]
|
||||
|
@ -77,7 +77,7 @@ class ShutdownLeaks(object):
|
|||
|
||||
# log line has invalid format
|
||||
if not pid or not serial:
|
||||
self.logger.warning(
|
||||
self.logger.error(
|
||||
"TEST-UNEXPECTED-FAIL | ShutdownLeaks | failed to parse line <%s>" % line)
|
||||
return
|
||||
|
||||
|
@ -99,7 +99,7 @@ class ShutdownLeaks(object):
|
|||
|
||||
# log line has invalid format
|
||||
if not pid or not id:
|
||||
self.logger.warning(
|
||||
self.logger.error(
|
||||
"TEST-UNEXPECTED-FAIL | ShutdownLeaks | failed to parse line <%s>" % line)
|
||||
return
|
||||
|
||||
|
@ -233,8 +233,8 @@ class LSANLeaks(object):
|
|||
|
||||
def process(self):
|
||||
if self.fatalError:
|
||||
self.logger.warning("TEST-UNEXPECTED-FAIL | LeakSanitizer | LeakSanitizer "
|
||||
"has encountered a fatal error.")
|
||||
self.logger.error("TEST-UNEXPECTED-FAIL | LeakSanitizer | LeakSanitizer "
|
||||
"has encountered a fatal error.")
|
||||
|
||||
if self.foundFrames:
|
||||
self.logger.info("TEST-INFO | LeakSanitizer | To show the "
|
||||
|
@ -243,7 +243,7 @@ class LSANLeaks(object):
|
|||
"in testing/mozbase/mozrunner/mozrunner/utils.py")
|
||||
|
||||
for f in self.foundFrames:
|
||||
self.logger.warning(
|
||||
self.logger.error(
|
||||
"TEST-UNEXPECTED-FAIL | LeakSanitizer | leak at " + f)
|
||||
|
||||
def _finishStack(self):
|
||||
|
|
|
@ -38,8 +38,6 @@ def process_single_leak_file(leakLogFileName, processType, leakThreshold,
|
|||
processString = "%s process:" % processType
|
||||
crashedOnPurpose = False
|
||||
totalBytesLeaked = None
|
||||
logAsWarning = False
|
||||
leakAnalysis = []
|
||||
leakedObjectAnalysis = []
|
||||
leakedObjectNames = []
|
||||
recordLeakedObjects = False
|
||||
|
@ -68,9 +66,9 @@ def process_single_leak_file(leakLogFileName, processType, leakThreshold,
|
|||
# log, particularly on B2G. Eventually, these should be split into multiple
|
||||
# logs (bug 1068869), but for now, we report the largest leak.
|
||||
if totalBytesLeaked is not None:
|
||||
leakAnalysis.append("WARNING | leakcheck | %s "
|
||||
"multiple BloatView byte totals found"
|
||||
% processString)
|
||||
log.warning("leakcheck | %s "
|
||||
"multiple BloatView byte totals found"
|
||||
% processString)
|
||||
else:
|
||||
totalBytesLeaked = 0
|
||||
if bytesLeaked > totalBytesLeaked:
|
||||
|
@ -83,22 +81,15 @@ def process_single_leak_file(leakLogFileName, processType, leakThreshold,
|
|||
else:
|
||||
recordLeakedObjects = False
|
||||
if size < 0 or bytesLeaked < 0 or numLeaked < 0:
|
||||
leakAnalysis.append("TEST-UNEXPECTED-FAIL | leakcheck | %s negative leaks caught!"
|
||||
% processString)
|
||||
logAsWarning = True
|
||||
log.error("TEST-UNEXPECTED-FAIL | leakcheck | %s negative leaks caught!"
|
||||
% processString)
|
||||
continue
|
||||
if name != "TOTAL" and numLeaked != 0 and recordLeakedObjects:
|
||||
leakedObjectNames.append(name)
|
||||
leakedObjectAnalysis.append("TEST-INFO | leakcheck | %s leaked %d %s"
|
||||
% (processString, numLeaked, name))
|
||||
|
||||
leakAnalysis.extend(leakedObjectAnalysis)
|
||||
if logAsWarning:
|
||||
log.warning('\n'.join(leakAnalysis))
|
||||
else:
|
||||
log.info('\n'.join(leakAnalysis))
|
||||
|
||||
logAsWarning = False
|
||||
log.info('\n'.join(leakedObjectAnalysis))
|
||||
|
||||
if totalBytesLeaked is None:
|
||||
# We didn't see a line with name 'TOTAL'
|
||||
|
@ -109,8 +100,8 @@ def process_single_leak_file(leakLogFileName, processType, leakThreshold,
|
|||
log.info("TEST-INFO | leakcheck | %s ignoring missing output line for total leaks"
|
||||
% processString)
|
||||
else:
|
||||
log.info("TEST-UNEXPECTED-FAIL | leakcheck | %s missing output line for total leaks!"
|
||||
% processString)
|
||||
log.error("TEST-UNEXPECTED-FAIL | leakcheck | %s missing output line for total leaks!"
|
||||
% processString)
|
||||
log.info("TEST-INFO | leakcheck | missing output line from log file %s"
|
||||
% leakLogFileName)
|
||||
return
|
||||
|
@ -120,12 +111,6 @@ def process_single_leak_file(leakLogFileName, processType, leakThreshold,
|
|||
processString)
|
||||
return
|
||||
|
||||
if totalBytesLeaked > leakThreshold:
|
||||
logAsWarning = True
|
||||
# Fail the run if we're over the threshold (which defaults to 0)
|
||||
prefix = "TEST-UNEXPECTED-FAIL"
|
||||
else:
|
||||
prefix = "WARNING"
|
||||
# Create a comma delimited string of the first N leaked objects found,
|
||||
# to aid with bug summary matching in TBPL. Note: The order of the objects
|
||||
# had no significance (they're sorted alphabetically).
|
||||
|
@ -134,14 +119,15 @@ def process_single_leak_file(leakLogFileName, processType, leakThreshold,
|
|||
if len(leakedObjectNames) > maxSummaryObjects:
|
||||
leakedObjectSummary += ', ...'
|
||||
|
||||
message = "leakcheck | %s %d bytes leaked (%s)" % (
|
||||
processString, totalBytesLeaked, leakedObjectSummary)
|
||||
|
||||
# totalBytesLeaked will include any expected leaks, so it can be off
|
||||
# by a few thousand bytes.
|
||||
if logAsWarning:
|
||||
log.warning("%s | leakcheck | %s %d bytes leaked (%s)"
|
||||
% (prefix, processString, totalBytesLeaked, leakedObjectSummary))
|
||||
if totalBytesLeaked > leakThreshold:
|
||||
log.error("TEST-UNEXPECTED-FAIL | %s" % message)
|
||||
else:
|
||||
log.info("%s | leakcheck | %s %d bytes leaked (%s)"
|
||||
% (prefix, processString, totalBytesLeaked, leakedObjectSummary))
|
||||
log.warning(message)
|
||||
|
||||
|
||||
def process_leak_log(leak_log_file, leak_thresholds=None,
|
||||
|
@ -175,8 +161,8 @@ def process_leak_log(leak_log_file, leak_thresholds=None,
|
|||
|
||||
leakLogFile = leak_log_file
|
||||
if not os.path.exists(leakLogFile):
|
||||
log.info(
|
||||
"WARNING | leakcheck | refcount logging is off, so leaks can't be detected!")
|
||||
log.warning(
|
||||
"leakcheck | refcount logging is off, so leaks can't be detected!")
|
||||
return
|
||||
|
||||
leakThresholds = leak_thresholds or {}
|
||||
|
@ -192,8 +178,8 @@ def process_leak_log(leak_log_file, leak_thresholds=None,
|
|||
|
||||
for processType in leakThresholds:
|
||||
if processType not in knownProcessTypes:
|
||||
log.info("TEST-UNEXPECTED-FAIL | leakcheck | Unknown process type %s in leakThresholds"
|
||||
% processType)
|
||||
log.error("TEST-UNEXPECTED-FAIL | leakcheck | "
|
||||
"Unknown process type %s in leakThresholds" % processType)
|
||||
|
||||
(leakLogFileDir, leakFileBase) = os.path.split(leakLogFile)
|
||||
if leakFileBase[-4:] == ".log":
|
||||
|
@ -211,8 +197,8 @@ def process_leak_log(leak_log_file, leak_thresholds=None,
|
|||
else:
|
||||
processType = "default"
|
||||
if processType not in knownProcessTypes:
|
||||
log.info("TEST-UNEXPECTED-FAIL | leakcheck | Leak log with unknown process type %s"
|
||||
% processType)
|
||||
log.error("TEST-UNEXPECTED-FAIL | leakcheck | "
|
||||
"Leak log with unknown process type %s" % processType)
|
||||
leakThreshold = leakThresholds.get(processType, 0)
|
||||
process_single_leak_file(thisFile, processType, leakThreshold,
|
||||
processType in ignoreMissingLeaks,
|
||||
|
|
Загрузка…
Ссылка в новой задаче