Beispiel #1
0
def looks_like_a_workflow(path):
    """Return boolean indicating if this path looks like a workflow."""
    if POTENTIAL_WORKFLOW_FILES.match(os.path.basename(path)):
        with open(path, "r") as f:
            workflow_dict = ordered_load(f)
        if not isinstance(workflow_dict, dict):
            # Not exactly right - could have a #main def - do better and sync with Galaxy.
            return False
        return workflow_dict.get("class") == "GalaxyWorkflow" or workflow_dict.get("a_galaxy_workflow")
    return False
Beispiel #2
0
def test_normalized_workflow():
    # same workflow with slightly different input definitions, make sure normalize
    # unifies these
    for wf in [INTEGER_INPUT, INT_INPUT]:
        int_input_normalized = NormalizedWorkflow(
            ordered_load(INT_INPUT)).normalized_workflow_dict
        inputs = int_input_normalized["inputs"]
        assert isinstance(inputs, list)
        assert isinstance(inputs[0], dict)  # str converted to dictionary
        assert inputs[0]["id"] == "input_d"
        assert inputs[0]["type"] == "data"  # converted from File to data
        assert isinstance(inputs[1], dict)
        assert inputs[1]["type"] == "int"
def main(argv):
    """Script entry point for linting workflows."""
    path = argv[1]
    with open(path, "r") as f:
        try:
            workflow_dict = ordered_load(f)
        except Exception:
            return EXIT_CODE_FILE_PARSE_FAILED
    workflow_class = workflow_dict.get("class")
    lint_func = lint_format2 if workflow_class == "GalaxyWorkflow" else lint_ga
    lint_context = LintContext()
    lint_func(lint_context, workflow_dict, path=path)
    lint_context.print_messages()
    if lint_context.found_errors:
        return EXIT_CODE_FORMAT_ERROR
    elif lint_context.found_warns:
        return EXIT_CODE_LINT_FAILED
    else:
        return EXIT_CODE_SUCCESS
Beispiel #4
0
def test_export_native_no_labels():
    # Ensure outputs don't get mapped to 'null' key and ensure
    native_unicycler = ordered_load(
        open(os.path.join(TEST_PATH, "unicycler.ga"), "r").read())
    before_output_count = 0
    for workflow_output in native_workflow_outputs(native_unicycler):
        before_output_count += 1
    before_step_count = len(native_unicycler["steps"])

    unicycler_no_output_labels = copy_without_workflow_output_labels(
        native_unicycler)
    as_format2 = from_native(unicycler_no_output_labels)
    assert len(as_format2["outputs"]) == before_output_count
    round_trip_unicycler = to_native(as_format2)

    after_output_count = 0
    for workflow_output in native_workflow_outputs(round_trip_unicycler):
        after_output_count += 1
    after_step_count = len(round_trip_unicycler["steps"])

    assert after_step_count == before_step_count
    assert after_output_count == before_output_count, round_trip_unicycler
Beispiel #5
0
 def structure(path, lint_context):
     with open(path, "r") as f:
         workflow_dict = ordered_load(f)
     workflow_class = workflow_dict.get("class")
     lint_func = lint_format2 if workflow_class == "GalaxyWorkflow" else lint_ga
     lint_func(lint_context, workflow_dict, path=path)
Beispiel #6
0
def setup_module(module):
    # Setup an examples directory with examples we want to correspond to what exit codes,
    # do this so we can run same tests in Java.
    green_format2 = ordered_load(BASIC_WORKFLOW)
    _dump_with_exit_code(green_format2, 0, "basic_format2")
    green_native = to_native(BASIC_WORKFLOW)
    assert_valid_native(green_native)
    _dump_with_exit_code(green_native, 0, "basic_native")

    green_explicit_errors_null = _deep_copy(green_native)
    for step, step_def in green_explicit_errors_null["steps"].items():
        step_def["errors"] = None
    _dump_with_exit_code(green_explicit_errors_null, 0, "basic_native_explicit_no_errors")

    invalid_format2_no_format_dict = _deep_copy(green_format2)
    del invalid_format2_no_format_dict["class"]
    _dump_with_exit_code(invalid_format2_no_format_dict, 2, "format2_no_class")

    invalid_ga_no_format_dict = _deep_copy(green_native)
    del invalid_ga_no_format_dict["a_galaxy_workflow"]
    _dump_with_exit_code(invalid_ga_no_format_dict, 2, "native_no_class")

    invalid_ga_steps_not_order_index_dict = _deep_copy(green_native)
    steps = invalid_ga_steps_not_order_index_dict["steps"]
    step_0 = steps.pop("0")
    steps["moo_0"] = step_0
    _dump_with_exit_code(invalid_ga_steps_not_order_index_dict, 2, "native_step_not_order_index")

    invalid_ga_no_steps = _deep_copy(green_native)
    invalid_ga_no_steps.pop("steps")
    _dump_with_exit_code(invalid_ga_no_steps, 2, "native_no_steps")

    invalid_format2_no_steps_dict = _deep_copy(green_format2)
    del invalid_format2_no_steps_dict["steps"]
    _dump_with_exit_code(invalid_format2_no_steps_dict, 2, "format2_no_steps")

    red_format2_step_errors = _deep_copy(green_format2)
    red_format2_step_errors["steps"]["cat"]["errors"] = "Tool is not installed."
    _dump_with_exit_code(red_format2_step_errors, 1, "format2_step_errors")

    red_native_step_errors = _deep_copy(green_native)
    red_native_step_errors["steps"]["1"]["errors"] = "Tool is not installed."
    _dump_with_exit_code(red_native_step_errors, 1, "native_step_errors")

    red_ga_no_outputs = _deep_copy(green_native)
    red_ga_no_outputs_steps = red_ga_no_outputs.get("steps")
    for step in red_ga_no_outputs_steps.values():
        step.pop("workflow_outputs", None)
    _dump_with_exit_code(red_ga_no_outputs, 1, "native_no_outputs")

    red_ga_no_output_labels = copy_without_workflow_output_labels(green_native)
    _dump_with_exit_code(red_ga_no_output_labels, 1, "native_no_output_labels")

    # gotta call this a format error to implement Process in schema...
    red_format2_no_outputs = _deep_copy(green_format2)
    del red_format2_no_outputs["outputs"]
    _dump_with_exit_code(red_format2_no_outputs, 2, "format2_no_output")

    green_format2_rules = ordered_load(RULES_TOOL)
    _dump_with_exit_code(green_format2_rules, 0, "format2_rules")

    green_native_rules = to_native(RULES_TOOL)
    _dump_with_exit_code(green_native_rules, 0, "native_format")

    green_format2_repeat = ordered_load(WORKFLOW_WITH_REPEAT)
    _dump_with_exit_code(green_format2_repeat, 0, "format2_repeat")
    green_native_rules = to_native(WORKFLOW_WITH_REPEAT)
    _dump_with_exit_code(green_native_rules, 0, "native_repeat")

    green_format2_nested = ordered_load(NESTED_WORKFLOW)
    _dump_with_exit_code(green_format2_nested, 0, "format2_nested")
    green_native_nested = to_native(NESTED_WORKFLOW)
    _dump_with_exit_code(green_native_nested, 0, "native_nested")

    invalid_format2_nested = _deep_copy(green_format2_nested)
    del invalid_format2_nested["steps"]["nested_workflow"]["run"]["steps"]
    _dump_with_exit_code(invalid_format2_nested, 2, "format2_nested_no_steps")

    invalid_native_nested = _deep_copy(green_native_nested)
    del invalid_native_nested["steps"]['2']['subworkflow']['steps']
    _dump_with_exit_code(invalid_native_nested, 2, "native_nested_no_steps")

    green_format2_runtime_inputs = ordered_load(RUNTIME_INPUTS)
    _dump_with_exit_code(green_format2_runtime_inputs, 0, "format2_runtime_inputs")
    green_native_runtime_inputs = to_native(RUNTIME_INPUTS)
    _dump_with_exit_code(green_native_runtime_inputs, 0, "native_runtime_inputs")

    green_format2_runtime_inputs = ordered_load(RUNTIME_INPUTS)
    invalid_format2_runtime_inputs_type = _deep_copy(green_format2_runtime_inputs)
    invalid_format2_runtime_inputs_type['steps']['random']['runtime_inputs'][0] = 5
    _dump_with_exit_code(invalid_format2_runtime_inputs_type, 2, "format2_runtime_inputs_invalid_type")

    green_format2_pja = ordered_load(PJA_1)
    _dump_with_exit_code(green_format2_runtime_inputs, 0, "format2_pja1")

    invalid_format2_pja_hide_type = _deep_copy(green_format2_pja)
    invalid_format2_pja_hide_type['steps']['first_cat']['out']['out_file1']['hide'] = "moocow"
    _dump_with_exit_code(invalid_format2_pja_hide_type, 2, "format2_pja_hide_invalid_type")

    green_format2_report = ordered_load(WITH_REPORT)
    _dump_with_exit_code(green_format2_report, 0, "format2_report")
    green_native_report = to_native(WITH_REPORT)
    _dump_with_exit_code(green_native_report, 0, "native_report")

    invalid_format2_report_type = _deep_copy(green_format2_report)
    invalid_format2_report_type["report"]["markdown"] = 5
    _dump_with_exit_code(invalid_format2_report_type, 2, "format2_report_invalid_type")

    invalid_native_report_type = _deep_copy(green_native_report)
    invalid_native_report_type["report"]["markdown"] = 5
    _dump_with_exit_code(invalid_native_report_type, 2, "native_report_invalid_type")

    invalid_format2_report_markdown = _deep_copy(green_format2_report)
    invalid_format2_report_markdown["report"]["markdown"] += "\n```galaxy\ncow()\n```\n"
    _dump_with_exit_code(invalid_format2_report_markdown, 2, "format2_report_invalid_markdown")

    invalid_native_report_markdown = _deep_copy(green_native_report)
    invalid_native_report_markdown["report"]["markdown"] += "\n```galaxy\ncow()\n```\n"
    _dump_with_exit_code(invalid_native_report_markdown, 2, "native_report_invalid_markdown")

    invalid_format2_report_missing_markdown = _deep_copy(green_format2_report)
    del invalid_format2_report_missing_markdown["report"]["markdown"]
    _dump_with_exit_code(invalid_format2_report_missing_markdown, 2, "format2_report_missing_markdown")

    invalid_native_report_missing_markdown = _deep_copy(green_native_report)
    del invalid_native_report_missing_markdown["report"]["markdown"]
    _dump_with_exit_code(invalid_native_report_missing_markdown, 2, "native_report_missing_markdown")

    green_format2_vocab_keys = ordered_load(WORKFLOW_VOCAB_KEYS)
    _dump_with_exit_code(green_format2_vocab_keys, 0, "format2_vocab_keys")

    green_format2_int_input = ordered_load(INT_INPUT)
    _dump_with_exit_code(green_format2_int_input, 0, "format2_int_input")

    valid_int_default_type = _deep_copy(green_format2_int_input)
    valid_int_default_type["inputs"]["num_lines"]["default"] = 5
    _dump_with_exit_code(valid_int_default_type, 0, "format2_int_input_valid_default")

    valid_float_default_type = _deep_copy(green_format2_int_input)
    valid_float_default_type["inputs"]["num_lines"]["type"] = "float"
    valid_float_default_type["inputs"]["num_lines"]["default"] = 5.0
    _dump_with_exit_code(valid_float_default_type, 0, "format2_int_input_valid_default")

    invalid_int_default_type = _deep_copy(green_format2_int_input)
    invalid_int_default_type["inputs"]["num_lines"]["default"] = "bad_default"
    _dump_with_exit_code(invalid_int_default_type, 2, "format2_int_input_bad_default")

    invalid_float_default_type = _deep_copy(green_format2_int_input)
    invalid_float_default_type["inputs"]["num_lines"]["type"] = "float"
    invalid_float_default_type["inputs"]["num_lines"]["default"] = "bad_default"
    _dump_with_exit_code(invalid_float_default_type, 2, "format2_float_input_bad_default")

    green_format2_text_input = ordered_load(STRING_INPUT)
    _dump_with_exit_code(green_format2_text_input, 0, "format2_string_input")

    invalid_string_default_type = _deep_copy(green_format2_text_input)
    invalid_string_default_type["inputs"]["seed"]["default"] = 6
    _dump_with_exit_code(invalid_string_default_type, 2, "format2_string_input_bad_default")

    # ensure that round tripping all green format2 workflows still lint green.
    for file_name in os.listdir(TEST_LINT_EXAMPLES):
        if file_name.startswith("0_format2") and "roundtrip" not in file_name:
            roundtrip_contents = round_trip(open(os.path.join(TEST_LINT_EXAMPLES, file_name), "r").read())
            base = os.path.splitext(file_name)[0][len("0_"):]
            _dump_with_exit_code(roundtrip_contents, 0, base + "_roundtrip")
Beispiel #7
0
def test_nested_workflow():
    path = _examples_path_for("nested_format2.cwl")
    _run_example(ordered_load(NESTED_WORKFLOW), out=path)
Beispiel #8
0
def _run_example_path(path):
    out = _examples_path_for(path)
    with open(path, "r") as f:
        return _run_example(ordered_load(f), out)
Beispiel #9
0
def _both_formats(contents):
    return [ordered_load(contents), to_native(contents)]