blob: 823660699087297ca7542783074f5d943e21720f [file] [log] [blame]
Joshua Heskethda8ac652014-07-09 20:13:46 +10001#!/usr/bin/python
2# This tool is useful to query gerrit for negative or missing votes left by
3# a user. It may require tweaking for different failure messages etc.
4
5import json
6import requests
7import traceback
8
9# Set the user to watch
10user = 'turbo-hipster'
Joshua Hesketh0d2c8b82014-08-14 12:51:46 +100011author_name = 'DB Datasets CI'
Joshua Hesketh426742f2015-12-17 17:11:38 +110012author_account_id = 9578
Joshua Hesketh6730ed42015-06-12 21:33:57 +100013upstream_user = 'jenkins'
14upstream_author_name = "Jenkins"
Joshua Hesketh426742f2015-12-17 17:11:38 +110015upstream_author_account_id = 3
Joshua Heskethda8ac652014-07-09 20:13:46 +100016
17# Grab a list of missing or negative reviews for a user:
18url = ("https://review.openstack.org/changes/?q=status:open "
19 "project:openstack/nova NOT label:Verified>=0,%s "
20 "branch:master&o=CURRENT_REVISION&o=MESSAGES" % user)
21
22print "Grabbing reviews from %s" % url
23r = requests.get(url)
24
25no_votes = []
26negative_votes = []
27merge_failures = []
Joshua Hesketh6730ed42015-06-12 21:33:57 +100028upstream_merge_failures = []
Joshua Heskethda8ac652014-07-09 20:13:46 +100029unknown = []
30
31for change in json.loads(r.text[5:]):
32 try:
33 patchset = change['revisions'][change['current_revision']]['_number']
34 change_id = str(change['_number']) + ',' + str(patchset)
35 last_message = None
Joshua Hesketh6730ed42015-06-12 21:33:57 +100036 last_upstream_message = None
Joshua Heskethda8ac652014-07-09 20:13:46 +100037 for message in sorted(change['messages'],
38 key=lambda k: (k['_revision_number'],
39 k['date']), reverse=True):
40 if message['_revision_number'] < patchset:
41 # Finished looking at all the messages on this patchset
42 break
Joshua Hesketh426742f2015-12-17 17:11:38 +110043 if (not last_message and
44 message['author']['_account_id'] == author_account_id):
Joshua Heskethda8ac652014-07-09 20:13:46 +100045 last_message = message['message']
Joshua Hesketh6730ed42015-06-12 21:33:57 +100046 if (not last_upstream_message and
Joshua Hesketh426742f2015-12-17 17:11:38 +110047 message['author']['_account_id'] ==
48 upstream_author_account_id):
Joshua Hesketh6730ed42015-06-12 21:33:57 +100049 last_upstream_message = message['message']
Joshua Heskethda8ac652014-07-09 20:13:46 +100050
Joshua Hesketh6730ed42015-06-12 21:33:57 +100051 if (last_upstream_message and
52 'Merge Failed.' in last_upstream_message.split('\n')[2]):
53 upstream_merge_failures.append({
54 'change_id': change_id,
55 'updated': change['updated'],
56 'change': change,
57 'last_upstream_message': last_upstream_message,
58 })
59 elif not last_message:
Joshua Heskethda8ac652014-07-09 20:13:46 +100060 # turbo-hister hasn't commented on this patchset
61 no_votes.append({
62 'change_id': change_id,
63 'updated': change['updated'],
Joshua Hesketh6730ed42015-06-12 21:33:57 +100064 'change': change,
65 'last_upstream_message': last_upstream_message,
Joshua Heskethda8ac652014-07-09 20:13:46 +100066 })
67 elif ('This change was unable to be automatically merged with the '
68 'current state of the repository.' in last_message):
69 merge_failures.append({
70 'change_id': change_id,
71 'updated': change['updated'],
Joshua Hesketh6730ed42015-06-12 21:33:57 +100072 'change': change,
73 'last_upstream_message': last_upstream_message,
Joshua Heskethda8ac652014-07-09 20:13:46 +100074 })
75 elif 'Database migration testing failed' in last_message:
76 negative_votes.append({
77 'change_id': change_id,
78 'updated': change['updated'],
Joshua Hesketh6730ed42015-06-12 21:33:57 +100079 'change': change,
80 'last_upstream_message': last_upstream_message,
Joshua Heskethda8ac652014-07-09 20:13:46 +100081 })
82 else:
83 unknown.append({
84 'change_id': change_id,
85 'updated': change['updated'],
Joshua Hesketh6730ed42015-06-12 21:33:57 +100086 'change': change,
87 'last_upstream_message': last_upstream_message,
Joshua Heskethda8ac652014-07-09 20:13:46 +100088 })
89
90 except Exception:
91 print "Something failed.. Here is the change..."
92 print change
93 traceback.print_exc()
94
95
96def print_enqueues(changes):
97 for change in sorted(changes, key=lambda k: k['updated'], reverse=True):
98 print ("zuul enqueue --trigger gerrit --pipeline check "
99 "--project openstack/nova --change %s" % (change['change_id']))
100
101print "=" * 20 + (" Changes with no votes (%d) " % len(no_votes)) + "=" * 20
102print_enqueues(no_votes)
103print ("=" * 20 + (" Changes with negative votes (%d) " % len(negative_votes))
104 + "=" * 20)
105print_enqueues(negative_votes)
106print ("=" * 20 + (" Changes with merge failure (%d) " % len(merge_failures)) +
107 "=" * 20)
108print_enqueues(merge_failures)
109print "=" * 20 + (" Others in this query (%d) " % len(unknown)) + "=" * 20
110print_enqueues(unknown)
Joshua Hesketh6730ed42015-06-12 21:33:57 +1000111print "=" * 20 + (" Changes with merge failures upstream (%d) "
112 % len(upstream_merge_failures)) + "=" * 20
113print_enqueues(upstream_merge_failures)