Merge lp:~tsimonq2/ubuntu-qa-website/python-library-merge into lp:ubuntu-qa-website
- python-library-merge
- Merge into drupal7-rewrite
Proposed by
Simon Quigley
Status: | Merged |
---|---|
Merged at revision: | 427 |
Proposed branch: | lp:~tsimonq2/ubuntu-qa-website/python-library-merge |
Merge into: | lp:ubuntu-qa-website |
Diff against target: |
1271 lines (+1210/-0) 12 files modified
python-library/qatracker.py (+535/-0) python-library/tests/run (+35/-0) python-library/tests/setup.sql (+4/-0) python-library/tests/test_bug.py (+17/-0) python-library/tests/test_build.py (+98/-0) python-library/tests/test_milestone.py (+56/-0) python-library/tests/test_product.py (+51/-0) python-library/tests/test_rebuilds.py (+69/-0) python-library/tests/test_result.py (+173/-0) python-library/tests/test_rpc.py (+27/-0) python-library/tests/test_series.py (+77/-0) python-library/tests/test_testcase.py (+68/-0) |
To merge this branch: | bzr merge lp:~tsimonq2/ubuntu-qa-website/python-library-merge |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Nicholas Skaggs | Pending | ||
Review via email: mp+287711@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === added directory 'python-library' |
2 | === added file 'python-library/qatracker.py' |
3 | --- python-library/qatracker.py 1970-01-01 00:00:00 +0000 |
4 | +++ python-library/qatracker.py 2016-03-01 21:32:25 +0000 |
5 | @@ -0,0 +1,535 @@ |
6 | +#!/usr/bin/python3 |
7 | +# -*- coding: utf-8 -*- |
8 | + |
9 | +# Copyright (C) 2011, 2012 Canonical Ltd. |
10 | +# Author: Stéphane Graber <stgraber@ubuntu.com> |
11 | + |
12 | +# This library is free software; you can redistribute it and/or |
13 | +# modify it under the terms of the GNU Lesser General Public |
14 | +# License as published by the Free Software Foundation; either |
15 | +# version 2.1 of the License, or (at your option) any later version. |
16 | + |
17 | +# This library is distributed in the hope that it will be useful, |
18 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
19 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
20 | +# Lesser General Public License for more details. |
21 | + |
22 | +# You should have received a copy of the GNU Lesser General Public |
23 | +# License along with this library; if not, write to the Free Software |
24 | +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 |
25 | +# USA |
26 | + |
27 | +try: |
28 | + import xmlrpc.client as xmlrpclib |
29 | +except ImportError: |
30 | + import xmlrpclib |
31 | + |
32 | +import base64 |
33 | +from datetime import datetime |
34 | + |
35 | +# Taken from qatracker/qatracker.modules (PHP code) |
36 | +# cat qatracker.module | grep " = array" | sed -e 's/^\$//g' \ |
37 | +# -e 's/array(/[/g' -e 's/);/]/g' -e "s/t('/\"/g" -e "s/')/\"/g" |
38 | +### AUTO-GENERATED -> |
39 | +qatracker_build_milestone_status = ["Active", "Re-building", "Disabled", |
40 | + "Superseded", "Ready"] |
41 | +qatracker_milestone_notify = ["No", "Yes"] |
42 | +qatracker_milestone_autofill = ["No", "Yes"] |
43 | +qatracker_milestone_status = ["Testing", "Released", "Archived"] |
44 | +qatracker_milestone_series_status = ["Active", "Disabled"] |
45 | +qatracker_milestone_series_manifest_status = ["Active", "Disabled"] |
46 | +qatracker_product_status = ["Active", "Disabled"] |
47 | +qatracker_product_type = ["iso", "package", "hardware"] |
48 | +qatracker_product_download_type = ["HTTP", "RSYNC", "ZSYNC", |
49 | + "GPG signature", "MD5 checksum", "Comment", |
50 | + "Torrent"] |
51 | +qatracker_testsuite_testcase_status = ["Mandatory", "Disabled", "Run-once", |
52 | + "Optional"] |
53 | +qatracker_result_result = ["Failed", "Passed", "In progress"] |
54 | +qatracker_result_status = ["Active", "Disabled"] |
55 | +qatracker_rebuild_status = ["Requested", "Queued", "Building", "Built", |
56 | + "Published", "Canceled"] |
57 | +### <- AUTO-GENERATED |
58 | + |
59 | + |
60 | +class QATrackerRPCObject(): |
61 | + """Base class for objects received over XML-RPC""" |
62 | + |
63 | + CONVERT_BOOL = [] |
64 | + CONVERT_DATE = [] |
65 | + CONVERT_INT = [] |
66 | + |
67 | + def __init__(self, tracker, rpc_dict): |
68 | + # Convert the dict we get from the API into an object |
69 | + |
70 | + for key in rpc_dict: |
71 | + if key in self.CONVERT_INT: |
72 | + try: |
73 | + setattr(self, key, int(rpc_dict[key])) |
74 | + except ValueError: |
75 | + setattr(self, key, None) |
76 | + elif key in self.CONVERT_BOOL: |
77 | + setattr(self, key, rpc_dict[key] == "true") |
78 | + elif key in self.CONVERT_DATE: |
79 | + try: |
80 | + setattr(self, key, datetime.strptime(rpc_dict[key], |
81 | + '%Y-%m-%d %H:%M:%S')) |
82 | + except ValueError: |
83 | + setattr(self, key, None) |
84 | + else: |
85 | + setattr(self, key, str(rpc_dict[key])) |
86 | + |
87 | + self.tracker = tracker |
88 | + |
89 | + def __repr__(self): |
90 | + return "%s: %s" % (self.__class__.__name__, self.title) |
91 | + |
92 | + |
93 | +class QATrackerBug(QATrackerRPCObject): |
94 | + """A bug entry""" |
95 | + |
96 | + CONVERT_INT = ['bugnumber', 'count'] |
97 | + CONVERT_DATE = ['earliest_report', 'latest_report'] |
98 | + |
99 | + def __repr__(self): |
100 | + return "%s: %s" % (self.__class__.__name__, self.bugnumber) |
101 | + |
102 | + |
103 | +class QATrackerBuild(QATrackerRPCObject): |
104 | + """A build entry""" |
105 | + |
106 | + CONVERT_INT = ['id', 'productid', 'userid', 'status'] |
107 | + CONVERT_DATE = ['date'] |
108 | + |
109 | + def __repr__(self): |
110 | + return "%s: %s" % (self.__class__.__name__, self.id) |
111 | + |
112 | + def add_result(self, testcase, result, comment='', hardware='', bugs={}): |
113 | + """Add a result to the build""" |
114 | + |
115 | + if (self.tracker.access not in ("user", "admin") and |
116 | + self.tracker.access is not None): |
117 | + raise Exception("Access denied, you need 'user' but are '%s'" % |
118 | + self.tracker.access) |
119 | + |
120 | + build_testcase = None |
121 | + |
122 | + # FIXME: Supporting 'str' containing the testcase name would be nice |
123 | + if isinstance(testcase, QATrackerTestcase): |
124 | + build_testcase = testcase.id |
125 | + elif isinstance(testcase, int): |
126 | + build_testcase = testcase |
127 | + |
128 | + if not build_testcase: |
129 | + raise IndexError("Couldn't find testcase: %s" % (testcase,)) |
130 | + |
131 | + if isinstance(result, list): |
132 | + raise TypeError("result must be a string or an integer") |
133 | + |
134 | + build_result = self.tracker._get_valid_id_list(qatracker_result_result, |
135 | + result) |
136 | + |
137 | + if not isinstance(bugs, dict): |
138 | + raise TypeError("bugs must be a dict") |
139 | + |
140 | + for bug in bugs: |
141 | + if not isinstance(bug, int) or bug <= 0: |
142 | + raise ValueError("A bugnumber must be a number >= 0") |
143 | + |
144 | + if not isinstance(bugs[bug], int) or bugs[bug] not in (0, 1): |
145 | + raise ValueError("A bugimportance must be in (0,1)") |
146 | + |
147 | + resultid = int(self.tracker.tracker.results.add(self.id, |
148 | + build_testcase, |
149 | + build_result[0], |
150 | + str(comment), |
151 | + str(hardware), |
152 | + bugs)) |
153 | + if resultid == -1: |
154 | + raise Exception("Couldn't post your result.") |
155 | + |
156 | + new_result = None |
157 | + for entry in self.get_results(build_testcase, 0): |
158 | + if entry.id == resultid: |
159 | + new_result = entry |
160 | + break |
161 | + |
162 | + return new_result |
163 | + |
164 | + def get_results(self, testcase, status=qatracker_result_status): |
165 | + """Get a list of results for the given build and testcase""" |
166 | + |
167 | + build_testcase = None |
168 | + |
169 | + # FIXME: Supporting 'str' containing the testcase name would be nice |
170 | + if isinstance(testcase, QATrackerTestcase): |
171 | + build_testcase = testcase.id |
172 | + elif isinstance(testcase, int): |
173 | + build_testcase = testcase |
174 | + |
175 | + if not build_testcase: |
176 | + raise IndexError("Couldn't find testcase: %s" % (testcase,)) |
177 | + |
178 | + record_filter = self.tracker._get_valid_id_list( |
179 | + qatracker_result_status, |
180 | + status) |
181 | + |
182 | + if len(record_filter) == 0: |
183 | + return [] |
184 | + |
185 | + results = [] |
186 | + for entry in self.tracker.tracker.results.get_list( |
187 | + self.id, build_testcase, list(record_filter)): |
188 | + results.append(QATrackerResult(self.tracker, entry)) |
189 | + |
190 | + return results |
191 | + |
192 | + |
193 | +class QATrackerMilestone(QATrackerRPCObject): |
194 | + """A milestone entry""" |
195 | + |
196 | + CONVERT_INT = ['id', 'status', 'series'] |
197 | + CONVERT_BOOL = ['notify'] |
198 | + |
199 | + def get_bugs(self): |
200 | + """Returns a list of all bugs linked to this milestone""" |
201 | + |
202 | + bugs = [] |
203 | + for entry in self.tracker.tracker.bugs.get_list(self.id): |
204 | + bugs.append(QATrackerBug(self.tracker, entry)) |
205 | + |
206 | + return bugs |
207 | + |
208 | + def add_build(self, product, version, note="", notify=True): |
209 | + """Add a build to the milestone""" |
210 | + |
211 | + if self.status != 0: |
212 | + raise TypeError("Only active milestones are accepted") |
213 | + |
214 | + if self.tracker.access != "admin" and self.tracker.access is not None: |
215 | + raise Exception("Access denied, you need 'admin' but are '%s'" % |
216 | + self.tracker.access) |
217 | + |
218 | + if not isinstance(notify, bool): |
219 | + raise TypeError("notify must be a boolean") |
220 | + |
221 | + build_product = None |
222 | + |
223 | + if isinstance(product, QATrackerProduct): |
224 | + build_product = product |
225 | + else: |
226 | + valid_products = self.tracker.get_products(0) |
227 | + |
228 | + for entry in valid_products: |
229 | + if (entry.title.lower() == str(product).lower() or |
230 | + entry.id == product): |
231 | + build_product = entry |
232 | + break |
233 | + |
234 | + if not build_product: |
235 | + raise IndexError("Couldn't find product: %s" % product) |
236 | + |
237 | + if build_product.status != 0: |
238 | + raise TypeError("Only active products are accepted") |
239 | + |
240 | + self.tracker.tracker.builds.add(build_product.id, self.id, |
241 | + str(version), str(note), notify) |
242 | + |
243 | + new_build = None |
244 | + for entry in self.get_builds(0): |
245 | + if (entry.productid == build_product.id |
246 | + and entry.version == str(version)): |
247 | + new_build = entry |
248 | + break |
249 | + |
250 | + return new_build |
251 | + |
252 | + def get_builds(self, status=qatracker_build_milestone_status): |
253 | + """Get a list of builds for the milestone""" |
254 | + |
255 | + record_filter = self.tracker._get_valid_id_list( |
256 | + qatracker_build_milestone_status, status) |
257 | + |
258 | + if len(record_filter) == 0: |
259 | + return [] |
260 | + |
261 | + builds = [] |
262 | + for entry in self.tracker.tracker.builds.get_list(self.id, |
263 | + list(record_filter)): |
264 | + builds.append(QATrackerBuild(self.tracker, entry)) |
265 | + |
266 | + return builds |
267 | + |
268 | + |
269 | +class QATrackerProduct(QATrackerRPCObject): |
270 | + CONVERT_INT = ['id', 'type', 'status'] |
271 | + |
272 | + def get_testcases(self, series, |
273 | + status=qatracker_testsuite_testcase_status): |
274 | + """Get a list of testcases associated with the product""" |
275 | + |
276 | + record_filter = self.tracker._get_valid_id_list( |
277 | + qatracker_testsuite_testcase_status, status) |
278 | + |
279 | + if len(record_filter) == 0: |
280 | + return [] |
281 | + |
282 | + if isinstance(series, QATrackerMilestone): |
283 | + seriesid = series.series |
284 | + elif isinstance(series, int): |
285 | + seriesid = series |
286 | + else: |
287 | + raise TypeError("series needs to be a valid QATrackerMilestone" |
288 | + " instance or an integer") |
289 | + |
290 | + testcases = [] |
291 | + for entry in self.tracker.tracker.testcases.get_list( |
292 | + self.id, seriesid, list(record_filter)): |
293 | + testcases.append(QATrackerTestcase(self.tracker, entry)) |
294 | + |
295 | + return testcases |
296 | + |
297 | + |
298 | +class QATrackerRebuild(QATrackerRPCObject): |
299 | + CONVERT_INT = ['id', 'seriesid', 'productid', 'milestoneid', 'requestedby', |
300 | + 'changedby', 'status'] |
301 | + CONVERT_DATE = ['requestedat', 'changedat'] |
302 | + |
303 | + def __repr__(self): |
304 | + return "%s: %s" % (self.__class__.__name__, self.id) |
305 | + |
306 | + def save(self): |
307 | + """Save any change that happened on this entry. |
308 | + NOTE: At the moment only supports the status field.""" |
309 | + |
310 | + if (self.tracker.access != "admin" and |
311 | + self.tracker.access is not None): |
312 | + raise Exception("Access denied, you need 'admin' but are '%s'" % |
313 | + self.tracker.access) |
314 | + |
315 | + retval = self.tracker.tracker.rebuilds.update_status(self.id, |
316 | + self.status) |
317 | + if retval is not True: |
318 | + raise Exception("Failed to update rebuild") |
319 | + |
320 | + return retval |
321 | + |
322 | + |
323 | +class QATrackerResult(QATrackerRPCObject): |
324 | + CONVERT_INT = ['id', 'reporterid', 'revisionid', 'result', 'changedby', |
325 | + 'status'] |
326 | + CONVERT_DATE = ['date', 'lastchange'] |
327 | + __deleted = False |
328 | + |
329 | + def __repr__(self): |
330 | + return "%s: %s" % (self.__class__.__name__, self.id) |
331 | + |
332 | + def delete(self): |
333 | + """Remove the result from the tracker""" |
334 | + |
335 | + if (self.tracker.access not in ("user", "admin") and |
336 | + self.tracker.access is not None): |
337 | + raise Exception("Access denied, you need 'user' but are '%s'" % |
338 | + self.tracker.access) |
339 | + |
340 | + if self.__deleted: |
341 | + raise IndexError("Result has already been removed") |
342 | + |
343 | + retval = self.tracker.tracker.results.delete(self.id) |
344 | + if retval is not True: |
345 | + raise Exception("Failed to remove result") |
346 | + |
347 | + self.status = 1 |
348 | + self.__deleted = True |
349 | + |
350 | + def save(self): |
351 | + """Save any change that happened on this entry""" |
352 | + |
353 | + if (self.tracker.access not in ("user", "admin") and |
354 | + self.tracker.access is not None): |
355 | + raise Exception("Access denied, you need 'user' but are '%s'" % |
356 | + self.tracker.access) |
357 | + |
358 | + if self.__deleted: |
359 | + raise IndexError("Result no longer exists") |
360 | + |
361 | + retval = self.tracker.tracker.results.update(self.id, self.result, |
362 | + self.comment, |
363 | + self.hardware, |
364 | + self.bugs) |
365 | + if retval is not True: |
366 | + raise Exception("Failed to update result") |
367 | + |
368 | + return retval |
369 | + |
370 | + |
371 | +class QATrackerSeries(QATrackerRPCObject): |
372 | + CONVERT_INT = ['id', 'status'] |
373 | + |
374 | + def get_manifest(self, status=qatracker_milestone_series_manifest_status): |
375 | + """Get a list of products in the series' manifest""" |
376 | + |
377 | + record_filter = self.tracker._get_valid_id_list( |
378 | + qatracker_milestone_series_manifest_status, status) |
379 | + |
380 | + if len(record_filter) == 0: |
381 | + return [] |
382 | + |
383 | + manifest_entries = [] |
384 | + for entry in self.tracker.tracker.series.get_manifest( |
385 | + self.id, list(record_filter)): |
386 | + manifest_entries.append(QATrackerSeriesManifest( |
387 | + self.tracker, entry)) |
388 | + |
389 | + return manifest_entries |
390 | + |
391 | + |
392 | +class QATrackerSeriesManifest(QATrackerRPCObject): |
393 | + CONVERT_INT = ['id', 'productid', 'status'] |
394 | + |
395 | + def __repr__(self): |
396 | + return "%s: %s" % (self.__class__.__name__, self.product_title) |
397 | + |
398 | + |
399 | +class QATrackerTestcase(QATrackerRPCObject): |
400 | + CONVERT_INT = ['id', 'status', 'weight', 'suite'] |
401 | + |
402 | + |
403 | +class QATracker(): |
404 | + def __init__(self, url, username=None, password=None): |
405 | + class AuthTransport(xmlrpclib.Transport): |
406 | + def set_auth(self, auth): |
407 | + self.auth = auth |
408 | + |
409 | + def get_host_info(self, host): |
410 | + host, extra_headers, x509 = \ |
411 | + xmlrpclib.Transport.get_host_info(self, host) |
412 | + if extra_headers is None: |
413 | + extra_headers = [] |
414 | + extra_headers.append(('Authorization', 'Basic %s' % auth)) |
415 | + return host, extra_headers, x509 |
416 | + |
417 | + if username and password: |
418 | + try: |
419 | + auth = str(base64.b64encode( |
420 | + bytes('%s:%s' % (username, password), 'utf-8')), |
421 | + 'utf-8') |
422 | + except TypeError: |
423 | + auth = base64.b64encode('%s:%s' % (username, password)) |
424 | + |
425 | + transport = AuthTransport() |
426 | + transport.set_auth(auth) |
427 | + drupal = xmlrpclib.ServerProxy(url, transport=transport) |
428 | + else: |
429 | + drupal = xmlrpclib.ServerProxy(url) |
430 | + |
431 | + # Call listMethods() so if something is wrong we know it immediately |
432 | + drupal.system.listMethods() |
433 | + |
434 | + # Get our current access |
435 | + self.access = drupal.qatracker.get_access() |
436 | + |
437 | + self.tracker = drupal.qatracker |
438 | + |
439 | + def _get_valid_id_list(self, status_list, status): |
440 | + """ Get a list of valid keys and a list or just a single |
441 | + entry of input to check against the list of valid keys. |
442 | + The function looks for valid indexes and content, doing |
443 | + case insensitive checking for strings and returns a list |
444 | + of indexes for the list of valid keys. """ |
445 | + |
446 | + def process(status_list, status): |
447 | + valid_status = [entry.lower() for entry in status_list] |
448 | + |
449 | + if isinstance(status, int): |
450 | + if status < 0 or status >= len(valid_status): |
451 | + raise IndexError("Invalid status: %s" % status) |
452 | + return int(status) |
453 | + |
454 | + if isinstance(status, str): |
455 | + status = status.lower() |
456 | + if status not in valid_status: |
457 | + raise IndexError("Invalid status: %s" % status) |
458 | + return valid_status.index(status) |
459 | + |
460 | + raise TypeError("Invalid status type: %s (expected str or int)" % |
461 | + type(status)) |
462 | + |
463 | + record_filter = set() |
464 | + |
465 | + if isinstance(status, list): |
466 | + for entry in status: |
467 | + record_filter.add(process(status_list, entry)) |
468 | + else: |
469 | + record_filter.add(process(status_list, status)) |
470 | + |
471 | + return list(record_filter) |
472 | + |
473 | + def get_bugs(self): |
474 | + """Get a list of all bugs reported on the site""" |
475 | + |
476 | + bugs = [] |
477 | + for entry in self.tracker.bugs.get_list(0): |
478 | + bugs.append(QATrackerBug(self, entry)) |
479 | + |
480 | + return bugs |
481 | + |
482 | + def get_milestones(self, status=qatracker_milestone_status): |
483 | + """Get a list of all milestones""" |
484 | + |
485 | + record_filter = self._get_valid_id_list(qatracker_milestone_status, |
486 | + status) |
487 | + |
488 | + if len(record_filter) == 0: |
489 | + return [] |
490 | + |
491 | + milestones = [] |
492 | + for entry in self.tracker.milestones.get_list(list(record_filter)): |
493 | + milestones.append(QATrackerMilestone(self, entry)) |
494 | + |
495 | + return milestones |
496 | + |
497 | + def get_products(self, status=qatracker_product_status): |
498 | + """Get a list of all products""" |
499 | + |
500 | + record_filter = self._get_valid_id_list(qatracker_product_status, |
501 | + status) |
502 | + |
503 | + if len(record_filter) == 0: |
504 | + return [] |
505 | + |
506 | + products = [] |
507 | + for entry in self.tracker.products.get_list(list(record_filter)): |
508 | + products.append(QATrackerProduct(self, entry)) |
509 | + |
510 | + return products |
511 | + |
512 | + def get_rebuilds(self, status=qatracker_rebuild_status): |
513 | + """Get a list of all rebuilds""" |
514 | + |
515 | + record_filter = self._get_valid_id_list( |
516 | + qatracker_rebuild_status, status) |
517 | + |
518 | + if len(record_filter) == 0: |
519 | + return [] |
520 | + |
521 | + rebuilds = [] |
522 | + for entry in self.tracker.rebuilds.get_list(list(record_filter)): |
523 | + rebuilds.append(QATrackerRebuild(self, entry)) |
524 | + |
525 | + return rebuilds |
526 | + |
527 | + def get_series(self, status=qatracker_milestone_series_status): |
528 | + """Get a list of all series""" |
529 | + |
530 | + record_filter = self._get_valid_id_list( |
531 | + qatracker_milestone_series_status, status) |
532 | + |
533 | + if len(record_filter) == 0: |
534 | + return [] |
535 | + |
536 | + series = [] |
537 | + for entry in self.tracker.series.get_list(list(record_filter)): |
538 | + series.append(QATrackerSeries(self, entry)) |
539 | + |
540 | + return series |
541 | |
542 | === added directory 'python-library/tests' |
543 | === added file 'python-library/tests/run' |
544 | --- python-library/tests/run 1970-01-01 00:00:00 +0000 |
545 | +++ python-library/tests/run 2016-03-01 21:32:25 +0000 |
546 | @@ -0,0 +1,35 @@ |
547 | +#!/usr/bin/python3 |
548 | +import unittest |
549 | +import os |
550 | +import re |
551 | +import shutil |
552 | +import sys |
553 | + |
554 | +coverage = True |
555 | +try: |
556 | + from coverage import coverage |
557 | + cov = coverage() |
558 | + cov.start() |
559 | +except ImportError: |
560 | + print("No coverage report, make sure python-coverage is installed") |
561 | + coverage = False |
562 | + |
563 | +sys.path.insert(0, '.') |
564 | + |
565 | +if len(sys.argv) > 1: |
566 | + test_filter = sys.argv[1] |
567 | +else: |
568 | + test_filter = '' |
569 | + |
570 | +tests = [t[:-3] for t in os.listdir('tests') |
571 | + if t.startswith('test_') and t.endswith('.py') and |
572 | + re.search(test_filter, t)] |
573 | +tests.sort() |
574 | +suite = unittest.TestLoader().loadTestsFromNames(tests) |
575 | +res = unittest.TextTestRunner(verbosity=2).run(suite) |
576 | + |
577 | +if coverage: |
578 | + if os.path.exists('tests/coverage'): |
579 | + shutil.rmtree('tests/coverage') |
580 | + cov.stop() |
581 | + cov.html_report(include=["qatracker.py"], directory='tests/coverage') |
582 | |
583 | === added file 'python-library/tests/setup.sql' |
584 | --- python-library/tests/setup.sql 1970-01-01 00:00:00 +0000 |
585 | +++ python-library/tests/setup.sql 2016-03-01 21:32:25 +0000 |
586 | @@ -0,0 +1,4 @@ |
587 | +INSERT INTO users (uid, name, data, status) VALUES (99999, 'user', 'a:1:{s:17:"qatracker_api_key";s:4:"user";}', 1); |
588 | +INSERT INTO users (uid, name, data, status) VALUES (99998, 'admin', 'a:1:{s:17:"qatracker_api_key";s:5:"admin";}', 1); |
589 | +INSERT INTO users_roles (uid, rid) VALUES (99999, 2); |
590 | +INSERT INTO users_roles (uid, rid) VALUES (99998, 4); |
591 | |
592 | === added file 'python-library/tests/test_bug.py' |
593 | --- python-library/tests/test_bug.py 1970-01-01 00:00:00 +0000 |
594 | +++ python-library/tests/test_bug.py 2016-03-01 21:32:25 +0000 |
595 | @@ -0,0 +1,17 @@ |
596 | +import unittest |
597 | +import qatracker |
598 | +import datetime |
599 | + |
600 | +URL = 'http://iso.qa.dev.stgraber.org/xmlrpc.php' |
601 | + |
602 | + |
603 | +class BugTests(unittest.TestCase): |
604 | + def setUp(self): |
605 | + self.instance = qatracker.QATracker(URL) |
606 | + |
607 | + def test_all_bugs(self): |
608 | + bugs = self.instance.get_bugs() |
609 | + if bugs: |
610 | + self.assertIsInstance(bugs[0].bugnumber, int) |
611 | + self.assertIsInstance(bugs[0].earliest_report, datetime.datetime) |
612 | + self.assertTrue(str(bugs[0]).startswith('QATrackerBug: ')) |
613 | |
614 | === added file 'python-library/tests/test_build.py' |
615 | --- python-library/tests/test_build.py 1970-01-01 00:00:00 +0000 |
616 | +++ python-library/tests/test_build.py 2016-03-01 21:32:25 +0000 |
617 | @@ -0,0 +1,98 @@ |
618 | +import unittest |
619 | +import qatracker |
620 | + |
621 | +URL = 'http://iso.qa.dev.stgraber.org/xmlrpc.php' |
622 | + |
623 | + |
624 | +class BuildTests(unittest.TestCase): |
625 | + def setUp(self): |
626 | + self.instance = qatracker.QATracker(URL, 'admin', 'admin') |
627 | + self.milestone = self.instance.get_milestones('testing')[0] |
628 | + |
629 | + def test_build_lower(self): |
630 | + self.assertIsInstance(self.milestone.get_builds('active'), list) |
631 | + |
632 | + def test_build_mixed(self): |
633 | + self.assertIsInstance(self.milestone.get_builds('DisAblEd'), list) |
634 | + |
635 | + def test_build_upper(self): |
636 | + self.assertIsInstance(self.milestone.get_builds('RE-BUILDING'), list) |
637 | + |
638 | + def test_build_id(self): |
639 | + self.assertIsInstance(self.milestone.get_builds(3), list) |
640 | + |
641 | + def test_build_list(self): |
642 | + self.assertIsInstance(self.milestone.get_builds(['Re-Building', 0, |
643 | + 'DISABLED', |
644 | + 'SuperSeded']), list) |
645 | + |
646 | + def test_build_empty_list(self): |
647 | + self.assertEquals(self.milestone.get_builds([]), []) |
648 | + |
649 | + def test_build_all(self): |
650 | + self.assertIsInstance(self.milestone.get_builds(), list) |
651 | + |
652 | + def test_build_type(self): |
653 | + build = self.milestone.get_builds(0)[0] |
654 | + self.assertIsInstance(build, qatracker.QATrackerBuild) |
655 | + self.assertIsInstance(build.status, int) |
656 | + self.assertIsInstance(build.version, str) |
657 | + |
658 | + def test_build_repr(self): |
659 | + build = self.milestone.get_builds(0)[0] |
660 | + self.assertTrue(str(build).startswith('QATrackerBuild: ')) |
661 | + |
662 | + def test_build_add_by_name(self): |
663 | + product = self.instance.get_products(0)[0] |
664 | + self.milestone.add_build(product.title, '1234', '', False) |
665 | + |
666 | + def test_build_add_by_id(self): |
667 | + product = self.instance.get_products(0)[0] |
668 | + build = self.milestone.add_build(product.id, '1234', '', False) |
669 | + self.assertEquals(build.productid, product.id) |
670 | + self.assertEquals(build.version, '1234') |
671 | + self.assertEquals(build.note, '') |
672 | + |
673 | + def test_build_invalid_add_disabled_product_by_id(self): |
674 | + product = self.instance.get_products(1)[0] |
675 | + self.assertRaises(IndexError, self.milestone.add_build, |
676 | + product=product.id, version='1234') |
677 | + |
678 | + def test_build_invalid_add_disabled_product_by_object(self): |
679 | + product = self.instance.get_products(1)[0] |
680 | + self.assertRaises(TypeError, self.milestone.add_build, |
681 | + product=product, version='1234') |
682 | + |
683 | + def test_build_invalid_add_disabled_milestone_by_object(self): |
684 | + milestone = self.instance.get_milestones('archived')[0] |
685 | + product = self.instance.get_products(1)[0] |
686 | + self.assertRaises(TypeError, milestone.add_build, |
687 | + product=product, version='1234') |
688 | + |
689 | + def test_build_invalid_add_invalid_by_name(self): |
690 | + self.assertRaises(IndexError, self.milestone.add_build, |
691 | + product='bmaifno', version='1234') |
692 | + |
693 | + def test_build_invalid_add_invalid_by_id(self): |
694 | + self.assertRaises(IndexError, self.milestone.add_build, |
695 | + product=-1, version='1234') |
696 | + |
697 | + def test_build_invalid_add_invalid_notify(self): |
698 | + product = self.instance.get_products(0)[0] |
699 | + self.assertRaises(TypeError, self.milestone.add_build, |
700 | + product=product.id, version='1234', notify=object()) |
701 | + |
702 | + def test_build_invalid_add_invalid_no_access(self): |
703 | + instance = qatracker.QATracker(URL, 'user', 'user') |
704 | + milestone = instance.get_milestones('testing')[0] |
705 | + self.assertRaises(Exception, milestone.add_build, product=0, |
706 | + version='1234') |
707 | + |
708 | + def test_build_invalid_id(self): |
709 | + self.assertRaises(IndexError, self.milestone.get_builds, (-1)) |
710 | + |
711 | + def test_build_invalid_string(self): |
712 | + self.assertRaises(IndexError, self.milestone.get_builds, ('bla')) |
713 | + |
714 | + def test_build_invalid_type(self): |
715 | + self.assertRaises(TypeError, self.milestone.get_builds, (object())) |
716 | |
717 | === added file 'python-library/tests/test_milestone.py' |
718 | --- python-library/tests/test_milestone.py 1970-01-01 00:00:00 +0000 |
719 | +++ python-library/tests/test_milestone.py 2016-03-01 21:32:25 +0000 |
720 | @@ -0,0 +1,56 @@ |
721 | +import unittest |
722 | +import qatracker |
723 | + |
724 | +URL = 'http://iso.qa.dev.stgraber.org/xmlrpc.php' |
725 | + |
726 | + |
727 | +class MilestoneTests(unittest.TestCase): |
728 | + def setUp(self): |
729 | + self.instance = qatracker.QATracker(URL) |
730 | + |
731 | + def test_milestone_lower(self): |
732 | + milestones = self.instance.get_milestones('testing') |
733 | + self.assertIsInstance(milestones, list) |
734 | + |
735 | + def test_milestone_mixed(self): |
736 | + milestones = self.instance.get_milestones('RelEaSed') |
737 | + self.assertIsInstance(milestones, list) |
738 | + |
739 | + def test_milestone_upper(self): |
740 | + milestones = self.instance.get_milestones('ARCHIVED') |
741 | + self.assertIsInstance(milestones, list) |
742 | + |
743 | + def test_milestone_id(self): |
744 | + milestones = self.instance.get_milestones(2) |
745 | + self.assertIsInstance(milestones, list) |
746 | + |
747 | + def test_milestone_list(self): |
748 | + milestones = self.instance.get_milestones(['testing', 2, 'archIved']) |
749 | + self.assertIsInstance(milestones, list) |
750 | + |
751 | + def test_milestone_empty_list(self): |
752 | + self.assertEquals(self.instance.get_milestones([]), []) |
753 | + |
754 | + def test_milestone_all(self): |
755 | + self.assertIsInstance(self.instance.get_milestones(), list) |
756 | + |
757 | + def test_milestone_type(self): |
758 | + milestone = self.instance.get_milestones(2)[10] |
759 | + self.assertIsInstance(milestone, qatracker.QATrackerMilestone) |
760 | + self.assertIsInstance(milestone.notify, bool) |
761 | + self.assertIsInstance(milestone.status, int) |
762 | + self.assertIsInstance(milestone.title, str) |
763 | + self.assertIsInstance(milestone.get_bugs(), list) |
764 | + |
765 | + def test_milestone_repr(self): |
766 | + milestone = self.instance.get_milestones(2)[0] |
767 | + self.assertTrue(str(milestone).startswith('QATrackerMilestone: ')) |
768 | + |
769 | + def test_milestone_invalid_id(self): |
770 | + self.assertRaises(IndexError, self.instance.get_milestones, (-1)) |
771 | + |
772 | + def test_milestone_invalid_string(self): |
773 | + self.assertRaises(IndexError, self.instance.get_milestones, ('bla')) |
774 | + |
775 | + def test_milestone_invalid_type(self): |
776 | + self.assertRaises(TypeError, self.instance.get_milestones, (object())) |
777 | |
778 | === added file 'python-library/tests/test_product.py' |
779 | --- python-library/tests/test_product.py 1970-01-01 00:00:00 +0000 |
780 | +++ python-library/tests/test_product.py 2016-03-01 21:32:25 +0000 |
781 | @@ -0,0 +1,51 @@ |
782 | +import unittest |
783 | +import qatracker |
784 | + |
785 | +URL = 'http://iso.qa.dev.stgraber.org/xmlrpc.php' |
786 | + |
787 | + |
788 | +class ProductTests(unittest.TestCase): |
789 | + def setUp(self): |
790 | + self.instance = qatracker.QATracker(URL) |
791 | + |
792 | + def test_product_lower(self): |
793 | + self.assertIsInstance(self.instance.get_products('active'), list) |
794 | + |
795 | + def test_product_mixed(self): |
796 | + self.assertIsInstance(self.instance.get_products('DisAblEd'), list) |
797 | + |
798 | + def test_product_upper(self): |
799 | + self.assertIsInstance(self.instance.get_products('ACTIVE'), list) |
800 | + |
801 | + def test_product_id(self): |
802 | + self.assertIsInstance(self.instance.get_products(1), list) |
803 | + |
804 | + def test_product_list(self): |
805 | + self.assertIsInstance(self.instance.get_products(['ActivE', 1, |
806 | + 'DISABLED', |
807 | + 'disabled']), list) |
808 | + |
809 | + def test_product_empty_list(self): |
810 | + self.assertEquals(self.instance.get_products([]), []) |
811 | + |
812 | + def test_product_all(self): |
813 | + self.assertIsInstance(self.instance.get_products(), list) |
814 | + |
815 | + def test_product_type(self): |
816 | + product = self.instance.get_products(0)[0] |
817 | + self.assertIsInstance(product, qatracker.QATrackerProduct) |
818 | + self.assertIsInstance(product.status, int) |
819 | + self.assertIsInstance(product.title, str) |
820 | + |
821 | + def test_product_repr(self): |
822 | + product = self.instance.get_products(0)[0] |
823 | + self.assertTrue(str(product).startswith('QATrackerProduct: ')) |
824 | + |
825 | + def test_product_invalid_id(self): |
826 | + self.assertRaises(IndexError, self.instance.get_products, (-1)) |
827 | + |
828 | + def test_product_invalid_string(self): |
829 | + self.assertRaises(IndexError, self.instance.get_products, ('bla')) |
830 | + |
831 | + def test_product_invalid_type(self): |
832 | + self.assertRaises(TypeError, self.instance.get_products, (object())) |
833 | |
834 | === added file 'python-library/tests/test_rebuilds.py' |
835 | --- python-library/tests/test_rebuilds.py 1970-01-01 00:00:00 +0000 |
836 | +++ python-library/tests/test_rebuilds.py 2016-03-01 21:32:25 +0000 |
837 | @@ -0,0 +1,69 @@ |
838 | +import unittest |
839 | +import qatracker |
840 | +from datetime import datetime |
841 | + |
842 | +URL = 'http://iso.qa.dev.stgraber.org/xmlrpc.php' |
843 | + |
844 | + |
845 | +class ProductTests(unittest.TestCase): |
846 | + def setUp(self): |
847 | + self.instance = qatracker.QATracker(URL, 'admin', 'admin') |
848 | + |
849 | + def test_rebuilds_lower(self): |
850 | + self.assertIsInstance(self.instance.get_rebuilds('requested'), list) |
851 | + |
852 | + def test_rebuilds_mixed(self): |
853 | + self.assertIsInstance(self.instance.get_rebuilds('BuIlDing'), list) |
854 | + |
855 | + def test_rebuilds_upper(self): |
856 | + self.assertIsInstance(self.instance.get_rebuilds('PUBLISHED'), list) |
857 | + |
858 | + def test_rebuilds_id(self): |
859 | + self.assertIsInstance(self.instance.get_rebuilds(3), list) |
860 | + |
861 | + def test_rebuilds_list(self): |
862 | + self.assertIsInstance(self.instance.get_rebuilds(['reQuested', 1, |
863 | + 'PUBLISHED', |
864 | + 'canceled']), list) |
865 | + |
866 | + def test_rebuilds_empty_list(self): |
867 | + self.assertEquals(self.instance.get_rebuilds([]), []) |
868 | + |
869 | + def test_rebuilds_all(self): |
870 | + self.assertIsInstance(self.instance.get_rebuilds(), list) |
871 | + |
872 | + def test_rebuilds_type(self): |
873 | + rebuild = self.instance.get_rebuilds()[0] |
874 | + self.assertIsInstance(rebuild, qatracker.QATrackerRebuild) |
875 | + self.assertIsInstance(rebuild.id, int) |
876 | + self.assertIsInstance(rebuild.product_title, str) |
877 | + self.assertIsInstance(rebuild.requestedat, datetime) |
878 | + |
879 | + def test_rebuilds_repr(self): |
880 | + rebuild = self.instance.get_rebuilds()[0] |
881 | + self.assertTrue(str(rebuild).startswith('QATrackerRebuild: ')) |
882 | + |
883 | + def test_rebuilds_invalid_id(self): |
884 | + self.assertRaises(IndexError, self.instance.get_rebuilds, -1) |
885 | + |
886 | + def test_rebuilds_invalid_string(self): |
887 | + self.assertRaises(IndexError, self.instance.get_rebuilds, 'bla') |
888 | + |
889 | + def test_rebuilds_invalid_type(self): |
890 | + self.assertRaises(TypeError, self.instance.get_rebuilds, object()) |
891 | + |
892 | + def test_rebuilds_invalid_save_no_access(self): |
893 | + instance = qatracker.QATracker(URL) |
894 | + rebuild = instance.get_rebuilds()[0] |
895 | + rebuild.status = 2 |
896 | + self.assertRaises(Exception, rebuild.save) |
897 | + |
898 | + def test_rebuilds_valid_save(self): |
899 | + rebuild = self.instance.get_rebuilds()[0] |
900 | + rebuild.status = 2 |
901 | + self.assertTrue(rebuild.save()) |
902 | + |
903 | + def test_rebuilds_invalid_status_save(self): |
904 | + rebuild = self.instance.get_rebuilds()[0] |
905 | + rebuild.status = 99 |
906 | + self.assertRaises(Exception, rebuild.save) |
907 | |
908 | === added file 'python-library/tests/test_result.py' |
909 | --- python-library/tests/test_result.py 1970-01-01 00:00:00 +0000 |
910 | +++ python-library/tests/test_result.py 2016-03-01 21:32:25 +0000 |
911 | @@ -0,0 +1,173 @@ |
912 | +import unittest |
913 | +import qatracker |
914 | +import datetime |
915 | + |
916 | +URL = 'http://iso.qa.dev.stgraber.org/xmlrpc.php' |
917 | + |
918 | + |
919 | +class ResultTests(unittest.TestCase): |
920 | + def setUp(self): |
921 | + self.instance = qatracker.QATracker(URL, 'user', 'user') |
922 | + self.milestone = self.instance.get_milestones('testing')[0] |
923 | + self.builds = self.milestone.get_builds('active') |
924 | + |
925 | + def test_result_by_object(self): |
926 | + results = [] |
927 | + for product in self.instance.get_products('active'): |
928 | + builds = [build for build in self.builds |
929 | + if build.productid == product.id] |
930 | + if len(builds) == 0: |
931 | + continue |
932 | + |
933 | + for testcase in product.get_testcases(self.milestone, 'mandatory'): |
934 | + build = builds[0] |
935 | + results += build.get_results(testcase) |
936 | + if len(results) > 0: |
937 | + break |
938 | + else: |
939 | + continue |
940 | + break |
941 | + |
942 | + result = results[0] |
943 | + self.assertIsInstance(result, qatracker.QATrackerResult) |
944 | + self.assertIsInstance(result.id, int) |
945 | + self.assertIsInstance(result.date, datetime.datetime) |
946 | + self.assertIsInstance(result.comment, str) |
947 | + self.assertTrue(str(result).startswith('QATrackerResult: ')) |
948 | + |
949 | + def test_result_by_id(self): |
950 | + results = [] |
951 | + for product in self.instance.get_products('active'): |
952 | + builds = [build for build in self.builds |
953 | + if build.productid == product.id] |
954 | + if len(builds) == 0: |
955 | + continue |
956 | + |
957 | + for testcase in product.get_testcases(self.milestone, 'mandatory'): |
958 | + build = builds[0] |
959 | + results += build.get_results(testcase.id) |
960 | + if len(results) > 0: |
961 | + break |
962 | + else: |
963 | + continue |
964 | + break |
965 | + |
966 | + result = results[0] |
967 | + self.assertIsInstance(result, qatracker.QATrackerResult) |
968 | + self.assertIsInstance(result.id, int) |
969 | + self.assertIsInstance(result.date, datetime.datetime) |
970 | + self.assertIsInstance(result.comment, str) |
971 | + self.assertTrue(str(result).startswith('QATrackerResult: ')) |
972 | + |
973 | + def test_result_add_by_object(self): |
974 | + testcase = None |
975 | + build = None |
976 | + |
977 | + for product in self.instance.get_products('active'): |
978 | + builds = [build for build in self.builds |
979 | + if build.productid == product.id] |
980 | + if len(builds) == 0: |
981 | + continue |
982 | + |
983 | + build = builds[0] |
984 | + testcase = product.get_testcases(self.milestone, 'mandatory')[0] |
985 | + break |
986 | + |
987 | + result = build.add_result(testcase, 'failed') |
988 | + self.assertIsInstance(result, qatracker.QATrackerResult) |
989 | + self.assertIsInstance(result.id, int) |
990 | + self.assertIsInstance(result.date, datetime.datetime) |
991 | + self.assertIsInstance(result.comment, str) |
992 | + self.assertEquals(result.result, 0) |
993 | + self.assertTrue(str(result).startswith('QATrackerResult: ')) |
994 | + |
995 | + result.comment = "edited" |
996 | + result.save() |
997 | + result.delete() |
998 | + |
999 | + self.assertRaises(Exception, result.save) |
1000 | + |
1001 | + def test_result_add_by_id(self): |
1002 | + testcase = None |
1003 | + build = None |
1004 | + |
1005 | + for product in self.instance.get_products('active'): |
1006 | + builds = [build for build in self.builds |
1007 | + if build.productid == product.id] |
1008 | + if len(builds) == 0: |
1009 | + continue |
1010 | + |
1011 | + build = builds[0] |
1012 | + testcase = product.get_testcases(self.milestone, 'mandatory')[0] |
1013 | + break |
1014 | + |
1015 | + result = build.add_result(testcase.id, 2) |
1016 | + self.assertIsInstance(result, qatracker.QATrackerResult) |
1017 | + self.assertIsInstance(result.id, int) |
1018 | + self.assertIsInstance(result.date, datetime.datetime) |
1019 | + self.assertIsInstance(result.comment, str) |
1020 | + self.assertEquals(result.result, 2) |
1021 | + self.assertTrue(str(result).startswith('QATrackerResult: ')) |
1022 | + |
1023 | + result.delete() |
1024 | + |
1025 | + self.assertRaises(Exception, result.delete) |
1026 | + |
1027 | + def test_result_invalid_remove(self): |
1028 | + result = qatracker.QATrackerResult(self.instance, {'id': '0'}) |
1029 | + self.assertRaises(Exception, result.delete) |
1030 | + |
1031 | + def test_result_invalid_remove_no_access(self): |
1032 | + instance = qatracker.QATracker(URL) |
1033 | + result = qatracker.QATrackerResult(instance, {'id': '0'}) |
1034 | + self.assertRaises(Exception, result.delete) |
1035 | + |
1036 | + def test_result_invalid_save(self): |
1037 | + result = qatracker.QATrackerResult(self.instance, {'id': '0', |
1038 | + 'comment': '', |
1039 | + 'result': '0', |
1040 | + 'hardware': '', |
1041 | + 'bugs': {}}) |
1042 | + self.assertRaises(Exception, result.save) |
1043 | + |
1044 | + def test_result_invalid_save_no_access(self): |
1045 | + instance = qatracker.QATracker(URL) |
1046 | + result = qatracker.QATrackerResult(instance, {'id': '0'}) |
1047 | + self.assertRaises(Exception, result.save) |
1048 | + |
1049 | + def test_result_invalid_add_invalid_testcase(self): |
1050 | + self.assertRaises(IndexError, self.builds[0].add_result, |
1051 | + testcase=object(), result='in progress') |
1052 | + |
1053 | + def test_result_invalid_add_invalid_result(self): |
1054 | + self.assertRaises(TypeError, self.builds[0].add_result, |
1055 | + testcase=1, result=['in progress']) |
1056 | + |
1057 | + def test_result_invalid_add_invalid_bugs(self): |
1058 | + self.assertRaises(TypeError, self.builds[0].add_result, |
1059 | + testcase=1, result='in progress', bugs="bla") |
1060 | + |
1061 | + def test_result_invalid_add_invalid_bugnumber(self): |
1062 | + self.assertRaises(ValueError, self.builds[0].add_result, |
1063 | + testcase=1, result='in progress', bugs={-1: 0}) |
1064 | + |
1065 | + def test_result_invalid_add_invalid_bugimportance(self): |
1066 | + self.assertRaises(ValueError, self.builds[0].add_result, |
1067 | + testcase=1, result='in progress', bugs={123: 'a'}) |
1068 | + |
1069 | + def test_result_invalid_add_invalid_response(self): |
1070 | + self.assertRaises(Exception, self.builds[0].add_result, |
1071 | + testcase=-1, result='in progress') |
1072 | + |
1073 | + def test_result_invalid_add_invalid_no_access(self): |
1074 | + instance = qatracker.QATracker(URL) |
1075 | + milestone = instance.get_milestones('testing')[0] |
1076 | + builds = milestone.get_builds('active') |
1077 | + self.assertRaises(Exception, builds[0].add_result, |
1078 | + testcase=10, result='in progress') |
1079 | + |
1080 | + def test_result_invalid_id(self): |
1081 | + self.assertRaises(IndexError, self.builds[0].get_results, (object())) |
1082 | + |
1083 | + def test_result_invalid_no_status(self): |
1084 | + self.assertEquals(self.builds[0].get_results(1234, []), []) |
1085 | |
1086 | === added file 'python-library/tests/test_rpc.py' |
1087 | --- python-library/tests/test_rpc.py 1970-01-01 00:00:00 +0000 |
1088 | +++ python-library/tests/test_rpc.py 2016-03-01 21:32:25 +0000 |
1089 | @@ -0,0 +1,27 @@ |
1090 | +import unittest |
1091 | +import qatracker |
1092 | + |
1093 | +URL = 'http://iso.qa.dev.stgraber.org/xmlrpc.php' |
1094 | + |
1095 | +try: |
1096 | + import xmlrpc.client as xmlrpclib |
1097 | +except ImportError: |
1098 | + import xmlrpclib |
1099 | + |
1100 | + |
1101 | +class RPCTests(unittest.TestCase): |
1102 | + def test_rpc_anonymous(self): |
1103 | + tracker = qatracker.QATracker(URL) |
1104 | + self.assertEquals(tracker.access, 'public') |
1105 | + |
1106 | + def test_rpc_authenticated_user(self): |
1107 | + tracker = qatracker.QATracker(URL, 'user', 'user') |
1108 | + self.assertEquals(tracker.access, 'user') |
1109 | + |
1110 | + def test_rpc_authenticated_admin(self): |
1111 | + tracker = qatracker.QATracker(URL, 'admin', 'admin') |
1112 | + self.assertEquals(tracker.access, 'admin') |
1113 | + |
1114 | + def test_rpc_invalid_target(self): |
1115 | + self.assertRaises(xmlrpclib.ProtocolError, qatracker.QATracker, |
1116 | + ("%s.invalid" % URL)) |
1117 | |
1118 | === added file 'python-library/tests/test_series.py' |
1119 | --- python-library/tests/test_series.py 1970-01-01 00:00:00 +0000 |
1120 | +++ python-library/tests/test_series.py 2016-03-01 21:32:25 +0000 |
1121 | @@ -0,0 +1,77 @@ |
1122 | +import unittest |
1123 | +import qatracker |
1124 | + |
1125 | +URL = 'http://iso.qa.dev.stgraber.org/xmlrpc.php' |
1126 | + |
1127 | + |
1128 | +class ProductTests(unittest.TestCase): |
1129 | + def setUp(self): |
1130 | + self.instance = qatracker.QATracker(URL) |
1131 | + |
1132 | + def test_series_lower(self): |
1133 | + self.assertIsInstance(self.instance.get_series('active'), list) |
1134 | + |
1135 | + def test_series_mixed(self): |
1136 | + self.assertIsInstance(self.instance.get_series('DisAblEd'), list) |
1137 | + |
1138 | + def test_series_upper(self): |
1139 | + self.assertIsInstance(self.instance.get_series('ACTIVE'), list) |
1140 | + |
1141 | + def test_series_id(self): |
1142 | + self.assertIsInstance(self.instance.get_series(1), list) |
1143 | + |
1144 | + def test_series_list(self): |
1145 | + self.assertIsInstance(self.instance.get_series(['AcTiVe', 1, |
1146 | + 'DISABLED', |
1147 | + 'active']), list) |
1148 | + |
1149 | + def test_series_empty_list(self): |
1150 | + self.assertEquals(self.instance.get_series([]), []) |
1151 | + |
1152 | + def test_series_all(self): |
1153 | + self.assertIsInstance(self.instance.get_series(), list) |
1154 | + |
1155 | + def test_series_type(self): |
1156 | + series = self.instance.get_series()[0] |
1157 | + self.assertIsInstance(series, qatracker.QATrackerSeries) |
1158 | + self.assertIsInstance(series.id, int) |
1159 | + self.assertIsInstance(series.title, str) |
1160 | + |
1161 | + def test_series_repr(self): |
1162 | + series = self.instance.get_series()[0] |
1163 | + self.assertTrue(str(series).startswith('QATrackerSeries: ')) |
1164 | + |
1165 | + def test_series_invalid_id(self): |
1166 | + self.assertRaises(IndexError, self.instance.get_series, -1) |
1167 | + |
1168 | + def test_series_invalid_string(self): |
1169 | + self.assertRaises(IndexError, self.instance.get_series, 'bla') |
1170 | + |
1171 | + def test_series_invalid_type(self): |
1172 | + self.assertRaises(TypeError, self.instance.get_series, object()) |
1173 | + |
1174 | + def test_series_manifest_all(self): |
1175 | + self.assertIsInstance(self.instance.get_series()[0].get_manifest(), |
1176 | + list) |
1177 | + |
1178 | + def test_series_manifest_none(self): |
1179 | + self.assertIsInstance(self.instance.get_series()[0].get_manifest([]), |
1180 | + list) |
1181 | + |
1182 | + def test_series_manifest_type(self): |
1183 | + for series in self.instance.get_series(): |
1184 | + manifest = series.get_manifest() |
1185 | + if manifest: |
1186 | + self.assertIsInstance(manifest[0], |
1187 | + qatracker.QATrackerSeriesManifest) |
1188 | + self.assertIsInstance(manifest[0].productid, int) |
1189 | + self.assertIsInstance(manifest[0].product_title, str) |
1190 | + break |
1191 | + |
1192 | + def test_series_manifest_repr(self): |
1193 | + for series in self.instance.get_series(): |
1194 | + manifest = series.get_manifest() |
1195 | + if manifest: |
1196 | + self.assertTrue(str(manifest[0]).startswith( |
1197 | + 'QATrackerSeriesManifest: ')) |
1198 | + break |
1199 | |
1200 | === added file 'python-library/tests/test_testcase.py' |
1201 | --- python-library/tests/test_testcase.py 1970-01-01 00:00:00 +0000 |
1202 | +++ python-library/tests/test_testcase.py 2016-03-01 21:32:25 +0000 |
1203 | @@ -0,0 +1,68 @@ |
1204 | +import unittest |
1205 | +import qatracker |
1206 | + |
1207 | +URL = 'http://iso.qa.dev.stgraber.org/xmlrpc.php' |
1208 | + |
1209 | + |
1210 | +class TestcaseTests(unittest.TestCase): |
1211 | + def setUp(self): |
1212 | + self.instance = qatracker.QATracker(URL) |
1213 | + self.product = self.instance.get_products(0)[0] |
1214 | + self.milestone = self.instance.get_milestones()[0] |
1215 | + |
1216 | + def test_testcase_lower(self): |
1217 | + self.assertIsInstance(self.product.get_testcases(self.milestone, |
1218 | + 'mandatory'), list) |
1219 | + |
1220 | + def test_testcase_mixed(self): |
1221 | + self.assertIsInstance(self.product.get_testcases(self.milestone, |
1222 | + 'DisAblEd'), list) |
1223 | + |
1224 | + def test_testcase_upper(self): |
1225 | + self.assertIsInstance(self.product.get_testcases(self.milestone, |
1226 | + 'RUN-ONCE'), list) |
1227 | + |
1228 | + def test_testcase_id(self): |
1229 | + self.assertIsInstance(self.product.get_testcases(self.milestone, |
1230 | + 3), list) |
1231 | + |
1232 | + def test_testcase_seriesid(self): |
1233 | + self.assertIsInstance(self.product.get_testcases(self.milestone.series, |
1234 | + 3), list) |
1235 | + |
1236 | + def test_testcase_list(self): |
1237 | + self.assertIsInstance(self.product.get_testcases(self.milestone, |
1238 | + ['Run-once', 0, |
1239 | + 'DISABLED', |
1240 | + 'optional']), list) |
1241 | + |
1242 | + def test_testcase_empty_list(self): |
1243 | + self.assertEquals(self.product.get_testcases(self.milestone, []), []) |
1244 | + |
1245 | + def test_testcase_all(self): |
1246 | + self.assertIsInstance(self.product.get_testcases(self.milestone), list) |
1247 | + |
1248 | + def test_testcase_type(self): |
1249 | + testcase = self.product.get_testcases(self.milestone, 0)[0] |
1250 | + self.assertIsInstance(testcase, qatracker.QATrackerTestcase) |
1251 | + self.assertIsInstance(testcase.status, int) |
1252 | + self.assertIsInstance(testcase.title, str) |
1253 | + |
1254 | + def test_testcase_repr(self): |
1255 | + testcase = self.product.get_testcases(self.milestone, 0)[0] |
1256 | + self.assertTrue(str(testcase).startswith('QATrackerTestcase: ')) |
1257 | + |
1258 | + def test_testcase_invalid_id(self): |
1259 | + self.assertRaises(IndexError, self.product.get_testcases, |
1260 | + self.milestone, -1) |
1261 | + |
1262 | + def test_testcase_invalid_string(self): |
1263 | + self.assertRaises(IndexError, self.product.get_testcases, |
1264 | + self.milestone, 'bla') |
1265 | + |
1266 | + def test_testcase_invalid_type(self): |
1267 | + self.assertRaises(TypeError, self.product.get_testcases, |
1268 | + self.milestone, object()) |
1269 | + |
1270 | + def test_testcase_invalid_seriesid(self): |
1271 | + self.assertRaises(TypeError, self.product.get_testcases, object(), 3) |