File: test_package_selection.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 (193 lines) | stat: -rw-r--r-- 7,746 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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# Copyright 2016-2018 Dirk Thomas
# Licensed under the Apache License, Version 2.0

from argparse import Namespace
import os
from unittest.mock import Mock
from unittest.mock import patch

from colcon_core.package_descriptor import PackageDescriptor
from colcon_core.package_selection import _add_package_selection_arguments
from colcon_core.package_selection import _check_package_selection_parameters
from colcon_core.package_selection import add_arguments
from colcon_core.package_selection import get_package_selection_extensions
from colcon_core.package_selection import get_packages
from colcon_core.package_selection import PackageSelectionExtensionPoint
from colcon_core.package_selection import select_package_decorators
import pytest

from .extension_point_context import ExtensionPointContext


class Extension1(PackageSelectionExtensionPoint):
    pass


class Extension2(PackageSelectionExtensionPoint):
    pass


def test_get_package_selection_extensions():
    with ExtensionPointContext(extension1=Extension1, extension2=Extension2):
        extensions = get_package_selection_extensions()
        assert ['extension1', 'extension2'] == list(extensions.keys())


def add_dummy_arguments(parser):
    parser.add_argument('arg')


def test__add_package_selection_arguments():
    parser = Mock()
    with ExtensionPointContext(extension1=Extension1, extension2=Extension2):
        extensions = get_package_selection_extensions()

        # invalid return value
        extensions['extension1'].add_arguments = Mock(return_value=True)
        with patch(
            'colcon_core.package_selection.add_package_discovery_arguments'
        ) as add_package_discovery_arguments:
            with patch('colcon_core.package_selection.logger.error') as error:
                add_arguments(parser)
        assert add_package_discovery_arguments.call_count == 1
        # the raised assertion is catched and results in an error message
        assert error.call_count == 1
        assert len(error.call_args[0]) == 1
        assert error.call_args[0][0].startswith(
            "Exception in package selection extension 'extension1': "
            'add_arguments() should return None\n')

        # raise exception
        extensions['extension1'].add_arguments = Mock(
            side_effect=RuntimeError('custom exception'))
        # check that arguments can be added
        extensions['extension2'].add_arguments = Mock(
            side_effect=add_dummy_arguments)
        with patch('colcon_core.package_selection.logger.error') as error:
            _add_package_selection_arguments(parser)
        assert extensions['extension2'].add_arguments.call_count == 1
        # the raised exception is catched and results in an error message
        assert error.call_count == 1
        assert len(error.call_args[0]) == 1
        assert error.call_args[0][0].startswith(
            "Exception in package selection extension 'extension1': "
            'custom exception\n')


def test_get_packages():
    args = Namespace()
    d1 = PackageDescriptor('/some/path')
    d1.name = 'one'
    d2 = PackageDescriptor('/other/path')
    d2.name = 'two'
    with patch(
        'colcon_core.package_selection.discover_packages',
        return_value=[d1, d2]
    ):
        decos = get_packages(args)
    assert len(decos) == 2
    assert decos[0].descriptor.name == 'one'
    assert decos[0].selected is True
    assert decos[1].descriptor.name == 'two'
    assert decos[1].selected is True

    d2.name = 'one'
    with patch(
        'colcon_core.package_selection.discover_packages',
        return_value=[d1, d2]
    ):
        with pytest.raises(RuntimeError) as e:
            get_packages(args)
        assert 'Duplicate package names not supported:' in str(e.value)
        assert '- one:' in str(e.value)
        assert '- {sep}some{sep}path'.format(sep=os.sep) in str(e.value)
        assert '- {sep}other{sep}path'.format(sep=os.sep) in str(e.value)


def test__check_package_selection_parameters():
    args = Mock()
    pkg_names = Mock()

    with ExtensionPointContext(extension1=Extension1, extension2=Extension2):
        extensions = get_package_selection_extensions()

        # nothing wrong with the arguments
        _check_package_selection_parameters(args, pkg_names)

        # raise exception
        extensions['extension1'].check_parameters = Mock(
            side_effect=RuntimeError('custom exception'))
        extensions['extension2'].check_parameters = Mock(return_value=None)
        with patch('colcon_core.package_selection.logger.error') as error:
            _check_package_selection_parameters(args, pkg_names)
        assert extensions['extension2'].check_parameters.call_count == 1
        # the raised exception is catched and results in an error message
        assert error.call_count == 1
        assert len(error.call_args[0]) == 1
        assert error.call_args[0][0].startswith(
            "Exception in package selection extension 'extension1': custom "
            'exception\n')

        # invalid return value
        extensions['extension1'].check_parameters = Mock(return_value=True)
        extensions['extension2'].check_parameters.reset_mock()
        with patch('colcon_core.package_selection.logger.error') as error:
            _check_package_selection_parameters(args, pkg_names)
        assert extensions['extension2'].check_parameters.call_count == 1
        # the raised assertion is catched and results in an error message
        assert error.call_count == 1
        assert len(error.call_args[0]) == 1
        assert error.call_args[0][0].startswith(
            "Exception in package selection extension 'extension1': "
            'check_parameters() should return None\n')

        # select some packages
        extensions['extension1'].check_parameters = Mock(
            side_effect=SystemExit(1))
        with pytest.raises(SystemExit):
            _check_package_selection_parameters(args, pkg_names)


def select_some_packages(*, args, decorators):
    for i, decorator in enumerate(decorators):
        decorator.selected = bool(i % 2)


def test_select_package_decorators():
    args = Mock()
    deco1 = Mock()
    deco1.selected = True
    deco2 = Mock()
    deco2.selected = True
    decos = [deco1, deco2]

    with ExtensionPointContext(extension1=Extension1, extension2=Extension2):
        extensions = get_package_selection_extensions()

        # raise exception
        extensions['extension2'].select_packages = Mock(return_value=None)
        with patch('colcon_core.package_selection.logger.error') as error:
            select_package_decorators(args, decos)
        # the raised exception is catched and results in an error message
        assert error.call_count == 1
        assert len(error.call_args[0]) == 1
        assert error.call_args[0][0].startswith(
            "Exception in package selection extension 'extension1': \n")

        # invalid return value
        extensions['extension1'].select_packages = Mock(return_value=True)
        with patch('colcon_core.package_selection.logger.error') as error:
            select_package_decorators(args, decos)
        # the raised assertion is catched and results in an error message
        assert error.call_count == 1
        assert len(error.call_args[0]) == 1
        assert error.call_args[0][0].startswith(
            "Exception in package selection extension 'extension1': "
            'select_packages() should return None\n')

        # select some packages
        extensions['extension1'].select_packages = Mock(
            side_effect=select_some_packages)
        select_package_decorators(args, decos)
        assert not deco1.selected
        assert deco2.selected