def test_failed_operation(water, result_input, opti_failure):
    failed = FailedOperation(garbage=water, **result_input, **opti_failure)
    assert isinstance(failed.error, ComputeError)
    assert isinstance(failed.dict(), dict)
    failed_json = failed.json()
    assert isinstance(failed_json, str)
    assert 'its all good' in failed_json
Example #2
0
def test_failed_operation(water, result_input):
    failed = FailedOperation(extras={"garbage": water},
                             input_data=result_input,
                             error={
                                 "error_type": "expected_testing_error",
                                 "error_message": "If you see this, its all good"
                             })
    assert isinstance(failed.error, ComputeError)
    assert isinstance(failed.dict(), dict)
    failed_json = failed.json()
    assert isinstance(failed_json, str)
    assert 'its all good' in failed_json
Example #3
0
def handle_output_metadata(
        output_data: Union[Dict[str, Any], 'BaseModel'],
        metadata: Dict[str, Any],
        raise_error: bool = False,
        return_dict: bool = True) -> Union[Dict[str, Any], 'BaseModel']:
    """
    Fuses general metadata and output together.

    Returns
    -------
    result : dict or pydantic.models.Result
        Output type depends on return_dict or a dict if an error was generated in model construction
    """

    if isinstance(output_data, dict):
        output_fusion = output_data  # Error handling
    else:
        output_fusion = output_data.dict()

    # Do not override if computer generates
    output_fusion["stdout"] = output_fusion.get("stdout",
                                                None) or metadata["stdout"]
    output_fusion["stderr"] = output_fusion.get("stderr",
                                                None) or metadata["stderr"]

    if metadata["success"] is not True:
        output_fusion["success"] = False
        output_fusion["error"] = {
            "error_type": metadata["error_type"],
            "error_message": metadata["error_message"]
        }

    # Raise an error if one exists and a user requested a raise
    if raise_error and (output_fusion["success"] is not True):
        msg = "stdout:\n{}".format(output_fusion["stdout"])
        msg += "\nstderr:\n{}".format(output_fusion["stderr"])
        LOGGER.info(msg)
        raise ValueError(output_fusion["error"]["error_message"])

    # Fill out provenance datadata
    provenance_augments = get_provenance_augments()
    provenance_augments["wall_time"] = metadata["wall_time"]
    if "provenance" in output_fusion:
        output_fusion["provenance"].update(provenance_augments)
    else:
        # Add onto the augments with some missing info
        provenance_augments["creator"] = "QCEngine"
        provenance_augments["version"] = provenance_augments[
            "qcengine_version"]
        output_fusion["provenance"] = provenance_augments

    if metadata["retries"] != 0:
        output_fusion["provenance"]["retries"] = metadata["retries"]

    # Make sure pydantic sparsity is upheld
    for val in ["stdout", "stderr"]:
        if output_fusion[val] is None:
            output_fusion.pop(val)

    # We need to return the correct objects; e.g. Results, Procedures
    if output_fusion["success"]:
        # This will only execute if everything went well
        ret = output_data.__class__(**output_fusion)
    else:
        # Should only be reachable on failures
        ret = FailedOperation(success=output_fusion.pop("success", False),
                              error=output_fusion.pop("error"),
                              input_data=output_fusion)

    if return_dict:
        return json.loads(
            ret.json()
        )  # Use Pydantic to serialize, then reconstruct as Python dict of Python Primals
    else:
        return ret
Example #4
0
def handle_output_metadata(output_data,
                           metadata,
                           raise_error=False,
                           return_dict=True):
    """
    Fuses general metadata and output together.

    Returns
    -------
    result : dict or pydantic.models.Result
        Output type depends on return_dict or a dict if an error was generated in model construction
    """

    if isinstance(output_data, dict):
        output_fusion = output_data  # Error handling
    else:
        output_fusion = output_data.dict()

    output_fusion["stdout"] = metadata["stdout"]
    output_fusion["stderr"] = metadata["stderr"]
    if metadata["success"] is not True:
        output_fusion["success"] = False
        output_fusion["error"] = {
            "error_type": "meta_error",
            "error_message": metadata["error_message"]
        }

    # Raise an error if one exists and a user requested a raise
    if raise_error and (output_fusion["success"] is not True):
        msg = "stdout:\n" + output_fusion["stdout"]
        msg += "\nstderr:\n" + output_fusion["stderr"]
        print(msg)
        raise ValueError(output_fusion["error"]["error_message"])

    # Fill out provenance datadata
    wall_time = metadata["wall_time"]
    provenance_augments = config.get_provenance_augments()
    provenance_augments["wall_time"] = wall_time
    if "provenance" in output_fusion:
        output_fusion["provenance"].update(provenance_augments)
    else:
        # Add onto the augments with some missing info
        provenance_augments["creator"] = "QCEngine"
        provenance_augments["version"] = provenance_augments[
            "qcengine_version"]
        output_fusion["provenance"] = provenance_augments

    # We need to return the correct objects; e.g. Results, Procedures
    if output_fusion["success"]:
        # This will only execute if everything went well
        ret = output_data.__class__(**output_fusion)
    else:
        # Should only be reachable on failures
        ret = FailedOperation(success=output_fusion.pop("success", False),
                              error=output_fusion.pop("error"),
                              input_data=output_fusion)
    if return_dict:
        return json.loads(
            ret.json()
        )  # Use Pydantic to serialize, then reconstruct as Python dict of Python Primals
    else:
        return ret