1import json
2from mock import patch
3
4import jenkins
5from tests.helper import build_response_mock
6from tests.jobs.base import JenkinsJobsTestBase
7
8
9class JenkinsGetJobInfoTest(JenkinsJobsTestBase):
10
11    @patch.object(jenkins.Jenkins, 'jenkins_open')
12    def test_simple(self, jenkins_mock):
13        job_info_to_return = {
14            u'building': False,
15            u'msg': u'test',
16            u'revision': 66,
17            u'user': u'unknown'
18        }
19        jenkins_mock.return_value = json.dumps(job_info_to_return)
20
21        job_info = self.j.get_job_info(u'Test Job')
22
23        self.assertEqual(job_info, job_info_to_return)
24        self.assertEqual(
25            jenkins_mock.call_args[0][0].url,
26            self.make_url('job/Test%20Job/api/json?depth=0'))
27        self._check_requests(jenkins_mock.call_args_list)
28
29    @patch.object(jenkins.Jenkins, 'jenkins_open')
30    def test_all_builds(self, jenkins_mock):
31        job_info_to_return = {
32            u'building': False,
33            u'msg': u'test',
34            u'revision': 66,
35            u'user': u'unknown',
36            u'firstBuild': {u'number': 4},
37            u'builds': [{u'number': 5}],
38            u'name': u'Test Job',
39            u'fullName': u'Test Job'
40        }
41        all_builds_to_return = {u'allBuilds': [{u'number': 4},
42                                               {u'number': 5}]}
43        jenkins_mock.side_effect = [json.dumps(job_info_to_return),
44                                    json.dumps(all_builds_to_return)]
45
46        job_info = self.j.get_job_info(u'Test Job', fetch_all_builds=True)
47
48        expected = dict(job_info_to_return)
49        expected["builds"] = [{u'number': 4}, {u'number': 5}]
50
51        self.assertEqual(job_info, expected)
52        self.assertEqual(
53            jenkins_mock.call_args_list[0][0][0].url,
54            self.make_url('job/Test%20Job/api/json?depth=0'))
55        self.assertEqual(
56            jenkins_mock.call_args_list[1][0][0].url,
57            self.make_url(
58                'job/Test%20Job/api/json?tree=allBuilds[number,url]'))
59        self._check_requests(jenkins_mock.call_args_list)
60
61    @patch.object(jenkins.Jenkins, 'jenkins_open')
62    def test_in_folder(self, jenkins_mock):
63        job_info_to_return = {
64            u'building': False,
65            u'msg': u'test',
66            u'revision': 66,
67            u'user': u'unknown'
68        }
69        jenkins_mock.return_value = json.dumps(job_info_to_return)
70
71        job_info = self.j.get_job_info(u'a Folder/Test Job')
72
73        self.assertEqual(job_info, job_info_to_return)
74        self.assertEqual(
75            jenkins_mock.call_args[0][0].url,
76            self.make_url('job/a%20Folder/job/Test%20Job/api/json?depth=0'))
77        self._check_requests(jenkins_mock.call_args_list)
78
79    @patch.object(jenkins.Jenkins, 'jenkins_open')
80    def test_all_builds_in_folder(self, jenkins_mock):
81        job_info_to_return = {
82            u'building': False,
83            u'msg': u'test',
84            u'revision': 66,
85            u'user': u'unknown',
86            u'firstBuild': {u'number': 4},
87            u'builds': [{u'number': 5}],
88            u'name': u'Test Job',
89            u'fullName': u'a Folder/Test Job'
90        }
91        all_builds_to_return = {u'allBuilds': [{u'number': 4},
92                                               {u'number': 5}]}
93        jenkins_mock.side_effect = [json.dumps(job_info_to_return),
94                                    json.dumps(all_builds_to_return)]
95
96        job_info = self.j.get_job_info(u'a Folder/Test Job', fetch_all_builds=True)
97
98        expected = dict(job_info_to_return)
99        expected["builds"] = [{u'number': 4}, {u'number': 5}]
100
101        self.assertEqual(job_info, expected)
102        self.assertEqual(
103            jenkins_mock.call_args_list[0][0][0].url,
104            self.make_url('job/a%20Folder/job/Test%20Job/api/json?depth=0'))
105        self.assertEqual(
106            jenkins_mock.call_args_list[1][0][0].url,
107            self.make_url(
108                'job/a%20Folder/job/Test%20Job/api/json?tree=allBuilds[number,url]'))
109        self._check_requests(jenkins_mock.call_args_list)
110
111    @patch.object(jenkins.Jenkins, 'jenkins_open')
112    def test_regex(self, jenkins_mock):
113        jobs = [
114            {u'name': u'my-job-1'},
115            {u'name': u'my-job-2'},
116            {u'name': u'your-job-1'},
117            {u'name': u'Your-Job-1'},
118            {u'name': u'my-project-1'},
119        ]
120        job_info_to_return = {u'jobs': jobs}
121        jenkins_mock.return_value = json.dumps(job_info_to_return)
122
123        self.assertEqual(len(self.j.get_job_info_regex('her-job')), 0)
124        self.assertEqual(len(self.j.get_job_info_regex('my-job-1')), 1)
125        self.assertEqual(len(self.j.get_job_info_regex('my-job')), 2)
126        self.assertEqual(len(self.j.get_job_info_regex('job')), 3)
127        self.assertEqual(len(self.j.get_job_info_regex('project')), 1)
128        self.assertEqual(len(self.j.get_job_info_regex('[Yy]our-[Jj]ob-1')), 2)
129        self._check_requests(jenkins_mock.call_args_list)
130
131    @patch.object(jenkins.Jenkins, 'jenkins_open')
132    def test_return_none(self, jenkins_mock):
133        jenkins_mock.return_value = None
134
135        with self.assertRaises(jenkins.JenkinsException) as context_manager:
136            self.j.get_job_info(u'TestJob')
137        self.assertEqual(
138            jenkins_mock.call_args[0][0].url,
139            self.make_url('job/TestJob/api/json?depth=0'))
140        self.assertEqual(
141            str(context_manager.exception),
142            'job[TestJob] does not exist')
143        self._check_requests(jenkins_mock.call_args_list)
144
145    @patch.object(jenkins.Jenkins, 'jenkins_open')
146    def test_return_invalid_json(self, jenkins_mock):
147        jenkins_mock.return_value = 'Invalid JSON'
148
149        with self.assertRaises(jenkins.JenkinsException) as context_manager:
150            self.j.get_job_info(u'TestJob')
151        self.assertEqual(
152            jenkins_mock.call_args[0][0].url,
153            self.make_url('job/TestJob/api/json?depth=0'))
154        self.assertEqual(
155            str(context_manager.exception),
156            'Could not parse JSON info for job[TestJob]')
157        self._check_requests(jenkins_mock.call_args_list)
158
159    @patch('jenkins.requests.Session.send', autospec=True)
160    def test_raise_HTTPError(self, session_send_mock):
161        session_send_mock.side_effect = iter([
162            build_response_mock(404, reason="Not Found"),  # crumb
163            build_response_mock(404, reason="Not Found"),  # request
164        ])
165
166        with self.assertRaises(jenkins.JenkinsException) as context_manager:
167            self.j.get_job_info(u'TestJob')
168        self.assertEqual(
169            session_send_mock.call_args_list[1][0][1].url,
170            self.make_url('job/TestJob/api/json?depth=0'))
171        self.assertEqual(
172            str(context_manager.exception),
173            'job[TestJob] does not exist')
174
175    @patch('jenkins.requests.Session.send', autospec=True)
176    def test_in_folder_raise_HTTPError(self, session_send_mock):
177        session_send_mock.side_effect = iter([
178            build_response_mock(404, reason="Not Found"),  # crumb
179            build_response_mock(404, reason="Not Found"),  # request
180        ])
181
182        with self.assertRaises(jenkins.JenkinsException) as context_manager:
183            self.j.get_job_info(u'a Folder/TestJob')
184        self.assertEqual(
185            session_send_mock.call_args_list[1][0][1].url,
186            self.make_url('job/a%20Folder/job/TestJob/api/json?depth=0'))
187        self.assertEqual(
188            str(context_manager.exception),
189            'job[a Folder/TestJob] does not exist')
190