FreeCAD

Форк
0
/
test_dependency_installer.py 
201 строка · 8.3 Кб
1
# SPDX-License-Identifier: LGPL-2.1-or-later
2
# ***************************************************************************
3
# *                                                                         *
4
# *   Copyright (c) 2022 FreeCAD Project Association                        *
5
# *                                                                         *
6
# *   This file is part of FreeCAD.                                         *
7
# *                                                                         *
8
# *   FreeCAD is free software: you can redistribute it and/or modify it    *
9
# *   under the terms of the GNU Lesser General Public License as           *
10
# *   published by the Free Software Foundation, either version 2.1 of the  *
11
# *   License, or (at your option) any later version.                       *
12
# *                                                                         *
13
# *   FreeCAD is distributed in the hope that it will be useful, but        *
14
# *   WITHOUT ANY WARRANTY; without even the implied warranty of            *
15
# *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      *
16
# *   Lesser General Public License for more details.                       *
17
# *                                                                         *
18
# *   You should have received a copy of the GNU Lesser General Public      *
19
# *   License along with FreeCAD. If not, see                               *
20
# *   <https://www.gnu.org/licenses/>.                                      *
21
# *                                                                         *
22
# ***************************************************************************
23

24
import functools
25
import os
26
import subprocess
27
import tempfile
28
from time import sleep
29
import unittest
30

31
from addonmanager_dependency_installer import DependencyInstaller
32

33

34
class CompleteProcessMock(subprocess.CompletedProcess):
35
    def __init__(self):
36
        super().__init__(["fake_arg"], 0)
37
        self.stdout = "Mock subprocess call stdout result"
38

39

40
class SubprocessMock:
41
    def __init__(self):
42
        self.arg_log = []
43
        self.called = False
44
        self.call_count = 0
45
        self.delay = 0
46
        self.succeed = True
47

48
    def subprocess_interceptor(self, args):
49
        self.arg_log.append(args)
50
        self.called = True
51
        self.call_count += 1
52
        sleep(self.delay)
53
        if self.succeed:
54
            return CompleteProcessMock()
55
        raise subprocess.CalledProcessError(1, " ".join(args), "Unit test mock output")
56

57

58
class FakeFunction:
59
    def __init__(self):
60
        self.called = False
61
        self.call_count = 0
62
        self.return_value = None
63
        self.arg_log = []
64

65
    def func_call(self, *args):
66
        self.arg_log.append(args)
67
        self.called = True
68
        self.call_count += 1
69
        return self.return_value
70

71

72
class TestDependencyInstaller(unittest.TestCase):
73
    """Test the dependency installation class"""
74

75
    def setUp(self):
76
        self.subprocess_mock = SubprocessMock()
77
        self.test_object = DependencyInstaller([], ["required_py_package"], ["optional_py_package"])
78
        self.test_object._subprocess_wrapper = self.subprocess_mock.subprocess_interceptor
79
        self.signals_caught = []
80
        self.test_object.failure.connect(functools.partial(self.catch_signal, "failure"))
81
        self.test_object.finished.connect(functools.partial(self.catch_signal, "finished"))
82
        self.test_object.no_pip.connect(functools.partial(self.catch_signal, "no_pip"))
83
        self.test_object.no_python_exe.connect(
84
            functools.partial(self.catch_signal, "no_python_exe")
85
        )
86

87
    def tearDown(self):
88
        pass
89

90
    def catch_signal(self, signal_name, *_):
91
        self.signals_caught.append(signal_name)
92

93
    def test_run_no_pip(self):
94
        self.test_object._verify_pip = lambda: False
95
        self.test_object.run()
96
        self.assertIn("finished", self.signals_caught)
97

98
    def test_run_with_pip(self):
99
        ff = FakeFunction()
100
        self.test_object._verify_pip = lambda: True
101
        self.test_object._install_python_packages = ff.func_call
102
        self.test_object.run()
103
        self.assertIn("finished", self.signals_caught)
104
        self.assertTrue(ff.called)
105

106
    def test_run_with_no_packages(self):
107
        ff = FakeFunction()
108
        self.test_object._verify_pip = lambda: True
109
        self.test_object._install_python_packages = ff.func_call
110
        self.test_object.python_requires = []
111
        self.test_object.python_optional = []
112
        self.test_object.run()
113
        self.assertIn("finished", self.signals_caught)
114
        self.assertFalse(ff.called)
115

116
    def test_install_python_packages_new_location(self):
117
        ff_required = FakeFunction()
118
        ff_optional = FakeFunction()
119
        self.test_object._install_required = ff_required.func_call
120
        self.test_object._install_optional = ff_optional.func_call
121
        with tempfile.TemporaryDirectory() as td:
122
            self.test_object.location = os.path.join(td, "UnitTestLocation")
123
            self.test_object._install_python_packages()
124
            self.assertTrue(ff_required.called)
125
            self.assertTrue(ff_optional.called)
126
            self.assertTrue(os.path.exists(self.test_object.location))
127

128
    def test_install_python_packages_existing_location(self):
129
        ff_required = FakeFunction()
130
        ff_optional = FakeFunction()
131
        self.test_object._install_required = ff_required.func_call
132
        self.test_object._install_optional = ff_optional.func_call
133
        with tempfile.TemporaryDirectory() as td:
134
            self.test_object.location = td
135
            self.test_object._install_python_packages()
136
            self.assertTrue(ff_required.called)
137
            self.assertTrue(ff_optional.called)
138

139
    def test_verify_pip_no_python(self):
140
        self.test_object._get_python = lambda: None
141
        should_continue = self.test_object._verify_pip()
142
        self.assertFalse(should_continue)
143
        self.assertEqual(len(self.signals_caught), 0)
144

145
    def test_verify_pip_no_pip(self):
146
        sm = SubprocessMock()
147
        sm.succeed = False
148
        self.test_object._subprocess_wrapper = sm.subprocess_interceptor
149
        self.test_object._get_python = lambda: "fake_python"
150
        result = self.test_object._verify_pip()
151
        self.assertFalse(result)
152
        self.assertIn("no_pip", self.signals_caught)
153

154
    def test_verify_pip_with_pip(self):
155
        sm = SubprocessMock()
156
        sm.succeed = True
157
        self.test_object._subprocess_wrapper = sm.subprocess_interceptor
158
        self.test_object._get_python = lambda: "fake_python"
159
        result = self.test_object._verify_pip()
160
        self.assertTrue(result)
161
        self.assertNotIn("no_pip", self.signals_caught)
162

163
    def test_install_required_loops(self):
164
        sm = SubprocessMock()
165
        sm.succeed = True
166
        self.test_object._subprocess_wrapper = sm.subprocess_interceptor
167
        self.test_object._get_python = lambda: "fake_python"
168
        self.test_object.python_requires = ["test1", "test2", "test3"]
169
        self.test_object._install_required("vendor_path")
170
        self.assertEqual(sm.call_count, 3)
171

172
    def test_install_required_failure(self):
173
        sm = SubprocessMock()
174
        sm.succeed = False
175
        self.test_object._subprocess_wrapper = sm.subprocess_interceptor
176
        self.test_object._get_python = lambda: "fake_python"
177
        self.test_object.python_requires = ["test1", "test2", "test3"]
178
        self.test_object._install_required("vendor_path")
179
        self.assertEqual(sm.call_count, 1)
180
        self.assertIn("failure", self.signals_caught)
181

182
    def test_install_optional_loops(self):
183
        sm = SubprocessMock()
184
        sm.succeed = True
185
        self.test_object._subprocess_wrapper = sm.subprocess_interceptor
186
        self.test_object._get_python = lambda: "fake_python"
187
        self.test_object.python_optional = ["test1", "test2", "test3"]
188
        self.test_object._install_optional("vendor_path")
189
        self.assertEqual(sm.call_count, 3)
190

191
    def test_install_optional_failure(self):
192
        sm = SubprocessMock()
193
        sm.succeed = False
194
        self.test_object._subprocess_wrapper = sm.subprocess_interceptor
195
        self.test_object._get_python = lambda: "fake_python"
196
        self.test_object.python_optional = ["test1", "test2", "test3"]
197
        self.test_object._install_optional("vendor_path")
198
        self.assertEqual(sm.call_count, 3)
199

200
    def test_run_pip(self):
201
        pass
202

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.