fescobar / allure-docker-service

This docker container allows you to see up to date reports simply mounting your "allure-results" directory in the container (for a Single Project) or your "projects" directory (for Multiple Projects). Every time appears new results (generated for your tests), Allure Docker Service will detect those changes and it will generate a new report automatically (optional: send results / generate report through API), what you will see refreshing your browser.
Apache License 2.0
637 stars 183 forks source link

Error Generating Report API: 'Processing files for project_id 'project_demo'. Please Retry Later.' #246

Closed Vinit-Sapiens closed 5 months ago

Vinit-Sapiens commented 5 months ago

While running a comprehensive test suite, I encountered an error. Upon making an API request, the response I received was: 'Processing files for project_id 'project_demo'. Please Retry Later.

i am using a python script to send results and generate a report.

import sys
import os
import requests
import logging
import time
from pathlib import Path

def setup_logging():
    logging.basicConfig(level=logging.INFO, format='%(levelname)s: %(message)s')

def send_allure_results(allure_results_directory, allure_server, project_id, security_user, security_pass, allure_generate="false", allure_clean_results="false"):
    base_url = f'{allure_server}/allure-docker-service'

    try:
        check_allure_version(base_url)
    except requests.exceptions.RequestException as e:
        logging.error(f'Error checking Allure Docker Service version: {e}')
        sys.exit(1)

    with requests.Session() as session:
        try:
            csrf_access_token = login_to_allure(session, base_url, security_user, security_pass)
        except requests.exceptions.RequestException as e:
            logging.error(f'Error logging in to Allure: {e}')
            sys.exit(1)

        if allure_clean_results.lower() == "true":
            try:
                clean_results(session, base_url, project_id, csrf_access_token)
            except requests.exceptions.RequestException as e:
                logging.error(f'Error cleaning Allure results: {e}')
                sys.exit(1)

        try:
            files_to_send = get_files_to_send(allure_results_directory)
            if files_to_send:
                send_results(session, base_url, project_id, files_to_send, csrf_access_token)
        except requests.exceptions.RequestException as e:
            logging.error(f'Error sending Allure results: {e}')
            sys.exit(1)

        if allure_generate.lower() == "true":
            try:
                generate_report_with_retry(session, base_url, project_id, csrf_access_token)
            except requests.exceptions.RequestException as e:
                logging.error(f'Error generating Allure report: {e}')
                sys.exit(1)

def check_allure_version(base_url):
    response = requests.get(f'{base_url}/version')
    response.raise_for_status()
    logging.info("Allure Docker Service Version: %s", response.text)

def login_to_allure(session, base_url, security_user, security_pass):
    logging.info("Logging in...")
    login_response = session.post(
        f'{base_url}/login',
        headers={'Content-Type': 'application/json'},
        json={"username": security_user, "password": security_pass}
    )
    login_response.raise_for_status()
    csrf_access_token = login_response.cookies.get('csrf_access_token')
    logging.info("Login successful")
    return csrf_access_token

def clean_results(session, base_url, project_id, csrf_access_token):
    logging.info("Cleaning results...")
    clean_results_response = session.get(
        f'{base_url}/clean-results',
        params={'project_id': project_id},
        headers={'X-CSRF-TOKEN': csrf_access_token}
    )
        # Check the response status code
    if clean_results_response.status_code == 200:
        logging.info('Results cleaned successfully')
    else:
        logging.error('Error cleaning results : %s', clean_results_response.text)

def get_files_to_send(allure_results_directory):
    files_to_send = [f for f in Path(allure_results_directory).iterdir() if f.is_file()]
    if not files_to_send:
        logging.info("No files found")
    else:
        files_list = ', '.join(str(f) for f in files_to_send)
        logging.info("Files to send: [%s]", files_list)
    return files_to_send

def send_results(session, base_url, project_id, files_to_send, csrf_access_token):
    logging.info("Sending results...")
    files = [('files[]', open(str(file), 'rb')) for file in files_to_send]
    try:
        send_results_response = session.post(
            f'{base_url}/send-results',
            params={'project_id': project_id},
            headers={'X-CSRF-TOKEN': csrf_access_token},
            files=files
        )
        send_results_response.raise_for_status()
        logging.info("Results sent successfully")
    except requests.exceptions.RequestException as e:
        logging.error(f"Error sending results: {e}")
        # Optionally, raise or handle the exception here according to your application logic
        raise
    finally:
        for file_tuple in files:
            file_object = file_tuple[1]  # Extract the file object from the tuple
            file_object.close()

def generate_report(session, base_url, project_id, csrf_access_token):
    logging.info("Generating report...")
    execution_name = os.environ.get('EXECUTION_NAME', 'local')
    execution_type = os.environ.get('EXECUTION_TYPE', 'local')
    execution_from = os.environ.get('EXECUTION_FROM', '')

    # Construct the URL and query parameters
    url = f"{base_url}/generate-report"
    params = {
        "project_id": project_id,
        "execution_name": execution_name,
        "execution_from": execution_from,
        "execution_type": execution_type
    }

    # Send the GET request with the query parameters and headers
    response = session.get(
        url,
        params=params,
        headers={'X-CSRF-TOKEN': csrf_access_token}
    )

    # Check the response status code
    if response.status_code == 200:
        report_data = response.json().get('data', {})
        if 'report_url' in report_data:
            logging.info('ALLURE REPORT URL: %s', report_data["report_url"])
        else:
            logging.error('Error: No report URL found in response.')
    else:
        logging.error('Error generating report: %s', response.text)

    logging.info("Report generation process completed.")

def generate_report_with_retry(session, base_url, project_id, csrf_access_token, max_attempts=3, retry_interval=10):
    logging.info("Generating report...")
    execution_name = os.environ.get('EXECUTION_NAME', 'local')
    execution_type = os.environ.get('EXECUTION_TYPE', 'local')
    execution_from = os.environ.get('EXECUTION_FROM', '')
    url = f"{base_url}/generate-report"
    params = {
        "project_id": project_id,
        "execution_name": execution_name,
        "execution_from": execution_from,
        "execution_type": execution_type
    }

    for attempt in range(1, max_attempts + 1):
        logging.info(f"Attempt {attempt} to generate report...")
        generate_report_response = session.get(
            url,
            params=params,
            headers={'X-CSRF-TOKEN': csrf_access_token}
        )
        if generate_report_response.status_code == 200:
            logging.info("Report generated successfully")
            if 'report_url' in generate_report_response.json().get('data', {}):
                logging.info('ALLURE REPORT URL: %s', generate_report_response.json()["data"]["report_url"])
            else:
                logging.error('Error: No report URL found in response.')
            return True
        elif generate_report_response.status_code == 400:
            error_message = generate_report_response.json().get('meta_data', {}).get('message', 'Unknown error')
            logging.error(f"Error generating report (Attempt {attempt}): {error_message}")
        else:
            logging.error(f"Failed to generate report (Attempt {attempt}): Status Code {generate_report_response.status_code}")

        if attempt < max_attempts:
            logging.info(f"Retrying in {retry_interval} seconds...")
            time.sleep(retry_interval)

    logging.error(f"Reached maximum number of attempts ({max_attempts}). Report generation failed.")
    return False

if __name__ == "__main__":
    setup_logging()
    if len(sys.argv) < 6:
        logging.error("Usage: python script.py ALLURE_RESULTS_DIRECTORY ALLURE_SERVER PROJECT_ID SECURITY_USER SECURITY_PASSWORD [ALLURE_GENERATE] [ALLURE_CLEAN_RESULTS]")
        sys.exit(1)

    allure_results_directory, allure_server, project_id, security_user, security_pass = sys.argv[1:6]
    allure_generate = sys.argv[6] if len(sys.argv) >= 7 else "false"
    allure_clean_results = sys.argv[7] if len(sys.argv) >= 8 else "false"

    send_allure_results(allure_results_directory, allure_server,project_id, security_user, security_pass, allure_generate, allure_clean_results)
fescobar commented 5 months ago

The /generate-report is sync. You can't request multiple times while it is processing. It's not an issue. It's a limitation from the native project.

Vinit-Sapiens commented 5 months ago

The /generate-report is sync. You can't request multiple times while it is processing. It's not an issue. It's a limitation from the native project.

Even when I submit a single report generation request for a project, I still encounter the same error.

fescobar commented 5 months ago

Share your configuration and logs, otherwise, it's impossible to help you. Use CHECK_RESULTS_EVERY_SECONDS: NONE if you use the api. https://github.com/fescobar/allure-docker-service?tab=readme-ov-file#updating-seconds-to-check-allure-results

Vinit-Sapiens commented 5 months ago

Share your configuration and logs, otherwise, it's impossible to help you. Use CHECK_RESULTS_EVERY_SECONDS: NONE if you use the api. https://github.com/fescobar/allure-docker-service?tab=readme-ov-file#updating-seconds-to-check-allure-results

image image

fescobar commented 5 months ago

Please, add the container logs

Vinit-Sapiens commented 2 months ago

@fescobar PFA allure-report.csv and screenshots of Console image

Note: I am sending results in chunks and using Python script. Below are two errors :

  1. INFO: Generating report... ERROR: Error generating report: {"meta_data":{"message":"Processing files for project_id 'wc-emp-nightly'. Try later!"}}
  2. ERROR: Error generating report: 502 Bad Gateway

    502 Bad Gateway


    nginx