Merge lp:~allanlesage/qa-coverage-dashboard/test-jenkins-pull-coverage into lp:qa-coverage-dashboard

Proposed by Allan LeSage
Status: Merged
Approved by: Chris Gagnon
Approved revision: 764
Merged at revision: 764
Proposed branch: lp:~allanlesage/qa-coverage-dashboard/test-jenkins-pull-coverage
Merge into: lp:qa-coverage-dashboard
Diff against target: 392 lines (+276/-80)
4 files modified
gaps/tests/__init__.py (+4/-75)
gaps/tests/test_jenkins_pull.py (+179/-0)
gaps/tests/test_jenkins_pull_coverage.py (+82/-0)
gaps/util/jenkins_pull.py (+11/-5)
To merge this branch: bzr merge lp:~allanlesage/qa-coverage-dashboard/test-jenkins-pull-coverage
Reviewer Review Type Date Requested Status
Chris Gagnon (community) Approve
Review via email: mp+214659@code.launchpad.net

Description of the change

Some unit tests for util/jenkins_pull.py , in preparation for possible refaxtoring.

To post a comment you must log in.
Revision history for this message
Allan LeSage (allanlesage) wrote :

Run these test by ./manage.py test gaps .

762. By Allan LeSage

Merge trunk, resolving conflicts.

Revision history for this message
Chris Gagnon (chris.gagnon) wrote :

There are some issues with code style

 gaps/tests/test_jenkins_pull.py|7 col 1| F401 'time' imported but unused
  2 gaps/tests/test_jenkins_pull.py|34 col 71| E231 missing whitespace after ','
  3 gaps/tests/test_jenkins_pull.py|45 col 61| E231 missing whitespace after ','
  4 gaps/tests/test_jenkins_pull.py|58 col 80| E231 missing whitespace after ','
  5 gaps/tests/test_jenkins_pull.py|58 col 80| E501 line too long (82 > 79 characters)
  6 gaps/tests/test_jenkins_pull.py|106 col 43| E225 missing whitespace around operator

review: Needs Fixing
763. By Allan LeSage

Some flake8 fixes.

764. By Allan LeSage

Last teensy #noqa for tests/__init__.py .

Revision history for this message
Chris Gagnon (chris.gagnon) wrote :

lgtm

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'gaps/tests/__init__.py'
2--- gaps/tests/__init__.py 2014-04-04 20:34:26 +0000
3+++ gaps/tests/__init__.py 2014-04-09 19:08:53 +0000
4@@ -1,77 +1,6 @@
5
6-import datetime
7-from mock import Mock
8-from os import path
9-
10-from django.test import TestCase
11-
12-import common
13-from gaps.models import (
14- CoverageBuild,
15- CoverageData,
16- CoverageProject,
17- CoverageStack
18+from gaps.tests.test_jenkins_pull_coverage import TestJenkinsPullCoverage # noqa
19+from gaps.tests.test_jenkins_pull import ( # noqa
20+ GetArtifactUrlsTestCase,
21+ UrlArtifactListTestCase,
22 )
23-from gaps.util import add, jenkins_pull
24-
25-
26-class TestJenkinsPullCoverage(TestCase):
27- def setUp(self):
28- self.url_list = [
29- {
30- 'url': 'http://jenkins.qa.ubuntu.com/job/libqtdbustest-trusty'
31- '-i386-ci/10/artifact/work/results/coverage.xml',
32- 'build_id': 10,
33- 'ran_at': datetime.datetime(
34- 2014, 3, 18, 17, 31, 24)
35- }
36- ]
37-
38- localdir = path.dirname(__file__)
39- with open(path.join(localdir, 'data/coverage.xml'), 'r') as f:
40- jenkins_get_data = f.read()
41- f.close()
42- self.jdata = jenkins_get_data
43-
44- def test_jenkins_get_data_from_common_exists(self):
45- """Verify jenkins_get method is in common.managment"""
46- from common.management import jenkins_get # NOQA
47-
48- def test_added_data_are_correct(self):
49- jenkins_pull.url_artifact_list = Mock(return_value=self.url_list)
50- common.management.jenkins_get = Mock(return_value=self.jdata)
51- add.records(
52- 'qa',
53- 'libqtdbustest',
54- 'libqtdbustest-trusty-amd64-ci',
55- 'coverage.xml',
56- )
57-
58- self.assertEquals(1, CoverageData.objects.count())
59- coveragedata = CoverageData.objects.all()[0]
60- self.assertEquals(
61- 'http://jenkins.qa.ubuntu.com/job/libqtdbustest-trusty-i386-ci'
62- '/10/artifact/work/results/coverage.xml',
63- coveragedata.url
64- )
65- self.assertEquals('coverage.xml', coveragedata.name)
66- self.assertEquals('', coveragedata.xml_file)
67- self.assertEquals('0.514', str(coveragedata.branch_coverage))
68- self.assertEquals('0.884', str(coveragedata.line_coverage))
69- self.assertEquals('107', str(coveragedata.hit_count))
70- self.assertEquals('121', str(coveragedata.line_count))
71- self.assertEquals('75', str(coveragedata.taken_count))
72- self.assertEquals('146', str(coveragedata.total_count))
73-
74- self.assertEquals(1, CoverageBuild.objects.count())
75- build = CoverageBuild.objects.all()[0]
76- self.assertEquals('10', str(build.build_number))
77- self.assertEquals('None', build.build_description)
78-
79- self.assertEquals(1, CoverageProject.objects.count())
80- project = CoverageProject.objects.all()[0]
81- self.assertEquals('libqtdbustest', project.name)
82-
83- self.assertEqual(1, CoverageStack.objects.count())
84- stack = CoverageStack.objects.all()[0]
85- self.assertEquals('qa', stack.name)
86
87=== added file 'gaps/tests/test_jenkins_pull.py'
88--- gaps/tests/test_jenkins_pull.py 1970-01-01 00:00:00 +0000
89+++ gaps/tests/test_jenkins_pull.py 2014-04-09 19:08:53 +0000
90@@ -0,0 +1,179 @@
91+
92+import datetime
93+from mock import patch, MagicMock
94+
95+from django.test import TestCase
96+
97+from gaps.util.jenkins_pull import (
98+ _get_artifact_urls,
99+ build,
100+ JenkinsAPIException,
101+ job,
102+ url_artifact_list,
103+)
104+from jenkinsapi.api import Jenkins
105+
106+
107+class GetArtifactUrlsTestCase(TestCase):
108+
109+ def setUp(self):
110+ jenkinsapi_build_mock = MagicMock(
111+ spec=build.Build,
112+ return_value=None)
113+ jenkinsapi_build_patch = patch.object(
114+ build.Build,
115+ '__init__',
116+ new=jenkinsapi_build_mock)
117+ jenkinsapi_build_patch.start()
118+ self.addCleanup(jenkinsapi_build_patch.stop)
119+ self.jenkinsapi_build = build.Build()
120+
121+ def test_get_artifact_urls_can_match(self):
122+ self.jenkinsapi_build.get_artifacts = MagicMock(
123+ return_value=[MagicMock(url='http://foo.com/coverage.xml'), ])
124+ urls = _get_artifact_urls(
125+ self.jenkinsapi_build,
126+ 'coverage.xml')
127+ self.assertEquals(['http://foo.com/coverage.xml'], urls)
128+
129+ def test_get_artifact_urls_is_selective(self):
130+ self.jenkinsapi_build.get_artifacts = MagicMock(
131+ return_value=[
132+ MagicMock(url='http://foo.com/coverage.xml'),
133+ MagicMock(url='http://dungeonofdelight.com/foo'),
134+ MagicMock(url='http://jenkins/coverage.xml'), ])
135+ urls = _get_artifact_urls(
136+ self.jenkinsapi_build,
137+ 'coverage.xml')
138+ self.assertEquals([
139+ 'http://foo.com/coverage.xml',
140+ 'http://jenkins/coverage.xml'], urls)
141+
142+ def test_get_artifact_urls_returns_empty_list(self):
143+ self.jenkinsapi_build.get_artifacts = MagicMock(
144+ return_value=[
145+ MagicMock(url='http://cnn.com/this-url-has-no-match'),
146+ MagicMock(
147+ url='http://zombo.com/match-is-not-possible'), ])
148+ urls = _get_artifact_urls(
149+ self.jenkinsapi_build,
150+ 'coverage.xml')
151+ self.assertEquals([], urls)
152+
153+
154+class UrlArtifactListTestCase(TestCase):
155+
156+ def setUp(self):
157+ super(UrlArtifactListTestCase, self).setUp()
158+
159+ self.jenkinsapi_jenkins_mock = MagicMock(
160+ spec=Jenkins)
161+ jenkinsapi_jenkins_patch = patch(
162+ 'gaps.util.jenkins_pull.Jenkins',
163+ new=self.jenkinsapi_jenkins_mock)
164+ jenkinsapi_jenkins_patch.start()
165+ self.addCleanup(jenkinsapi_jenkins_patch.stop)
166+
167+ self.jenkinsapi_job_mock = MagicMock(
168+ spec=job.Job)
169+ jenkinsapi_job_patch = patch(
170+ 'gaps.util.jenkins_pull.job.Job',
171+ new=self.jenkinsapi_job_mock)
172+ jenkinsapi_job_patch.start()
173+ self.addCleanup(jenkinsapi_job_patch.stop)
174+
175+ self.jenkinsapi_build_mock = MagicMock(
176+ spec=build.Build)
177+ jenkinsapi_build_patch = patch(
178+ 'gaps.util.jenkins_pull.job.Job',
179+ new=self.jenkinsapi_build_mock)
180+ jenkinsapi_build_patch.start()
181+ self.addCleanup(jenkinsapi_build_patch.stop)
182+
183+ # set up a few fake constants
184+ self.fake_build_ids = [1, 2, 3]
185+ self.fake_datetime = datetime.datetime.now()
186+ self.fake_baseurl = 'http://www.fake-baseurl.com'
187+
188+ self.jenkinsapi_build_mock.get_timestamp = MagicMock(
189+ return_value=self.fake_datetime
190+ )
191+ self.jenkinsapi_job_mock.baseurl = self.fake_baseurl
192+ self.jenkinsapi_job_mock.get_build_ids = MagicMock(
193+ return_value=self.fake_build_ids
194+ )
195+ self.jenkinsapi_job_mock.get_build = MagicMock(
196+ return_value=self.jenkinsapi_build_mock
197+ )
198+
199+ self.jenkinsapi_jenkins_mock.return_value.get_job = MagicMock(
200+ return_value=self.jenkinsapi_job_mock
201+ )
202+
203+ def test_url_artifact_list_is_correct_if_no_artifact_urls(self):
204+ result = url_artifact_list(
205+ 'mir-trusty-amd64-ci',
206+ 'coverage.xml'
207+ )
208+ self.assertEqual(
209+ [{'url': self.fake_baseurl,
210+ 'build_id': self.fake_build_ids[0],
211+ 'ran_at': self.fake_datetime},
212+ {'url': self.fake_baseurl,
213+ 'build_id': self.fake_build_ids[1],
214+ 'ran_at': self.fake_datetime},
215+ {'url': self.fake_baseurl,
216+ 'build_id': self.fake_build_ids[2],
217+ 'ran_at': self.fake_datetime}],
218+ result)
219+
220+ @patch('gaps.util.jenkins_pull._get_artifact_urls')
221+ def test_url_artifact_list_is_correct_if_normal_artifact_urls(
222+ self, get_artifact_urls_mock):
223+ get_artifact_urls_mock.return_value = [
224+ 'http://foo.com/coverage.xml',
225+ 'http://dungeonofdelight.com/foo',
226+ 'http://jenkins/coverage.xml',
227+ ]
228+ result = url_artifact_list(
229+ 'mir-trusty-amd64-ci',
230+ 'coverage.xml')
231+ self.assertEqual(
232+ [{'url': self.fake_baseurl,
233+ 'build_id': self.fake_build_ids[0],
234+ 'ran_at': self.fake_datetime},
235+ {'url': self.fake_baseurl,
236+ 'build_id': self.fake_build_ids[1],
237+ 'ran_at': self.fake_datetime},
238+ {'url': self.fake_baseurl,
239+ 'build_id': self.fake_build_ids[2],
240+ 'ran_at': self.fake_datetime}],
241+ result)
242+
243+ def test_return_false_if_job_not_found(self):
244+ self.jenkinsapi_jenkins_mock.return_value.get_job = MagicMock(
245+ return_value=self.jenkinsapi_job_mock,
246+ side_effect=OSError,
247+ )
248+ result = url_artifact_list(
249+ 'mir-trusty-amd64-ci',
250+ 'coverage.xml')
251+ self.assertFalse(result)
252+
253+ def test_return_false_if_jenkinsapi_exception_on_get_build_ids(self):
254+ jenkinsapi_job = MagicMock(
255+ baseurl=self.fake_baseurl,
256+ get_build_ids=MagicMock(
257+ return_value=self.fake_build_ids,
258+ side_effect=JenkinsAPIException
259+ ),
260+ get_build=MagicMock(return_value=self.jenkinsapi_build_mock)
261+ )
262+ self.jenkinsapi_jenkins_mock.return_value.get_job = MagicMock(
263+ return_value=jenkinsapi_job
264+ )
265+ result = url_artifact_list(
266+ 'mir-trusty-amd64-ci',
267+ 'coverage.xml'
268+ )
269+ self.assertFalse(result)
270
271=== added file 'gaps/tests/test_jenkins_pull_coverage.py'
272--- gaps/tests/test_jenkins_pull_coverage.py 1970-01-01 00:00:00 +0000
273+++ gaps/tests/test_jenkins_pull_coverage.py 2014-04-09 19:08:53 +0000
274@@ -0,0 +1,82 @@
275+import datetime
276+
277+import common
278+
279+from django.test import TestCase
280+
281+from gaps.models import (
282+ CoverageBuild,
283+ CoverageData,
284+ CoverageProject,
285+ CoverageStack,
286+)
287+from gaps.util import add, jenkins_pull
288+
289+from mock import Mock
290+from os import path
291+
292+
293+class TestJenkinsPullCoverage(TestCase):
294+ def setUp(self):
295+ self.url_list = [
296+ {
297+ 'url': 'http://jenkins.qa.ubuntu.com/job/libqtdbustest-trusty'
298+ '-i386-ci/10/artifact/work/results/coverage.xml',
299+ 'build_id': 10,
300+ 'ran_at': datetime.datetime(
301+ 2014, 3, 18, 17, 31, 24)
302+ }
303+ ]
304+
305+ localdir = path.dirname(__file__)
306+ with open(path.join(localdir, 'data/coverage.xml'), 'r') as f:
307+ jenkins_get_data = f.read()
308+ f.close()
309+ self.jdata = jenkins_get_data
310+
311+ def test_jenkins_get_data_from_common_exists(self):
312+ """Verify jenkins_get method is in common.managment"""
313+ from common.management import jenkins_get
314+
315+ def test_jenkins_pull_coverage_add_to_database(self):
316+ jenkins_pull.url_artifact_list = Mock(return_value=self.url_list)
317+ common.management.jenkins_get = Mock(return_value=self.jdata)
318+ add.records(
319+ 'qa',
320+ 'libqtdbustest',
321+ 'libqtdbustest-trusty-amd64-ci',
322+ 'coverage.xml',
323+ )
324+
325+ data_result = CoverageData.objects.filter(
326+ url__contains='coverage.xml').latest('coverage_build')
327+
328+ self.assertEquals(
329+ data_result.url,
330+ 'http://jenkins.qa.ubuntu.com/job/libqtdbustest-trusty-i386-ci'
331+ '/10/artifact/work/results/coverage.xml'
332+ )
333+ self.assertEquals(data_result.name, 'coverage.xml')
334+ self.assertEquals(data_result.xml_file, '')
335+ self.assertEquals(str(data_result.branch_coverage), '0.514')
336+ self.assertEquals(str(data_result.line_coverage), '0.884')
337+ self.assertEquals(str(data_result.hit_count), '107')
338+ self.assertEquals(str(data_result.line_count), '121')
339+ self.assertEquals(str(data_result.taken_count), '75')
340+ self.assertEquals(str(data_result.total_count), '146')
341+
342+ build_result = CoverageBuild.objects.filter(
343+ build_number='10').latest('ran_at')
344+
345+ self.assertEquals(str(build_result.build_number), '10')
346+ self.assertEqual(build_result.build_description, 'None')
347+
348+ project_result = CoverageProject.objects.filter(
349+ name='libqtdbustest').latest('name')
350+
351+ self.assertEquals(project_result.name, 'libqtdbustest')
352+
353+ stack_result = CoverageStack.objects.filter(
354+ name='qa').latest('name')
355+
356+ self.assertEquals(stack_result.name, 'qa')
357
358=== modified file 'gaps/util/jenkins_pull.py'
359--- gaps/util/jenkins_pull.py 2014-03-20 21:19:09 +0000
360+++ gaps/util/jenkins_pull.py 2014-04-09 19:08:53 +0000
361@@ -1,6 +1,12 @@
362-import jenkinsapi
363+
364 import time
365-from jenkinsapi import *
366+from jenkinsapi import (
367+ #api,
368+ build,
369+ job,
370+)
371+from jenkinsapi.api import Jenkins
372+from jenkinsapi.custom_exceptions import JenkinsAPIException
373 from qa_dashboard.settings import JENKINS_URL
374
375
376@@ -31,13 +37,13 @@
377 'armhf-ci',
378 'coverage.xml')
379
380- return: List of urls
381+ :return: List of urls
382 """
383 try:
384- jenkapi = jenkinsapi.api.Jenkins(JENKINS_URL)
385+ jenkapi = Jenkins(JENKINS_URL)
386 except:
387 time.sleep(5)
388- jenkapi = jenkinsapi.api.Jenkins(JENKINS_URL)
389+ jenkapi = Jenkins(JENKINS_URL)
390 try:
391 job = jenkapi.get_job(jenkins_job_name)
392 except:

Subscribers

People subscribed via source and target branches

to all changes: