Merge lp:~cjohnston/helipad/1208654 into lp:helipad/ci

Proposed by Chris Johnston
Status: Merged
Merged at revision: 43
Proposed branch: lp:~cjohnston/helipad/1208654
Merge into: lp:helipad/ci
Diff against target: 868 lines (+155/-114) (has conflicts)
22 files modified
api.py (+0/-3)
management/commands/jenkins_pull_ci.py (+16/-11)
models.py (+6/-9)
templatetags/ci_extras.py (+0/-2)
templatetags/percentage.py (+0/-2)
tests/integration/test_jenkins_build.py (+3/-3)
tests/integration/test_jenkins_job.py (+9/-9)
tests/test_jenkins_pull_ci.py (+3/-3)
tests/unit/test_ci_project.py (+4/-4)
tests/unit/test_ci_project_import.py (+3/-3)
tests/unit/test_cu2d_stack_import.py (+3/-3)
tests/unit/test_jenkins_build.py (+3/-3)
tests/unit/test_jenkins_build_import.py (+3/-3)
tests/unit/test_jenkins_coverage_report_import.py (+3/-3)
tests/unit/test_jenkins_job.py (+3/-3)
tests/unit/test_jenkins_job_import.py (+6/-6)
tests/unit/test_launchpad_project_import.py (+3/-3)
util/coverage_report.py (+1/-3)
util/extractor.py (+25/-2)
util/jenkins_build.py (+40/-23)
util/jenkins_job.py (+21/-10)
views.py (+0/-3)
Text conflict in util/extractor.py
Text conflict in util/jenkins_build.py
Text conflict in util/jenkins_job.py
To merge this branch: bzr merge lp:~cjohnston/helipad/1208654
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Needs Fixing
Francis Ginther Pending
Review via email: mp+180383@code.launchpad.net

This proposal supersedes a proposal from 2013-08-08.

Description of the change

Since the default logging handler will do everything that we need (send emails when there are errors) and with the addition of verbosity to the jenkins_pull_ci command (-v 2/-v 3), there is no need to have a custom logger.

To post a comment you must log in.
Revision history for this message
Francis Ginther (fginther) wrote : Posted in a previous version of this proposal

This effectively moves all of the logging to the default handler.

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

FAILED: Autolanding.
More details in the following jenkins job:
http://s-jenkins:8080/job/helipad-ci-autolanding/40/
Executed test runs:

review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:39
http://s-jenkins:8080/job/helipad-ci-ci/64/
Executed test runs:

Click here to trigger a rebuild:
http://s-jenkins:8080/job/helipad-ci-ci/64/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:39
http://s-jenkins:8080/job/helipad-ci-ci/65/
Executed test runs:

Click here to trigger a rebuild:
http://s-jenkins:8080/job/helipad-ci-ci/65/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:39
http://s-jenkins:8080/job/helipad-ci-ci/66/
Executed test runs:

Click here to trigger a rebuild:
http://s-jenkins:8080/job/helipad-ci-ci/66/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:39
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https://code.launchpad.net/~cjohnston/helipad/1208654/+merge/180383/+edit-commit-message

http://s-jenkins:8080/job/helipad-ci-ci/68/
Executed test runs:

Click here to trigger a rebuild:
http://s-jenkins:8080/job/helipad-ci-ci/68/rebuild

review: Needs Fixing (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'api.py'
2--- api.py 2013-07-23 16:12:36 +0000
3+++ api.py 2013-08-15 17:12:47 +0000
4@@ -13,7 +13,6 @@
5 # You should have received a copy of the GNU Affero General Public License
6 # along with this program. If not, see <http://www.gnu.org/licenses/>.
7
8-import logging
9 import json
10 from django.shortcuts import get_object_or_404
11 from django.utils.dateformat import format
12@@ -21,8 +20,6 @@
13 from common.utils import JSONResponse
14 from ci.models import CiProject, JenkinsBuild
15
16-logger = logging.getLogger('qa_dashboard')
17-
18
19 def project(request, name):
20 project = get_object_or_404(
21
22=== modified file 'management/commands/jenkins_pull_ci.py'
23--- management/commands/jenkins_pull_ci.py 2013-07-29 17:12:18 +0000
24+++ management/commands/jenkins_pull_ci.py 2013-08-15 17:12:47 +0000
25@@ -28,8 +28,6 @@
26
27 from common.management import JenkinsBaseCommand, jenkins_get
28
29-logger = logging.getLogger("qa_dashboard")
30-
31 # Job name which contains the data dump
32 CUPSTREAM2DISTRO_CONFIG_DATA_SOURCE = 'dump-cupstream2distro-config'
33
34@@ -61,8 +59,8 @@
35 stack_config['ppa'] = stackcfg.get('ppa', '')
36 stack_config['server'] = settings.JENKINS_URL
37 stack_config['job'] = '{}-{}-{}'.format('cu2d', name, release)
38- logger.debug("Slurping stack: {}".format(stack_name))
39- logger.debug("Using job: {}".format(stack_config['job']))
40+ logging.debug("Slurping stack: {}".format(stack_name))
41+ logging.debug("Using job: {}".format(stack_config['job']))
42 create_cu2d_stack_from_config(stack_config)
43 return stack_name
44
45@@ -83,9 +81,9 @@
46 project_data = stackcfg['projects'][project_name]
47 project_config['ci'] = project_data.get('ci', None)
48 project_config['autolanding'] = project_data.get('autolanding', None)
49- logger.debug("Slurping project: {}".format(project_name))
50- logger.debug("Ci job: {}".format(project_config['ci']))
51- logger.debug(
52+ logging.debug("Slurping project: {}".format(project_name))
53+ logging.debug("Ci job: {}".format(project_config['ci']))
54+ logging.debug(
55 "Autolanding job: {}".format(project_config['autolanding']),
56 )
57 create_ci_project(project_config)
58@@ -146,19 +144,21 @@
59 # Parse the stack release and name from the url
60 (release, config_name) = self._extract_release_and_config_name(url)
61 if config_is_on_blacklist(config_name):
62- logger.debug("Skipping cu2d config at {} due to blacklist "
63- "match.".format(config_name))
64+ logging.debug(
65+ "Skipping cu2d config at {} due to blacklist "
66+ "match.".format(config_name),
67+ )
68 continue
69
70 data = self._load_artifact(url)
71 # Process the stack
72 if not data:
73 # Stack has no contents
74- logger.debug("No projects found in {}".format(url))
75+ logging.debug("No projects found in {}".format(url))
76 continue
77 if 'projects' not in data:
78 # Stack has no projects
79- logger.debug("No projects found in {}".format(url))
80+ logging.debug("No projects found in {}".format(url))
81 continue
82 stack_name = self._create_stack(data, release)
83
84@@ -170,6 +170,11 @@
85 return
86
87 def handle(self, *args, **options):
88+ verbosity = int(options.get('verbosity'))
89+ if verbosity == 2:
90+ logging.basicConfig(level=logging.INFO)
91+ elif verbosity > 2:
92+ logging.basicConfig(level=logging.DEBUG)
93 if options.get('initial_run'):
94 self.initial_run()
95 else:
96
97=== modified file 'models.py'
98--- models.py 2013-08-09 16:00:35 +0000
99+++ models.py 2013-08-15 17:12:47 +0000
100@@ -20,9 +20,6 @@
101 import util.heuristics as heuristics
102 from launchpadlib.launchpad import Launchpad
103 from lxml.etree import XMLSyntaxError
104-#import common.models
105-
106-logger = logging.getLogger("qa_dashboard")
107
108
109 BLACKLIST_JOBS = [
110@@ -75,7 +72,7 @@
111 try:
112 return self.last_successful_build.coverage_report.line_count
113 except AttributeError:
114- logger.debug("line_count AttributeError in JenkinsJob")
115+ logging.debug("line_count AttributeError in JenkinsJob")
116 return None
117
118 @property
119@@ -83,7 +80,7 @@
120 try:
121 return self.last_successful_build.coverage_report.hit_count
122 except AttributeError:
123- logger.debug('hit_count AttributeError in JenkinsJob')
124+ logging.debug('hit_count AttributeError in JenkinsJob')
125 return None
126
127 @property
128@@ -91,7 +88,7 @@
129 try:
130 return self.last_successful_build.coverage_report.taken_count
131 except AttributeError:
132- logger.debug('taken_count AttributeError in JenkinsJob')
133+ logging.debug('taken_count AttributeError in JenkinsJob')
134 return None
135
136 @property
137@@ -99,7 +96,7 @@
138 try:
139 return self.last_successful_build.coverage_report.total_count
140 except AttributeError:
141- logger.debug('total_count AttributeError in JenkinsJob')
142+ logging.debug('total_count AttributeError in JenkinsJob')
143 return None
144
145 @property
146@@ -361,7 +358,7 @@
147 try:
148 return self.integration_job.last_build
149 except AttributeError:
150- logger.debug("No integration_job set for {}.".format(self.name))
151+ logging.debug("No integration_job set for {}.".format(self.name))
152 return None
153
154 @property
155@@ -369,7 +366,7 @@
156 try:
157 return self.integration_job.last_successful_build
158 except AttributeError:
159- logger.debug("No integration_job set for {}.".format(self.name))
160+ logging.debug("No integration_job set for {}.".format(self.name))
161 return None
162
163 @property
164
165=== modified file 'templatetags/ci_extras.py'
166--- templatetags/ci_extras.py 2013-07-25 18:35:05 +0000
167+++ templatetags/ci_extras.py 2013-08-15 17:12:47 +0000
168@@ -14,9 +14,7 @@
169 # along with this program. If not, see <http://www.gnu.org/licenses/>.
170
171 from django import template
172-import logging
173
174-logger = logging.getLogger('qa_dashboard')
175 register = template.Library()
176
177
178
179=== modified file 'templatetags/percentage.py'
180--- templatetags/percentage.py 2013-07-25 15:43:21 +0000
181+++ templatetags/percentage.py 2013-08-15 17:12:47 +0000
182@@ -14,9 +14,7 @@
183 # along with this program. If not, see <http://www.gnu.org/licenses/>.
184
185 from django import template
186-import logging
187
188-logger = logging.getLogger('qa_dashboard')
189 register = template.Library()
190
191
192
193=== modified file 'tests/integration/test_jenkins_build.py'
194--- tests/integration/test_jenkins_build.py 2013-07-16 17:11:09 +0000
195+++ tests/integration/test_jenkins_build.py 2013-08-15 17:12:47 +0000
196@@ -36,8 +36,8 @@
197 class JenkinsBuildTestCase(TestCase):
198
199 def setUp(self):
200- self.logger_patch = patch('ci.models.logger')
201- self.logger_patch.start()
202+ self.logging_patch = patch('ci.models.logging')
203+ self.logging_patch.start()
204 # slurp a vanilla JenkinsJob and JenkinsBuild
205 self.jenkins_job_url = urljoin(
206 JENKINS_BASE_URL,
207@@ -54,7 +54,7 @@
208 self.jenkins_job)
209
210 def tearDown(self):
211- self.logger_patch.stop()
212+ self.logging_patch.stop()
213
214
215 class TestBuildCreation(JenkinsBuildTestCase):
216
217=== modified file 'tests/integration/test_jenkins_job.py'
218--- tests/integration/test_jenkins_job.py 2013-07-16 17:29:47 +0000
219+++ tests/integration/test_jenkins_job.py 2013-08-15 17:12:47 +0000
220@@ -38,11 +38,11 @@
221 class TestJenkinsJobCreateFromUrl(TestCase):
222
223 def setUp(self):
224- self.logger_patch = patch('ci.models.logger')
225- self.logger_patch.start()
226+ self.logging_patch = patch('ci.models.logging')
227+ self.logging_patch.start()
228
229 def tearDown(self):
230- self.logger_patch.stop()
231+ self.logging_patch.stop()
232
233 @attr('qa_lab')
234 def test_no_builds_param_doesnt_create_builds(self):
235@@ -63,8 +63,8 @@
236 fixtures = ['duplicate_job_fixture.json']
237
238 def setUp(self):
239- self.logger_patch = patch('ci.models.logger')
240- #self.logger_patch.start()
241+ self.logging_patch = patch('ci.models.logging')
242+ #self.logging_patch.start()
243 # slurp a vanilla JenkinsJob and JenkinsBuild
244 self.jenkins_job_url = urljoin(
245 JENKINS_BASE_URL,
246@@ -72,7 +72,7 @@
247
248 def tearDown(self):
249 pass
250- #self.logger_patch.stop()
251+ #self.logging_patch.stop()
252
253 @skip
254 @attr('qa_lab')
255@@ -93,11 +93,11 @@
256 fixtures = ['head-indicators.json']
257
258 def setUp(self):
259- self.logger_patch = patch('ci.models.logger')
260- self.logger_patch.start()
261+ self.logging_patch = patch('ci.models.logging')
262+ self.logging_patch.start()
263
264 def tearDown(self):
265- self.logger_patch.stop()
266+ self.logging_patch.stop()
267
268 @attr('qa_lab')
269 def test_update_job(self):
270
271=== modified file 'tests/test_jenkins_pull_ci.py'
272--- tests/test_jenkins_pull_ci.py 2013-07-28 21:26:11 +0000
273+++ tests/test_jenkins_pull_ci.py 2013-08-15 17:12:47 +0000
274@@ -57,13 +57,13 @@
275 new=command_mock)
276 self.command_patch.start()
277 self.command = Command()
278- self.logger_patch = patch('ci.models.logger')
279- self.logger_patch.start()
280+ self.logging_patch = patch('ci.models.logging')
281+ self.logging_patch.start()
282
283
284 def tearDown(self):
285 self.command_patch.stop()
286- self.logger_patch.stop()
287+ self.logging_patch.stop()
288
289
290 class TestJenkinsPullCiCommand(JenkinsPullCiCommandTestCase):
291
292=== modified file 'tests/unit/test_ci_project.py'
293--- tests/unit/test_ci_project.py 2013-07-16 17:29:47 +0000
294+++ tests/unit/test_ci_project.py 2013-08-15 17:12:47 +0000
295@@ -139,13 +139,13 @@
296 new=ci_project_mock)
297 self.ci_project_patch.start()
298 self.ci_project = CiProject()
299- self.logger_patch = patch(
300- 'ci.models.logger')
301- self.logger_patch.start()
302+ self.logging_patch = patch(
303+ 'ci.models.logging')
304+ self.logging_patch.start()
305
306 def tearDown(self):
307 self.ci_project_patch.stop()
308- self.logger_patch.stop()
309+ self.logging_patch.stop()
310
311
312 class TestLastCoverageBuild(CiProjectUnitTestCase):
313
314=== modified file 'tests/unit/test_ci_project_import.py'
315--- tests/unit/test_ci_project_import.py 2013-07-26 01:50:54 +0000
316+++ tests/unit/test_ci_project_import.py 2013-08-15 17:12:47 +0000
317@@ -25,11 +25,11 @@
318 class CiProjectManagerTestCase(TestCase):
319
320 def setUp(self):
321- self.logger_patch = patch('ci.models.logger')
322- self.logger_patch.start()
323+ self.logging_patch = patch('ci.models.logging')
324+ self.logging_patch.start()
325
326 def tearDown(self):
327- self.logger_patch.stop()
328+ self.logging_patch.stop()
329
330
331 class TestCreate(CiProjectManagerTestCase):
332
333=== modified file 'tests/unit/test_cu2d_stack_import.py'
334--- tests/unit/test_cu2d_stack_import.py 2013-07-16 17:29:47 +0000
335+++ tests/unit/test_cu2d_stack_import.py 2013-08-15 17:12:47 +0000
336@@ -22,11 +22,11 @@
337 class TestCreateFromConfig(TestCase):
338
339 def setUp(self):
340- self.logger_patch = patch('ci.models.logger')
341- self.logger_patch.start()
342+ self.logging_patch = patch('ci.models.logging')
343+ self.logging_patch.start()
344
345 def tearDown(self):
346- self.logger_patch.stop()
347+ self.logging_patch.stop()
348
349 def test_vanilla(self):
350 series_get_or_create = MagicMock(
351
352=== modified file 'tests/unit/test_jenkins_build.py'
353--- tests/unit/test_jenkins_build.py 2013-07-16 17:29:47 +0000
354+++ tests/unit/test_jenkins_build.py 2013-08-15 17:12:47 +0000
355@@ -33,13 +33,13 @@
356 self.jenkins_build_patch.start()
357 self.jenkins_build = \
358 JenkinsBuild()
359- self.logger_patch = patch('ci.models.logger')
360- self.logger_patch.start()
361+ self.logging_patch = patch('ci.models.logging')
362+ self.logging_patch.start()
363
364
365 def tearDown(self):
366 self.jenkins_build_patch.stop()
367- self.logger_patch.stop()
368+ self.logging_patch.stop()
369
370
371 def test_unicode(self):
372
373=== modified file 'tests/unit/test_jenkins_build_import.py'
374--- tests/unit/test_jenkins_build_import.py 2013-08-02 20:45:21 +0000
375+++ tests/unit/test_jenkins_build_import.py 2013-08-15 17:12:47 +0000
376@@ -31,14 +31,14 @@
377 'create',
378 new=jenkins_build_objects_create_mock)
379 self.jenkins_build_objects_create = self.jenkins_build_objects_create_patch.start()
380- self.logger_patch = patch('ci.models.logger')
381- self.logger_patch.start()
382+ self.logging_patch = patch('ci.models.logging')
383+ self.logging_patch.start()
384 self.dummy_url = "http://this.string.is.actually.a.URL/no/kidding"
385 self.dummy_jenkins_job = "a Django representation of a Jenkins job"
386
387 def tearDown(self):
388 self.jenkins_build_objects_create_patch.stop()
389- self.logger_patch.stop()
390+ self.logging_patch.stop()
391
392
393 class TestCreateFromUrl(JenkinsBuildManagerTestCase):
394
395=== modified file 'tests/unit/test_jenkins_coverage_report_import.py'
396--- tests/unit/test_jenkins_coverage_report_import.py 2013-07-16 17:29:47 +0000
397+++ tests/unit/test_jenkins_coverage_report_import.py 2013-08-15 17:12:47 +0000
398@@ -22,8 +22,8 @@
399 class TestCreateFromCoberturaXml(TestCase):
400
401 def setUp(self):
402- self.logger_patch = patch('ci.models.logger')
403- self.logger_patch.start()
404+ self.logging_patch = patch('ci.models.logging')
405+ self.logging_patch.start()
406 self.fake_url = "http://this.is.a.url.com/click/me"
407 self.fake_jenkins_build = "fake_jenkins_build"
408 self.extractor_jenkins_coverage_params = {
409@@ -47,7 +47,7 @@
410 def tearDown(self):
411 self.extractor_jenkins_coverage_patch.stop()
412 self.jenkins_coverage_report_create_patch.stop()
413- self.logger_patch.stop()
414+ self.logging_patch.stop()
415
416 def test_vanilla(self):
417 result = util_coverage_report.create_coverage_report_from_url(
418
419=== modified file 'tests/unit/test_jenkins_job.py'
420--- tests/unit/test_jenkins_job.py 2013-07-16 17:11:09 +0000
421+++ tests/unit/test_jenkins_job.py 2013-08-15 17:12:47 +0000
422@@ -34,12 +34,12 @@
423 self.jenkins_job_patch.start()
424 self.jenkins_job = \
425 JenkinsJob()
426- self.logger_patch = patch('ci.models.logger')
427- self.logger_patch.start()
428+ self.logging_patch = patch('ci.models.logging')
429+ self.logging_patch.start()
430
431 def tearDown(self):
432 self.jenkins_job_patch.stop()
433- self.logger_patch.stop()
434+ self.logging_patch.stop()
435
436 def test_unicode(self):
437 self.jenkins_job.name = 'deep-thought-autolanding'
438
439=== modified file 'tests/unit/test_jenkins_job_import.py'
440--- tests/unit/test_jenkins_job_import.py 2013-07-16 17:11:09 +0000
441+++ tests/unit/test_jenkins_job_import.py 2013-08-15 17:12:47 +0000
442@@ -33,8 +33,8 @@
443 'create',
444 new=jenkins_job_objects_create_mock)
445 self.jenkins_job_objects_create = self.jenkins_job_objects_create_patch.start()
446- self.logger_patch = patch('ci.models.logger')
447- self.logger_patch.start()
448+ self.logging_patch = patch('ci.models.logging')
449+ self.logging_patch.start()
450 self.extractor_job_params = {
451 'name': 'fake-autolanding',
452 'buildable': True,
453@@ -48,7 +48,7 @@
454
455 def tearDown(self):
456 self.jenkins_job_objects_create_patch.stop()
457- self.logger_patch.stop()
458+ self.logging_patch.stop()
459
460 def test_vanilla(self):
461 extractor_jenkins_job = MagicMock(
462@@ -187,8 +187,8 @@
463 class TestCreateFromName(TestCase):
464
465 def setUp(self):
466- self.logger_patch = patch('ci.models.logger')
467- self.logger_patch.start()
468+ self.logging_patch = patch('ci.models.logging')
469+ self.logging_patch.start()
470 jenkins_job_mock = MagicMock(
471 spec=JenkinsJob,
472 return_value=None)
473@@ -201,7 +201,7 @@
474 JenkinsJob()
475
476 def tearDown(self):
477- self.logger_patch.stop()
478+ self.logging_patch.stop()
479 self.jenkins_job_patch.stop()
480
481 def test_vanilla(self):
482
483=== modified file 'tests/unit/test_launchpad_project_import.py'
484--- tests/unit/test_launchpad_project_import.py 2013-07-26 01:50:54 +0000
485+++ tests/unit/test_launchpad_project_import.py 2013-08-15 17:12:47 +0000
486@@ -22,11 +22,11 @@
487 class TestCreateFromName(TestCase):
488
489 def setUp(self):
490- self.logger_patch = patch('ci.models.logger')
491- self.logger_patch.start()
492+ self.logging_patch = patch('ci.models.logging')
493+ self.logging_patch.start()
494
495 def tearDown(self):
496- self.logger_patch.stop()
497+ self.logging_patch.stop()
498
499 # TODO restore this when we're really dealing with Launchpad
500 def test_vanilla(self):
501
502=== modified file 'util/coverage_report.py'
503--- util/coverage_report.py 2013-07-16 17:29:47 +0000
504+++ util/coverage_report.py 2013-08-15 17:12:47 +0000
505@@ -18,14 +18,12 @@
506 from ci.models import JenkinsCoverageReport
507 import ci.util.extractor as extractor
508
509-logger = logging.getLogger('qa_dashboard')
510-
511
512 def create_coverage_report_from_url(jenkins_build, url):
513 try:
514 extractor_report = extractor.JenkinsCoverage(url)
515 except XMLSyntaxError:
516- logger.error("XML parsing error for coverage report at {} .".format(url))
517+ logging.error("XML parsing error for coverage report at {} .".format(url))
518 return None
519 return JenkinsCoverageReport.objects.create(
520 jenkins_build=jenkins_build,
521
522=== modified file 'util/extractor.py'
523--- util/extractor.py 2013-08-09 16:00:35 +0000
524+++ util/extractor.py 2013-08-15 17:12:47 +0000
525@@ -24,8 +24,6 @@
526
527 """Classes and utilities to extract QA data from jenkins"""
528
529-logger = logging.getLogger('qa_dashboard')
530-
531
532 class BuildUrl(object):
533 def __init__(self, number=None, url=None):
534@@ -97,6 +95,18 @@
535 downstream_jobs.append(job)
536 return downstream_jobs
537
538+<<<<<<< TREE
539+=======
540+ def _get_parameters(self):
541+ parameters = []
542+ try:
543+ parameters = super(JenkinsJob, self)._get_parameters(
544+ self.data['actions'][0]['parameterDefinitions'])
545+ except (KeyError, IndexError) as e:
546+ logging.error('Failed parameter parsing: {}'.format(e))
547+ return parameters
548+
549+>>>>>>> MERGE-SOURCE
550 def _get_build_number(self, build):
551 # A build will be None when the last*Build has not occurred yet
552 if build is None:
553@@ -191,6 +201,19 @@
554 return series
555 return None
556
557+<<<<<<< TREE
558+=======
559+ def _get_parameters(self):
560+ parameters = []
561+ try:
562+ parameters = super(JenkinsBuild, self)._get_parameters(
563+ self.data['actions'][0]['parameters'])
564+ except (KeyError, IndexError) as e:
565+ logging.error('Failed parameter parsing: {}'.format(e))
566+ logging.error(e)
567+ return parameters
568+
569+>>>>>>> MERGE-SOURCE
570 def refresh(self):
571 super(JenkinsBuild, self).refresh()
572 self.duration = self._get_duration()
573
574=== modified file 'util/jenkins_build.py'
575--- util/jenkins_build.py 2013-08-09 16:00:35 +0000
576+++ util/jenkins_build.py 2013-08-15 17:12:47 +0000
577@@ -24,7 +24,6 @@
578 from ci.util.coverage_report import create_coverage_report_from_url
579 from ci.util.jenkins_test_report import create_jenkins_test_report_from_url
580
581-logger = logging.getLogger('qa_dashboard')
582
583 BLACKLIST_JOBS = [
584 'generic-dput',
585@@ -47,17 +46,17 @@
586 try:
587 extractor_build = extractor.JenkinsBuild(downstream_build.url)
588 except EnvironmentError, e:
589- logger.info("EnvironmentError: {}".format(e))
590+ logging.info("EnvironmentError: {}".format(e))
591 continue
592 job_name = extractor_build.job_name
593 build_number = extractor_build.number
594- logger.debug("downstream job: {}\tbuild: {}".format(job_name,
595+ logging.debug("downstream job: {}\tbuild: {}".format(job_name,
596 build_number))
597 # make sure we have the JenkinsJob
598 try:
599 jenkins_job = JenkinsJob.objects.get(name=job_name)
600 except JenkinsJob.DoesNotExist:
601- logger.debug("Need to create job: {}".format(job_name))
602+ logging.debug("Need to create job: {}".format(job_name))
603 # TODO reexamine circular import problem
604 from ci.util.jenkins_job import create_jenkins_job_from_name
605 jenkins_job = create_jenkins_job_from_name(server,
606@@ -87,25 +86,25 @@
607 """
608
609 # get a Cobertura coverage report, if it exists
610- logger.debug("Slurping Cobertura reports.")
611+ logging.debug("Slurping Cobertura reports.")
612 try:
613 coverage_url = extractor_build.get_coverage_report_url()
614 jenkins_coverage_report = create_coverage_report_from_url(
615 jenkins_build, coverage_url)
616 jenkins_build.coverage_report = jenkins_coverage_report
617 jenkins_build.save()
618- logger.info("Cobertura created: {}.".format(jenkins_build.number))
619+ logging.info("Cobertura created: {}.".format(jenkins_build.number))
620 except EnvironmentError, e:
621 # no biggie, we just don't have a Cobertura report
622- logger.info("No Cobertura data: {}".format(e))
623+ logging.info("No Cobertura data: {}".format(e))
624 except IntegrityError, e:
625- logger.info("Cobertura duplicate encountered.")
626+ logging.info("Cobertura duplicate encountered.")
627 #transaction.rollback()
628 pass
629
630 def aggregate_coverage_report(jenkins_build):
631 # TODO use django aggregation?
632- logger.debug("Aggegate coverage reports: %s" % jenkins_build)
633+ logging.debug("Aggegate coverage reports: %s" % jenkins_build)
634 if jenkins_build.coverage_report:
635 # Don't aggregate when the build already has a coverage report
636 return
637@@ -137,26 +136,26 @@
638
639 def create_jenkins_test_report(jenkins_build, extractor_build):
640
641- logger.debug("Slurping Test Reports.")
642+ logging.debug("Slurping Test Reports.")
643 try:
644 test_url = extractor_build.get_test_report_url()
645 jenkins_test_report = create_jenkins_test_report_from_url(
646 jenkins_build, test_url)
647 jenkins_build.test_report = jenkins_test_report
648 jenkins_build.save()
649- logger.info("Test Report created: {}.".format(jenkins_build.number))
650+ logging.info("Test Report created: {}.".format(jenkins_build.number))
651 except EnvironmentError, e:
652 # no data if the build failed, e.g.
653- logger.info("No test report data found: {}".format(e))
654+ logging.info("No test report data found: {}".format(e))
655 except IntegrityError, e:
656- logger.info("Test Report duplicate encountered.")
657- logger.debug(e)
658+ logging.info("Test Report duplicate encountered.")
659+ logging.debug(e)
660 transaction.rollback()
661
662
663 def aggregate_test_report(jenkins_build):
664 # TODO use django aggregation?
665- logger.debug("Aggegate test reports: %s" % jenkins_build)
666+ logging.debug("Aggegate test reports: %s" % jenkins_build)
667 if jenkins_build.test_report:
668 # Don't aggregate when the build already has a test report
669 return
670@@ -192,26 +191,26 @@
671 :rtype: Django JenkinsBuild
672 """
673
674- logger.debug("JenkinsBuildManager creating build from url {}.".format(url))
675+ logging.debug("JenkinsBuildManager creating build from url {}.".format(url))
676 for name in BLACKLIST_JOBS:
677 if name in url:
678- logger.info("Skipping blacklisted job at {}.".format(url))
679+ logging.info("Skipping blacklisted job at {}.".format(url))
680 return None
681 try:
682 extractor_build = extractor.JenkinsBuild(url)
683 except Exception, e:
684 transaction.rollback()
685- logger.error("Exception: {}".format(e))
686+ logging.error("Exception: {}".format(e))
687 return None
688 try:
689 if extractor_build.result is None:
690 # This build is actively running, no need to slurp it
691- logger.info("Skipping build at {}: may be actively running.".format(url))
692+ logging.info("Skipping build at {}: may be actively running.".format(url))
693 transaction.rollback()
694 return None
695 except Exception, e:
696 # in some cases this 404s; same as above, no need to slurp a broken build
697- logger.error("Exception while sluring build at {}: {}".format(url, e))
698+ logging.error("Exception while sluring build at {}: {}".format(url, e))
699 transaction.rollback()
700 return None
701
702@@ -220,8 +219,9 @@
703 except IntegrityError, e:
704 # no builds yet, IntegrityError when attempting to create JenkinsResult with None name
705 transaction.rollback()
706- logger.debug("No builds yet.")
707+ logging.debug("No builds yet.")
708 return None
709+<<<<<<< TREE
710
711 logger.debug("Creating JenkinsBuild at {}.".format(url))
712 if jenkins_job is None:
713@@ -234,6 +234,23 @@
714 result=result)
715 if not created:
716 return jenkins_build
717+=======
718+
719+ try:
720+ logging.debug("Creating JenkinsBuild at {}.".format(url))
721+ if jenkins_job is None:
722+ logging.warning("Creating JenkinsBuild at {} with no parent job.".format(url))
723+ jenkins_build = JenkinsBuild.objects.create(
724+ jenkins_job=jenkins_job,
725+ url=url,
726+ number=extractor_build.number,
727+ timestamp=extractor_build.timestamp,
728+ result=result)
729+ except IntegrityError:
730+ transaction.rollback()
731+ logging.info("Duplicate Jenkins build found at {}".format(url))
732+ return None
733+>>>>>>> MERGE-SOURCE
734
735 create_downstream_builds(jenkins_build, extractor_build)
736 create_cobertura_report(jenkins_build, extractor_build)
737@@ -257,9 +274,9 @@
738
739 for blacklist in BLACKLIST_JOBS:
740 if blacklist in name:
741- logger.info("Skipping blacklisted build {} #{}.".format(name, number))
742+ logging.info("Skipping blacklisted build {} #{}.".format(name, number))
743 return None
744- logger.debug("Creating JenkinsBuild for {} #{}.".format(name, number))
745+ logging.debug("Creating JenkinsBuild for {} #{}.".format(name, number))
746 try:
747 jenkins_job = JenkinsJob.objects.get(name=name)
748 except JenkinsJob.DoesNotExist:
749
750=== modified file 'util/jenkins_job.py'
751--- util/jenkins_job.py 2013-08-15 15:39:04 +0000
752+++ util/jenkins_job.py 2013-08-15 17:12:47 +0000
753@@ -28,7 +28,6 @@
754 class CiException(Exception):
755 pass
756
757-logger = logging.getLogger('qa_dashboard')
758
759 BLACKLIST_JOBS = [
760 'generic-dput',
761@@ -60,10 +59,10 @@
762 :rtype: Django JenkinsJob
763 """
764
765- logger.info("JenkinsJob create_from_url: %s" % (url))
766+ logging.info("JenkinsJob create_from_url: %s" % (url))
767 for name in BLACKLIST_JOBS:
768 if name in url:
769- logger.info("Skipping blacklisted job {}.".format(name))
770+ logging.info("Skipping blacklisted job {}.".format(name))
771 return None
772 try:
773 extractor_job = extractor.JenkinsJob(url)
774@@ -76,13 +75,21 @@
775 # No job found on the server: this can happen when a project is
776 # defined in a stack but the jobs have not yet been deployed.
777 transaction.rollback()
778- logger.debug(e)
779+ logging.debug(e)
780 return None
781+<<<<<<< TREE
782 if not created:
783 # The job already exists in the database: this is normal even during
784 # a fresh import due to the multiple build/job discovery paths.
785+=======
786+ except IntegrityError, e:
787+ # uniqueness constraint violated
788+ transaction.rollback()
789+ logging.debug(e)
790+ jenkins_job = JenkinsJob.objects.get(name=extractor_job.name)
791+>>>>>>> MERGE-SOURCE
792 if update:
793- logger.debug("Updating job from {}".format(url))
794+ logging.debug("Updating job from {}".format(url))
795 jenkins_job.update(**params)
796 if create_downstream_jobs:
797 try:
798@@ -90,13 +97,13 @@
799 # TODO: protect against circular refs, just sayin'
800 downstream_jenkins_job = create_jenkins_job_from_url(
801 downstream_extractor_job.url)
802- logger.info("downstream job created: {}".format(downstream_jenkins_job))
803+ logging.info("downstream job created: {}".format(downstream_jenkins_job))
804 if downstream_jenkins_job:
805 downstream_jenkins_job.upstream_job = jenkins_job
806 downstream_jenkins_job.project = jenkins_job.project
807 downstream_jenkins_job.save()
808 except EnvironmentError, e:
809- logger.info("EnvironmentError: {}".format(e))
810+ logging.info("EnvironmentError: {}".format(e))
811 if create_builds:
812 for build in extractor_job.builds:
813 try:
814@@ -105,12 +112,12 @@
815 # DEBUGGING: Hack, only return 1 build to speed things up
816 #break
817 except EnvironmentError, e:
818- logger.info("EnvironmentError: {}".format(e))
819+ logging.info("EnvironmentError: {}".format(e))
820 return jenkins_job
821
822
823 def create_jenkins_job_from_name(server, name):
824- logger.debug("Creating JenkinsJob from name {}.".format(name))
825+ logging.debug("Creating JenkinsJob from name {}.".format(name))
826 return create_jenkins_job_from_url(extractor.get_job_url(server, name))
827
828
829@@ -139,8 +146,9 @@
830 build = util_jenkins_build.create_jenkins_build_from_url(
831 jenkinsapi_build.baseurl, jenkins_job)
832 if not build:
833- logger.error("Failed to create build for {}.".format(jenkins_job))
834+ logging.error("Failed to create build for {}.".format(jenkins_job))
835 except CiException:
836+<<<<<<< TREE
837 # This happens when a job that was published in the past is not
838 # found. This can happen due to multiconfiguration jobs that have
839 # to be purged before the new style jobs can publish. In some cases
840@@ -149,4 +157,7 @@
841 # from jenkins.
842 # The dashboard should handle this gracefully.
843 logger.info("Jenkins job {} not known on Jenkins server {}.".format(
844+=======
845+ logging.error("Jenkins job {} not known on Jenkins server {}.".format(
846+>>>>>>> MERGE-SOURCE
847 jenkins_job.name, settings.JENKINS_URL))
848
849=== modified file 'views.py'
850--- views.py 2013-07-25 15:40:32 +0000
851+++ views.py 2013-08-15 17:12:47 +0000
852@@ -13,7 +13,6 @@
853 # You should have received a copy of the GNU Affero General Public License
854 # along with this program. If not, see <http://www.gnu.org/licenses/>.
855
856-import logging
857 from django.template import RequestContext
858 from django.shortcuts import get_object_or_404, render_to_response
859
860@@ -27,8 +26,6 @@
861 LaunchpadProject,
862 )
863
864-logger = logging.getLogger('qa_dashboard')
865-
866
867 BRANCH_FILTER_TYPES = ['all',
868 'autolanding',

Subscribers

People subscribed via source and target branches

to all changes: