File: test_plugin_system.py

package info (click to toggle)
ros2-colcon-core 0.20.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,156 kB
  • sloc: python: 10,333; makefile: 7
file content (168 lines) | stat: -rw-r--r-- 5,964 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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# Copyright 2016-2018 Dirk Thomas
# Licensed under the Apache License, Version 2.0

from unittest.mock import patch

from colcon_core.plugin_system import get_first_line_doc
from colcon_core.plugin_system import instantiate_extensions
from colcon_core.plugin_system import order_extensions_by_name
from colcon_core.plugin_system import order_extensions_by_priority
from colcon_core.plugin_system import order_extensions_grouped_by_priority
from colcon_core.plugin_system import satisfies_version
from colcon_core.plugin_system import SkipExtensionException
import pytest

from .extension_point_context import ExtensionPointContext


def test_instantiate_extensions():
    class Extension1:
        pass

    class Extension2:
        pass

    with ExtensionPointContext(extension1=Extension1, extension2=Extension2):
        # successful instantiation of extensions
        extensions = instantiate_extensions('group')
        assert 'extension1' in extensions.keys()
        assert isinstance(extensions['extension1'], Extension1)
        assert 'extension2' in extensions.keys()
        assert isinstance(extensions['extension2'], Extension2)

        # unique extension instances
        unique_extensions = instantiate_extensions(
            'group', unique_instance=True)
        assert 'extension1' in unique_extensions.keys()
        assert isinstance(unique_extensions['extension1'], Extension1)
        assert extensions['extension1'] != unique_extensions['extension1']

        # exclude extension names
        extensions = instantiate_extensions(
            'group', exclude_names=['extension1'])
        assert 'extension1' not in extensions.keys()
        assert 'extension2' in extensions.keys()


def test_instantiate_extensions_exception():
    class ExtensionRaisingException:

        def __init__(self):
            raise Exception('extension raising exception')

    class ExtensionSkipExtensionException:

        def __init__(self):
            raise SkipExtensionException(
                'extension raising skip extension exception')

    with ExtensionPointContext(
        exception=ExtensionRaisingException,
        skip_extension_exception=ExtensionSkipExtensionException
    ):
        with patch('colcon_core.plugin_system.logger.error') as error:
            with patch('colcon_core.plugin_system.logger.info') as info:
                extensions = instantiate_extensions('group')

                # the entry point raising an exception different than a skip
                # extension exception results in an error message in the log
                assert error.call_count == 1
                assert len(error.call_args[0]) == 1
                assert "Exception instantiating extension 'group.exception'" \
                    in error.call_args[0][0]
                assert 'extension raising exception' in error.call_args[0][0]

                # the entry point raising a skip extension exception results in
                # an info message in the log
                assert info.call_count == 1
                assert len(info.call_args[0]) == 1
                assert "Skipping extension 'group.skip_extension_exception'" \
                    in info.call_args[0][0]
                assert 'extension raising skip extension exception' \
                    in info.call_args[0][0]
        # neither of the entry points was loaded successfully
        assert extensions == {}


class ExtensionA:
    PRIORITY = 100


class ExtensionB:
    PRIORITY = 100


class ExtensionC:
    PRIORITY = 110


def test_order_extensions_by_name():
    with ExtensionPointContext(foo=ExtensionA, bar=ExtensionB, baz=ExtensionC):
        extensions = instantiate_extensions('group')
    # ensure correct order based on name
    ordered_extensions = order_extensions_by_name(extensions)
    assert list(ordered_extensions.keys()) == ['bar', 'baz', 'foo']


def test_order_extensions_by_priority():
    with ExtensionPointContext(foo=ExtensionA, bar=ExtensionB, baz=ExtensionC):
        extensions = instantiate_extensions('group')
    # ensure correct order based on priority
    ordered_extensions = order_extensions_by_priority(extensions)
    assert list(ordered_extensions.keys()) == ['baz', 'bar', 'foo']


def test_order_extensions_grouped_by_priority():
    with ExtensionPointContext(foo=ExtensionA, bar=ExtensionB, baz=ExtensionC):
        extensions = instantiate_extensions('group')
    # ensure correct order based on priority
    grouped_extensions = order_extensions_grouped_by_priority(extensions)
    assert list(grouped_extensions.keys()) == [110, 100]
    # ensure correct order in each priority group based on name
    assert list(grouped_extensions[110].keys()) == ['baz']
    assert list(grouped_extensions[100].keys()) == ['bar', 'foo']


def test_get_first_line_doc():
    def single_line_doc():
        """Single line."""
    assert get_first_line_doc(single_line_doc) == 'Single line'

    def multi_line_doc():  # noqa: D400
        """
        First line.

        Second line.
        """
    assert get_first_line_doc(multi_line_doc) == 'First line'

    def no_doc():
        pass  # pragma: no cover
    assert get_first_line_doc(no_doc) == ''

    def whitespace_doc():
        """ """  # noqa: D419
    assert get_first_line_doc(whitespace_doc) == ''

    def empty_lines_doc():
        """
        """  # noqa: D419
    assert get_first_line_doc(empty_lines_doc) == ''


def test_satisfies_version():
    satisfies_version('1.2.3', '^1')
    satisfies_version('1.2.3', '^1.1')

    with pytest.raises(RuntimeError) as e:
        satisfies_version('1.0.3', '^1.1')
    assert 'too old' in str(e.value)

    with pytest.raises(RuntimeError) as e:
        satisfies_version('2.0.0', '^1.2')
    assert 'newer' in str(e.value)

    # different semantic for version numbers before 1.0
    with pytest.raises(RuntimeError) as e:
        satisfies_version('0.2.3', '^0.1')
    assert 'newer' in str(e.value)