Exemple #1
0
def test_validate_error_msg_not_in_package() -> None:
    validator = Validator([SPEC_DIR / "in_ethernet.rflx"],
                          CHECKSUM_MODULE,
                          skip_model_verification=True)
    with pytest.raises(
            ValidationError,
            match=
            r'^message "Message" could not be found in package "Ethernet"$'):
        validator.validate(ID("Ethernet::Message"), None, None, None)
Exemple #2
0
def test_validate_positive() -> None:
    validator = Validator([SPEC_DIR / "in_ethernet.rflx"],
                          CHECKSUM_MODULE,
                          skip_model_verification=True)
    validator.validate(
        ID("Ethernet::Frame"),
        TEST_DIR / "ethernet/frame/invalid",
        TEST_DIR / "ethernet/frame/valid",
    )
Exemple #3
0
def test_validate_checksum_positive() -> None:
    validator = Validator(
        [SPEC_DIR / "checksum_message.rflx"],
        CHECKSUM_MODULE,
        skip_model_verification=True,
    )
    validator.validate(
        ID("Checksum_Message::Message"),
        TEST_DIR / "checksum_message/invalid",
        TEST_DIR / "checksum_message/valid",
    )
Exemple #4
0
def test_validate_message_parameterized_message() -> None:
    validator = Validator([], skip_model_verification=True)
    message = (PyRFLX.from_specs(["tests/data/specs/parameterized.rflx"],
                                 skip_model_verification=True).package(
                                     "Parameterized").new_message("Message"))
    validation_result = validator._validate_message(  # pylint: disable = protected-access
        Path(TEST_DIR /
             "parameterized/message/valid/parameterized_message.raw"),
        valid_original_message=True,
        message_value=message,
    )
    assert validation_result.validation_success
Exemple #5
0
def test_validate_message_original_and_parsed_not_equal() -> None:
    validator = Validator([], skip_model_verification=True)
    ethernet_too_short_value = (PyRFLX.from_specs(
        [SPEC_DIR / "ethernet.rflx"],
        skip_model_verification=True).package("Ethernet").new_message("Frame"))
    validation_result = validator._validate_message(  # pylint: disable = protected-access
        Path(TEST_DIR /
             "ethernet/frame/invalid/ethernet_invalid_too_long.raw"),
        valid_original_message=True,
        message_value=ethernet_too_short_value,
    )
    assert (validation_result.parser_error ==
            "message parsed by PyRFLX is shorter than the original message")
Exemple #6
0
def test_validate_not_regular_file(tmp_path: Path) -> None:
    subdir = tmp_path / "test.raw"
    subdir.mkdir()
    validator = Validator([SPEC_DIR / "in_ethernet.rflx"],
                          CHECKSUM_MODULE,
                          skip_model_verification=True)
    with pytest.raises(
            ValidationError,
            match=(r"^"
                   rf"{subdir} is not a regular file"
                   r"$"),
    ):
        validator.validate(ID("Ethernet::Frame"), tmp_path)
Exemple #7
0
def test_validate_pyrflx_checksum_negative() -> None:
    validator = Validator(
        [SPEC_DIR / "checksum_message.rflx"],
        CHECKSUM_MODULE,
        skip_model_verification=True,
    )
    with pytest.raises(ValidationError,
                       match=r"^3 messages were classified incorrectly$"):
        validator.validate(
            ID("Checksum_Message::Message"),
            TEST_DIR / "checksum_message/valid",
            TEST_DIR / "checksum_message/invalid",
        )
Exemple #8
0
def test_validate_positive_output(tmp_path: Path) -> None:
    validator = Validator([SPEC_DIR / "in_ethernet.rflx"],
                          CHECKSUM_MODULE,
                          skip_model_verification=True)
    validator.validate(
        ID("Ethernet::Frame"),
        TEST_DIR / "ethernet/frame/invalid",
        TEST_DIR / "ethernet/frame/valid",
        tmp_path / "output.json",
    )
    assert (tmp_path /
            "output.json").read_text() == (TEST_DIR /
                                           "output_positive.json").read_text(
                                               encoding="utf-8")
Exemple #9
0
def test_validate_coverage_threshold_invalid() -> None:
    validator = Validator([SPEC_DIR / "in_ethernet.rflx"],
                          CHECKSUM_MODULE,
                          skip_model_verification=True)
    with pytest.raises(
            ValidationError,
            match=r"^target coverage must be between 0 and 100, got 110$"):
        validator.validate(
            ID("Ethernet::Frame"),
            TEST_DIR / "ethernet/frame/invalid",
            TEST_DIR / "ethernet/frame/valid",
            coverage=True,
            target_coverage=110,
        )
Exemple #10
0
def test_initialize_pyrflx_spec_file_not_found() -> None:
    with pytest.raises(
            ValidationError,
            match=r'^specification file not found: "non_existent_file.rflx"$'):
        Validator(["non_existent_file.rflx"],
                  CHECKSUM_MODULE,
                  skip_model_verification=True)
Exemple #11
0
def test_validate_negative() -> None:
    number = len(
        list((TEST_DIR / "ethernet/frame/invalid").glob("*.raw")) +
        list((TEST_DIR / "ethernet/frame/valid").glob("*.raw")))
    validator = Validator([SPEC_DIR / "in_ethernet.rflx"],
                          CHECKSUM_MODULE,
                          skip_model_verification=True)
    with pytest.raises(
            ValidationError,
            match=rf"^{number} messages were classified incorrectly$",
    ):
        validator.validate(
            ID("Ethernet::Frame"),
            TEST_DIR / "ethernet/frame/valid",
            TEST_DIR / "ethernet/frame/invalid",
        )
Exemple #12
0
def test_validate_cannot_open_output_file(tmp_path_restricted: Path) -> None:
    validator = Validator([SPEC_DIR / "in_ethernet.rflx"],
                          CHECKSUM_MODULE,
                          skip_model_verification=True)
    with pytest.raises(
            ValidationError,
            match=
        (r"^"
         rf"cannot open output file {tmp_path_restricted}/test.json:"
         rf" \[Errno 13\] Permission denied: '{tmp_path_restricted}/test.json'"
         r"$"),
    ):
        validator.validate(
            ID("Ethernet::Frame"),
            TEST_DIR / "ethernet/frame/valid",
            TEST_DIR / "ethernet/frame/invalid",
            tmp_path_restricted / "test.json",
        )
Exemple #13
0
def test_validate_abort_on_error() -> None:
    validator = Validator([SPEC_DIR / "in_ethernet.rflx"],
                          CHECKSUM_MODULE,
                          skip_model_verification=True)
    with pytest.raises(
            ValidationError,
            match=(
                r"^"
                rf"aborted: message {TEST_DIR}/ethernet/frame/invalid.+\.raw "
                r"was classified incorrectly"
                r"$"),
    ):
        validator.validate(
            ID("Ethernet::Frame"),
            TEST_DIR / "ethernet/frame/valid",
            TEST_DIR / "ethernet/frame/invalid",
            abort_on_error=True,
        )
Exemple #14
0
def test_initialize_pyrflx_checksum_invalid_field_dict_type() -> None:
    with pytest.raises(
            ValidationError,
            match=r'^value at key "Checksum_Message::Message" is not a dict$',
    ):
        Validator(
            [SPEC_DIR / "checksum_message.rflx"],
            "tests.data.validator.checksum_invalid_field_dict_type",
            skip_model_verification=True,
        )
Exemple #15
0
def test_initialize_pyrflx_checksum_no_checksum_provided() -> None:
    with pytest.raises(
            ValidationError,
            match=
            r'^missing checksum definition for field "C" of "Checksum_Message::Message"$',
    ):
        Validator(
            [SPEC_DIR / "checksum_message.rflx"],
            skip_model_verification=True,
        )
Exemple #16
0
def test_initialize_pyrflx_checksum_invalid_function_type() -> None:
    with pytest.raises(
            ValidationError,
            match=
            r'^value at key "Checksum" is not a callable checksum function$',
    ):
        Validator(
            [SPEC_DIR / "checksum_message.rflx"],
            "tests.data.validator.checksum_invalid_function_type",
            skip_model_verification=True,
        )
Exemple #17
0
def test_initialize_pyrflx_checksum_invalid_attribute_type() -> None:
    checksum_module = "tests.data.validator.checksum_invalid_attribute_type"
    with pytest.raises(
            ValidationError,
            match=
            rf'^attribute "checksum_function" of "{checksum_module}" is not a dict$',
    ):
        Validator(
            [SPEC_DIR / "checksum_message.rflx"],
            checksum_module,
            skip_model_verification=True,
        )
Exemple #18
0
def test_validate_negative_output(tmp_path: Path) -> None:
    number = len(
        list((TEST_DIR / "ethernet/frame/invalid").glob("*.raw")) +
        list((TEST_DIR / "ethernet/frame/valid").glob("*.raw")))
    validator = Validator([SPEC_DIR / "in_ethernet.rflx"],
                          CHECKSUM_MODULE,
                          skip_model_verification=True)
    with pytest.raises(
            ValidationError,
            match=rf"^{number} messages were classified incorrectly$",
    ):
        validator.validate(
            ID("Ethernet::Frame"),
            TEST_DIR / "ethernet/frame/valid",
            TEST_DIR / "ethernet/frame/invalid",
            tmp_path / "output.json",
        )
    assert (tmp_path /
            "output.json").read_text() == (TEST_DIR /
                                           "output_negative.json").read_text(
                                               encoding="utf-8")
Exemple #19
0
def test_parameterized_message_excess_parameter() -> None:
    validator = Validator([], skip_model_verification=True)
    message = (PyRFLX.from_specs(["tests/data/specs/parameterized.rflx"],
                                 skip_model_verification=True).package(
                                     "Parameterized").new_message("Message"))
    with pytest.raises(
            ValidationError,
            match=
        (r"^"
         f"{TEST_DIR}/parameterized/message/invalid/parameterized_message_excess_parameter.raw:"
         r" pyrflx: error: unexpected parameter values: Excess"
         r"$"),
    ):
        validator._validate_message(  # pylint: disable = protected-access
            Path(
                TEST_DIR /
                "parameterized/message/invalid/parameterized_message_excess_parameter.raw"
            ),
            valid_original_message=True,
            message_value=message,
        )
Exemple #20
0
def test_validate_coverage(capsys: CaptureFixture[str]) -> None:
    validator = Validator([SPEC_DIR / "ethernet.rflx"],
                          CHECKSUM_MODULE,
                          skip_model_verification=True)
    validator.validate(
        ID("Ethernet::Frame"),
        TEST_DIR / "ethernet/frame/invalid",
        TEST_DIR / "ethernet/frame/valid",
        coverage=True,
        target_coverage=100,
    )
    expected_output = f"""model: warning: model verification skipped
{TEST_DIR}/ethernet/frame/valid/802.3-LLC-CDP.raw                      PASSED
{TEST_DIR}/ethernet/frame/valid/EII-802.1AD-802.1Q-IPv4.raw            PASSED
{TEST_DIR}/ethernet/frame/valid/EII-802.1Q-802.1Q-IPv4-ICMP.raw        PASSED
{TEST_DIR}/ethernet/frame/valid/EII-802.1Q-LLC-CDP.raw                 PASSED
{TEST_DIR}/ethernet/frame/valid/EII-802.1Q-LLC-STP.raw                 PASSED
{TEST_DIR}/ethernet/frame/valid/ethernet_802.3.raw                     PASSED
{TEST_DIR}/ethernet/frame/valid/ethernet_double_vlan_tag.raw           PASSED
{TEST_DIR}/ethernet/frame/valid/ethernet_ipv4_udp.raw                  PASSED
{TEST_DIR}/ethernet/frame/valid/ethernet_vlan_tag.raw                  PASSED
{TEST_DIR}/ethernet/frame/invalid/ethernet_802.3_invalid_length.raw    PASSED
{TEST_DIR}/ethernet/frame/invalid/ethernet_invalid_too_long.raw        PASSED
{TEST_DIR}/ethernet/frame/invalid/ethernet_invalid_too_short.raw       PASSED
{TEST_DIR}/ethernet/frame/invalid/ethernet_undefined.raw               PASSED


--------------------------------------------------------------------------------
                     RecordFlux Validation Coverage Report
Directory: {os.getcwd()}
--------------------------------------------------------------------------------
File                                          Links       Used        Coverage
ethernet.rflx                                    10         10         100.00%
--------------------------------------------------------------------------------
TOTAL                                            10         10         100.00%
--------------------------------------------------------------------------------
"""
    assert capsys.readouterr().out == expected_output
Exemple #21
0
def test_initialize_pyrflx_checksum_missing_attribute() -> None:
    checksum_module = "tests.data.validator.checksum_missing_attribute"
    with pytest.raises(
            ValidationError,
            match=
        (r"^"
         rf'missing attribute "checksum_function" in checksum module "{checksum_module}"'
         r"$"),
    ):
        Validator(
            [SPEC_DIR / "checksum_message.rflx"],
            checksum_module,
            skip_model_verification=True,
        )
Exemple #22
0
def test_initialize_pyrflx_checksum_invalid_field() -> None:
    with pytest.raises(
            ValidationError,
            match=
        (r"^"
         r"invalid checksum definition: "
         r"pyrflx: error: cannot set checksum function: field Invalid_Field is not defined"
         r"$"),
    ):
        Validator(
            [SPEC_DIR / "checksum_message.rflx"],
            "tests.data.validator.checksum_invalid_field",
            skip_model_verification=True,
        )
Exemple #23
0
def test_initialize_pyrflx_checksum_invalid_message() -> None:
    with pytest.raises(
            ValidationError,
            match=
        (r"^"
         r"invalid checksum definition: "
         r'pyrflx: error: "Invalid_Message" is not a message in Checksum_Message'
         r"$"),
    ):
        Validator(
            [SPEC_DIR / "checksum_message.rflx"],
            "tests.data.validator.checksum_invalid_message",
            skip_model_verification=True,
        )
Exemple #24
0
def test_initialize_pyrflx_checksum_import_error() -> None:
    with pytest.raises(
            ValidationError,
            match=
        (r"^"
         r'provided module "tests/checksum" cannot be imported, make sure module name is'
         r' provided as "package.module" and not as file system path:'
         r" No module named 'tests/checksum'"
         r"$"),
    ):
        Validator(
            [SPEC_DIR / "checksum_message.rflx"],
            "tests/checksum",
            skip_model_verification=True,
        )
Exemple #25
0
def validate(args: argparse.Namespace) -> None:
    if args.valid_samples_directory is None and args.invalid_samples_directory is None:
        fail("must provide directory with valid and/or invalid messages",
             Subsystem.CLI)

    for path in [args.valid_samples_directory, args.invalid_samples_directory]:
        if path is not None and not path.is_dir():
            fail(f"{path} does not exist or is not a directory", Subsystem.CLI)

    if args.output_file is not None and args.output_file.exists():
        fail(f"output file already exists: {args.output_file}", Subsystem.CLI)

    try:
        identifier = ID(args.message_identifier)
    except FatalError as e:
        fail(f"invalid identifier: {e}", Subsystem.CLI)

    try:
        Validator(
            [args.specification],
            args.checksum_module,
            args.no_verification,
            args.split_disjunctions,
        ).validate(
            identifier,
            args.invalid_samples_directory,
            args.valid_samples_directory,
            args.output_file,
            args.abort_on_error,
            args.coverage,
            args.target_coverage,
        )
    except ValidationError as e:
        fail(str(e), Subsystem.VALIDATOR)
    except PyRFLXError as e:
        fatal_error = FatalError()
        fatal_error.extend(e)
        raise fatal_error from e
Exemple #26
0
def test_coverage_threshold_missed(capsys: CaptureFixture[str]) -> None:
    validator = Validator(
        [SPEC_DIR / "in_ethernet.rflx"],
        CHECKSUM_MODULE,
        skip_model_verification=True,
        split_disjunctions=True,
    )
    with pytest.raises(
            ValidationError,
            match=r"missed target coverage of 90.00%, reached 73.68%"):
        validator.validate(
            ID("Ethernet::Frame"),
            TEST_DIR / "ethernet/frame/invalid",
            TEST_DIR / "ethernet/frame/valid",
            coverage=True,
            target_coverage=90,
        )
    expected_output = f"""model: warning: model verification skipped
{TEST_DIR}/ethernet/frame/valid/802.3-LLC-CDP.raw                      PASSED
{TEST_DIR}/ethernet/frame/valid/EII-802.1AD-802.1Q-IPv4.raw            PASSED
{TEST_DIR}/ethernet/frame/valid/EII-802.1Q-802.1Q-IPv4-ICMP.raw        PASSED
{TEST_DIR}/ethernet/frame/valid/EII-802.1Q-LLC-CDP.raw                 PASSED
{TEST_DIR}/ethernet/frame/valid/EII-802.1Q-LLC-STP.raw                 PASSED
{TEST_DIR}/ethernet/frame/valid/ethernet_802.3.raw                     PASSED
{TEST_DIR}/ethernet/frame/valid/ethernet_double_vlan_tag.raw           PASSED
{TEST_DIR}/ethernet/frame/valid/ethernet_ipv4_udp.raw                  PASSED
{TEST_DIR}/ethernet/frame/valid/ethernet_vlan_tag.raw                  PASSED
{TEST_DIR}/ethernet/frame/invalid/ethernet_802.3_invalid_length.raw    PASSED
{TEST_DIR}/ethernet/frame/invalid/ethernet_invalid_too_long.raw        PASSED
{TEST_DIR}/ethernet/frame/invalid/ethernet_invalid_too_short.raw       PASSED
{TEST_DIR}/ethernet/frame/invalid/ethernet_undefined.raw               PASSED


--------------------------------------------------------------------------------
                     RecordFlux Validation Coverage Report
Directory: {os.getcwd()}
--------------------------------------------------------------------------------
File                                          Links       Used        Coverage
ipv4.rflx                                        28         18          64.29%
ethernet.rflx                                    10         10         100.00%
--------------------------------------------------------------------------------
TOTAL                                            38         28          73.68%
--------------------------------------------------------------------------------


================================================================================
                                Uncovered Links
================================================================================


                                   ipv4.rflx
--------------------------------------------------------------------------------
{SPEC_DIR}/ipv4.rflx:21:10: missing link          Initial          ->        Copied
{SPEC_DIR}/ipv4.rflx:21:27: missing link          Copied           ->     Option_Class
{SPEC_DIR}/ipv4.rflx:22:38: missing link       Option_Class        ->    Option_Number
{SPEC_DIR}/ipv4.rflx:24:13: missing link       Option_Number       ->        Final
{SPEC_DIR}/ipv4.rflx:26:13: missing link       Option_Number       ->    Option_Length
{SPEC_DIR}/ipv4.rflx:29:17: missing link       Option_Length       ->     Option_Data
{SPEC_DIR}/ipv4.rflx:30:20: missing link       Option_Length       ->     Option_Data
{SPEC_DIR}/ipv4.rflx:31:20: missing link       Option_Length       ->     Option_Data
{SPEC_DIR}/ipv4.rflx:32:20: missing link       Option_Length       ->     Option_Data
{SPEC_DIR}/ipv4.rflx:34:50: missing link        Option_Data        ->        Final
"""
    assert capsys.readouterr().out == expected_output
Exemple #27
0
def test_expand_expression(expression: expr.Expr,
                           expected: Sequence[expr.Expr]) -> None:
    # pylint: disable = protected-access
    assert Validator._expand_expression(expression) == expected