Merge lp:~milo/linaro-patchmetrics/bug1013577 into lp:linaro-patchmetrics

Proposed by Milo Casagrande
Status: Merged
Merged at revision: 365
Proposed branch: lp:~milo/linaro-patchmetrics/bug1013577
Merge into: lp:linaro-patchmetrics
Diff against target: 219 lines (+79/-31)
4 files modified
apps/patchmetrics/bin/sync-gerrit-changes.py (+25/-18)
apps/patchmetrics/gerrit.py (+18/-9)
apps/patchmetrics/gerrit_values.py (+12/-1)
apps/patchmetrics/tests/test_gerrit.py (+24/-3)
To merge this branch: bzr merge lp:~milo/linaro-patchmetrics/bug1013577
Reviewer Review Type Date Requested Status
Deepti B. Kalakeri (community) Approve
Review via email: mp+112290@code.launchpad.net

Description of the change

Hello,

requesting a new merge: we are still getting the error from gerrit about user not found, but this should be handled correctly. I fixed the error string we get back to be exactly as the one we receive, fixed also the query parameters to use to start a new query from the last value. I renamed one module to use a more generic name in order to store also other values than JSON keys.

To post a comment you must log in.
370. By Milo Casagrande

Remove white chars from email, just in case.

371. By Milo Casagrande

Force string on the query, and remove white spaces.

372. By Milo Casagrande

Fixed param name on docstring.

Revision history for this message
Deepti B. Kalakeri (deeptik) wrote :

As discussed on IRC, somehow the email formation/query seems to be incorrect in the existing code even before the changes done here. I will wait for you to push the changes for the query format and will then proceed with the review.

Thanks!!!
Deepti.

373. By Milo Casagrande

Fixed query quoting.

Revision history for this message
Deepti B. Kalakeri (deeptik) wrote :

=== modified file 'apps/patchmetrics/tests/test_gerrit.py'
--- apps/patchmetrics/tests/test_gerrit.py 2012-06-22 14:33:32 +0000
+++ apps/patchmetrics/tests/test_gerrit.py 2012-06-27 10:48:42 +0000
@@ -102,10 +102,11 @@
     def test_create_request_query_url(self):
         """Tests the creation of a valid request URL."""
         params = {'format': 'JSON', 'n': 100}
- query_params = {'owner': '<email address hidden>', 'sortkey_after': 'abcd'}
+ query_params = {'owner': '<email address hidden>',
+ 'resume_sortkey': 'abcd'}
         expected_result = ROOT_REST_URL + CHANGES_QUERY_PATH + \
         QUERY_STRING_START + \
- "n=100&format=JSON&q=owner:<email address hidden>+sortkey_after:abcd"
+ "n=100&format=JSON&q=owner:<email address hidden>+resume_sortkey:abcd"

Should this be fixed to the address the <email address hidden> ?
or have one more test for it ?
         self.assertEquals(expected_result,
                           create_request_query_url(ROOT_REST_URL,
                                                    CHANGES_QUERY_PATH,

review: Needs Fixing
374. By Milo Casagrande

Fixed tests.

Revision history for this message
Milo Casagrande (milo) wrote :

Thanks Deepti,

fixed those as well, and added a new one.

Revision history for this message
Deepti B. Kalakeri (deeptik) wrote :

112 query_params = {'owner': '<email address hidden>', 'sortkey_after': 'abcd'}
113 expected_result = (ROOT_REST_URL + CHANGES_QUERY_PATH +
114 QUERY_STRING_START + "n=100&format=JSON&q=owner:"
115 "person%40example.org+sortkey_after:abcd")

Should not this be resume_key instead of sortkery_after ?

review: Needs Fixing
375. By Milo Casagrande

Fixed wrong query parameter.

Revision history for this message
Milo Casagrande (milo) wrote :

> Should not this be resume_key instead of sortkery_after ?

Yep, it should be "resume_sortkey", now is fixed.
Thanks again.

Revision history for this message
Deepti B. Kalakeri (deeptik) wrote :

looks good +1.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'apps/patchmetrics/bin/sync-gerrit-changes.py'
--- apps/patchmetrics/bin/sync-gerrit-changes.py 2012-06-25 09:12:00 +0000
+++ apps/patchmetrics/bin/sync-gerrit-changes.py 2012-06-27 12:19:18 +0000
@@ -10,7 +10,7 @@
10 create_or_update_patches_from_aosp_changes,10 create_or_update_patches_from_aosp_changes,
11 get_aosp_changes_from,11 get_aosp_changes_from,
12 )12 )
13from patchmetrics.gerrit_json import (13from patchmetrics.gerrit_values import (
14 GERRIT_MORE_CHANGES,14 GERRIT_MORE_CHANGES,
15 GERRIT_SORT_KEY,15 GERRIT_SORT_KEY,
16)16)
@@ -18,30 +18,37 @@
1818
19linaro_engineers = Person.objects.filter(19linaro_engineers = Person.objects.filter(
20 user__id__in=TeamMembership.objects.values('member').query).distinct()20 user__id__in=TeamMembership.objects.values('member').query).distinct()
21
21for person in linaro_engineers:22for person in linaro_engineers:
22 start_after = None23 resume_key = None
24 # We are just being a little bit paranoid here.
25 user_email = person.email.strip()
23 while True:26 while True:
24 try:27 try:
25 results = get_aosp_changes_from(person.email,28 results = get_aosp_changes_from(user_email, resume_key=resume_key)
26 start_after=start_after)
27 except GerritError, e:29 except GerritError, e:
28 if '%s not found' % person.email in str(e):30 if ('User %s not found' % user_email) in str(e):
29 # Gerrit returns an error when you search for changes owned by31 # Gerrit returns an error when you search for changes owned by
30 # an email address that's not registered, but in this case we32 # an email address that's not registered, but in this case we
31 # just skip to the next email.33 # just skip to the next email.
32 break34 break
33 raise35 raise
34 # If we get all the changes in a single batch, the GERRIT_MORE_CHANGES36
35 # key will not be in the JSON output, so we set it to False.37 if results:
36 more_changes = results[-1].get(GERRIT_MORE_CHANGES) or False38 # If we get all the changes in a single batch, the
37 created_or_updated_patches = (39 # GERRIT_MORE_CHANGES key will not be in the JSON output, so we
38 create_or_update_patches_from_aosp_changes(results, person))40 # set it to False.
3941 more_changes = results[-1].get(GERRIT_MORE_CHANGES) or False
40 # If there are less created/updated changes than the number of changes42 created_or_updated_patches = (
41 # returned by Gerrit we know we can stop as they're sorted most43 create_or_update_patches_from_aosp_changes(results, person))
42 # recently updated first.44
43 if len(results) != len(created_or_updated_patches) or \45 # If there are less created/updated changes than the number of
44 (not more_changes):46 # changes returned by Gerrit we know we can stop as they're sorted
47 # most recently updated first.
48 if len(results) != len(created_or_updated_patches) or \
49 (not more_changes):
50 break
51
52 resume_key = results[-1].get(GERRIT_SORT_KEY)
53 else:
45 break54 break
46
47 start_after = results[-1].get(GERRIT_SORT_KEY)
4855
=== modified file 'apps/patchmetrics/gerrit.py'
--- apps/patchmetrics/gerrit.py 2012-06-25 12:50:28 +0000
+++ apps/patchmetrics/gerrit.py 2012-06-27 12:19:18 +0000
@@ -1,17 +1,22 @@
1from datetime import datetime1from datetime import datetime
2import email2import email
3import urllib
3import urllib24import urllib2
4from urllib import urlencode
55
6import json6import json
77
8from patchwork.models import Patch, Project, State8from patchwork.models import Patch, Project, State
9from patchmetrics.models import GerritChange9from patchmetrics.models import GerritChange
10from patchmetrics.gerrit_json import (10from patchmetrics.gerrit_values import (
11 GERRIT_CREATED_KEY,11 GERRIT_CREATED_KEY,
12 GERRIT_DEFAULT_JSON,
12 GERRIT_ID_KEY,13 GERRIT_ID_KEY,
13 GERRIT_NUMBER_KEY,14 GERRIT_NUMBER_KEY,
14 GERRIT_PROJECT_KEY,15 GERRIT_PROJECT_KEY,
16 GERRIT_QUERY_FORMAT,
17 GERRIT_QUERY_OWNER,
18 GERRIT_QUERY_PG_SIZE,
19 GERRIT_QUERY_RESUME_SORTKEY,
15 GERRIT_SANITIZABLE_VALUE,20 GERRIT_SANITIZABLE_VALUE,
16 GERRIT_STATUS_KEY,21 GERRIT_STATUS_KEY,
17 GERRIT_SUBJECT_KEY,22 GERRIT_SUBJECT_KEY,
@@ -40,12 +45,12 @@
40 """The gerrit server returned an error in response to a query."""45 """The gerrit server returned an error in response to a query."""
4146
4247
43def get_aosp_changes_from(email, start_after=None, page_size=25,48def get_aosp_changes_from(email, resume_key=None, page_size=25,
44 return_format='JSON_COMPACT'):49 return_format=GERRIT_DEFAULT_JSON):
45 """Get the list of changes authored by the given email address.50 """Get the list of changes authored by the given email address.
4651
47 :param email: The email of the user to get the changes of.52 :param email: The email of the user to get the changes of.
48 :param start_after: Only include changes whose 'sortkey_after' is lower53 :param resume_key: Only include changes whose 'sortkey_after' is lower
49 than this. Use None if you want to start from the54 than this. Use None if you want to start from the
50 beginning.55 beginning.
51 :param page_size: Number of items to include in the list, defaults to 25.56 :param page_size: Number of items to include in the list, defaults to 25.
@@ -53,8 +58,10 @@
53 'JSON_COMPACT' for JSON format without spaces, also58 'JSON_COMPACT' for JSON format without spaces, also
54 possible to specify 'JSON'.59 possible to specify 'JSON'.
55 """60 """
56 params = {'format': return_format, 'n': page_size}61 params = {GERRIT_QUERY_FORMAT: return_format,
57 query_params = {'owner': email, 'sortkey_after': start_after}62 GERRIT_QUERY_PG_SIZE: page_size}
63 query_params = {GERRIT_QUERY_OWNER: email,
64 GERRIT_QUERY_RESUME_SORTKEY: resume_key}
58 return rest_api_request(ROOT_REST_URL, CHANGES_QUERY_PATH, params,65 return rest_api_request(ROOT_REST_URL, CHANGES_QUERY_PATH, params,
59 query_params)66 query_params)
6067
@@ -88,7 +95,7 @@
88 path += '/'95 path += '/'
89 request_url = url + path + QUERY_STRING_START96 request_url = url + path + QUERY_STRING_START
9097
91 request_url += urlencode(params)98 request_url += urllib.urlencode(params)
92 request_url += create_gerrit_rest_query(query_params)99 request_url += create_gerrit_rest_query(query_params)
93100
94 return request_url101 return request_url
@@ -113,7 +120,9 @@
113 for key, value in query_params.iteritems():120 for key, value in query_params.iteritems():
114 # We cannot have None values here, we just skip them.121 # We cannot have None values here, we just skip them.
115 if value is not None:122 if value is not None:
116 params_list.append(":".join((key, value)))123 # We need strings here, and we remove white spaces.
124 params_list.append(":".join((key,
125 urllib.quote(str(value).strip()))))
117 # The resulting query string, without separators or prefixes, should be in126 # The resulting query string, without separators or prefixes, should be in
118 # the form of:127 # the form of:
119 # key:value+key:value128 # key:value+key:value
120129
=== renamed file 'apps/patchmetrics/gerrit_json.py' => 'apps/patchmetrics/gerrit_values.py'
--- apps/patchmetrics/gerrit_json.py 2012-06-22 14:33:32 +0000
+++ apps/patchmetrics/gerrit_values.py 2012-06-27 12:19:18 +0000
@@ -1,4 +1,4 @@
1# File with all the gerrit JSON valid keys.1# File with the gerrit JSON valid keys and other gerrit values.
2# For more information about the values defined here, look:2# For more information about the values defined here, look:
3# https://gerrit-review.googlesource.com/Documentation/json.html3# https://gerrit-review.googlesource.com/Documentation/json.html
4# Also, on bug https://bugs.launchpad.net/linaro-patchmetrics/+bug/1013577,4# Also, on bug https://bugs.launchpad.net/linaro-patchmetrics/+bug/1013577,
@@ -14,7 +14,18 @@
14GERRIT_STATUS_KEY = 'status'14GERRIT_STATUS_KEY = 'status'
15GERRIT_PROJECT_KEY = 'project'15GERRIT_PROJECT_KEY = 'project'
16GERRIT_SUBJECT_KEY = 'subject'16GERRIT_SUBJECT_KEY = 'subject'
17
17# Gerrit JSON output starts with a magic prefix, making it not valid JSON.18# Gerrit JSON output starts with a magic prefix, making it not valid JSON.
18# For more info:19# For more info:
19# https://gerrit-review.googlesource.com/Documentation/rest-api.html20# https://gerrit-review.googlesource.com/Documentation/rest-api.html
20GERRIT_SANITIZABLE_VALUE = ")]}'"21GERRIT_SANITIZABLE_VALUE = ")]}'"
22
23# The possible values for the output format of the Gerrit query.
24GERRIT_DEFAULT_JSON = 'JSON_COMPACT'
25GERRIT_NORMAL_JSON = 'JSON'
26
27# Gerrit query parameters
28GERRIT_QUERY_OWNER = 'owner'
29GERRIT_QUERY_FORMAT = 'format'
30GERRIT_QUERY_PG_SIZE = 'n'
31GERRIT_QUERY_RESUME_SORTKEY = 'resume_sortkey'
2132
=== modified file 'apps/patchmetrics/tests/test_gerrit.py'
--- apps/patchmetrics/tests/test_gerrit.py 2012-06-22 14:33:32 +0000
+++ apps/patchmetrics/tests/test_gerrit.py 2012-06-27 12:19:18 +0000
@@ -3,6 +3,13 @@
33
4from django.test import TestCase4from django.test import TestCase
55
6from patchmetrics.gerrit_values import (
7 GERRIT_QUERY_FORMAT,
8 GERRIT_QUERY_OWNER,
9 GERRIT_QUERY_PG_SIZE,
10 GERRIT_QUERY_RESUME_SORTKEY,
11)
12
6from patchmetrics.gerrit import (13from patchmetrics.gerrit import (
7 CHANGES_QUERY_PATH,14 CHANGES_QUERY_PATH,
8 QUERY_STRING_START,15 QUERY_STRING_START,
@@ -103,9 +110,23 @@
103 """Tests the creation of a valid request URL."""110 """Tests the creation of a valid request URL."""
104 params = {'format': 'JSON', 'n': 100}111 params = {'format': 'JSON', 'n': 100}
105 query_params = {'owner': 'person@example.org', 'sortkey_after': 'abcd'}112 query_params = {'owner': 'person@example.org', 'sortkey_after': 'abcd'}
106 expected_result = ROOT_REST_URL + CHANGES_QUERY_PATH + \113 expected_result = (ROOT_REST_URL + CHANGES_QUERY_PATH +
107 QUERY_STRING_START + \114 QUERY_STRING_START + "n=100&format=JSON&q=owner:"
108 "n=100&format=JSON&q=owner:person@example.org+sortkey_after:abcd"115 "person%40example.org+resume_sortkey:abcd")
116 self.assertEquals(expected_result,
117 create_request_query_url(ROOT_REST_URL,
118 CHANGES_QUERY_PATH,
119 params, query_params))
120
121 def test_create_request_query_url_quoted(self):
122 """Tests the creation of a valid request URL with a complex email."""
123 params = {GERRIT_QUERY_FORMAT: 'JSON', GERRIT_QUERY_PG_SIZE: 100}
124 query_params = {GERRIT_QUERY_OWNER: 'name+surname.person@example.org',
125 GERRIT_QUERY_RESUME_SORTKEY: 'abcd'}
126 expected_result = (ROOT_REST_URL + CHANGES_QUERY_PATH +
127 QUERY_STRING_START + "n=100&format=JSON&q=owner:"
128 "name%2Bsurname.person%40example.org+"
129 "resume_sortkey:abcd")
109 self.assertEquals(expected_result,130 self.assertEquals(expected_result,
110 create_request_query_url(ROOT_REST_URL,131 create_request_query_url(ROOT_REST_URL,
111 CHANGES_QUERY_PATH,132 CHANGES_QUERY_PATH,

Subscribers

People subscribed via source and target branches