forked from kivy/python-for-android
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_hostpython3.py
More file actions
164 lines (144 loc) · 6.88 KB
/
test_hostpython3.py
File metadata and controls
164 lines (144 loc) · 6.88 KB
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
import unittest
from os.path import join
from unittest import mock
from pythonforandroid.recipes.hostpython3 import (
HOSTPYTHON_VERSION_UNSET_MESSAGE, SETUP_DIST_NOT_FIND_MESSAGE,
)
from pythonforandroid.util import BuildInterruptingException
from tests.recipes.recipe_lib_test import RecipeCtx
class TestHostPython3Recipe(RecipeCtx, unittest.TestCase):
"""
TestCase for recipe :mod:`~pythonforandroid.recipes.hostpython3`
"""
recipe_name = "hostpython3"
def test_property__exe_name_no_version(self):
hostpython_version = self.recipe.version
self.recipe._version = None
with self.assertRaises(BuildInterruptingException) as e:
py_exe = self.recipe._exe_name # noqa: F841
self.assertEqual(e.exception.args[0], HOSTPYTHON_VERSION_UNSET_MESSAGE)
# restore recipe's version or we will get failures with other test,
# since we share `self.recipe with all the tests of the class
self.recipe._version = hostpython_version
def test_property__exe_name(self):
self.assertEqual(self.recipe._exe_name, 'python3')
def test_property_python_exe(self):
self.assertEqual(
self.recipe.python_exe,
join(self.recipe.get_path_to_python(), 'python3')
)
@mock.patch("pythonforandroid.recipes.hostpython3.Path.exists")
def test_should_build(self, mock_exists):
# test case for existing python exe which shouldn't trigger the build
mock_exists.return_value = True
self.assertFalse(self.recipe.should_build(self.arch))
# test case for existing python exe which should trigger the build
mock_exists.return_value = False
self.assertTrue(self.recipe.should_build(self.arch))
@mock.patch("pythonforandroid.util.chdir")
@mock.patch("pythonforandroid.util.makedirs")
def test_build_arch(self, mock_makedirs, mock_chdir):
"""
Test case for
:meth:`~pythonforandroid.recipes.python3.HostPython3Recipe.build_arch`,
where we simulate the build for Python 3.8+.
"""
with mock.patch(
"pythonforandroid.recipes.hostpython3.Path.exists"
) as mock_path_exists, mock.patch(
"pythonforandroid.recipes.hostpython3.sh.Command"
) as mock_sh_command, mock.patch(
"pythonforandroid.recipes.hostpython3.sh.make"
) as mock_make, mock.patch(
"pythonforandroid.recipes.hostpython3.Path.is_file"
) as mock_path_isfile, mock.patch(
"pythonforandroid.recipes.hostpython3.sh.cp"
) as mock_sh_cp:
# here we simulate the expected behaviour for Python 3.8+
mock_path_exists.side_effect = [
False, # "config.status" not exists, so we trigger.configure
False, # "Modules/Setup.dist" shouldn't exist (3.8+ case)
True, # "Modules/Setup" exists, so we skip raise exception
]
self.recipe.build_arch(self.arch)
# make sure that the mocked methods are actually called
mock_path_exists.assert_called()
recipe_src = self.recipe.get_build_dir(self.arch.arch)
self.assertIn(
mock.call(f"{recipe_src}/configure"),
mock_sh_command.mock_calls,
)
mock_make.assert_called()
exe = join(self.recipe.get_path_to_python(), 'python.exe')
mock_path_isfile.assert_called()
self.assertEqual(mock_sh_cp.call_count, 1)
mock_call_args, mock_call_kwargs = mock_sh_cp.call_args_list[0]
self.assertEqual(mock_call_args[0], exe)
self.assertEqual(mock_call_args[1], self.recipe.python_exe)
mock_makedirs.assert_called()
mock_chdir.assert_called()
@mock.patch("pythonforandroid.util.chdir")
@mock.patch("pythonforandroid.util.makedirs")
def test_build_arch_python_lower_than_3_8(self, mock_makedirs, mock_chdir):
"""
Test case for
:meth:`~pythonforandroid.recipes.python3.HostPython3Recipe.build_arch`,
where we simulate a Python 3.7 build. Here we copy an extra file:
- Modules/Setup.dist -> Modules/Setup.
.. note:: We omit some checks because we already dit that at
`test_build_arch`. Also we skip configure command for the
same reason.
"""
with mock.patch(
"pythonforandroid.recipes.hostpython3.Path.exists"
) as mock_path_exists, mock.patch(
"pythonforandroid.recipes.hostpython3.sh.make"
) as mock_make, mock.patch(
"pythonforandroid.recipes.hostpython3.Path.is_file"
) as mock_path_isfile, mock.patch(
"pythonforandroid.recipes.hostpython3.sh.cp"
) as mock_sh_cp:
mock_path_exists.side_effect = [
True, # simulate that "config.status" exists to skip configure
True, # "Modules/Setup.dist" exist for Python 3.7
True, # "Modules/Setup" exists...we skip raise exception
]
self.recipe.build_arch(self.arch)
build_dir = join(
self.recipe.get_build_dir(self.arch.arch), self.recipe.build_subdir
)
# we expect two calls to copy command, The one described below and the
# copy of the python binary which already chechet at `test_build_arch`.
self.assertEqual(mock_sh_cp.call_count, 2)
mock_call_args, mock_call_kwargs = mock_sh_cp.call_args_list[0]
self.assertEqual(mock_call_args[0], "Modules/Setup.dist")
self.assertEqual(mock_call_args[1], join(build_dir, "Modules/Setup"))
mock_path_exists.assert_called()
mock_make.assert_called()
mock_path_isfile.assert_called()
mock_makedirs.assert_called()
mock_chdir.assert_called()
@mock.patch("pythonforandroid.util.chdir")
@mock.patch("pythonforandroid.util.makedirs")
def test_build_arch_setup_dist_exception(self, mock_makedirs, mock_chdir):
"""
Test case for
:meth:`~pythonforandroid.recipes.python3.HostPython3Recipe.build_arch`,
where we simulate that the sources hasn't Setup.dist file, which should
raise an exception.
.. note:: We skip configure command because already tested at
`test_build_arch`.
"""
with mock.patch(
"pythonforandroid.recipes.hostpython3.Path.exists"
) as mock_path_exists:
mock_path_exists.side_effect = [
True, # simulate that "config.status" exists to skip configure
False, # "Modules/Setup.dist" shouldn't exist (3.8+ case)
False, # "Modules/Setup" doesn't exists...raise exception
]
with self.assertRaises(BuildInterruptingException) as e:
self.recipe.build_arch(self.arch)
self.assertEqual(e.exception.args[0], SETUP_DIST_NOT_FIND_MESSAGE)
mock_makedirs.assert_called()
mock_chdir.assert_called()