コード例 #1
0
def update_run(id_, run=None, token_info=None, user=None):
    """Updates a single run

    :param id: ID of run to update
    :type id: int
    :param body: Run
    :type body: dict

    :rtype: Run
    """
    if not connexion.request.is_json:
        return "Bad request, JSON required", 400
    run_dict = connexion.request.get_json()
    if run_dict.get("metadata", {}).get("project"):
        run_dict["project_id"] = get_project_id(
            run_dict["metadata"]["project"])
        if not project_has_user(run_dict["project_id"], user):
            return "Forbidden", 403
    run = Run.query.get(id_)
    if run and not project_has_user(run.project, user):
        return "Forbidden", 403
    if not run:
        return "Run not found", 404
    run.update(run_dict)
    session.add(run)
    session.commit()
    update_run_task.apply_async((id_, ), countdown=5)
    return run.to_dict()
コード例 #2
0
def update_widget_config(id_):
    """Updates a single widget config

    :param id: ID of widget to update
    :type id: int
    :param body: Result
    :type body: dict

    :rtype: Result
    """
    if not connexion.request.is_json:
        return "Bad request, JSON required", 400
    widget_config = connexion.request.get_json()
    if widget_config.get(
            "widget") and widget_config["widget"] not in WIDGET_TYPES.keys():
        return "Bad request, widget type does not exist", 400
    # Look up the project id
    if widget_config.get("project"):
        widget_config["project"] = get_project_id(widget_config["project"])
    existing_widget_config = mongo.widget_config.find_one(
        {"_id": ObjectId(id_)})
    # add default weight of 10
    if not existing_widget_config.get("weight"):
        existing_widget_config["weight"] = 10
    # default to make views navigable
    if widget_config.get(
            "type") == "view" and not widget_config.get("navigable"):
        widget_config["navigable"] = "true"
    merge_dicts(existing_widget_config, widget_config)
    mongo.widget_config.replace_one({"_id": ObjectId(id_)}, widget_config)
    return serialize(widget_config)
コード例 #3
0
def add_widget_config(widget_config=None):
    """Create a new widget config

    :param widget_config: The widget_config to save
    :type widget_config: dict | bytes

    :rtype: WidgetConfig
    """
    if not connexion.request.is_json:
        return "Bad request, JSON required", 400
    widget_config = connexion.request.json
    if widget_config["widget"] not in WIDGET_TYPES.keys():
        return "Bad request, widget type does not exist", 400
    # add default weight of 10
    if not widget_config.get("weight"):
        widget_config["weight"] = 10
    # Look up the project id
    if widget_config.get("project"):
        widget_config["project"] = get_project_id(widget_config["project"])
    # default to make views navigable
    if widget_config.get(
            "type") == "view" and not widget_config.get("navigable"):
        widget_config["navigable"] = "true"
    mongo.widget_config.insert_one(widget_config)
    widget_config = serialize(widget_config)
    return widget_config, 201
コード例 #4
0
def get_report_list(page=1, page_size=25, project=None):
    """Get a list of reports

    :param page: Set the page of items to return, defaults to 1
    :type page: int
    :param page_size: Set the number of items per page, defaults to 25
    :type page_size: int

    :rtype: ReportList
    """
    params = {}
    if project:
        params["parameters.project"] = get_project_id(project)
    offset = (page * page_size) - page_size
    total_items = mongo.reports.count(params)
    total_pages = (total_items //
                   page_size) + (1 if total_items % page_size > 0 else 0)
    reports = mongo.reports.find(params,
                                 skip=offset,
                                 limit=page_size,
                                 sort=[("created", DESCENDING)])
    return {
        "reports": [serialize(report) for report in reports],
        "pagination": {
            "page": page,
            "pageSize": page_size,
            "totalItems": total_items,
            "totalPages": total_pages,
        },
    }
コード例 #5
0
def add_report(report_parameters=None):
    """Create a new report

    :param report: The report to generate
    :type report: dict | bytes

    :rtype: Report
    """
    if not connexion.request.is_json:
        return "Bad request, JSON required", 400
    report_parameters = connexion.request.json
    if report_parameters["type"] not in REPORTS:
        return "Bad request, report type does not exist", 400
    if "project" in report_parameters:
        report_parameters["project"] = get_project_id(
            report_parameters["project"])
    report = {
        "filename": "",
        "mimetype": "",
        "url": "",
        "download_url": "",
        "view_url": "",
        "parameters": report_parameters,
        "created": datetime.utcnow().isoformat(),
    }
    mongo.reports.insert_one(report)
    report = serialize(report)
    REPORTS[report_parameters["type"]]["func"].delay(report)
    return report, 201
コード例 #6
0
ファイル: reports.py プロジェクト: john-dupuy/ibutsu-server
def _build_filters(report):
    """Build the filters from a report object"""
    filters = {}
    if report["parameters"].get("filter"):
        for f in report["parameters"]["filter"].split(","):
            filters.update(generate_filter_object(f.strip()))
    if report["parameters"]["source"]:
        filters["source"] = {"$eq": report["parameters"]["source"]}
    if report["parameters"].get("project"):
        filters["metadata.project"] = get_project_id(
            report["parameters"]["project"])
    return filters
コード例 #7
0
ファイル: reports.py プロジェクト: rsnyman/ibutsu-server
def _build_query(report):
    """Build the filters from a report object"""
    query = Result.query
    if report["params"].get("filter"):
        filters = report["params"]["filter"].split(",")
        if filters:
            query = apply_filters(query, filters, Result)
    if report["params"]["source"]:
        query = query.filter(Result.source == report["params"]["source"])
    if report["params"].get("project"):
        query = query.filter(
            Result.project_id == get_project_id(report["params"]["project"]))
    return query
コード例 #8
0
def _populate_metadata(run_dict, import_record):
    """To reduce cognitive complexity"""
    if import_record.data.get("project_id"):
        run_dict["project_id"] = import_record.data["project_id"]
    elif run_dict.get("metadata", {}).get("project"):
        run_dict["project_id"] = get_project_id(
            run_dict["metadata"]["project"])
    if run_dict.get("metadata", {}).get("component"):
        run_dict["component"] = run_dict["metadata"]["component"]
    if run_dict.get("metadata", {}).get("env"):
        run_dict["env"] = run_dict["metadata"]["env"]
    if import_record.data.get("source"):
        run_dict["source"] = import_record.data["source"]
コード例 #9
0
def update_result(id_, result=None):
    """Updates a single result

    :param id: ID of result to update
    :type id: int
    :param body: Result
    :type body: dict

    :rtype: Result
    """
    if not connexion.request.is_json:
        return "Bad request, JSON required", 400
    result = connexion.request.get_json()
    if result.get("metadata", {}).get("project"):
        result["metadata"]["project"] = get_project_id(result["metadata"]["project"])
    existing_result = mongo.results.find_one({"_id": ObjectId(id_)})
    merge_dicts(existing_result, result)
    mongo.results.replace_one({"_id": ObjectId(id_)}, result)
    return serialize(result)
コード例 #10
0
def add_result(result=None):
    """Creates a test result

    :param body: Result item
    :type body: dict | bytes

    :rtype: Result
    """
    if not connexion.request.is_json:
        return "Bad request, JSON required", 400
    result = connexion.request.get_json()
    if result.get("metadata", {}).get("project"):
        result["metadata"]["project"] = get_project_id(result["metadata"]["project"])
    if "start_time" not in result:
        if "starttime" in result:
            result["start_time"] = result["starttime"]
        else:
            result["start_time"] = time.time()
    mongo.results.insert_one(result)
    return serialize(result), 201
コード例 #11
0
def update_run(id_, run=None):
    """Updates a single run

    :param id: ID of run to update
    :type id: int
    :param body: Run
    :type body: dict

    :rtype: Run
    """
    if not connexion.request.is_json:
        return "Bad request, JSON required", 400
    run = connexion.request.get_json()
    if run.get("metadata") and run.get("metadata", {}).get("project"):
        run["metadata"]["project"] = get_project_id(run["metadata"]["project"])
    existing_run = mongo.runs.find_one({"_id": ObjectId(id_)})
    merge_dicts(existing_run, run)
    mongo.runs.replace_one({"_id": ObjectId(id_)}, run)
    update_run_task.delay(id_)
    return serialize(run)
コード例 #12
0
def add_run(run=None):
    """Create a new run

    :param body: Run object
    :type body: dict | bytes

    :rtype: Run
    """
    if not connexion.request.is_json:
        return "Bad request, JSON is required", 400
    run_dict = connexion.request.get_json()
    current_time = datetime.utcnow()
    if "created" not in run_dict:
        run_dict["created"] = current_time.isoformat()
    if "start_time" not in run_dict:
        run_dict["start_time"] = current_time.timestamp()
    if "id" in run_dict:
        run_dict["_id"] = ObjectId(run_dict["id"])
    if run_dict.get("metadata") and run_dict.get("metadata", {}).get("project"):
        run_dict["metadata"]["project"] = get_project_id(run_dict["metadata"]["project"])
    mongo.runs.insert_one(run_dict)
    run_dict = serialize(run_dict)
    update_run_task.apply_async((run_dict["id"],), countdown=5)
    return run_dict, 201
コード例 #13
0
def run_archive_import(import_):
    """Import a test run from an Ibutsu archive file"""
    # Update the status of the import
    import_["status"] = "running"
    mongo.imports.replace_one({"_id": ObjectId(import_["id"])}, import_)
    # Fetch the file contents
    try:
        import_file = [f for f in mongo.import_files.find({"metadata.importId": import_["id"]})][0]
    except KeyError:
        import_["status"] = "error"
        mongo.imports.replace_one({"_id": ObjectId(import_["id"])}, import_)
        return

    # First open the tarball and pull in the results
    run = None
    run_dict = None
    results = []
    result_artifacts = {}
    current_dir = None
    result = None
    artifacts = []
    start_time = None
    with tarfile.open(mode="r:gz", fileobj=import_file) as tar:
        # run through the files and dirs, skipping the first one as it is the base directory
        for member in tar.getmembers()[1:]:
            if member.isdir() and member.name != current_dir:
                if result:
                    results.append(result)
                    result_artifacts[result["id"]] = artifacts
                artifacts = []
                result = None
            elif member.name.endswith("result.json"):
                result = json.loads(tar.extractfile(member).read())
                result_start_time = result.get("start_time", result.get("starttime"))
                if not start_time or start_time > result_start_time:
                    start_time = result_start_time
            elif member.name.endswith("run.json"):
                run = json.loads(tar.extractfile(member).read())
            elif member.isfile():
                artifacts.append(member)
        if result:
            results.append(result)
            result_artifacts[result["id"]] = artifacts
        if run:
            run_dict = run
        else:
            run_dict = {
                "duration": 0,
                "summary": {"errors": 0, "failures": 0, "skips": 0, "tests": 0},
            }
        # patch things up a bit, if necessary
        if run_dict.get("start_time") and not run_dict.get("created"):
            run_dict["created"] = run_dict["start_time"]
        elif run_dict.get("created") and not run_dict.get("start_time"):
            run_dict["start_time"] = run_dict["created"]
        elif not run_dict.get("created") and not run_dict.get("start_time"):
            run_dict["created"] = start_time
            run_dict["start_time"] = start_time
        if run_dict.get("metadata", {}).get("project"):
            run_dict["metadata"]["project"] = get_project_id(run_dict["metadata"]["project"])
        # If this run has a valid ObjectId, check if this run exists
        run_exists = False
        if run_dict.get("id") and ObjectId.is_valid(run_dict["id"]):
            # Just check if this exists first
            run_exists = mongo.runs.find_one({"_id": ObjectId(run_dict["id"])}) is not None
        if run_exists:
            mongo.run_dicts.replace_one({"_id": ObjectId(run_dict["id"])}, run_dict)
        else:
            if run_dict.get("id"):
                del run_dict["id"]
            mongo.runs.insert_one(run_dict)
        run_dict = serialize(run_dict)
        import_["run_id"] = run_dict["id"]
        # Now loop through all the results, and create or update them
        for result in results:
            artifacts = result_artifacts.get(result["id"], [])
            _create_result(tar, run_dict["id"], result, artifacts)
    # Update the import record
    import_["status"] = "done"
    mongo.imports.replace_one({"_id": ObjectId(import_["id"])}, import_)
    if run_dict:
        update_run.delay(run_dict["id"])
コード例 #14
0
def import_run(xml_file):
    """Imports a JUnit XML file and creates a test run and results from it.

    :param xmlFile: file to upload
    :type xmlFile: werkzeug.datastructures.FileStorage

    :rtype: Run
    """
    if not xml_file:
        return "Bad request, no file uploaded", 400
    tree = objectify.parse(xml_file.stream)
    root = tree.getroot()
    run_dict = {
        "duration": root.get("time"),
        "summary": {
            "errors": root.get("errors"),
            "failures": root.get("failures"),
            "skips": root.get("skips"),
            "tests": root.get("tests"),
        },
    }
    if run_dict.get("metadata", {}).get("project"):
        run_dict["metadata"]["project"] = get_project_id(run_dict["metadata"]["project"])
    rec = mongo.runs.insert_one(run_dict)
    run_dict["id"] = str(run_dict.pop("_id"))
    for testcase in root.testcase:
        test_name = testcase.get("name").split(".")[-1]
        if testcase.get("classname"):
            test_name = testcase.get("classname").split(".")[-1] + "." + test_name
        result_dict = {
            "test_id": test_name,
            "start_time": 0,
            "duration": float(testcase.get("time")),
            "metadata": {
                "run": run_dict["id"],
                "fspath": testcase.get("file"),
                "line": testcase.get("line"),
            },
            "params": {},
            "source": root.get("name"),
        }
        traceback = None
        if testcase.find("failure"):
            result_dict["result"] = "failed"
            traceback = bytes(str(testcase.failure), "utf8")
        elif testcase.find("error"):
            result_dict["result"] = "error"
            traceback = bytes(str(testcase.error), "utf8")
        else:
            result_dict["result"] = "passed"
        rec = mongo.results.insert_one(result_dict)
        if traceback:
            mongo.fs.upload_from_stream(
                "traceback.log",
                traceback,
                metadata={"contentType": "text/plain", "resultId": str(rec.inserted_id)},
            )
        if testcase.find("system-out"):
            system_out = bytes(str(testcase["system-out"]), "utf8")
            mongo.fs.upload_from_stream(
                "system-out.log",
                system_out,
                metadata={"contentType": "text/plain", "resultId": str(rec.inserted_id)},
            )
        if testcase.find("system-err"):
            system_err = bytes(str(testcase["system-err"]), "utf8")
            mongo.fs.upload_from_stream(
                "system-err.log",
                system_err,
                metadata={"contentType": "text/plain", "resultId": str(rec.inserted_id)},
            )
    return run_dict, 201