-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Add unittest for module pythonforandroid.distribution
#1847
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,216 @@ | ||
import os | ||
import json | ||
import unittest | ||
|
||
try: | ||
from unittest import mock | ||
except ImportError: | ||
# `Python 2` or lower than `Python 3.3` does not | ||
# have the `unittest.mock` module built-in | ||
import mock | ||
from pythonforandroid.bootstrap import Bootstrap | ||
from pythonforandroid.distribution import Distribution | ||
from pythonforandroid.recipe import Recipe | ||
from pythonforandroid.util import BuildInterruptingException | ||
from pythonforandroid.build import Context | ||
|
||
dist_info_data = { | ||
"dist_name": None, | ||
"bootstrap": "sdl2", | ||
"archs": ["armeabi", "armeabi-v7a", "x86", "x86_64", "arm64-v8a"], | ||
"ndk_api": 21, | ||
"use_setup_py": False, | ||
"recipes": ["hostpython3", "python3", "sdl2", "kivy", "requests"], | ||
"hostpython": "/some/fake/hostpython3", | ||
"python_version": "3.7", | ||
} | ||
|
||
|
||
class TestDistribution(unittest.TestCase): | ||
def setUp(self): | ||
self.ctx = Context() | ||
self.ctx.ndk_api = 21 | ||
self.ctx.android_api = 27 | ||
self.ctx._sdk_dir = "/opt/android/android-sdk" | ||
self.ctx._ndk_dir = "/opt/android/android-ndk" | ||
self.ctx.setup_dirs(os.getcwd()) | ||
self.ctx.recipe_build_order = [ | ||
"hostpython3", | ||
"python3", | ||
"sdl2", | ||
"kivy", | ||
] | ||
|
||
def setUp_distribution_with_bootstrap(self, bs, **kwargs): | ||
# extend the setUp by configuring a distribution, because some test | ||
# needs a distribution to be set to be properly tested | ||
self.ctx.bootstrap = bs | ||
self.ctx.bootstrap.distribution = Distribution.get_distribution( | ||
self.ctx, | ||
name=kwargs.pop("name", "test_prj"), | ||
recipes=kwargs.pop("recipes", ["python3", "kivy"]), | ||
**kwargs | ||
) | ||
|
||
def tearDown(self): | ||
self.ctx.bootstrap = None | ||
|
||
def test_properties(self): | ||
self.setUp_distribution_with_bootstrap( | ||
Bootstrap().get_bootstrap("sdl2", self.ctx) | ||
) | ||
distribution = self.ctx.bootstrap.distribution | ||
self.assertEqual(self.ctx, distribution.ctx) | ||
expected_repr = ( | ||
"<Distribution: name test_prj with recipes (python3, kivy)>" | ||
) | ||
self.assertEqual(distribution.__str__(), expected_repr) | ||
self.assertEqual(distribution.__repr__(), expected_repr) | ||
|
||
@mock.patch("pythonforandroid.distribution.exists") | ||
def test_folder_exist(self, mock_exists): | ||
|
||
self.setUp_distribution_with_bootstrap( | ||
Bootstrap().get_bootstrap("sdl2", self.ctx) | ||
) | ||
self.ctx.bootstrap.distribution.folder_exists() | ||
mock_exists.assert_called_with( | ||
self.ctx.bootstrap.distribution.dist_dir | ||
) | ||
|
||
@mock.patch("pythonforandroid.distribution.rmtree") | ||
def test_delete(self, mock_rmtree): | ||
|
||
self.setUp_distribution_with_bootstrap( | ||
Bootstrap().get_bootstrap("sdl2", self.ctx) | ||
) | ||
self.ctx.bootstrap.distribution.delete() | ||
mock_rmtree.assert_called_with( | ||
self.ctx.bootstrap.distribution.dist_dir | ||
) | ||
|
||
@mock.patch("pythonforandroid.distribution.exists") | ||
def test_get_distribution_no_name(self, mock_exists): | ||
|
||
mock_exists.return_value = False | ||
opacam marked this conversation as resolved.
Show resolved
Hide resolved
|
||
self.ctx.bootstrap = Bootstrap().get_bootstrap("sdl2", self.ctx) | ||
dist = Distribution.get_distribution(self.ctx) | ||
self.assertEqual(dist.name, "unnamed_dist_1") | ||
|
||
@mock.patch("pythonforandroid.util.chdir") | ||
@mock.patch("pythonforandroid.distribution.open", create=True) | ||
def test_save_info(self, mock_open_dist_info, mock_chdir): | ||
self.setUp_distribution_with_bootstrap( | ||
Bootstrap().get_bootstrap("sdl2", self.ctx) | ||
) | ||
self.ctx.hostpython = "/some/fake/hostpython3" | ||
self.ctx.python_recipe = Recipe.get_recipe("python3", self.ctx) | ||
self.ctx.python_modules = ["requests"] | ||
mock_open_dist_info.side_effect = [ | ||
mock.mock_open(read_data=json.dumps(dist_info_data)).return_value | ||
] | ||
self.ctx.bootstrap.distribution.save_info("/fake_dir") | ||
mock_open_dist_info.assert_called_once_with("dist_info.json", "w") | ||
mock_open_dist_info.reset_mock() | ||
|
||
@mock.patch("pythonforandroid.distribution.open", create=True) | ||
@mock.patch("pythonforandroid.distribution.exists") | ||
@mock.patch("pythonforandroid.distribution.glob.glob") | ||
def test_get_distributions( | ||
self, mock_glob, mock_exists, mock_open_dist_info | ||
): | ||
self.setUp_distribution_with_bootstrap( | ||
Bootstrap().get_bootstrap("sdl2", self.ctx) | ||
) | ||
mock_glob.return_value = ["sdl2-python3"] | ||
mock_open_dist_info.side_effect = [ | ||
mock.mock_open(read_data=json.dumps(dist_info_data)).return_value | ||
] | ||
|
||
dists = self.ctx.bootstrap.distribution.get_distributions(self.ctx) | ||
self.assertIsInstance(dists, list) | ||
self.assertEqual(len(dists), 1) | ||
self.assertIsInstance(dists[0], Distribution) | ||
self.assertEqual(dists[0].name, "sdl2-python3") | ||
self.assertEqual(dists[0].ndk_api, 21) | ||
self.assertEqual( | ||
dists[0].recipes, | ||
["hostpython3", "python3", "sdl2", "kivy", "requests"], | ||
) | ||
mock_open_dist_info.assert_called_with("sdl2-python3/dist_info.json") | ||
mock_open_dist_info.reset_mock() | ||
|
||
@mock.patch("pythonforandroid.distribution.open", create=True) | ||
@mock.patch("pythonforandroid.distribution.exists") | ||
@mock.patch("pythonforandroid.distribution.glob.glob") | ||
def test_get_distributions_error_ndk_api( | ||
self, mock_glob, mock_exists, mock_open_dist_info | ||
): | ||
dist_info_data_no_ndk_api = dist_info_data.copy() | ||
dist_info_data_no_ndk_api.pop("ndk_api") | ||
self.setUp_distribution_with_bootstrap( | ||
Bootstrap().get_bootstrap("sdl2", self.ctx) | ||
) | ||
mock_glob.return_value = ["sdl2-python3"] | ||
mock_open_dist_info.side_effect = [ | ||
mock.mock_open( | ||
read_data=json.dumps(dist_info_data_no_ndk_api) | ||
).return_value | ||
] | ||
|
||
dists = self.ctx.bootstrap.distribution.get_distributions(self.ctx) | ||
self.assertEqual(dists[0].ndk_api, None) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. just a random idea, we could also have mocked There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You are right we could do that, but I more concerned to mock the stuff that could slow down our tests (mostly file operations: copy, paste, pack, unpack, read files...) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes I just throw that idea, because I may have mocked it, just to show we're throwing a warning in this specific case. But you're covering the case anyway asserting ndk_api is None. By the way if you like self.assert you also have |
||
mock_open_dist_info.assert_called_with("sdl2-python3/dist_info.json") | ||
mock_open_dist_info.reset_mock() | ||
|
||
@mock.patch("pythonforandroid.distribution.Distribution.get_distributions") | ||
@mock.patch("pythonforandroid.distribution.exists") | ||
@mock.patch("pythonforandroid.distribution.glob.glob") | ||
def test_get_distributions_error_ndk_api_mismatch( | ||
self, mock_glob, mock_exists, mock_get_dists | ||
): | ||
expected_dist = Distribution.get_distribution( | ||
self.ctx, name="test_prj", recipes=["python3", "kivy"] | ||
) | ||
mock_get_dists.return_value = [expected_dist] | ||
mock_glob.return_value = ["sdl2-python3"] | ||
|
||
with self.assertRaises(BuildInterruptingException) as e: | ||
self.setUp_distribution_with_bootstrap( | ||
Bootstrap().get_bootstrap("sdl2", self.ctx), | ||
allow_replace_dist=False, | ||
ndk_api=22, | ||
) | ||
self.assertEqual( | ||
e.exception.args[0], | ||
"Asked for dist with name test_prj with recipes (python3, kivy)" | ||
" and NDK API 22, but a dist with this name already exists and has" | ||
" either incompatible recipes (python3, kivy) or NDK API 21", | ||
) | ||
|
||
def test_get_distributions_error_extra_dist_dirs(self): | ||
self.setUp_distribution_with_bootstrap( | ||
Bootstrap().get_bootstrap("sdl2", self.ctx) | ||
) | ||
|
||
with self.assertRaises(BuildInterruptingException) as e: | ||
self.ctx.bootstrap.distribution.get_distributions( | ||
self.ctx, extra_dist_dirs=["/fake/extra/dist_dirs"] | ||
) | ||
self.assertEqual( | ||
e.exception.args[0], | ||
"extra_dist_dirs argument to get" | ||
"_distributions is not yet implemented", | ||
) | ||
|
||
@mock.patch("pythonforandroid.distribution.Distribution.get_distributions") | ||
def test_get_distributions_possible_dists(self, mock_get_dists): | ||
expected_dist = Distribution.get_distribution( | ||
self.ctx, name="test_prj", recipes=["python3", "kivy"] | ||
) | ||
mock_get_dists.return_value = [expected_dist] | ||
self.setUp_distribution_with_bootstrap( | ||
Bootstrap().get_bootstrap("sdl2", self.ctx), name="test_prj" | ||
) | ||
dists = self.ctx.bootstrap.distribution.get_distributions(self.ctx) | ||
self.assertEqual(dists[0], expected_dist) |
Uh oh!
There was an error while loading. Please reload this page.