File: test_scanner.py

package info (click to toggle)
libei 1.5.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,916 kB
  • sloc: ansic: 23,868; python: 2,712; xml: 1,243; sh: 142; makefile: 63; cpp: 12; lisp: 2
file content (140 lines) | stat: -rw-r--r-- 5,481 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#!/usr/bin/env python3

# We can't import ei-scanner, so let's go via this route. The proper
# handling would be to have ei-scanner be the entry point for a ei_scanner
# module but.. well, one day we'll do that maybe.
import pytest

try:
    from eiscanner import parse, scanner, Protocol
except ImportError:
    print("Run tests from within the build directory")
    pytest.skip(allow_module_level=True)

from pathlib import Path

# set to the protocol file by meson
protofile = "@PROTOFILE@"


@pytest.fixture
def protocol_xml() -> Path:
    return Path(protofile)


@pytest.fixture
def protocol(protocol_xml: Path, component: str) -> Protocol:
    print(f"protocol for component {component}")
    return parse(protocol_xml, component)


@pytest.mark.skipif(
    protofile.startswith("@"),
    reason="Protocol XML file path invalid, run tests in the build dir",
)
class TestScanner:
    @pytest.mark.parametrize("component", ("eis", "ei", "brei"))
    def test_ei_names(self, component: str, protocol: Protocol):
        for interface in protocol.interfaces:
            assert interface.name.startswith(component)
            assert not interface.plainname.startswith(component)
            assert not interface.plainname.startswith("ei_")

        # just some manual checks
        assert "handshake" in [i.plainname for i in protocol.interfaces]
        assert "connection" in [i.plainname for i in protocol.interfaces]
        assert "button" in [i.plainname for i in protocol.interfaces]

    @pytest.mark.parametrize("component", ("ei",))
    def test_interface_arg(self, protocol: Protocol):
        intf = next((i for i in protocol.interfaces if i.name == "ei_device"))
        event = next((e for e in intf.events if e.name == "interface"))

        obj, interface_name, version = event.arguments
        assert obj.interface_arg == interface_name
        assert obj.interface_arg_for is None
        assert interface_name.interface_arg_for == obj
        assert interface_name.interface_arg is None
        assert version.interface_arg is None
        assert version.interface_arg_for is None

    def iterate_args(self, protocol: Protocol):
        for interface in protocol.interfaces:
            for request in interface.requests:
                for arg in request.arguments:
                    yield interface, request, arg
            for event in interface.events:
                for arg in event.arguments:
                    yield interface, event, arg

    @pytest.mark.parametrize("component", ("ei",))
    def test_versione_arg(self, protocol: Protocol):
        for interface, message, arg in self.iterate_args(protocol):
            if arg.protocol_type == "new_id":
                if f"{interface.plainname}.{message.name}" not in [
                    "connection.sync",
                ]:
                    assert arg.version_arg is not None, (
                        f"{interface.name}.{message.name}::{arg.name}"
                    )
                    assert arg.version_arg.name == "version", (
                        f"{interface.name}.{message.name}::{arg.name}"
                    )
            elif arg.name == "version":
                if f"{interface.plainname}.{message.name}" not in [
                    "handshake.handshake_version",
                    "handshake.interface_version",
                ]:
                    assert arg.version_arg_for is not None, (
                        f"{interface.name}.{message.name}::{arg.name}"
                    )
                    assert arg.version_arg_for.name != "version", (
                        f"{interface.name}.{message.name}::{arg.name}"
                    )
            else:
                assert arg.version_arg is None, (
                    f"{interface.name}.{message.name}::{arg.name}"
                )
                assert arg.version_arg_for is None, (
                    f"{interface.name}.{message.name}::{arg.name}"
                )

    @pytest.mark.parametrize("method", ("yamlfile", "jsonfile", "string"))
    def test_cli_extra_data(self, tmp_path, method):
        result_path = tmp_path / "result"
        tmpl_path = tmp_path / "template"
        with open(tmpl_path, "w") as template:
            template.write(">{{extra.foo}}<")

        if method == "yamlfile":
            extra_path = tmp_path / "extra_data.yml"
            with open(extra_path, "w") as extra_data:
                extra_data.write("foo: 'yes'")
            extra_data_arg = f"--jinja-extra-data-file={extra_path}"
        elif method == "jsonfile":
            extra_path = tmp_path / "extra_data.json"
            with open(extra_path, "w") as extra_data:
                extra_data.write('{"foo": "yes"}')
            extra_data_arg = f"--jinja-extra-data-file={extra_path}"
        elif method == "string":
            extra_data = '{"foo": "yes"}'
            extra_data_arg = f"--jinja-extra-data={extra_data}"
        else:
            pytest.fail(f"Unsupported method {method}")

        try:
            scanner(
                [
                    f"--output={result_path}",
                    extra_data_arg,
                    protofile,
                    str(tmpl_path),
                ]
            )
        except SystemExit as e:
            pytest.fail(reason=f"Unexpected system exit code {e}")

        assert result_path.exists()
        with open(result_path) as fd:
            result = fd.read()
            assert result == ">yes<"