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

Allowed compressed result file upload #149 using two approaches : archived data in form-data or archived data in body #263

Open
wants to merge 1 commit 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
5 changes: 5 additions & 0 deletions allure-docker-api-usage/send_results.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ done
set -o xtrace
echo "------------------SEND-RESULTS------------------"
curl -X POST "$ALLURE_SERVER/allure-docker-service/send-results?project_id=$PROJECT_ID" -H 'Content-Type: multipart/form-data' $FILES -ik
# send archived allure-results files with form-data
#curl -X POST "$ALLURE_SERVER/allure-docker-service/send-results?project_id=$PROJECT_ID" -H 'Content-Type: multipart/form-data' "-F zip=allure-results-example/allure-results-example.zip" -ik
# send archived allure-results as body
#curl -X POST "$ALLURE_SERVER/allure-docker-service/send-results?project_id=$PROJECT_ID" -H 'Content-Type: application/zip' --data-binary @'allure-results-example/allure-results-example.zip' -ik
#curl -X POST "$ALLURE_SERVER/allure-docker-service/send-results?project_id=$PROJECT_ID" -H 'Content-Type: application/gzip' --data-binary @'allure-results-example/allure-results-example.tar.gz' -ik


#If you want to generate reports on demand use the endpoint `GET /generate-report` and disable the Automatic Execution >> `CHECK_RESULTS_EVERY_SECONDS: NONE`
Expand Down
80 changes: 76 additions & 4 deletions allure-docker-api/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import tempfile
import subprocess
import zipfile
import tarfile
import waitress
from werkzeug.utils import secure_filename
from flask import (
Expand Down Expand Up @@ -860,13 +861,15 @@ def send_results_endpoint(): #pylint: disable=too-many-branches

content_type = str(request.content_type)
if content_type is None:
raise Exception("Header 'Content-Type' should start with 'application/json' or 'multipart/form-data'") #pylint: disable=line-too-long
raise Exception("Header 'Content-Type' should start with 'application/json' or 'multipart/form-data' or 'application/zip' or 'application/gzip'") #pylint: disable=line-too-long

if (
content_type.startswith('application/json') is False and
content_type.startswith('application/zip') is False and
content_type.startswith('application/gzip') is False and
content_type.startswith('multipart/form-data') is False
):
raise Exception("Header 'Content-Type' should start with 'application/json' or 'multipart/form-data'") #pylint: disable=line-too-long
raise Exception("Header 'Content-Type' should start with 'application/json' or 'multipart/form-data' or 'application/zip' or 'application/gzip'") #pylint: disable=line-too-long

project_id = resolve_project(request.args.get('project_id'))
if is_existent_project(project_id) is False:
Expand Down Expand Up @@ -897,8 +900,17 @@ def send_results_endpoint(): #pylint: disable=too-many-branches
send_json_results(results_project, validated_results, processed_files, failed_files)

if content_type.startswith('multipart/form-data') is True:
validated_results = validate_files_array(request.files.getlist('files[]'))
send_files_results(results_project, validated_results, processed_files, failed_files)
if request.files.getlist('files[]'):
validated_results = validate_files_array(request.files.getlist('files[]'))
send_files_results(results_project, validated_results, processed_files, failed_files)
elif request.files.get('zip'):
extract_zipped_file_to_result(results_project, request.files.get('zip'), processed_files, failed_files)

if content_type.startswith('application/zip') is True:
extract_raw_zip_to_result(results_project, request.stream, processed_files, failed_files)

if content_type.startswith('application/gzip') is True:
extract_raw_gzip_to_result(results_project, request.stream, processed_files, failed_files)

failed_files_count = len(failed_files)
if failed_files_count > 0:
Expand Down Expand Up @@ -1533,6 +1545,66 @@ def validate_json_results(results):

return validated_results


def extract_raw_gzip_to_result(results_project, stream, processed_files, failed_files):
archive = tempfile.NamedTemporaryFile(suffix='.tar.gz')
try:
write_stream_to_archive(archive, stream)

with tarfile.open(archive.name) as tar:
#TODO add explicit filter='data' after migration to python 3.12+
tar.extractall(results_project)

processed_files.append("allure-results.gzip")
except Exception as ex:
LOGGER.error("Error occurred during saving allure gzip archive '%s': %s", archive.name, str(ex))
failed_files.append("allure-results.gzip")
finally:
archive.close()


def extract_raw_zip_to_result(results_project, stream, processed_files, failed_files):
archive = tempfile.NamedTemporaryFile(suffix='.zip')
try:
write_stream_to_archive(archive, stream)

with zipfile.ZipFile(archive, "r") as zip_ref:
zip_ref.extractall(results_project)

processed_files.append("allure-results.zip")
except Exception as ex:
LOGGER.error("Error occurred during saving allure zip archive '%s': %s", archive.name, str(ex))
failed_files.append("allure-results.zip")
finally:
archive.close()


def write_stream_to_archive(archive, stream):
chunk_size = 4096
while True:
chunk = stream.read(chunk_size)
if len(chunk) == 0:
break
archive.write(chunk)
archive.flush()


def extract_zipped_file_to_result(results_project, file, processed_files, failed_files):
filename = secure_filename(file.filename)
archive = tempfile.NamedTemporaryFile()
try:
file.save(archive)

with zipfile.ZipFile(archive, "r") as zip_ref:
zip_ref.extractall(results_project)

processed_files.append(filename)
except Exception as ex:
LOGGER.error("Error occurred during saving allure zip archive %s : %s", filename, str(ex))
failed_files.append(filename)
finally:
archive.close()

def send_files_results(results_project, validated_results, processed_files, failed_files):
for file in validated_results:
try:
Expand Down
22 changes: 20 additions & 2 deletions allure-docker-api/static/swagger/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,9 @@
"summary":"Send results files (from version 2.12.1)",
"consumes":[
"application/json",
"multipart/form-data"
"multipart/form-data",
"application/zip",
"application/gzip"
],
"parameters":[
{
Expand Down Expand Up @@ -189,6 +191,18 @@
"schema":{
"$ref":"#/components/schemas/files"
}
},
"application/zip": {
"schema": {
"type": "string",
"format": "binary"
}
},
"application/gzip": {
"schema": {
"type": "string",
"format": "binary"
}
}
}
},
Expand Down Expand Up @@ -773,13 +787,17 @@
},
"files":{
"type":"object",
"properties":{
"properties": {
"files[]":{
"type":"array",
"items":{
"type":"string",
"format":"binary"
}
},
"zip": {
"type": "string",
"format": "binary"
}
}
}
Expand Down