274 lines
11 KiB
Python
274 lines
11 KiB
Python
import os
|
|
import json
|
|
import unittest
|
|
from unittest 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": "sdl2_dist",
|
|
"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):
|
|
"""
|
|
An inherited class of `unittest.TestCase`to test the module
|
|
:mod:`~pythonforandroid.distribution`.
|
|
"""
|
|
|
|
TEST_ARCH = 'armeabi-v7a'
|
|
|
|
def setUp(self):
|
|
"""Configure a :class:`~pythonforandroid.build.Context` so we can
|
|
perform our unittests"""
|
|
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"]),
|
|
archs=[self.TEST_ARCH],
|
|
**kwargs
|
|
)
|
|
|
|
def tearDown(self):
|
|
"""Here we make sure that we reset a possible bootstrap created in
|
|
`setUp_distribution_with_bootstrap`"""
|
|
self.ctx.bootstrap = None
|
|
|
|
def test_properties(self):
|
|
"""Test that some attributes has the expected result (for now, we check
|
|
that `__repr__` and `__str__` return the proper values"""
|
|
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):
|
|
"""Test that method
|
|
:meth:`~pythonforandroid.distribution.Distribution.folder_exist` is
|
|
called once with the proper arguments."""
|
|
|
|
mock_exists.return_value = False
|
|
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):
|
|
"""Test that method
|
|
:meth:`~pythonforandroid.distribution.Distribution.delete` is
|
|
called once with the proper arguments."""
|
|
self.setUp_distribution_with_bootstrap(
|
|
Bootstrap().get_bootstrap("sdl2", self.ctx)
|
|
)
|
|
self.ctx.bootstrap.distribution.delete()
|
|
mock_rmtree.assert_called_once_with(
|
|
self.ctx.bootstrap.distribution.dist_dir
|
|
)
|
|
|
|
@mock.patch("pythonforandroid.distribution.exists")
|
|
def test_get_distribution_no_name(self, mock_exists):
|
|
"""Test that method
|
|
:meth:`~pythonforandroid.distribution.Distribution.get_distribution`
|
|
returns the proper result which should `unnamed_dist_1`."""
|
|
mock_exists.return_value = False
|
|
self.ctx.bootstrap = Bootstrap().get_bootstrap("sdl2", self.ctx)
|
|
dist = Distribution.get_distribution(self.ctx, archs=[self.TEST_ARCH])
|
|
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):
|
|
"""Test that method
|
|
:meth:`~pythonforandroid.distribution.Distribution.save_info`
|
|
is called once with the proper arguments."""
|
|
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
|
|
):
|
|
"""Test that method
|
|
:meth:`~pythonforandroid.distribution.Distribution.get_distributions`
|
|
returns some expected values:
|
|
|
|
- A list of instances of class
|
|
`~pythonforandroid.distribution.Distribution
|
|
- That one of the distributions returned in the result has the
|
|
proper values (`name`, `ndk_api` and `recipes`)
|
|
"""
|
|
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_dist")
|
|
self.assertEqual(dists[0].dist_dir, "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
|
|
):
|
|
"""Test method
|
|
:meth:`~pythonforandroid.distribution.Distribution.get_distributions`
|
|
in case that `ndk_api` is not set..which should return a `None`.
|
|
"""
|
|
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)
|
|
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
|
|
):
|
|
"""Test that method
|
|
:meth:`~pythonforandroid.distribution.Distribution.get_distribution`
|
|
raises an error in case that we have some distribution already build,
|
|
with a given `name` and `ndk_api`, and we try to get another
|
|
distribution with the same `name` but different `ndk_api`.
|
|
"""
|
|
expected_dist = Distribution.get_distribution(
|
|
self.ctx,
|
|
name="test_prj",
|
|
recipes=["python3", "kivy"],
|
|
archs=[self.TEST_ARCH],
|
|
)
|
|
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):
|
|
"""Test that method
|
|
:meth:`~pythonforandroid.distribution.Distribution.get_distributions`
|
|
raises an exception of
|
|
:class:`~pythonforandroid.util.BuildInterruptingException` in case that
|
|
we supply the kwargs `extra_dist_dirs`.
|
|
"""
|
|
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):
|
|
"""Test that method
|
|
:meth:`~pythonforandroid.distribution.Distribution.get_distributions`
|
|
returns the proper
|
|
`:class:`~pythonforandroid.distribution.Distribution` in case that we
|
|
already have it build and we request the same
|
|
`:class:`~pythonforandroid.distribution.Distribution`.
|
|
"""
|
|
expected_dist = Distribution.get_distribution(
|
|
self.ctx,
|
|
name="test_prj",
|
|
recipes=["python3", "kivy"],
|
|
archs=[self.TEST_ARCH],
|
|
)
|
|
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)
|