Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support remote allure server within allure logger #741

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 37 additions & 1 deletion allure-pytest/src/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import os

from allure_commons.types import LabelType, Severity
from allure_commons.logger import AllureFileLogger
from allure_commons.logger import AllureFileLogger, AllureHTTPLogger
from allure_commons.utils import get_testplan

from allure_pytest.utils import allure_label, allure_labels, allure_full_name
Expand All @@ -24,6 +24,25 @@ def pytest_addoption(parser):
default=None,
help="Generate Allure report in the specified directory (may not exist)")

parser.getgroup("reporting").addoption('--allureserver',
action="store",
dest="allure_server",
metavar="URL",
default=None,
help="Generate Allure report to a remote allure server")

parser.getgroup("reporting").addoption('--projectid',
action="store",
dest="project_id",
metavar="STR",
default=None,
help="Project id for remote allure server")

parser.getgroup("reporting").addoption('--clean-allurehistory',
action="store_true",
dest="clean_allurehistory",
help="Clean allure history in remote server")

parser.getgroup("reporting").addoption('--clean-alluredir',
action="store_true",
dest="clean_alluredir",
Expand Down Expand Up @@ -152,11 +171,15 @@ def pytest_addhooks(pluginmanager):
def pytest_configure(config):
report_dir = config.option.allure_report_dir
clean = config.option.clean_alluredir
clean_history = config.option.clean_allurehistory
allure_server = config.option.allure_server
project_id = config.option.project_id

test_helper = AllureTestHelper(config)
allure_commons.plugin_manager.register(test_helper)
config.add_cleanup(cleanup_factory(test_helper))

test_listener = None
if report_dir:
report_dir = os.path.abspath(report_dir)
test_listener = AllureListener(config)
Expand All @@ -168,6 +191,19 @@ def pytest_configure(config):
allure_commons.plugin_manager.register(file_logger)
config.add_cleanup(cleanup_factory(file_logger))

if allure_server:
if not test_listener:
test_listener = AllureListener(config)
config.pluginmanager.register(test_listener, 'allure_listener')
allure_commons.plugin_manager.register(test_listener)
config.add_cleanup(cleanup_factory(test_listener))

http_logger = AllureHTTPLogger(allure_server, project_id, clean_history)
allure_commons.plugin_manager.register(http_logger)
config.add_cleanup(cleanup_factory(http_logger))
config.add_cleanup(http_logger.create_report)
config.add_cleanup(http_logger.send_results)

config.addinivalue_line("markers", f"{ALLURE_LABEL_MARK}: allure label marker")
config.addinivalue_line("markers", f"{ALLURE_LINK_MARK}: allure link marker")
config.addinivalue_line("markers", f"{ALLURE_DESCRIPTION_MARK}: allure description")
Expand Down
82 changes: 82 additions & 0 deletions allure-python-commons/src/logger.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import base64
import io
import os
from pathlib import Path
import json
import uuid
import shutil
import requests
from attr import asdict
from allure_commons import hookimpl

Expand Down Expand Up @@ -53,6 +55,86 @@ def report_attached_data(self, body, file_name):
attached_file.write(body)


class AllureHTTPLogger:

def __init__(self, allure_server, project_id, clean=False):
self._allure_server = allure_server
self._project_id = project_id
self._headers = {'Content-type': 'application/json'}
self._ssl_verification = True
self._results = []
if clean:
self.clean_history()

def _report_item(self, item):
filename = item.file_pattern.format(prefix=uuid.uuid4())
data = asdict(
item,
filter=lambda attr, value: not (
type(value) != bool and not bool(value)
)
)
json_data = json.dumps(data, ensure_ascii=False)
b64_content = base64.b64encode(json_data.encode('utf-8'))
self._results.append({'file_name': filename, 'content_base64': b64_content.decode('UTF-8')})

@hookimpl
def send_results(self):
if self._results:
self._send_post_request('send-results', self._results)
self._results = []

@hookimpl
def create_report(self, execution_name=None):
return self._send_get_request('generate-report',
params={'execution_name': execution_name or uuid.uuid4(),
'execution_from': 'Python',
'execution_type': 'github'})

@hookimpl
def report_result(self, result):
self._report_item(result)

@hookimpl
def report_container(self, container):
self._report_item(container)

@hookimpl
def report_attached_file(self, source, file_name):
b64_content = base64.b64encode(source)
self._results.append({'file_name': file_name, 'content_base64': b64_content.decode('UTF-8')})

@hookimpl
def report_attached_data(self, body, file_name):
if isinstance(body, str):
b64_content = base64.b64encode(body.encode('utf-8'))
else:
b64_content = base64.b64encode(body)
self._results.append({'file_name': file_name, 'content_base64': b64_content.decode('UTF-8')})

def clean_results(self):
self._send_get_request('clean-results')

def clean_history(self):
self._send_get_request('clean-history')

def _send_post_request(self, route: str, results: list):
request_body = {"results": results}
json_request_body = json.dumps(request_body)

request_url = f'{self._allure_server}/allure-docker-service/{route}?project_id={self._project_id}'
response = requests.post(request_url, headers=self._headers, data=json_request_body,
verify=self._ssl_verification)
response.raise_for_status() # Raising exception if response is not ok
return json.loads(response.content)

def _send_get_request(self, route: str, params: dict = None):
request_url = f'{self._allure_server}/allure-docker-service/{route}?project_id={self._project_id}'
response = requests.get(request_url, params=params, headers=self._headers, verify=self._ssl_verification)
response.raise_for_status() # Raising exception if response is not ok
return json.loads(response.content)


class AllureMemoryLogger:

def __init__(self):
Expand Down
1 change: 1 addition & 0 deletions requirements/testing.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ poethepoet
PyHamcrest
Pygments
pytest
requests
2 changes: 1 addition & 1 deletion requirements/testing/allure-python-commons.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
# allure_commons testing deps
# allure_commons testing deps