rhevm-qe-automation / pytest_jira Goto Github PK
View Code? Open in Web Editor NEWpy.test plugin to integrate with JIRA
License: GNU General Public License v2.0
py.test plugin to integrate with JIRA
License: GNU General Public License v2.0
Often times I'd like to run the blocked test to verify that the issue was indeed resolved, without creating a temporary branch in which I for example add a skipif=False to the jira marker
for exaple:
--jira --force-run ORG-1234
and it fails tests
How about add support for custom issue resolved status ?
/jira.cfg
[DEFAULT]
url = https://jira.atlassian.com
username = USERNAME (or blank for no authentication
password = PASSWORD (or blank for no authentication)
# ssl_verification = True/False
# version = foo-1.0
# components = com1,second component,com3
# strategy = [open|strict|warn|ignore] (dealing with not found issues)
# docs_search = False (disable searching for issue id in docs)
# issue_regex = REGEX (replace default `[A-Z]+-[0-9]+` regular expression)
# resolve_status = ready-for-test, ...
Kindly use the install_requires instead of setup_requires so the dependencies are handled by pip instead of easy install. This causes a lot of problem if you are behind company proxies and creates more maintenance with more configuration files.
is this something you could look into or do I need to fork this?
I am trying to edit issue using issue.update(fields={'customfiled_10000':'edited'})
it returns response text = {"errorMessages":["Internal server error"],"errors":{}}
I can create issue and edit comments fine. Just not able to edit customfield.
Could someone help?
it might be not clear to new people that strategy option is meant to set behavior for issues which were not found.
I would also split 'mark' decorator, and 'docstring' section.
In addition I would put jira.cfg into ini section like
.. code: ini
HI,
I'm looking for a nice way to generate a report for all the tests with Jira tickets associated with them
i.e.:
test_one JIRA-234 open
test_two JIRA-342 assigned
test_three JIRA-1 closed
On this page: https://developer.atlassian.com/cloud/jira/platform/basic-auth-for-rest-apis/
it says that we should change the Authorization key in the header of API request to "Basic " instead of "Bearer as it is now.
The proposed solution is just to rename Bearer to Basic in the file pytest_jira at line 192
Python index is able to render reStructuredText automatically, so we will get nice page on python index site.
github is able to render both so there is no problem with it.
Setup:
We have a wrapper (wrapper_jira_issue
) for pytest_jira that logs the result in case of an HTTP error and retries the call.
Scenario:
When test runs, the flow checks for several jira tickets one by one.
For unknown reason, JsonDecoder exception occurred.
Expected result:
get_issue response should handle with json response
request = <SubRequest 'file_api_provider' for <Function test_file_creation_and_properties[docx-vendor:box_box_casb_license]>>
init_api_container = <function init_api_container.<locals>._init_api_container at 0x7f0d1f49e0d0>
@pytest.fixture
def file_api_provider(request, init_api_container):
> return init_api_container(request.param)
internal/fixtures/container.py:247:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
internal/fixtures/container.py:51: in _init_api_container
attach_container(container)
internal/fixtures/container.py:31: in _
test_skipper()
internal/fixtures/test_related.py:123: in _
if issue.match(**conditions, jira_issue=jira_issue, get_closest_marker=get_closest_marker):
models/skip_issue.py:55: in match
conditions.append(jira_issue(self.conditions.jira_issue))
utils/retrier.py:24: in retry_decorator
rv = retry_call(f, fargs, fkwargs, exceptions, tries, delay, max_delay, backoff, jitter, log)
.eggs/retry-0.9.2-py3.6.egg/retry/api.py:101: in retry_call
return __retry_internal(partial(f, *args, **kwargs), exceptions, tries, delay, max_delay, backoff, jitter, logger)
.eggs/retry-0.9.2-py3.6.egg/retry/api.py:33: in __retry_internal
return f()
internal/fixtures/test_related.py:137: in _
return jira_issue(ticket)
.eggs/pytest_jira-0.3.10-py3.6.egg/pytest_jira.py:514: in wrapper_jira_issue
return not jira_plugin.is_issue_resolved(issue_id)
.eggs/pytest_jira-0.3.10-py3.6.egg/pytest_jira.py:66: in is_issue_resolved
self.issue_cache[issue_id] = self.conn.get_issue(issue_id)
.eggs/pytest_jira-0.3.10-py3.6.egg/pytest_jira.py:223: in get_issue
issue = self._jira_request(issue_url).json()
.eggs/requests-2.20.1-py3.6.egg/requests/models.py:897: in json
return complexjson.loads(self.text, **kwargs)
/usr/lib/python3.6/json/__init__.py:354: in loads
return _default_decoder.decode(s)
/usr/lib/python3.6/json/decoder.py:339: in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <json.decoder.JSONDecoder object at 0x7f0d3013bcf8>
s = '{"expand":"renderedFields,names,schema,operations,editmeta,changelog,versionedRepresentations","id":"66816","self":"h...Type":"atlassian"},"created":"2019-07-22T01:28:26.738-0700","updated":"2019-07-22T01:28:26.738-0700","jsdPublic":true}'
idx = 0
def raw_decode(self, s, idx=0):
"""Decode a JSON document from ``s`` (a ``str`` beginning with
a JSON document) and return a 2-tuple of the Python
representation and the index in ``s`` where the document ended.
This can be used to decode a JSON document from a string that may
have extraneous data at the end.
"""
try:
> obj, end = self.scan_once(s, idx)
E json.decoder.JSONDecodeError: Expecting ',' delimiter: line 1 column 15727 (char 15726)
/usr/lib/python3.6/json/decoder.py:355: JSONDecodeError
When I'm starting tests from outside the internal company network, then Jira redirects to the Okta authentication service, and JSONDecodeError is raised, because in the response data there is no valid JSON from Jira, but HTML from the authentication service.
The check_connection
function fails:
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
at the 223 line:
elif not r.json()['permissions']['BROWSE_PROJECTS']['havePermission']
r.text
variable (from pytest_jira.py, line 216) looks like this:
'<html>\n
<head>\n
</head>\n
<body onload="document.forms[0].submit()">\n
<noscript><p>\n
<strong>Note:</strong> Your browser does not support JavaScript,\n
Press Continue to proceed... </p>\n
</noscript>\n
<form method="POST" action="https://dolby.okta.com/app/###edited###/sso/saml">\n
<div>\n
<input type="hidden" name="SAMLRequest" value="PHNhbW###edited###0Pg=="/> </div>\n
<noscript><div>\n
<input type="submit" value="Continue"/>\n
</div>\n
</noscript>\n</form>\n
</body>\n
</html>'
so it's a not a JSON response, as expected.
It would be great to add additional check, if the response content is valid, and if not, then behave same way as there is no access to the Jira server.
Stacktrace:
INTERNALERROR> File "/venv/lib/python3.8/site-packages/_pytest/main.py", line 240, in wrap_session
INTERNALERROR> session.exitstatus = doit(config, session) or 0
INTERNALERROR> File "/venv/lib/python3.8/site-packages/_pytest/main.py", line 295, in _main
INTERNALERROR> config.hook.pytest_collection(session=session)
INTERNALERROR> File "/venv/lib/python3.8/site-packages/pluggy/hooks.py", line 286, in __call__
INTERNALERROR> return self._hookexec(self, self.get_hookimpls(), kwargs)
INTERNALERROR> File "/venv/lib/python3.8/site-packages/pluggy/manager.py", line 93, in _hookexec
INTERNALERROR> return self._inner_hookexec(hook, methods, kwargs)
INTERNALERROR> File "/venv/lib/python3.8/site-packages/pluggy/manager.py", line 84, in <lambda>
INTERNALERROR> self._inner_hookexec = lambda hook, methods, kwargs: hook.multicall(
INTERNALERROR> File "/venv/lib/python3.8/site-packages/pluggy/callers.py", line 208, in _multicall
INTERNALERROR> return outcome.get_result()
INTERNALERROR> File "/venv/lib/python3.8/site-packages/pluggy/callers.py", line 80, in get_result
INTERNALERROR> raise ex[1].with_traceback(ex[2])
INTERNALERROR> File "/venv/lib/python3.8/site-packages/pluggy/callers.py", line 187, in _multicall
INTERNALERROR> res = hook_impl.function(*args)
INTERNALERROR> File "/venv/lib/python3.8/site-packages/_pytest/main.py", line 306, in pytest_collection
INTERNALERROR> session.perform_collect()
INTERNALERROR> File "/venv/lib/python3.8/site-packages/_pytest/main.py", line 518, in perform_collect
INTERNALERROR> hook.pytest_collection_modifyitems(
INTERNALERROR> File "/venv/lib/python3.8/site-packages/pluggy/hooks.py", line 286, in __call__
INTERNALERROR> return self._hookexec(self, self.get_hookimpls(), kwargs)
INTERNALERROR> File "/venv/lib/python3.8/site-packages/pluggy/manager.py", line 93, in _hookexec
INTERNALERROR> return self._inner_hookexec(hook, methods, kwargs)
INTERNALERROR> File "/venv/lib/python3.8/site-packages/pluggy/manager.py", line 84, in <lambda>
INTERNALERROR> self._inner_hookexec = lambda hook, methods, kwargs: hook.multicall(
INTERNALERROR> File "/venv/lib/python3.8/site-packages/pluggy/callers.py", line 208, in _multicall
INTERNALERROR> return outcome.get_result()
INTERNALERROR> File "/venv/lib/python3.8/site-packages/pluggy/callers.py", line 80, in get_result
INTERNALERROR> raise ex[1].with_traceback(ex[2])
INTERNALERROR> File "/venv/lib/python3.8/site-packages/pluggy/callers.py", line 187, in _multicall
INTERNALERROR> res = hook_impl.function(*args)
INTERNALERROR> File "/venv/lib/python3.8/site-packages/pytest_jira.py", line 114, in pytest_collection_modifyitems
INTERNALERROR> if not self.is_issue_resolved(issue_id):
INTERNALERROR> File "/venv/lib/python3.8/site-packages/pytest_jira.py", line 72, in is_issue_resolved
INTERNALERROR> self.issue_cache[issue_id] = self.conn.get_issue(
INTERNALERROR> File "<decorator-gen-2>", line 2, in get_issue
INTERNALERROR> File "/venv/lib/python3.8/site-packages/retry/api.py", line 73, in retry_decorator
INTERNALERROR> return __retry_internal(partial(f, *args, **kwargs), exceptions, tries, delay, max_delay, backoff, jitter,
INTERNALERROR> File "/venv/lib/python3.8/site-packages/retry/api.py", line 33, in __retry_internal
INTERNALERROR> return f()
INTERNALERROR> File "/venv/lib/python3.8/site-packages/pytest_jira.py", line 233, in get_issue
INTERNALERROR> self.check_connection()
INTERNALERROR> File "/venv/lib/python3.8/site-packages/pytest_jira.py", line 223, in check_connection
INTERNALERROR> elif not r.json()['permissions']['BROWSE_PROJECTS']['havePermission']:
INTERNALERROR> File "/venv/lib/python3.8/site-packages/requests/models.py", line 900, in json
INTERNALERROR> return complexjson.loads(self.text, **kwargs)
INTERNALERROR> File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/json/__init__.py", line 357, in loads
INTERNALERROR> return _default_decoder.decode(s)
INTERNALERROR> File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/json/decoder.py", line 337, in decode
INTERNALERROR> obj, end = self.raw_decode(s, idx=_w(s, 0).end())
INTERNALERROR> File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/json/decoder.py", line 355, in raw_decode
INTERNALERROR> raise JSONDecodeError("Expecting value", s, err.value) from None
INTERNALERROR> json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
Hi,
Try to use library with personal api in jira.cfg file
add url and api token (by instruction here https://docs.searchunify.com/Content/Content-Sources/Atlassian-Jira-Confluence-Authentication-Create-API-Token.htm)
by get
INTERNALERROR> Traceback (most recent call last):
INTERNALERROR> File "/Users/user/work/venv_3.10/lib/python3.10/site-packages/_pytest/main.py", line 268, in wrap_session
INTERNALERROR> session.exitstatus = doit(config, session) or 0
INTERNALERROR> File "/Users/user/work/venv_3.10/lib/python3.10/site-packages/_pytest/main.py", line 321, in _main
INTERNALERROR> config.hook.pytest_collection(session=session)
INTERNALERROR> File "/Users/user/work/venv_3.10/lib/python3.10/site-packages/pluggy/_hooks.py", line 265, in __call__
INTERNALERROR> return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)
INTERNALERROR> File "/Users/user/work/venv_3.10/lib/python3.10/site-packages/pluggy/_manager.py", line 80, in _hookexec
INTERNALERROR> return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
INTERNALERROR> File "/Users/user/work/venv_3.10/lib/python3.10/site-packages/pluggy/_callers.py", line 60, in _multicall
INTERNALERROR> return outcome.get_result()
INTERNALERROR> File "/Users/user/work/venv_3.10/lib/python3.10/site-packages/pluggy/_result.py", line 60, in get_result
INTERNALERROR> raise ex[1].with_traceback(ex[2])
INTERNALERROR> File "/Users/user/work/venv_3.10/lib/python3.10/site-packages/pluggy/_callers.py", line 39, in _multicall
INTERNALERROR> res = hook_impl.function(*args)
INTERNALERROR> File "/Users/user/work/venv_3.10/lib/python3.10/site-packages/_pytest/main.py", line 332, in pytest_collection
INTERNALERROR> session.perform_collect()
INTERNALERROR> File "/Users/user/work/venv_3.10/lib/python3.10/site-packages/_pytest/main.py", line 660, in perform_collect
INTERNALERROR> hook.pytest_collection_modifyitems(
INTERNALERROR> File "/Users/user/work/venv_3.10/lib/python3.10/site-packages/pluggy/_hooks.py", line 265, in __call__
INTERNALERROR> return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)
INTERNALERROR> File "/Users/user/work/venv_3.10/lib/python3.10/site-packages/pluggy/_manager.py", line 80, in _hookexec
INTERNALERROR> return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
INTERNALERROR> File "/Users/user/work/venv_3.10/lib/python3.10/site-packages/pluggy/_callers.py", line 60, in _multicall
INTERNALERROR> return outcome.get_result()
INTERNALERROR> File "/Users/user/work/venv_3.10/lib/python3.10/site-packages/pluggy/_result.py", line 60, in get_result
INTERNALERROR> raise ex[1].with_traceback(ex[2])
INTERNALERROR> File "/Users/user/work/venv_3.10/lib/python3.10/site-packages/pluggy/_callers.py", line 39, in _multicall
INTERNALERROR> res = hook_impl.function(*args)
INTERNALERROR> File "/Users/user/work/venv_3.10/lib/python3.10/site-packages/pytest_jira.py", line 125, in pytest_collection_modifyitems
INTERNALERROR> if not self.is_issue_resolved(issue_id):
INTERNALERROR> File "/Users/user/work/venv_3.10/lib/python3.10/site-packages/pytest_jira.py", line 78, in is_issue_resolved
INTERNALERROR> self.issue_cache[issue_id] = self.conn.get_issue(
INTERNALERROR> File "/Users/user/work/venv_3.10/lib/python3.10/site-packages/decorator.py", line 232, in fun
INTERNALERROR> return caller(func, *(extras + args), **kw)
INTERNALERROR> File "/Users/user/work/venv_3.10/lib/python3.10/site-packages/retry/api.py", line 73, in retry_decorator
INTERNALERROR> return __retry_internal(partial(f, *args, **kwargs), exceptions, tries, delay, max_delay, backoff, jitter,
INTERNALERROR> File "/Users/user/work/venv_3.10/lib/python3.10/site-packages/retry/api.py", line 33, in __retry_internal
INTERNALERROR> return f()
INTERNALERROR> File "/Users/user/work/venv_3.10/lib/python3.10/site-packages/pytest_jira.py", line 256, in get_issue
INTERNALERROR> self.check_connection()
INTERNALERROR> File "/Users/user/work/venv_3.10/lib/python3.10/site-packages/pytest_jira.py", line 233, in check_connection
INTERNALERROR> r = self._jira_request(
INTERNALERROR> File "/Users/user/work/venv_3.10/lib/python3.10/site-packages/pytest_jira.py", line 227, in _jira_request
INTERNALERROR> rsp.raise_for_status()
INTERNALERROR> File "/Users/user/work/venv_3.10/lib/python3.10/site-packages/requests/models.py", line 1021, in raise_for_status
INTERNALERROR> raise HTTPError(http_error_msg, response=self)
INTERNALERROR> requests.exceptions.HTTPError: 403 Client Error: Forbidden for url: https://eeeeeeee.atlassian.net/rest/api/2/mypermissions?permissions=BROWSE_PROJECTS
if it try in postman get answer
{"error": "Failed to parse Connect Session Auth Token"}
Sounds interesting, but it's not clear from the description what I get out of this?
If I mark my tests with Jira issue ids and then run py.test --jira
, what happens? Does it log a comment to Jira for every test run? Does it close the issue when the test passes?
http://plugincompat.herokuapp.com
https://github.com/pytest-dev/plugincompat
related to #32 as well
Jira has ability enable oauth authentication.
Read here about details what should be done from python code side.
https://jira.readthedocs.io/en/master/examples.html#oauth
I've setup jira.cfg
like the documentation described but I cannot seem to connect:
(stronghold-py) ip-192-168-0-8:stronghold-py orcarmi$ pytest --jira
INTERNALERROR> Traceback (most recent call last):
INTERNALERROR> File "/Users/orcarmi/stronghold-py/lib/python3.6/site-packages/_pytest/main.py", line 94, in wrap_session
INTERNALERROR> config._do_configure()
INTERNALERROR> File "/Users/orcarmi/stronghold-py/lib/python3.6/site-packages/_pytest/config.py", line 902, in _do_configure
INTERNALERROR> self.hook.pytest_configure.call_historic(kwargs=dict(config=self))
INTERNALERROR> File "/Users/orcarmi/stronghold-py/lib/python3.6/site-packages/_pytest/vendored_packages/pluggy.py", line 750, in call_historic
INTERNALERROR> self._hookexec(self, self._nonwrappers + self._wrappers, kwargs)
INTERNALERROR> File "/Users/orcarmi/stronghold-py/lib/python3.6/site-packages/_pytest/vendored_packages/pluggy.py", line 339, in _hookexec
INTERNALERROR> return self._inner_hookexec(hook, methods, kwargs)
INTERNALERROR> File "/Users/orcarmi/stronghold-py/lib/python3.6/site-packages/_pytest/vendored_packages/pluggy.py", line 334, in <lambda>
INTERNALERROR> _MultiCall(methods, kwargs, hook.spec_opts).execute()
INTERNALERROR> File "/Users/orcarmi/stronghold-py/lib/python3.6/site-packages/_pytest/vendored_packages/pluggy.py", line 614, in execute
INTERNALERROR> res = hook_impl.function(*args)
INTERNALERROR> File "/Users/orcarmi/stronghold-py/lib/python3.6/site-packages/pytest_jira.py", line 384, in pytest_configure
INTERNALERROR> config.getvalue('jira_verify'),
INTERNALERROR> File "/Users/orcarmi/stronghold-py/lib/python3.6/site-packages/pytest_jira.py", line 168, in __init__
INTERNALERROR> max_retries=1
INTERNALERROR> File "/Users/orcarmi/stronghold-py/lib/python3.6/site-packages/jira/client.py", line 307, in __init__
INTERNALERROR> user = self.session()
INTERNALERROR> File "/Users/orcarmi/stronghold-py/lib/python3.6/site-packages/jira/client.py", line 2082, in session
INTERNALERROR> r = self._session.post(url, data=json.dumps(authentication_data))
INTERNALERROR> File "/Users/orcarmi/stronghold-py/lib/python3.6/site-packages/jira/resilientsession.py", line 153, in post
INTERNALERROR> return self.__verb('POST', url, **kwargs)
INTERNALERROR> File "/Users/orcarmi/stronghold-py/lib/python3.6/site-packages/jira/resilientsession.py", line 146, in __verb
INTERNALERROR> raise_on_error(response, verb=verb, **kwargs)
INTERNALERROR> File "/Users/orcarmi/stronghold-py/lib/python3.6/site-packages/jira/resilientsession.py", line 56, in raise_on_error
INTERNALERROR> r.status_code, error, r.url, request=request, response=r, **kwargs)
INTERNALERROR> jira.exceptions.JIRAError: JiraError HTTP 500 url: https://REDACTED.jira.com/rest/auth/1/session
INTERNALERROR> text: Internal server error
INTERNALERROR>
INTERNALERROR> response headers = {'Server': 'nginx', 'Date': 'Tue, 09 May 2017 09:55:20 GMT', 'Content-Type': 'application/json;charset=UTF-8', 'Transfer-Encoding': 'chunked', 'Connection': 'keep-alive', 'X-AREQUESTID': '775x2085x1', 'X-AUSERNAME': 'test-agent', 'X-ATENANT-ID': 'REDACTED.jira.com', 'X-Seraph-LoginReason': 'OK', 'Cache-Control': 'no-cache, no-store, no-transform', 'X-Content-Type-Options': 'nosniff', 'Set-Cookie': 'JSESSIONID=6A24CD47D020312444192706B837D326; Path=/; Secure; HttpOnly, atlassian.xsrf.token=AG87-S37R-QM8W-6VWE|77ab169ca0173175b9d8654b07be1c2d5d4af311|lin; Path=/; Secure, studio.crowd.tokenkey=""; Domain=.REDACTED.jira.com; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; Secure; HttpOnly, studio.crowd.tokenkey=xQmVO1gW2eGOmNY3udKlng00; Domain=.REDACTED.jira.com; Path=/; Secure; HttpOnly'}
INTERNALERROR> response text = {"errorMessages":["Internal server error"],"errors":{}}
When trying to connect using basic auth directly via the jira
module it works:
from jira import JIRA
jira = JIRA('https://REDACTED.jira.com', basic_auth=('REDACTED', 'REDACTED'))
Any assistance would be appreciated
It would be great if the reason
args could be filled when tests are skipped/xfailed/xpassing.
Something like "Skipped due to issue XXX-1111 being unresolved"
I'd like to have the option wether to use the plugin or not pass as an envvar in my CI. Currently this is possible either via manipulating the command arts via a bash script or using the PYTEST_ADDOPTS
envvar. Both of these aren't nice.
I propose adding a --jira-enabled=true
option, that will accompany the other existing flags as to not break compatibility.
If you like this I can put out a PR for this change.
WDYT?
Since #72 verify
option does nothing. Need to be handled
I propose that the jira_issue
fixture will return a JiraIssue
model which will hold metadata in its attributes (like description, dates etc.).
This will enable a richer experience for both returning detailed skip messages, more complex conditional statements and more, all using data we already fetch but do nothing with.
The class will have a __bool__
dunder which will make previously the class backwards compatible with previous conditional checks on the fixture reply.
If you approve I'd be happy to put a PR for this.
WDYT?
pytest_jira/pytest_jira.py:279: DeprecationWarning: pytest now uses argparse. "%default" should be changed to "%(default)s"
help='JIRA url (default: %default)')
pytest_jira/pytest_jira.py:285: DeprecationWarning: pytest now uses argparse. "%default" should be changed to "%(default)s"
help='JIRA username (default: %default)')
===============================================
I am attempting to make one of the test iterations marked with the plugin's custom marker but I am not able to achieve it:
This does not work:
if test_id == "both_allow": pytest.mark.jira("PD-2366")
It does work using the default pytest markers, which seem to not require using 'mark' in this case:
if test_id == "both_allow": pytest.xfail(reason="Not testing both allow")
I am wondering if there is a way to achieve this with the jira marker. It does work if I add the marker to the test itself: @pytest.mark.jira("PD-2366") but then all iterations are affected
It might hide problems. see test_jira_marker_bad_args
test it reproduce problem.
On https://pypi.python.org/pypi/pytest-jira/0.01 is an old version of project. It causes error.
...
File "/mnt/tc-agent/a9343a0aef23cede/venv/local/lib/python2.7/site-packages/pytest_jira.py", line 95, in pytest_runtest_makereport
rep.wasxfail = "reason: " + call.excinfo.value.msg
AttributeError: 'error' object has no attribute 'msg'
On github pytest_runtest_makereport function differes with same function in tar.gz on pypi.python.org.
Travis-CI can do it for us, follow https://docs.travis-ci.com/user/deployment/pypi/
I'd like the default behavior to be to set run = False
on found issue, instead of explicitly setting this per issue.
It would be great if this value would be exposed in cfg as well.
I have the following in jira.cfg:
username = automation
password = 3#%SS
which is a valid value for password (jira works with it)
but when I run pytest with the --jira switch, I get the following Syntax Error:
File "/usr/local/lib/python3.7/site-packages/pluggy/manager.py", line 87, in _hookexec
return self._inner_hookexec(hook, methods, kwargs)
File "/usr/local/lib/python3.7/site-packages/pluggy/manager.py", line 81, in
firstresult=hook.spec.opts.get("firstresult") if hook.spec else False,
File "/usr/local/lib/python3.7/site-packages/pluggy/callers.py", line 208, in _multicall
return outcome.get_result()
File "/usr/local/lib/python3.7/site-packages/pluggy/callers.py", line 80, in get_result
raise ex[1].with_traceback(ex[2])
File "/usr/local/lib/python3.7/site-packages/pluggy/callers.py", line 187, in _multicall
res = hook_impl.function(*args)
File "/usr/local/lib/python3.7/site-packages/pytest_jira.py", line 376, in pytest_addoption
default=_get_value(config, 'DEFAULT', 'password'),
File "/usr/local/lib/python3.7/site-packages/pytest_jira.py", line 327, in _get_value
return config.get(section, name)
File "/usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/configparser.py", line 799, in get
d)
File "/usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/configparser.py", line 394, in before_get
self._interpolate_some(parser, option, L, value, section, defaults, 1)
File "/usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/configparser.py", line 444, in _interpolate_some
"found: %r" % (rest,))
configparser.InterpolationSyntaxError: '%' must be followed by '%' or '(', found: '%SS'
File "lib/python3.6/site-packages/importlib_metadata/__init__.py", line 92, in load
module = import_module(match.group('module'))
File "lib64/python3.6/importlib/__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 994, in _gcd_import
File "<frozen importlib._bootstrap>", line 971, in _find_and_load
File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
File "lib/python3.6/site-packages/_pytest/assertion/rewrite.py", line 142, in exec_module
exec(co, module.__dict__)
File "lib/python3.6/site-packages/pytest_jira.py", line 22, in <module>
from issue_model import JiraIssue, JiraIssueSchema
ModuleNotFoundError: No module named 'issue_model'
Hello,
Basic authentication with username or password does not work in Jira anymore:
https://confluence.atlassian.com/cloud/deprecation-of-basic-authentication-with-passwords-for-jira-and-confluence-apis-972355348.html
A 401 HTTP error is returned after pytest-jira tries to get permissions from Jira ('{url}rest/api/2/mypermissions?permissions=BROWSE_PROJECTS'). Is there any workaround? Or basically this plugin is completely unusable now? Thanks!
Currently pytest crashes on jira connection error since it doesn't catch request exceptions. This has an undesirable effect of making builds that run pytest fail which cause false positives.
I propose passing a flag that will enable either gracefully not load the plugin, or alternatively skip the test with a successful exit code.
Thoughts?
Hi,
Recently you have added the support for token based authentication using bearer tokens. However, this support is currently limited to JIRA Cloud deployment.
On Jira Server(Obsolete) and Jira Data Center, a different OAuth is needed. After the AccessToken is created, it can be used together with the consumer-key and the private-key
I've made local adjustments to your code supporting the OAuth 1.0 scheme. Below are the changes to jira.cfg (for reference) supporting the new variables and the changes to the connection class.
I've verified locally on our server
diff --git a/jira.cfg b/jira.cfg
index 98f0b01..88e4fbb 100644
--- a/jira.cfg
+++ b/jira.cfg
@@ -2,3 +2,22 @@
url = https://issues.jboss.org
username =
password =
+consumer_key=OauthKey
+token=PD1i7RMIvlg9IgojD1RVpUUEIe3J6woy
+private_key=
+ -----BEGIN RSA PRIVATE KEY-----
+ MIICXQIBAAKBgQDzsS3jO4729A9oRX/5oMRILJOPBY4FHTzhx8LuDNp7BXxuGZ3y
+ PJA/pSWPfgdh5qr8Yh0wtohUzSLvLyOgk/vldgZoKhZO6bTh1TTFmbEBKWYP8Dxy
+ Z84DFOUy67bEK8dI3ToiBVwf8+Oyo6j8WzYqDZWLzU8oC6BZ3/PnMO1n7wIDAQAB
+ AoGAI0ezbQJiYD5VPLNTI8CyqgBKHJqhRPxGpClXfz89IjJZIVd0Fm3ONGikV3HX
+ f8T1XDSYJUVH138bX6Vjcwv5m6Z3LUFdvdfs5RD6imQUz9Uk4oXe6ENTJONFhoZ1
+ 1E/E2o4Yk7B9ZfJaeu4T+cKUGh/F2qTjmoSTHjb85B2AyIECQQD8sjCpuPEVk9TV
+ 8SiU1pkdRrQHFVU0u3xqDvIKacm9rtjdZheQzhcHE5gKrhsb1Yn2VEyOZrAhWMcr
+ FnbKJqsjAkEA9uDaBeVf1ZDxbO1lzFJQd31DcfbQS82p5NX9NgNMTXhtwt+mDjY5
+ ttanGha6pi40fgA1492xHGvCyNr7ISPSxQJBAO3qt3aU8ifmsBVeoV7BThgKYaXp
+ p/emLlWNDMZRI+i7nuOVI8rqvzOidxxXIJ7sRqDubcYFWP+MnrkqxV0/WxECQQDa
+ /6tn/4l70g/YKN9c2Mg4tw3VUrSECfTj4k+0UkilkGcNr4eGo+Oepdul8POx5tr5
+ ywYDFO2/4Hfx5Q9Q3o5hAkAglpXZHYp8rAqxjmystt+ZPp4VjkkILAseE0PqQr0Q
+ HBqZnP/am4jKQRhUbzJcGbJjti+PoZ6yTjo09JiG4mud
+ -----END RSA PRIVATE KEY-----
+
diff --git a/pytest_jira.py b/pytest_jira.py
index 37929e4..5448c78 100644
--- a/pytest_jira.py
+++ b/pytest_jira.py
@@ -21,6 +21,9 @@ from retry import retry
from issue_model import JiraIssue, JiraIssueSchema
+from requests_oauthlib import OAuth1
+from oauthlib.oauth1 import SIGNATURE_RSA
+
DEFAULT_RESOLVE_STATUSES = 'closed', 'resolved'
DEFAULT_RUN_TEST_CASE = True
CONNECTION_SKIP_MESSAGE = 'Jira connection issue, skipping test: %s'
@@ -179,16 +182,26 @@ class JiraSiteConnection(object):
password=None,
verify=True,
token=None,
+ client_key=None,
+ private_key=None,
):
self.url = url
self.username = username
self.password = password
self.verify = verify
self.token = token
-
+ self.client_key = client_key
+ self.private_key = private_key
self.is_connected = False
-
- if self.token:
+ self.token_auth = None
+
+ if self.private_key:
+ self.token_auth = OAuth1(client_key=self.client_key,
+ resource_owner_key=self.token,
+ signature_method=SIGNATURE_RSA,
+ rsa_key=self.private_key,
+ signature_type='auth_header')
+ elif self.token:
token_bearer = f"Bearer {self.token}"
self.headers = {'Authorization': token_bearer}
@@ -203,7 +216,10 @@ class JiraSiteConnection(object):
if 'verify' not in kwargs:
kwargs['verify'] = self.verify
- if self.token:
+ if self.token_auth:
+ rsp = requests.get(url, auth=self.token_auth, **kwargs)
+
+ elif self.token:
rsp = requests.request(method, url, headers=self.headers, **kwargs)
elif self.basic_auth:
@@ -394,6 +410,18 @@ def pytest_addoption(parser):
default=_get_value(config, 'DEFAULT', 'token'),
metavar='token',
help='JIRA token.')
+ group.addoption('--jira-consumer-key',
+ action='store',
+ dest='jira_consumer_key',
+ default=_get_value(config, 'DEFAULT', 'consumer_key'),
+ metavar='consumer_key',
+ help='JIRA OAuth consumer key.')
+ group.addoption('--jira-private-key',
+ action='store',
+ dest='jira_private_key',
+ default=_get_value(config, 'DEFAULT', 'private_key'),
+ metavar='private_key',
+ help='JIRA private key.')
group.addoption('--jira-no-ssl-verify',
action='store_false',
dest='jira_verify',
@@ -517,6 +545,8 @@ def pytest_configure(config):
os.getenv(PASSWORD_ENV_VAR) or config.getvalue('jira_password'),
config.getvalue('jira_verify'),
config.getvalue('jira_token'),
+ config.getvalue('jira_consumer_key'),
+ config.getvalue('jira_private_key')
)
jira_marker = JiraMarkerReporter(
config.getvalue('jira_marker_strategy'),
C:\Python36_64\lib\site-packages\pytest_jira.py:79
C:\Python36_64\lib\site-packages\pytest_jira.py:79: RemovedInPytest4Warning: MarkInfo objects are deprecated as they contain merged marks which are hard to deal with correctly.
Please use node.get_closest_marker(name) or node.iter_markers(name).
Docs: https://docs.pytest.org/en/latest/mark.html#updating-code
jira_run = item.keywords['jira'].kwargs.get('run', jira_run)
C:\Python36_64\lib\site-packages\pytest_jira.py:233
C:\Python36_64\lib\site-packages\pytest_jira.py:233: RemovedInPytest4Warning: MarkInfo objects are deprecated as they contain merged marks which are hard to deal with correctly.
Please use node.get_closest_marker(name) or node.iter_markers(name).
Docs: https://docs.pytest.org/en/latest/mark.html#updating-code
skip_if = mark.kwargs.get('skipif', True)
C:\Python36_64\lib\site-packages\pytest_jira.py:235
C:\Python36_64\lib\site-packages\pytest_jira.py:235: RemovedInPytest4Warning: MarkInfo objects are deprecated as they contain merged marks which are hard to deal with correctly.
Please use node.get_closest_marker(name) or node.iter_markers(name).
Docs: https://docs.pytest.org/en/latest/mark.html#updating-code
if len(mark.args) == 0:
C:\Python36_64\lib\site-packages\pytest_jira.py:239
C:\Python36_64\lib\site-packages\pytest_jira.py:239: RemovedInPytest4Warning: MarkInfo objects are deprecated as they contain merged marks which are hard to deal with correctly.
Please use node.get_closest_marker(name) or node.iter_markers(name).
Docs: https://docs.pytest.org/en/latest/mark.html#updating-code
for arg in mark.args:
Add more locations:
As AQA engineer I want to check autotest statuses against different projects in Jira with different issue flows. So just one list of resolved statuses doesn't cover my needs. I want to have a possibility to set resolved statuses per project key
There are certain situation that I would rather to just skip via an internal if condition and not necessary skip the entire test. I could use a jira
fixture that would enable me to do that.
@lukas-bednar i'm pretty busy but i'll make an effort to support this myself and push a PR.
Jira has announced changes to /rest/api/2/mypermissions (Get my permissions) endpoint, this causes 400 error on connection
Error:
'{"errorMessages":["The \'permissions\' query parameter is required."],"errors":{}}'
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.