Add support for Zuulv3-specific parameters in elastic-recheck

This commit ensures elastic-recheck is able to support zuul v2 and v3
simultaneously:

- Add message queries based on v3 completion messages
- Include job-output.txt where console.html was expected

Change-Id: If3d7990d892a9698a112d9ff1dd5160998a4efe6
Depends-On: I7e34206d7968bf128e140468b9a222ecbce3a8f1
This commit is contained in:
David Moreau-Simard 2017-10-03 20:08:31 -04:00 committed by David Moreau-Simard
parent fe21639a1a
commit 97f6408b54
No known key found for this signature in database
GPG Key ID: 33A07694CBB71ECC
12 changed files with 52 additions and 33 deletions

View File

@ -24,6 +24,7 @@ import time
from launchpadlib import launchpad from launchpadlib import launchpad
import elastic_recheck.config as er_config
import elastic_recheck.elasticRecheck as er import elastic_recheck.elasticRecheck as er
import elastic_recheck.results as er_results import elastic_recheck.results as er_results
@ -51,17 +52,14 @@ def all_fails(classifier):
so we can figure out how good we are doing on total classification. so we can figure out how good we are doing on total classification.
""" """
all_fails = {} all_fails = {}
query = ('filename:"console.html" ' results = classifier.hits_by_query(er_config.ALL_FAILS_QUERY, size=30000)
'AND message:"Finished: FAILURE" '
'AND build_queue:"gate"')
results = classifier.hits_by_query(query, size=30000)
facets = er_results.FacetSet() facets = er_results.FacetSet()
facets.detect_facets(results, ["build_uuid"]) facets.detect_facets(results, ["build_uuid"])
for build in facets: for build in facets:
for result in facets[build]: for result in facets[build]:
# not perfect, but basically an attempt to show the integrated # not perfect, but basically an attempt to show the integrated
# gate. Would be nice if there was a zuul attr for this in es. # gate. Would be nice if there was a zuul attr for this in es.
if re.search("(^openstack/|devstack|grenade)", result.project): if re.search(er_config.INCLUDED_PROJECTS_REGEX, result.project):
all_fails["%s.%s" % (build, result.build_name)] = False all_fails["%s.%s" % (build, result.build_name)] = False
return all_fails return all_fails

View File

@ -125,7 +125,10 @@ def all_fails(classifier, config=None):
if result.project in integrated_gate_projects: if result.project in integrated_gate_projects:
name = result.build_name name = result.build_name
timestamp = dp.parse(result.timestamp) timestamp = dp.parse(result.timestamp)
log = result.log_url.split("console.html")[0] if 'console.html' in result.log_url:
log = result.log_url.split('console.html')[0]
elif 'job-output.txt' in result.log_url:
log = result.log_url.split('job-output.txt')[0]
integrated_fails["%s.%s" % (build, name)] = { integrated_fails["%s.%s" % (build, name)] = {
'log': log, 'log': log,
'timestamp': timestamp, 'timestamp': timestamp,
@ -137,7 +140,10 @@ def all_fails(classifier, config=None):
if re.search(config.included_projects_regex, result.project): if re.search(config.included_projects_regex, result.project):
name = result.build_name name = result.build_name
timestamp = dp.parse(result.timestamp) timestamp = dp.parse(result.timestamp)
log = result.log_url.split("console.html")[0] if 'console.html' in result.log_url:
log = result.log_url.split('console.html')[0]
elif 'job-output.txt' in result.log_url:
log = result.log_url.split('job-output.txt')[0]
other_fails["%s.%s" % (build, name)] = { other_fails["%s.%s" % (build, name)] = {
'log': log, 'log': log,
'timestamp': timestamp, 'timestamp': timestamp,

View File

@ -47,11 +47,16 @@ EXCLUDED_JOBS_REGEX = re.compile('(' + '|'.join(EXCLUDED_JOBS) + ')')
INCLUDED_PROJECTS_REGEX = "(^openstack/|devstack|grenade)" INCLUDED_PROJECTS_REGEX = "(^openstack/|devstack|grenade)"
ALL_FAILS_QUERY = ('filename:"console.html" ' # TODO(dmsimard): Revisit this query once Zuul v2 is no longer supported
'AND (message:"Finished: FAILURE" ' # Let's value legibility over pep8 line width here...
'OR message:"[Zuul] Job complete, result: FAILURE") ' ALL_FAILS_QUERY = (
'AND build_queue:"gate" ' '((filename:"job-output.txt" AND message:"POST-RUN END" AND message:"project-config/playbooks/base/post-ssh")' # flake8: noqa
'AND voting:"1"') ' OR '
'(filename:"console.html" AND (message:"[Zuul] Job complete" OR message:"[SCP] Copying console log" OR message:"Grabbing consoleLog"))' # flake8: noqa
' AND build_status:"FAILURE"'
' AND build_queue:"gate"'
' AND voting:"1"'
)
UNCAT_MAX_SEARCH_SIZE = 30000 UNCAT_MAX_SEARCH_SIZE = 30000

View File

@ -31,7 +31,7 @@ from elastic_recheck import results
def required_files(job): def required_files(job):
files = ['console.html'] files = []
if re.match("tempest-dsvm", job): if re.match("tempest-dsvm", job):
files.extend([ files.extend([
'logs/screen-n-api.txt', 'logs/screen-n-api.txt',
@ -246,9 +246,11 @@ class Stream(object):
query = qb.files_ready(change, patch, name, build_short_uuid) query = qb.files_ready(change, patch, name, build_short_uuid)
r = self.es.search(query, size='80', recent=True) r = self.es.search(query, size='80', recent=True)
files = [x['term'] for x in r.terms] files = [x['term'] for x in r.terms]
# TODO(dmsimard): Reliably differentiate zuul v2 and v3 jobs
required = required_files(name) required = required_files(name)
missing_files = [x for x in required if x not in files] missing_files = [x for x in required if x not in files]
if len(missing_files) != 0: if (len(missing_files) != 0 or
('console.html' not in files and 'job-output.txt' not in files)):
msg = ("%s missing for %s %s,%s,%s" % ( msg = ("%s missing for %s %s,%s,%s" % (
missing_files, name, change, patch, build_short_uuid)) missing_files, name, change, patch, build_short_uuid))
raise FilesNotReady(msg) raise FilesNotReady(msg)

View File

@ -69,22 +69,30 @@ def single_queue(query, queue, facet=None):
(query, queue), facet=facet) (query, queue), facet=facet)
def result_ready(review, patch, name, build_short_uuid): def result_ready(change, patchset, name, short_uuid):
"""A query to determine if we have a failure for a particular patch. """A query to determine if we have a failure for a particular patch.
This is looking for a particular FAILURE line in the console log, which This is looking for a particular FAILURE line in the console log, which
lets us know that we've got results waiting that we need to process. lets us know that we've got results waiting that we need to process.
""" """
return generic('filename:"console.html" AND ' # TODO(dmsimard): Revisit this query once Zuul v2 is no longer supported
'(message:"[SCP] Copying console log" ' # Let's value legibility over pep8 line width here...
'OR message:"Grabbing consoleLog" ' query = (
'OR message:"[Zuul] Job complete") ' '((filename:"job-output.txt" AND message:"POST-RUN END" AND message:"project-config/playbooks/base/post-ssh")' # flake8: noqa
'AND build_status:"FAILURE" ' ' OR '
'AND build_change:"%s" ' '(filename:"console.html" AND (message:"[Zuul] Job complete" OR message:"[SCP] Copying console log" OR message:"Grabbing consoleLog"))' # flake8: noqa
'AND build_patchset:"%s" ' ' AND build_status:"FAILURE"'
'AND build_name:"%s" ' ' AND build_change:"{change}"'
'AND build_short_uuid:%s' % ' AND build_patchset:"{patchset}"'
(review, patch, name, build_short_uuid)) ' AND build_name:"{name}"'
' AND build_short_uuid:"{short_uuid}"'
)
return generic(query.format(
change=change,
patchset=patchset,
name=name,
short_uuid=short_uuid
))
def files_ready(review, patch, name, build_short_uuid): def files_ready(review, patch, name, build_short_uuid):
@ -119,7 +127,7 @@ def single_patch(query, review, patch, build_short_uuid):
def most_recent_event(): def most_recent_event():
return generic( return generic(
'filename:console.html ' '(filename:"console.html" OR filename:"job-output.txt") '
'AND (build_queue:gate OR build_queue:check) ' 'AND (build_queue:gate OR build_queue:check) '
'AND NOT tags:_grokparsefailure ' 'AND NOT tags:_grokparsefailure '
'AND NOT message:"%{logmessage}" ') 'AND NOT message:"%{logmessage}" ')

View File

@ -1,4 +1,4 @@
query: > query: >
message:"java.io.InterruptedIOException" message:"java.io.InterruptedIOException"
AND tags:"console.html" AND (tags:"console.html" OR tags:"job-output.txt")
suppress-graph: true suppress-graph: true

View File

@ -2,5 +2,5 @@ query: >
message:"java.io.IOException" message:"java.io.IOException"
AND message:"Remote call on" AND message:"Remote call on"
AND message:"failed" AND message:"failed"
AND tags:"console.html" AND (tags:"console.html" OR tags:"job-output.txt")
suppress-graph: true suppress-graph: true

View File

@ -1,4 +1,4 @@
query: > query: >
message:"[EnvInject] - [ERROR] - SEVERE ERROR occurs:" message:"[EnvInject] - [ERROR] - SEVERE ERROR occurs:"
AND tags:"console.html" AND (tags:"console.html" OR tags:"job-output.txt")
suppress-graph: true suppress-graph: true

View File

@ -1,4 +1,4 @@
query: > query: >
message:"java.lang.InterruptedException" message:"java.lang.InterruptedException"
AND tags:"console.html" AND (tags:"console.html" OR tags:"job-output.txt")
suppress-graph: true suppress-graph: true

View File

@ -1,3 +1,3 @@
query: > query: >
message:"fatal: Could not read from remote repository." message:"fatal: Could not read from remote repository."
AND tags:"console.html" AND (tags:"console.html" OR tags:"job-output.txt")

View File

@ -1,3 +1,3 @@
query: >- query: >-
message:"mount: mounting /dev/sr0 on /mnt failed: Device or resource busy" message:"mount: mounting /dev/sr0 on /mnt failed: Device or resource busy"
AND tags:"console.html" AND (tags:"console.html" OR tags:"job-output.txt")

View File

@ -1,3 +1,3 @@
query: > query: >
message:"HTTP 500 curl 22 The requested URL returned error: 500 Internal Server Error" AND message:"HTTP 500 curl 22 The requested URL returned error: 500 Internal Server Error" AND
filename:"console.html" (filename:"console.html" OR filename:"job-output.txt")