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:
parent
fe21639a1a
commit
97f6408b54
@ -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
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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}" ')
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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")
|
||||||
|
@ -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")
|
||||||
|
@ -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")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user