Merge "moving readiness checks into stream"
This commit is contained in:
commit
9a195644d1
@ -144,8 +144,7 @@ class RecheckWatch(threading.Thread):
|
||||
change_id = "%s,%s" % (change, rev)
|
||||
project = event['change']['project']
|
||||
try:
|
||||
bug_numbers = classifier.classify(change, rev,
|
||||
event['comment'])
|
||||
bug_numbers = classifier.classify(change, rev)
|
||||
if not bug_numbers:
|
||||
self._read(event)
|
||||
else:
|
||||
|
@ -17,7 +17,6 @@
|
||||
|
||||
import gerritlib.gerrit
|
||||
import pyelasticsearch
|
||||
import urllib2
|
||||
|
||||
import ConfigParser
|
||||
import logging
|
||||
@ -32,16 +31,24 @@ from elastic_recheck import results
|
||||
|
||||
logging.basicConfig()
|
||||
|
||||
ES_URL = "http://logstash.openstack.org/elasticsearch"
|
||||
|
||||
REQUIRED_FILES = [
|
||||
'console.html',
|
||||
|
||||
def required_files(job):
|
||||
files = ['console.html']
|
||||
if re.match("tempest-dsvm", job):
|
||||
files.extend([
|
||||
'logs/screen-n-api.txt',
|
||||
'logs/screen-n-cpu.txt',
|
||||
'logs/screen-n-sch.txt',
|
||||
'logs/screen-c-api.txt',
|
||||
'logs/screen-c-vol.txt',
|
||||
'logs/syslog.txt',
|
||||
]
|
||||
'logs/syslog.txt'])
|
||||
return files
|
||||
|
||||
|
||||
class ResultNotReady(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class Stream(object):
|
||||
@ -55,6 +62,7 @@ class Stream(object):
|
||||
def __init__(self, user, host, key, thread=True):
|
||||
port = 29418
|
||||
self.gerrit = gerritlib.gerrit.Gerrit(host, user, port, key)
|
||||
self.es = results.SearchEngine(ES_URL)
|
||||
if thread:
|
||||
self.gerrit.startWatching()
|
||||
|
||||
@ -79,40 +87,82 @@ class Stream(object):
|
||||
failed_tests[m.group(1)] = m.group(2)
|
||||
return failed_tests
|
||||
|
||||
def _failed_unit_tests(self, line):
|
||||
"""Did we fail unit tests? If so not a valid failure."""
|
||||
fail = ("FAILURE" in line and ("python2" in line or "pep8" in line))
|
||||
if fail:
|
||||
self.log.debug("Failed unit tests, skipping this result")
|
||||
return fail
|
||||
def _job_console_uploaded(self, change, patch, name):
|
||||
query = qb.result_ready(change, patch, name)
|
||||
r = self.es.search(query, size='10')
|
||||
if len(r) == 0:
|
||||
raise ResultNotReady()
|
||||
|
||||
def _valid_failure(self, line):
|
||||
"""Is this the kind of failure we track."""
|
||||
return "FAILURE" in line and "tempest" in line
|
||||
def _has_required_files(self, change, patch, name):
|
||||
query = qb.files_ready(change, patch)
|
||||
r = self.es.search(query, size='80')
|
||||
files = [x['term'] for x in r.terms]
|
||||
required = required_files(name)
|
||||
missing_files = [x for x in required if x not in files]
|
||||
if len(missing_files) != 0:
|
||||
raise ResultNotReady()
|
||||
|
||||
def _does_es_have_data(self, change_number, patch_number, job_fails):
|
||||
"""Wait till ElasticSearch is ready, but return False if timeout."""
|
||||
NUMBER_OF_RETRIES = 20
|
||||
SLEEP_TIME = 40
|
||||
# this checks that we've got the console log uploaded, need to retry
|
||||
# in case ES goes bonkers on cold data, which it does some times.
|
||||
for i in range(NUMBER_OF_RETRIES):
|
||||
try:
|
||||
for job_name in job_fails:
|
||||
self._job_console_uploaded(
|
||||
change_number, patch_number, job_name)
|
||||
break
|
||||
|
||||
except ResultNotReady:
|
||||
time.sleep(SLEEP_TIME)
|
||||
continue
|
||||
except pyelasticsearch.exceptions.InvalidJsonResponseError:
|
||||
# If ElasticSearch returns an error code, sleep and retry
|
||||
# TODO(jogo): if this works pull out search into a helper
|
||||
# function that does this.
|
||||
self.log.exception(
|
||||
"Elastic Search not responding on attempt %d" % i)
|
||||
time.sleep(NUMBER_OF_RETRIES)
|
||||
continue
|
||||
|
||||
if i == NUMBER_OF_RETRIES - 1:
|
||||
return False
|
||||
|
||||
self.log.debug(
|
||||
"Found hits for change_number: %s, patch_number: %s"
|
||||
% (change_number, patch_number))
|
||||
|
||||
for i in range(NUMBER_OF_RETRIES):
|
||||
try:
|
||||
for job_name in job_fails:
|
||||
self._has_required_files(
|
||||
change_number, patch_number, job_name)
|
||||
self.log.debug(
|
||||
"All files present for change_number: %s, patch_number: %s"
|
||||
% (change_number, patch_number))
|
||||
time.sleep(10)
|
||||
return True
|
||||
except ResultNotReady:
|
||||
time.sleep(SLEEP_TIME)
|
||||
|
||||
# if we get to the end, we're broken
|
||||
return False
|
||||
|
||||
def get_failed_tempest(self):
|
||||
self.log.debug("entering get_failed_tempest")
|
||||
while True:
|
||||
event = self.gerrit.getEvent()
|
||||
failed_jobs = Stream.parse_jenkin_failure(event)
|
||||
failed_jobs = Stream.parse_jenkins_failure(event)
|
||||
if not failed_jobs:
|
||||
# nothing to see here, lets try the next event
|
||||
continue
|
||||
|
||||
self.log.debug("potential failed_tempest")
|
||||
found = False
|
||||
for line in event['comment'].split('\n'):
|
||||
if self._failed_unit_tests(line):
|
||||
found = False
|
||||
break
|
||||
if self._valid_failure(line):
|
||||
url = [x for x in line.split() if "http" in x][0]
|
||||
if RequiredFiles.files_at_url(url):
|
||||
self.log.debug("All file present")
|
||||
found = True
|
||||
if found:
|
||||
change = event['change']['number']
|
||||
rev = event['patchSet']['number']
|
||||
if self._does_es_have_data(change, rev, failed_jobs):
|
||||
return event
|
||||
continue
|
||||
|
||||
def leave_comment(self, project, commit, bugs=None):
|
||||
if bugs:
|
||||
@ -147,12 +197,11 @@ class Classifier():
|
||||
that are mapped to specific bugs.
|
||||
"""
|
||||
log = logging.getLogger("recheckwatchbot")
|
||||
ES_URL = "http://logstash.openstack.org/elasticsearch"
|
||||
|
||||
queries = None
|
||||
|
||||
def __init__(self, queries_dir):
|
||||
self.es = results.SearchEngine(self.ES_URL)
|
||||
self.es = results.SearchEngine(ES_URL)
|
||||
self.queries_dir = queries_dir
|
||||
self.queries = loader.load(self.queries_dir)
|
||||
|
||||
@ -160,20 +209,11 @@ class Classifier():
|
||||
es_query = qb.generic(query, facet=facet)
|
||||
return self.es.search(es_query, size=size)
|
||||
|
||||
def classify(self, change_number, patch_number, comment,
|
||||
skip_resolved=True):
|
||||
def classify(self, change_number, patch_number, skip_resolved=True):
|
||||
"""Returns either empty list or list with matched bugs."""
|
||||
self.log.debug("Entering classify")
|
||||
#Reload each time
|
||||
self.queries = loader.load(self.queries_dir, skip_resolved)
|
||||
#Wait till Elastic search is ready
|
||||
self.log.debug("checking if ElasticSearch is ready")
|
||||
if not self._is_ready(change_number, patch_number, comment):
|
||||
self.log.error(
|
||||
"something went wrong, ElasticSearch is still not ready, "
|
||||
"giving up and trying next failure")
|
||||
return None
|
||||
self.log.debug("ElasticSearch is ready, starting to classify")
|
||||
bug_matches = []
|
||||
for x in self.queries:
|
||||
self.log.debug(
|
||||
@ -181,89 +221,10 @@ class Classifier():
|
||||
% x['bug'])
|
||||
query = qb.single_patch(x['query'], change_number, patch_number)
|
||||
results = self.es.search(query, size='10')
|
||||
if self._urls_match(comment, results):
|
||||
if len(results) > 0:
|
||||
bug_matches.append(x['bug'])
|
||||
return bug_matches
|
||||
|
||||
def _is_ready(self, change_number, patch_number, comment):
|
||||
"""Wait till ElasticSearch is ready, but return False if timeout."""
|
||||
NUMBER_OF_RETRIES = 20
|
||||
SLEEP_TIME = 40
|
||||
query = qb.result_ready(change_number, patch_number)
|
||||
for i in range(NUMBER_OF_RETRIES):
|
||||
try:
|
||||
results = self.es.search(query, size='10')
|
||||
except pyelasticsearch.exceptions.InvalidJsonResponseError:
|
||||
# If ElasticSearch returns an error code, sleep and retry
|
||||
# TODO(jogo): if this works pull out search into a helper
|
||||
# function that does this.
|
||||
print "UHUH hit InvalidJsonResponseError"
|
||||
time.sleep(NUMBER_OF_RETRIES)
|
||||
continue
|
||||
if (len(results) > 0 and self._urls_match(comment, results)):
|
||||
break
|
||||
else:
|
||||
time.sleep(SLEEP_TIME)
|
||||
if i == NUMBER_OF_RETRIES - 1:
|
||||
return False
|
||||
self.log.debug(
|
||||
"Found hits for change_number: %s, patch_number: %s"
|
||||
% (change_number, patch_number))
|
||||
|
||||
query = qb.files_ready(change_number, patch_number)
|
||||
for i in range(NUMBER_OF_RETRIES):
|
||||
results = self.es.search(query, size='80')
|
||||
files = [x['term'] for x in results.terms]
|
||||
missing_files = [x for x in REQUIRED_FILES if x not in files]
|
||||
if len(missing_files) is 0:
|
||||
break
|
||||
else:
|
||||
time.sleep(SLEEP_TIME)
|
||||
if i == NUMBER_OF_RETRIES - 1:
|
||||
return False
|
||||
self.log.debug(
|
||||
"All files present for change_number: %s, patch_number: %s"
|
||||
% (change_number, patch_number))
|
||||
# Just because one file is parsed doesn't mean all are, so wait a
|
||||
# bit
|
||||
time.sleep(10)
|
||||
return True
|
||||
|
||||
def _urls_match(self, comment, results):
|
||||
for result in results:
|
||||
url = result.log_url
|
||||
if RequiredFiles.prep_url(url) in comment:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class RequiredFiles(object):
|
||||
|
||||
log = logging.getLogger("recheckwatchbot")
|
||||
|
||||
@staticmethod
|
||||
def prep_url(url):
|
||||
if isinstance(url, list):
|
||||
# The url is sometimes a list of one value
|
||||
url = url[0]
|
||||
if "/logs/" in url:
|
||||
return '/'.join(url.split('/')[:-2])
|
||||
return '/'.join(url.split('/')[:-1])
|
||||
|
||||
@staticmethod
|
||||
def files_at_url(url):
|
||||
for f in REQUIRED_FILES:
|
||||
try:
|
||||
urllib2.urlopen(url + '/' + f)
|
||||
except urllib2.HTTPError:
|
||||
try:
|
||||
urllib2.urlopen(url + '/' + f + '.gz')
|
||||
except urllib2.HTTPError:
|
||||
# File does not exist at URL
|
||||
RequiredFiles.log.debug("missing file %s" % f)
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def main():
|
||||
config = ConfigParser.ConfigParser()
|
||||
@ -285,7 +246,7 @@ def main():
|
||||
rev = event['patchSet']['number']
|
||||
print "======================="
|
||||
print "https://review.openstack.org/#/c/%(change)s/%(rev)s" % locals()
|
||||
bug_numbers = classifier.classify(change, rev, event['comment'])
|
||||
bug_numbers = classifier.classify(change, rev)
|
||||
if not bug_numbers:
|
||||
print "unable to classify failure"
|
||||
else:
|
||||
|
@ -59,7 +59,7 @@ def generic(raw_query, facet=None):
|
||||
return query
|
||||
|
||||
|
||||
def result_ready(review=None, patch=None):
|
||||
def result_ready(review=None, patch=None, name=None):
|
||||
"""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
|
||||
@ -70,8 +70,9 @@ def result_ready(review=None, patch=None):
|
||||
'OR message:"[SCP] Copying console log") '
|
||||
'AND build_status:"FAILURE" '
|
||||
'AND build_change:"%s" '
|
||||
'AND build_patchset:"%s"' %
|
||||
(review, patch))
|
||||
'AND build_patchset:"%s" '
|
||||
'AND build_name:"%s"' %
|
||||
(review, patch, name))
|
||||
|
||||
|
||||
def files_ready(review, patch):
|
||||
|
35
elastic_recheck/tests/unit/fake_gerrit.py
Normal file
35
elastic_recheck/tests/unit/fake_gerrit.py
Normal file
@ -0,0 +1,35 @@
|
||||
# Copyright 2014 Samsung Electronics. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import json
|
||||
|
||||
|
||||
class GerritDone(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class Gerrit(object):
|
||||
"""A fake gerrit libobject that emits a bunch of events."""
|
||||
def __init__(self, *args):
|
||||
with open("elastic_recheck/tests/unit/gerrit/events.json") as f:
|
||||
self.events = json.load(f)
|
||||
|
||||
def startWatching(self):
|
||||
pass
|
||||
|
||||
def getEvent(self):
|
||||
if len(self.events) > 0:
|
||||
return self.events.pop()
|
||||
else:
|
||||
raise GerritDone()
|
402
elastic_recheck/tests/unit/gerrit/events.json
Normal file
402
elastic_recheck/tests/unit/gerrit/events.json
Normal file
@ -0,0 +1,402 @@
|
||||
[
|
||||
{
|
||||
"comment": "Build succeeded.\n\n- gate-keystone-pep8 http:\/\/logs.openstack.org\/44\/60244\/12\/check\/gate-keystone-pep8\/5ef9f24 : SUCCESS in 1m 40s\n- gate-keystone-docs http:\/\/docs-draft.openstack.org\/44\/60244\/12\/check\/gate-keystone-docs\/60c7b1b\/doc\/build\/html\/ : SUCCESS in 4m 01s\n- gate-keystone-python26 http:\/\/logs.openstack.org\/44\/60244\/12\/check\/gate-keystone-python26\/d66253a : SUCCESS in 18m 02s\n- gate-keystone-python27 http:\/\/logs.openstack.org\/44\/60244\/12\/check\/gate-keystone-python27\/04102a5 : SUCCESS in 13m 57s\n- check-tempest-dsvm-full http:\/\/logs.openstack.org\/44\/60244\/12\/check\/check-tempest-dsvm-full\/0893acf : SUCCESS in 42m 30s\n- check-tempest-dsvm-postgres-full http:\/\/logs.openstack.org\/44\/60244\/12\/check\/check-tempest-dsvm-postgres-full\/671d371 : SUCCESS in 49m 30s\n- check-tempest-dsvm-neutron http:\/\/logs.openstack.org\/44\/60244\/12\/check\/check-tempest-dsvm-neutron\/4981e54 : SUCCESS in 35m 09s\n- gate-tempest-dsvm-large-ops http:\/\/logs.openstack.org\/44\/60244\/12\/check\/gate-tempest-dsvm-large-ops\/9e825fb : SUCCESS in 13m 11s\n- gate-tempest-dsvm-neutron-large-ops http:\/\/logs.openstack.org\/44\/60244\/12\/check\/gate-tempest-dsvm-neutron-large-ops\/286d887 : SUCCESS in 13m 22s\n- check-grenade-dsvm http:\/\/logs.openstack.org\/44\/60244\/12\/check\/check-grenade-dsvm\/b3b7478 : SUCCESS in 32m 01s\n- check-swift-dsvm-functional http:\/\/logs.openstack.org\/44\/60244\/12\/check\/check-swift-dsvm-functional\/350f34c : SUCCESS in 13m 12s\n",
|
||||
"author": {
|
||||
"username": "jenkins",
|
||||
"name": "Jenkins"
|
||||
},
|
||||
"approvals": [
|
||||
{
|
||||
"type": "VRIF",
|
||||
"description": "Verified",
|
||||
"value": "1"
|
||||
}
|
||||
],
|
||||
"patchSet": {
|
||||
"createdOn": 1389371115,
|
||||
"ref": "refs\/changes\/44\/60244\/12",
|
||||
"number": "12",
|
||||
"uploader": {
|
||||
"username": "stevemar",
|
||||
"name": "Steve Martinelli",
|
||||
"email": "stevemar@ca.ibm.com"
|
||||
},
|
||||
"revision": "74d75a1050c96eef498e9daaa80fcb9652003a20"
|
||||
},
|
||||
"type": "comment-added",
|
||||
"change": {
|
||||
"topic": "bp\/mapping",
|
||||
"url": "https:\/\/review.openstack.org\/60244",
|
||||
"number": "60244",
|
||||
"project": "openstack\/keystone",
|
||||
"branch": "master",
|
||||
"owner": {
|
||||
"username": "marek-denis",
|
||||
"name": "Marek Denis",
|
||||
"email": "marek.denis@cern.ch"
|
||||
},
|
||||
"id": "I0ce62e720e797718dbfde6bfcd4b22a213985867",
|
||||
"subject": "Identity Providers CRUD operations."
|
||||
}
|
||||
},
|
||||
{
|
||||
"comment": "Build failed. For information on how to proceed, see https:\/\/wiki.openstack.org\/wiki\/GerritJenkinsGit#Test_Failures\n\n- gate-requirements-pep8 http:\/\/logs.openstack.org\/61\/65361\/2\/check\/gate-requirements-pep8\/e8429d9 : SUCCESS in 25s\n- gate-requirements-python27 http:\/\/logs.openstack.org\/61\/65361\/2\/check\/gate-requirements-python27\/fb66d97 : SUCCESS in 1m 09s\n- gate-requirements-pypy http:\/\/logs.openstack.org\/61\/65361\/2\/check\/gate-requirements-pypy\/592002c : SUCCESS in 2m 09s\n- check-requirements-integration-dsvm http:\/\/logs.openstack.org\/61\/65361\/2\/check\/check-requirements-integration-dsvm\/8209fb4 : FAILURE in 9m 44s\n- check-tempest-dsvm-full http:\/\/logs.openstack.org\/61\/65361\/2\/check\/check-tempest-dsvm-full\/0db6b3f : SUCCESS in 48m 02s\n- check-tempest-dsvm-postgres-full http:\/\/logs.openstack.org\/61\/65361\/2\/check\/check-tempest-dsvm-postgres-full\/4a0c319 : SUCCESS in 45m 10s\n- check-tempest-dsvm-neutron http:\/\/logs.openstack.org\/61\/65361\/2\/check\/check-tempest-dsvm-neutron\/f4323cc : SUCCESS in 36m 49s\n- gate-tempest-dsvm-large-ops http:\/\/logs.openstack.org\/61\/65361\/2\/check\/gate-tempest-dsvm-large-ops\/1e625fc : SUCCESS in 17m 31s\n- gate-tempest-dsvm-neutron-large-ops http:\/\/logs.openstack.org\/61\/65361\/2\/check\/gate-tempest-dsvm-neutron-large-ops\/ffa7ae8 : SUCCESS in 14m 24s\n- check-grenade-dsvm http:\/\/logs.openstack.org\/61\/65361\/2\/check\/check-grenade-dsvm\/c416726 : SUCCESS in 31m 26s\n- check-swift-dsvm-functional http:\/\/logs.openstack.org\/61\/65361\/2\/check\/check-swift-dsvm-functional\/d027be3 : SUCCESS in 14m 30s\n",
|
||||
"author": {
|
||||
"username": "jenkins",
|
||||
"name": "Jenkins"
|
||||
},
|
||||
"approvals": [
|
||||
{
|
||||
"type": "VRIF",
|
||||
"description": "Verified",
|
||||
"value": "-1"
|
||||
}
|
||||
],
|
||||
"patchSet": {
|
||||
"createdOn": 1389384794,
|
||||
"ref": "refs\/changes\/61\/65361\/2",
|
||||
"number": "2",
|
||||
"uploader": {
|
||||
"username": "jaegerandi",
|
||||
"name": "Andreas Jaeger",
|
||||
"email": "jaegerandi@gmail.com"
|
||||
},
|
||||
"revision": "10d31584a0696cd77200a8fee45900d2343e295e"
|
||||
},
|
||||
"type": "comment-added",
|
||||
"change": {
|
||||
"topic": "65361",
|
||||
"url": "https:\/\/review.openstack.org\/65361",
|
||||
"number": "65361",
|
||||
"project": "openstack\/requirements",
|
||||
"branch": "master",
|
||||
"owner": {
|
||||
"username": "jaegerandi",
|
||||
"name": "Andreas Jaeger",
|
||||
"email": "jaegerandi@gmail.com"
|
||||
},
|
||||
"id": "Id6a79d3596c6cfaab92cfb8fc89d4298db61b7f0",
|
||||
"subject": "Add openstack-doc-tools"
|
||||
}
|
||||
},
|
||||
{
|
||||
"comment": "Build failed. For information on how to proceed, see https:\/\/wiki.openstack.org\/wiki\/GerritJenkinsGit#Test_Failures\n\n- gate-horizon-pep8 http:\/\/logs.openstack.org\/78\/63078\/19\/check\/gate-horizon-pep8\/37c96e0 : SUCCESS in 2m 54s\n- gate-horizon-docs http:\/\/docs-draft.openstack.org\/78\/63078\/19\/check\/gate-horizon-docs\/53f3535\/doc\/build\/html\/ : SUCCESS in 7m 10s\n- gate-horizon-python26 http:\/\/logs.openstack.org\/78\/63078\/19\/check\/gate-horizon-python26\/1006347 : SUCCESS in 4m 15s\n- gate-horizon-python27 http:\/\/logs.openstack.org\/78\/63078\/19\/check\/gate-horizon-python27\/a9fb840 : SUCCESS in 4m 07s\n- gate-horizon-python27-django14 http:\/\/logs.openstack.org\/78\/63078\/19\/check\/gate-horizon-python27-django14\/1f9c8e5 : SUCCESS in 5m 18s\n- gate-horizon-selenium http:\/\/logs.openstack.org\/78\/63078\/19\/check\/gate-horizon-selenium\/b215898 : SUCCESS in 3m 08s\n- check-tempest-dsvm-full http:\/\/logs.openstack.org\/78\/63078\/19\/check\/check-tempest-dsvm-full\/ab07162 : FAILURE in 54m 09s\n- check-tempest-dsvm-postgres-full http:\/\/logs.openstack.org\/78\/63078\/19\/check\/check-tempest-dsvm-postgres-full\/9bed62d : SUCCESS in 52m 49s\n- check-tempest-dsvm-neutron http:\/\/logs.openstack.org\/78\/63078\/19\/check\/check-tempest-dsvm-neutron\/06a24c0 : SUCCESS in 36m 00s\n- gate-tempest-dsvm-large-ops http:\/\/logs.openstack.org\/78\/63078\/19\/check\/gate-tempest-dsvm-large-ops\/a522f39 : SUCCESS in 13m 33s\n- gate-tempest-dsvm-neutron-large-ops http:\/\/logs.openstack.org\/78\/63078\/19\/check\/gate-tempest-dsvm-neutron-large-ops\/bcbe1da : SUCCESS in 13m 38s\n- check-grenade-dsvm http:\/\/logs.openstack.org\/78\/63078\/19\/check\/check-grenade-dsvm\/9c5b5d0 : SUCCESS in 27m 49s\n",
|
||||
"author": {
|
||||
"username": "jenkins",
|
||||
"name": "Jenkins"
|
||||
},
|
||||
"approvals": [
|
||||
{
|
||||
"type": "VRIF",
|
||||
"description": "Verified",
|
||||
"value": "-1"
|
||||
}
|
||||
],
|
||||
"patchSet": {
|
||||
"createdOn": 1389383805,
|
||||
"ref": "refs\/changes\/78\/63078\/19",
|
||||
"number": "19",
|
||||
"uploader": {
|
||||
"username": "yves",
|
||||
"name": "Yves-Gwenael Bourhis",
|
||||
"email": "yves-gwenael.bourhis@cloudwatt.com"
|
||||
},
|
||||
"revision": "2e5a51c3f4e0121dbaf47c13b12809f6e7820d09"
|
||||
},
|
||||
"type": "comment-added",
|
||||
"change": {
|
||||
"topic": "bp\/image-flavor-selection-ux-enhancement",
|
||||
"url": "https:\/\/review.openstack.org\/63078",
|
||||
"number": "63078",
|
||||
"project": "openstack\/horizon",
|
||||
"branch": "master",
|
||||
"owner": {
|
||||
"username": "yves",
|
||||
"name": "Yves-Gwenael Bourhis",
|
||||
"email": "yves-gwenael.bourhis@cloudwatt.com"
|
||||
},
|
||||
"id": "I6674ed1983904334c98a7b7d71c58a393858cbc4",
|
||||
"subject": "Changed LaunchInstance workflow to wizard mode"
|
||||
}
|
||||
},
|
||||
{
|
||||
"comment": "Build succeeded.\n\n- check-dg-tempest-dsvm-full http:\/\/logs.openstack.org\/05\/65805\/1\/check\/check-dg-tempest-dsvm-full\/6762ddb : SUCCESS in 51m 22s\n- check-dg-tempest-dsvm-full-reexec http:\/\/logs.openstack.org\/05\/65805\/1\/check\/check-dg-tempest-dsvm-full-reexec\/e97d803 : SUCCESS in 55m 24s\n- check-tempest-dsvm-full http:\/\/logs.openstack.org\/05\/65805\/1\/check\/check-tempest-dsvm-full\/9181576 : SUCCESS in 1h 04m 35s\n- check-tempest-dsvm-postgres-full http:\/\/logs.openstack.org\/05\/65805\/1\/check\/check-tempest-dsvm-postgres-full\/74b4386 : SUCCESS in 1h 29m 32s\n- check-tempest-dsvm-neutron http:\/\/logs.openstack.org\/05\/65805\/1\/check\/check-tempest-dsvm-neutron\/54850dd : SUCCESS in 39m 48s\n- gate-tempest-dsvm-large-ops http:\/\/logs.openstack.org\/05\/65805\/1\/check\/gate-tempest-dsvm-large-ops\/18d9e01 : SUCCESS in 13m 58s\n- gate-tempest-dsvm-neutron-large-ops http:\/\/logs.openstack.org\/05\/65805\/1\/check\/gate-tempest-dsvm-neutron-large-ops\/ee4b7eb : SUCCESS in 14m 12s\n- check-grenade-dsvm http:\/\/logs.openstack.org\/05\/65805\/1\/check\/check-grenade-dsvm\/d1e83f8 : SUCCESS in 35m 05s\n- check-swift-dsvm-functional http:\/\/logs.openstack.org\/05\/65805\/1\/check\/check-swift-dsvm-functional\/5f30c9f : SUCCESS in 15m 23s\n- check-tempest-dsvm-full-grizzly http:\/\/logs.openstack.org\/05\/65805\/1\/check\/check-tempest-dsvm-full-grizzly\/1b8d155 : FAILURE in 57m 18s (non-voting)\n- check-tempest-dsvm-neutron-grizzly http:\/\/logs.openstack.org\/05\/65805\/1\/check\/check-tempest-dsvm-neutron-grizzly\/70ee0a6 : SUCCESS in 22m 14s (non-voting)\n- check-tempest-dsvm-postgres-full-grizzly http:\/\/logs.openstack.org\/05\/65805\/1\/check\/check-tempest-dsvm-postgres-full-grizzly\/fa497b2 : FAILURE in 46m 51s (non-voting)\n- check-devstack-dsvm-cells-grizzly http:\/\/logs.openstack.org\/05\/65805\/1\/check\/check-devstack-dsvm-cells-grizzly\/5318390 : FAILURE in 13m 30s (non-voting)\n- check-tempest-dsvm-cells-grizzly http:\/\/logs.openstack.org\/05\/65805\/1\/check\/check-tempest-dsvm-cells-grizzly\/c01c8a0 : FAILURE in 28m 36s (non-voting)\n- check-tempest-dsvm-cells-full-grizzly http:\/\/logs.openstack.org\/05\/65805\/1\/check\/check-tempest-dsvm-cells-full-grizzly\/78b0d12 : FAILURE in 42m 59s (non-voting)\n- check-tempest-dsvm-full-havana http:\/\/logs.openstack.org\/05\/65805\/1\/check\/check-tempest-dsvm-full-havana\/183d433 : SUCCESS in 51m 17s (non-voting)\n- check-tempest-dsvm-neutron-havana http:\/\/logs.openstack.org\/05\/65805\/1\/check\/check-tempest-dsvm-neutron-havana\/85453e1 : SUCCESS in 31m 06s (non-voting)\n- check-tempest-dsvm-postgres-full-havana http:\/\/logs.openstack.org\/05\/65805\/1\/check\/check-tempest-dsvm-postgres-full-havana\/5243bb4 : SUCCESS in 41m 37s (non-voting)\n- check-devstack-dsvm-cells-havana http:\/\/logs.openstack.org\/05\/65805\/1\/check\/check-devstack-dsvm-cells-havana\/9432a96 : SUCCESS in 11m 11s (non-voting)\n- check-tempest-dsvm-cells-havana http:\/\/logs.openstack.org\/05\/65805\/1\/check\/check-tempest-dsvm-cells-havana\/d856118 : FAILURE in 15m 25s (non-voting)\n- check-tempest-dsvm-cells-full-havana http:\/\/logs.openstack.org\/05\/65805\/1\/check\/check-tempest-dsvm-cells-full-havana\/cc09d3c : FAILURE in 25m 32s (non-voting)\n",
|
||||
"author": {
|
||||
"username": "jenkins",
|
||||
"name": "Jenkins"
|
||||
},
|
||||
"approvals": [
|
||||
{
|
||||
"type": "VRIF",
|
||||
"description": "Verified",
|
||||
"value": "1"
|
||||
}
|
||||
],
|
||||
"patchSet": {
|
||||
"createdOn": 1389306576,
|
||||
"ref": "refs\/changes\/05\/65805\/1",
|
||||
"number": "1",
|
||||
"uploader": {
|
||||
"username": "russellb",
|
||||
"name": "Russell Bryant",
|
||||
"email": "rbryant@redhat.com"
|
||||
},
|
||||
"revision": "3ca110f8dc6a552e951074faaca3a11ce65e40f3"
|
||||
},
|
||||
"type": "comment-added",
|
||||
"change": {
|
||||
"topic": "slow-down-there-cowboy",
|
||||
"url": "https:\/\/review.openstack.org\/65805",
|
||||
"number": "65805",
|
||||
"project": "openstack-infra\/devstack-gate",
|
||||
"branch": "master",
|
||||
"owner": {
|
||||
"username": "russellb",
|
||||
"name": "Russell Bryant",
|
||||
"email": "rbryant@redhat.com"
|
||||
},
|
||||
"id": "I2338ebf5df8bced935e9ed9b0ebd2d4e859b5dbe",
|
||||
"subject": "Cut tempest concurrency in half"
|
||||
}
|
||||
},
|
||||
{
|
||||
"comment": "Build succeeded.\n\n- gate-noop http:\/\/logs.openstack.org\/78\/65378\/15\/check\/gate-noop\/05e95c4 : SUCCESS in 0s\n",
|
||||
"author": {
|
||||
"username": "jenkins",
|
||||
"name": "Jenkins"
|
||||
},
|
||||
"approvals": [
|
||||
{
|
||||
"type": "VRIF",
|
||||
"description": "Verified",
|
||||
"value": "1"
|
||||
}
|
||||
],
|
||||
"patchSet": {
|
||||
"createdOn": 1389391347,
|
||||
"ref": "refs\/changes\/78\/65378\/15",
|
||||
"number": "15",
|
||||
"uploader": {
|
||||
"username": "diane-fleming",
|
||||
"name": "Diane Fleming",
|
||||
"email": "diane.fleming@rackspace.com"
|
||||
},
|
||||
"revision": "4fe4f8b6dda390c432b2c6d2f6cff2152d3475f3"
|
||||
},
|
||||
"type": "comment-added",
|
||||
"change": {
|
||||
"topic": "1187119-a",
|
||||
"url": "https:\/\/review.openstack.org\/65378",
|
||||
"number": "65378",
|
||||
"project": "openstack\/api-site",
|
||||
"branch": "master",
|
||||
"owner": {
|
||||
"username": "diane-fleming",
|
||||
"name": "Diane Fleming",
|
||||
"email": "diane.fleming@rackspace.com"
|
||||
},
|
||||
"id": "I82331b1c3cfc5b19f91f7ac1379476e6a9e6806d",
|
||||
"subject": "Update object-api wadl with comments from Donagh"
|
||||
}
|
||||
},
|
||||
{
|
||||
"comment": "Build failed. For information on how to proceed, see https:\/\/wiki.openstack.org\/wiki\/GerritJenkinsGit#Test_Failures\n\n- gate-keystone-pep8 http:\/\/logs.openstack.org\/49\/64749\/6\/check\/gate-keystone-pep8\/16e0b97 : SUCCESS in 2m 25s\n- gate-keystone-docs http:\/\/docs-draft.openstack.org\/49\/64749\/6\/check\/gate-keystone-docs\/77c8f7a\/doc\/build\/html\/ : SUCCESS in 5m 25s\n- gate-keystone-python26 http:\/\/logs.openstack.org\/49\/64749\/6\/check\/gate-keystone-python26\/d3fd328 : FAILURE in 18m 04s\n- gate-keystone-python27 http:\/\/logs.openstack.org\/49\/64749\/6\/check\/gate-keystone-python27\/5dd41fe : FAILURE in 10m 01s\n- check-tempest-dsvm-full http:\/\/logs.openstack.org\/49\/64749\/6\/check\/check-tempest-dsvm-full\/fce905d : SUCCESS in 46m 00s\n- check-tempest-dsvm-postgres-full http:\/\/logs.openstack.org\/49\/64749\/6\/check\/check-tempest-dsvm-postgres-full\/e5cd968 : SUCCESS in 53m 30s\n- check-tempest-dsvm-neutron http:\/\/logs.openstack.org\/49\/64749\/6\/check\/check-tempest-dsvm-neutron\/0673b30 : SUCCESS in 37m 25s\n- gate-tempest-dsvm-large-ops http:\/\/logs.openstack.org\/49\/64749\/6\/check\/gate-tempest-dsvm-large-ops\/bdc661a : SUCCESS in 13m 21s\n- gate-tempest-dsvm-neutron-large-ops http:\/\/logs.openstack.org\/49\/64749\/6\/check\/gate-tempest-dsvm-neutron-large-ops\/991887c : SUCCESS in 12m 28s\n- check-grenade-dsvm http:\/\/logs.openstack.org\/49\/64749\/6\/check\/check-grenade-dsvm\/d098069 : SUCCESS in 31m 05s\n- check-swift-dsvm-functional http:\/\/logs.openstack.org\/49\/64749\/6\/check\/check-swift-dsvm-functional\/2f9377b : SUCCESS in 11m 56s\n",
|
||||
"author": {
|
||||
"username": "jenkins",
|
||||
"name": "Jenkins"
|
||||
},
|
||||
"approvals": [
|
||||
{
|
||||
"type": "VRIF",
|
||||
"description": "Verified",
|
||||
"value": "-1"
|
||||
}
|
||||
],
|
||||
"patchSet": {
|
||||
"createdOn": 1389378289,
|
||||
"ref": "refs\/changes\/49\/64749\/6",
|
||||
"number": "6",
|
||||
"uploader": {
|
||||
"username": "blk-u",
|
||||
"name": "Brant Knudson",
|
||||
"email": "bknudson@us.ibm.com"
|
||||
},
|
||||
"revision": "06b14616cb2a11514b0c151cc213c1ab5cea324b"
|
||||
},
|
||||
"type": "comment-added",
|
||||
"change": {
|
||||
"topic": "bug\/1265108",
|
||||
"url": "https:\/\/review.openstack.org\/64749",
|
||||
"number": "64749",
|
||||
"project": "openstack\/keystone",
|
||||
"branch": "master",
|
||||
"owner": {
|
||||
"username": "blk-u",
|
||||
"name": "Brant Knudson",
|
||||
"email": "bknudson@us.ibm.com"
|
||||
},
|
||||
"id": "I890a1c798d7f4a8a345404cd7754708ab0d36651",
|
||||
"subject": "Enhance auth tests for non-default default_domain_id"
|
||||
}
|
||||
},
|
||||
{
|
||||
"comment": "Build succeeded.\n\n- gate-neutron-pep8 http:\/\/logs.openstack.org\/02\/65902\/3\/check\/gate-neutron-pep8\/0ef123c : SUCCESS in 2m 13s\n- gate-neutron-docs http:\/\/docs-draft.openstack.org\/02\/65902\/3\/check\/gate-neutron-docs\/4a7a2ce\/doc\/build\/html\/ : SUCCESS in 1m 43s\n- gate-neutron-python26 http:\/\/logs.openstack.org\/02\/65902\/3\/check\/gate-neutron-python26\/d3e596e : SUCCESS in 43m 38s\n- gate-neutron-python27 http:\/\/logs.openstack.org\/02\/65902\/3\/check\/gate-neutron-python27\/525acec : SUCCESS in 27m 10s\n- check-tempest-dsvm-neutron http:\/\/logs.openstack.org\/02\/65902\/3\/check\/check-tempest-dsvm-neutron\/469682a : SUCCESS in 35m 59s\n- check-tempest-dsvm-neutron-pg http:\/\/logs.openstack.org\/02\/65902\/3\/check\/check-tempest-dsvm-neutron-pg\/91e8f4f : SUCCESS in 37m 11s\n- check-tempest-dsvm-neutron-isolated http:\/\/logs.openstack.org\/02\/65902\/3\/check\/check-tempest-dsvm-neutron-isolated\/90021b9 : SUCCESS in 41m 27s\n- check-tempest-dsvm-neutron-pg-isolated http:\/\/logs.openstack.org\/02\/65902\/3\/check\/check-tempest-dsvm-neutron-pg-isolated\/7bc809a : SUCCESS in 45m 35s\n- gate-tempest-dsvm-neutron-large-ops http:\/\/logs.openstack.org\/02\/65902\/3\/check\/gate-tempest-dsvm-neutron-large-ops\/aea24f9 : SUCCESS in 15m 01s\n- check-grenade-dsvm-neutron http:\/\/logs.openstack.org\/02\/65902\/3\/check\/check-grenade-dsvm-neutron\/59354b6 : FAILURE in 20m 16s (non-voting)\n- check-devstack-dsvm-neutron http:\/\/logs.openstack.org\/02\/65902\/3\/check\/check-devstack-dsvm-neutron\/d347313 : FAILURE in 17m 10s (non-voting)\n",
|
||||
"author": {
|
||||
"username": "jenkins",
|
||||
"name": "Jenkins"
|
||||
},
|
||||
"approvals": [
|
||||
{
|
||||
"type": "VRIF",
|
||||
"description": "Verified",
|
||||
"value": "1"
|
||||
}
|
||||
],
|
||||
"patchSet": {
|
||||
"createdOn": 1389387264,
|
||||
"ref": "refs\/changes\/02\/65902\/3",
|
||||
"number": "3",
|
||||
"uploader": {
|
||||
"username": "nanjj",
|
||||
"name": "Jun Jie Nan",
|
||||
"email": "nanjj@cn.ibm.com"
|
||||
},
|
||||
"revision": "8044bcbfe8f10aa3f965992e30e9548258d6c736"
|
||||
},
|
||||
"type": "comment-added",
|
||||
"change": {
|
||||
"topic": "bugs\/1267682",
|
||||
"url": "https:\/\/review.openstack.org\/65902",
|
||||
"number": "65902",
|
||||
"project": "openstack\/neutron",
|
||||
"branch": "master",
|
||||
"owner": {
|
||||
"username": "nanjj",
|
||||
"name": "Jun Jie Nan",
|
||||
"email": "nanjj@cn.ibm.com"
|
||||
},
|
||||
"id": "Id52c04b4739d2d11fe52d4b1631cb4f39e6b577f",
|
||||
"subject": "Check vxlan enablement via modinfo"
|
||||
}
|
||||
},
|
||||
{
|
||||
"comment": "Build succeeded.\n\n- gate-glance-pep8 http:\/\/logs.openstack.org\/64\/66064\/1\/check\/gate-glance-pep8\/250a70c : SUCCESS in 1m 50s\n- gate-glance-docs http:\/\/docs-draft.openstack.org\/64\/66064\/1\/check\/gate-glance-docs\/c641b72\/doc\/build\/html\/ : SUCCESS in 1m 55s\n- gate-glance-python26 http:\/\/logs.openstack.org\/64\/66064\/1\/check\/gate-glance-python26\/c36e87a : SUCCESS in 8m 57s\n- gate-glance-python27 http:\/\/logs.openstack.org\/64\/66064\/1\/check\/gate-glance-python27\/fb29142 : SUCCESS in 12m 30s\n- check-tempest-dsvm-full http:\/\/logs.openstack.org\/64\/66064\/1\/check\/check-tempest-dsvm-full\/21c38f3 : SUCCESS in 43m 54s\n- check-tempest-dsvm-postgres-full http:\/\/logs.openstack.org\/64\/66064\/1\/check\/check-tempest-dsvm-postgres-full\/958323e : SUCCESS in 42m 43s\n- check-tempest-dsvm-neutron http:\/\/logs.openstack.org\/64\/66064\/1\/check\/check-tempest-dsvm-neutron\/3824a0d : SUCCESS in 35m 09s\n- gate-tempest-dsvm-large-ops http:\/\/logs.openstack.org\/64\/66064\/1\/check\/gate-tempest-dsvm-large-ops\/3f113a8 : SUCCESS in 13m 20s\n- gate-tempest-dsvm-neutron-large-ops http:\/\/logs.openstack.org\/64\/66064\/1\/check\/gate-tempest-dsvm-neutron-large-ops\/f527f8c : SUCCESS in 12m 49s\n- check-grenade-dsvm http:\/\/logs.openstack.org\/64\/66064\/1\/check\/check-grenade-dsvm\/ab6a585 : SUCCESS in 28m 47s\n",
|
||||
"author": {
|
||||
"username": "jenkins",
|
||||
"name": "Jenkins"
|
||||
},
|
||||
"approvals": [
|
||||
{
|
||||
"type": "VRIF",
|
||||
"description": "Verified",
|
||||
"value": "1"
|
||||
}
|
||||
],
|
||||
"patchSet": {
|
||||
"createdOn": 1389388172,
|
||||
"ref": "refs\/changes\/64\/66064\/1",
|
||||
"number": "1",
|
||||
"uploader": {
|
||||
"username": "arnaud",
|
||||
"name": "Arnaud Legendre",
|
||||
"email": "arnaudleg@gmail.com"
|
||||
},
|
||||
"revision": "b05c9313f6873239897d7c88babdfa8ebe5fefed"
|
||||
},
|
||||
"type": "comment-added",
|
||||
"change": {
|
||||
"topic": "bug\/1253497",
|
||||
"url": "https:\/\/review.openstack.org\/66064",
|
||||
"number": "66064",
|
||||
"project": "openstack\/glance",
|
||||
"branch": "master",
|
||||
"owner": {
|
||||
"username": "arnaud",
|
||||
"name": "Arnaud Legendre",
|
||||
"email": "arnaudleg@gmail.com"
|
||||
},
|
||||
"id": "I657e20ac39fbace60f230652912a4bf792836206",
|
||||
"subject": "Update `openstack\/common\/context.py' from Oslo"
|
||||
}
|
||||
},
|
||||
{
|
||||
"comment": "Build succeeded.\n\n- gate-savanna-docs http:\/\/docs-draft.openstack.org\/25\/65925\/1\/gate\/gate-savanna-docs\/412dd7e\/doc\/build\/html\/ : SUCCESS in 2m 19s\n- gate-savanna-pep8 http:\/\/logs.openstack.org\/25\/65925\/1\/gate\/gate-savanna-pep8\/0e076e8 : SUCCESS in 2m 40s\n- gate-savanna-python26 http:\/\/logs.openstack.org\/25\/65925\/1\/gate\/gate-savanna-python26\/6f15ba8 : SUCCESS in 1m 57s\n- gate-savanna-python27 http:\/\/logs.openstack.org\/25\/65925\/1\/gate\/gate-savanna-python27\/e0545bd : SUCCESS in 2m 12s\n- gate-tempest-dsvm-savanna-full http:\/\/logs.openstack.org\/25\/65925\/1\/gate\/gate-tempest-dsvm-savanna-full\/04a5c22 : SUCCESS in 53m 34s (non-voting)\n- gate-tempest-dsvm-savanna-postgres-full http:\/\/logs.openstack.org\/25\/65925\/1\/gate\/gate-tempest-dsvm-savanna-postgres-full\/0143007 : SUCCESS in 43m 15s (non-voting)\n- gate-tempest-dsvm-savanna-neutron http:\/\/logs.openstack.org\/25\/65925\/1\/gate\/gate-tempest-dsvm-savanna-neutron\/350d103 : SUCCESS in 39m 27s (non-voting)\n",
|
||||
"author": {
|
||||
"username": "jenkins",
|
||||
"name": "Jenkins"
|
||||
},
|
||||
"approvals": [
|
||||
{
|
||||
"type": "VRIF",
|
||||
"description": "Verified",
|
||||
"value": "2"
|
||||
}
|
||||
],
|
||||
"patchSet": {
|
||||
"createdOn": 1389354908,
|
||||
"ref": "refs\/changes\/25\/65925\/1",
|
||||
"number": "1",
|
||||
"uploader": {
|
||||
"username": "sreshetniak",
|
||||
"name": "Sergey Reshetnyak",
|
||||
"email": "sreshetniak@mirantis.com"
|
||||
},
|
||||
"revision": "fd9bee400259d370e837799236b0a4a6f0343438"
|
||||
},
|
||||
"type": "comment-added",
|
||||
"change": {
|
||||
"topic": "del-param",
|
||||
"url": "https:\/\/review.openstack.org\/65925",
|
||||
"number": "65925",
|
||||
"project": "openstack\/savanna",
|
||||
"branch": "master",
|
||||
"owner": {
|
||||
"username": "sreshetniak",
|
||||
"name": "Sergey Reshetnyak",
|
||||
"email": "sreshetniak@mirantis.com"
|
||||
},
|
||||
"id": "I3e48e344b079c8eef81a18176147b8aec3c9f3b1",
|
||||
"subject": "Remove unused node_group parameter in get_config_value"
|
||||
}
|
||||
},
|
||||
{
|
||||
"comment": "Build succeeded.\n\n- gate-heat-docs http:\/\/docs-draft.openstack.org\/74\/61074\/12\/gate\/gate-heat-docs\/6afb5bb\/doc\/build\/html\/ : SUCCESS in 2m 20s\n- gate-heat-pep8 http:\/\/logs.openstack.org\/74\/61074\/12\/gate\/gate-heat-pep8\/9e7f091 : SUCCESS in 2m 33s\n- gate-heat-python26 http:\/\/logs.openstack.org\/74\/61074\/12\/gate\/gate-heat-python26\/011dd18 : SUCCESS in 2m 50s\n- gate-heat-python27 http:\/\/logs.openstack.org\/74\/61074\/12\/gate\/gate-heat-python27\/c883c86 : SUCCESS in 1m 54s\n- gate-tempest-dsvm-full http:\/\/logs.openstack.org\/74\/61074\/12\/gate\/gate-tempest-dsvm-full\/f228dfb : SUCCESS in 42m 46s\n- gate-tempest-dsvm-postgres-full http:\/\/logs.openstack.org\/74\/61074\/12\/gate\/gate-tempest-dsvm-postgres-full\/6f05326 : SUCCESS in 1h 21m 14s\n- gate-tempest-dsvm-neutron http:\/\/logs.openstack.org\/74\/61074\/12\/gate\/gate-tempest-dsvm-neutron\/3b361dc : SUCCESS in 43m 33s\n- gate-tempest-dsvm-large-ops http:\/\/logs.openstack.org\/74\/61074\/12\/gate\/gate-tempest-dsvm-large-ops\/47d0217 : SUCCESS in 14m 39s\n- gate-tempest-dsvm-neutron-large-ops http:\/\/logs.openstack.org\/74\/61074\/12\/gate\/gate-tempest-dsvm-neutron-large-ops\/cb67ba1 : SUCCESS in 15m 26s\n",
|
||||
"author": {
|
||||
"username": "jenkins",
|
||||
"name": "Jenkins"
|
||||
},
|
||||
"approvals": [
|
||||
{
|
||||
"type": "VRIF",
|
||||
"description": "Verified",
|
||||
"value": "2"
|
||||
}
|
||||
],
|
||||
"patchSet": {
|
||||
"createdOn": 1387806669,
|
||||
"ref": "refs\/changes\/74\/61074\/12",
|
||||
"number": "12",
|
||||
"uploader": {
|
||||
"username": "smelikyan",
|
||||
"name": "Serg Melikyan",
|
||||
"email": "smelikyan@mirantis.com"
|
||||
},
|
||||
"revision": "af064c7a5304c672f7d71e4c8df5f69c195c739a"
|
||||
},
|
||||
"type": "comment-added",
|
||||
"change": {
|
||||
"topic": "bug\/1259078",
|
||||
"url": "https:\/\/review.openstack.org\/61074",
|
||||
"number": "61074",
|
||||
"project": "openstack\/heat",
|
||||
"branch": "master",
|
||||
"owner": {
|
||||
"username": "smelikyan",
|
||||
"name": "Serg Melikyan",
|
||||
"email": "smelikyan@mirantis.com"
|
||||
},
|
||||
"id": "I9afd1a8c222110899a90a940e7a549278c4467b7",
|
||||
"subject": "Added session_persistence property to VIP"
|
||||
}
|
||||
}
|
||||
]
|
@ -1,116 +0,0 @@
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from elastic_recheck import elasticRecheck
|
||||
from elastic_recheck import loader
|
||||
from elastic_recheck import results
|
||||
from elastic_recheck import tests
|
||||
|
||||
|
||||
def fake_queries(directory='queries', skip_resolved=True):
|
||||
queries = [
|
||||
{'query': '@message:"fake query" AND @fields.filename:"fake"\n',
|
||||
'bug': 1226337},
|
||||
{'query': 'magic query',
|
||||
'bug': 1234567},
|
||||
{'query': '@message:"fake_query3" AND @fields.filename:"fake"\n',
|
||||
'bug': 1235437}]
|
||||
if not skip_resolved:
|
||||
queries.append({'query': 'magic query',
|
||||
'bug': 1252514,
|
||||
'resolved_at': 'Tue Dec 10 12:08:42 EST 2013'})
|
||||
return queries
|
||||
|
||||
|
||||
def _fake_search(query, size=None):
|
||||
files = ['console.html', 'logs/screen-n-api.txt',
|
||||
'logs/screen-n-cpu.txt', 'logs/screen-n-sch.txt',
|
||||
'logs/screen-c-api.txt', 'logs/screen-c-vol.txt',
|
||||
'logs/syslog.txt']
|
||||
file_list = []
|
||||
for f in files:
|
||||
file_list.append({'term': f})
|
||||
log_url = ('http://logs.openstack.org/57/51057/1/gate/gate-tempest-'
|
||||
'devstack-vm-full/f8965ee/console.html')
|
||||
hit_dict = {'_source': {'@fields': {'log_url': log_url}}}
|
||||
if 'magic query' in query['query']['query_string']['query']:
|
||||
fake_result = results.ResultSet(
|
||||
{'hits': {'total': 2, 'hits': [hit_dict, hit_dict]},
|
||||
'facets': {'tag': {'terms': file_list}}})
|
||||
else:
|
||||
fake_result = results.ResultSet(
|
||||
{'hits': {'total': 1, 'hits': [hit_dict]},
|
||||
'facets': {'tag': {'terms': file_list}}})
|
||||
return fake_result
|
||||
|
||||
|
||||
def _fake_urls_match(comment, results):
|
||||
# TODO(sdague): this is not a good fake url work around, however it will
|
||||
# get us through the merge in of the new result sets. We'll eventually
|
||||
# make this actual life like data.
|
||||
if len(results) == 2:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def _fake_is_ready_urls_match(comment, results):
|
||||
return True
|
||||
|
||||
|
||||
def _fake_is_ready(change_number, patch_number, comment):
|
||||
return True
|
||||
|
||||
|
||||
class TestClassifier(tests.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestClassifier, self).setUp()
|
||||
self.stubs.Set(loader, 'load', fake_queries)
|
||||
self.classifier = elasticRecheck.Classifier('queries.yaml')
|
||||
|
||||
def test_is_ready(self):
|
||||
self.stubs.Set(self.classifier.es, 'search', _fake_search)
|
||||
result = self.classifier._is_ready(
|
||||
'49282',
|
||||
'3',
|
||||
'BLAH http://logs.openstack.org/57/51057/1/gate/'
|
||||
'gate-tempest-devstack-vm-full/f8965ee'
|
||||
)
|
||||
self.assertTrue(result)
|
||||
|
||||
def test_classify(self):
|
||||
self.stubs.Set(self.classifier.es, 'search', _fake_search)
|
||||
self.stubs.Set(self.classifier, '_urls_match', _fake_urls_match)
|
||||
self.stubs.Set(self.classifier, '_is_ready', _fake_is_ready)
|
||||
bug_numbers = self.classifier.classify(
|
||||
'47463',
|
||||
'3',
|
||||
' blah http://logs.openstack.org/63/47463/3/gate/gate-tempest'
|
||||
'-devstack-vm-postgres-full/99bb8f6'
|
||||
)
|
||||
self.assertEqual(bug_numbers, [1234567])
|
||||
|
||||
def test_classify_without_skipping_resolved_bugs(self):
|
||||
self.stubs.Set(self.classifier.es, 'search', _fake_search)
|
||||
self.stubs.Set(self.classifier, '_urls_match', _fake_urls_match)
|
||||
self.stubs.Set(self.classifier, '_is_ready', _fake_is_ready)
|
||||
bug_numbers = self.classifier.classify(
|
||||
'47463',
|
||||
'3',
|
||||
' blah http://logs.openstack.org/63/47463/3/gate/gate-tempest'
|
||||
'-devstack-vm-postgres-full/99bb8f6',
|
||||
False
|
||||
)
|
||||
self.assertEqual(bug_numbers, [1234567, 1252514])
|
@ -1,51 +0,0 @@
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import urllib2
|
||||
|
||||
from elastic_recheck import elasticRecheck
|
||||
from elastic_recheck import tests
|
||||
|
||||
|
||||
class TestRequiredFiles(tests.TestCase):
|
||||
def test_url(self):
|
||||
url = elasticRecheck.RequiredFiles.prep_url(
|
||||
'http://logs.openstack.org/13/46613/2/check/'
|
||||
'gate-tempest-devstack-vm-full/864bf44/console.html')
|
||||
self.assertEqual(
|
||||
url,
|
||||
'http://logs.openstack.org/13/46613/2/check/'
|
||||
'gate-tempest-devstack-vm-full/864bf44')
|
||||
|
||||
def _fake_urlopen(self, url):
|
||||
pass
|
||||
|
||||
def test_files_at_url_pass(self):
|
||||
self.stubs.Set(urllib2, 'urlopen', self._fake_urlopen)
|
||||
result = elasticRecheck.RequiredFiles.files_at_url(
|
||||
'http://logs.openstack.org/13/46613/2/check/'
|
||||
'gate-tempest-devstack-vm-full/864bf44')
|
||||
self.assertTrue(result)
|
||||
|
||||
def _invalid_url_open(self, url):
|
||||
raise urllib2.HTTPError(url, 404, 'NotFound', '', None)
|
||||
|
||||
def test_files_at_url_fail(self):
|
||||
self.stubs.Set(urllib2, 'urlopen', self._invalid_url_open)
|
||||
self.assertFalse(elasticRecheck.RequiredFiles.files_at_url(
|
||||
'http://logs.openstack.org/02/44502/7/check/'
|
||||
'gate-tempest-devstack-vm-neutron/4f386e5'))
|
||||
self.assertFalse(elasticRecheck.RequiredFiles.files_at_url(
|
||||
'http://logs.openstack.org/45/47445/3/check/'
|
||||
'gate-tempest-devstack-vm-full/0e43e09/'))
|
@ -14,26 +14,50 @@
|
||||
|
||||
import json
|
||||
|
||||
import fixtures
|
||||
import mock
|
||||
|
||||
from elastic_recheck import elasticRecheck
|
||||
from elastic_recheck import tests
|
||||
import elastic_recheck.tests.unit.fake_gerrit as fg
|
||||
|
||||
|
||||
class TestStream(tests.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestStream, self).setUp()
|
||||
with open("elastic_recheck/tests/unit/jenkins/events.json") as f:
|
||||
j = json.load(f)
|
||||
self.events = j['events']
|
||||
self.useFixture(fixtures.MonkeyPatch(
|
||||
'gerritlib.gerrit.Gerrit',
|
||||
fg.Gerrit))
|
||||
|
||||
def test_gerrit_parsing_none(self):
|
||||
self.assertFalse(
|
||||
elasticRecheck.Stream.parse_jenkins_failure(self.events[1]))
|
||||
self.assertFalse(
|
||||
elasticRecheck.Stream.parse_jenkins_failure(self.events[2]))
|
||||
def test_gerrit_stream(self):
|
||||
"""Tests that we can use our mock gerrit to process events."""
|
||||
with mock.patch.object(
|
||||
elasticRecheck.Stream, '_does_es_have_data') as mock_data:
|
||||
mock_data.return_value = True
|
||||
stream = elasticRecheck.Stream("", "", "")
|
||||
|
||||
# there are currently 10 events in the stream, 3 are
|
||||
# failures
|
||||
for i in xrange(3):
|
||||
event = stream.get_failed_tempest()
|
||||
self.assertEqual(event['author']['username'], 'jenkins')
|
||||
self.assertIn('Build failed', event['comment'])
|
||||
self.assertRaises(
|
||||
fg.GerritDone,
|
||||
stream.get_failed_tempest)
|
||||
|
||||
def test_gerrit_parsing(self):
|
||||
jobs = elasticRecheck.Stream.parse_jenkins_failure(self.events[0])
|
||||
with open("elastic_recheck/tests/unit/jenkins/events.json") as f:
|
||||
j = json.load(f)
|
||||
events = j['events']
|
||||
|
||||
self.assertFalse(
|
||||
elasticRecheck.Stream.parse_jenkins_failure(events[1]))
|
||||
self.assertFalse(
|
||||
elasticRecheck.Stream.parse_jenkins_failure(events[2]))
|
||||
|
||||
jobs = elasticRecheck.Stream.parse_jenkins_failure(events[0])
|
||||
self.assertIn('check-requirements-integration-dsvm', jobs)
|
||||
self.assertIn('check-tempest-dsvm-full', jobs)
|
||||
self.assertIn('check-tempest-dsvm-postgres-full', jobs)
|
||||
|
@ -10,3 +10,4 @@ testrepository>=0.0.17
|
||||
testscenarios>=0.4,<0.5
|
||||
testtools>=0.9.32
|
||||
mox>=0.5.3
|
||||
mock>=1.0
|
||||
|
Loading…
Reference in New Issue
Block a user