def test_get_bootstraps_from_recipes(self):
        """A test which will initialize a bootstrap and will check if the
        method :meth:`~pythonforandroid.bootstrap.Bootstrap.
        get_bootstraps_from_recipes` returns the expected values
        """
        recipes_sdl2 = {"sdl2", "python3", "kivy"}
        bs = Bootstrap().get_bootstrap_from_recipes(recipes_sdl2, self.ctx)

        self.assertEqual(bs.name, "sdl2")

        # test wrong recipes
        wrong_recipes = {"python2", "python3", "pyjnius"}
        bs = Bootstrap().get_bootstrap_from_recipes(wrong_recipes, self.ctx)
        self.assertIsNone(bs)
Esempio n. 2
0
    def test_bootstrap_strip(
        self,
        mock_find_executable,
        mock_glob,
        mock_ensure_dir,
        mock_sh_command,
        mock_sh_print,
    ):
        mock_find_executable.return_value = os.path.join(
            self.ctx._ndk_dir,
            f"toolchains/llvm/prebuilt/{system().lower()}-x86_64/bin/clang",
        )
        mock_glob.return_value = [
            os.path.join(self.ctx._ndk_dir, "toolchains", "llvm")
        ]
        # prepare arch, bootstrap, distribution and PythonRecipe
        arch = ArchARMv7_a(self.ctx)
        bs = Bootstrap().get_bootstrap(self.bootstrap_name, self.ctx)
        self.setUp_distribution_with_bootstrap(bs)
        self.ctx.python_recipe = Recipe.get_recipe("python3", self.ctx)

        # test that strip_libraries runs with a fake distribution
        bs.strip_libraries(arch)

        mock_find_executable.assert_called_once()
        self.assertEqual(
            mock_find_executable.call_args[0][0],
            mock_find_executable.return_value,
        )
        mock_sh_command.assert_called_once_with("arm-linux-androideabi-strip")
        # check that the other mocks we made are actually called
        mock_ensure_dir.assert_called()
        mock_sh_print.assert_called()
    def test_bootstrap_strip(
        self,
        mock_find_executable,
        mock_ensure_dir,
        mock_sh_command,
        mock_sh_print,
    ):
        mock_find_executable.return_value = "arm-linux-androideabi-gcc"
        # prepare arch, bootstrap, distribution and PythonRecipe
        arch = ArchARMv7_a(self.ctx)
        bs = Bootstrap().get_bootstrap(self.bootstrap_name, self.ctx)
        self.setUp_distribution_with_bootstrap(bs)
        self.ctx.python_recipe = Recipe.get_recipe("python3", self.ctx)

        # test that strip_libraries runs with a fake distribution
        bs.strip_libraries(arch)

        mock_find_executable.assert_called_once()
        self.assertEqual(
            mock_find_executable.call_args[0][0],
            mock_find_executable.return_value,
        )
        mock_sh_command.assert_called_once_with("arm-linux-androideabi-strip")
        # check that the other mocks we made are actually called
        mock_ensure_dir.assert_called()
        mock_sh_print.assert_called()
Esempio n. 4
0
    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()
Esempio n. 5
0
    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"],
            arch_name=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_bootstrap_fry_eggs(self, mock_isdir, mock_sh_mv, mock_sh_rm,
                                mock_listdir):
        mock_listdir.return_value = [
            "jnius",
            "kivy",
            "Kivy-1.11.0.dev0-py3.7.egg-info",
            "pyjnius-1.2.1.dev0-py3.7.egg",
        ]

        # prepare bootstrap, context and distribution
        bs = Bootstrap().get_bootstrap(self.bootstrap_name, self.ctx)
        self.setUp_distribution_with_bootstrap(bs)

        # test that fry_eggs runs with a fake distribution
        site_packages = os.path.join(bs.dist_dir, "_python_bundle",
                                     "_python_bundle")
        bs.fry_eggs(site_packages)

        mock_listdir.assert_has_calls([
            mock.call(site_packages),
            mock.call(
                os.path.join(site_packages, "pyjnius-1.2.1.dev0-py3.7.egg")),
        ])
        self.assertEqual(mock_sh_rm.call_args[0][1],
                         "pyjnius-1.2.1.dev0-py3.7.egg")
        # check that the other mocks we made are actually called
        mock_isdir.assert_called()
        mock_sh_mv.assert_called()
Esempio n. 7
0
 def setUp(self):
     """
     Initialize a Context with a Bootstrap and a Distribution to properly
     test an library recipe, to do so we reuse `BaseClassSetupBootstrap`
     """
     super(TestLibraryRecipe, self).setUp()
     self.ctx.bootstrap = Bootstrap().get_bootstrap('sdl2', self.ctx)
     self.setUp_distribution_with_bootstrap(self.ctx.bootstrap)
    def test_run_distribute(self, *args):
        # prepare bootstrap
        bs = Bootstrap().get_bootstrap(self.bootstrap_name, self.ctx)
        self.ctx.bootstrap = bs

        # test dist_dir error
        with self.assertRaises(SystemExit) as e:
            bs.run_distribute()
        self.assertEqual(e.exception.args[0], 1)
Esempio n. 9
0
 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,
                                          arch_name=self.TEST_ARCH)
     self.assertEqual(dist.name, "unnamed_dist_1")
    def test_prepare_dist_dir(self, mock_ensure_dir):
        """A test which will initialize a bootstrap and will check if the
        method :meth:`~pythonforandroid.bootstrap.Bootstrap.prepare_dist_dir`
        successfully calls once the method `endure_dir`
        """
        bs = Bootstrap().get_bootstrap("sdl2", self.ctx)

        bs.prepare_dist_dir("fake_name")
        mock_ensure_dir.assert_called_once_with(bs.dist_dir)
Esempio n. 11
0
 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)
 def setUp(self):
     """
     Initialize a Context with a Bootstrap and a Distribution to properly
     test a recipe which depends on android's STL library, to do so we reuse
     `BaseClassSetupBootstrap`
     """
     super().setUp()
     self.ctx.bootstrap = Bootstrap().get_bootstrap('sdl2', self.ctx)
     self.setUp_distribution_with_bootstrap(self.ctx.bootstrap)
     self.ctx.python_recipe = Recipe.get_recipe('python3', self.ctx)
Esempio n. 13
0
 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)
 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.bootstrap = Bootstrap().get_bootstrap("sdl2", self.ctx)
     self.ctx.bootstrap.distribution = Distribution.get_distribution(
         self.ctx, name="sdl2", recipes=["python3", "kivy"])
     self.ctx.python_recipe = Recipe.get_recipe("python3", self.ctx)
Esempio n. 15
0
 def test_list_bootstraps(self):
     """A test which will initialize a bootstrap and will check if the
     method :meth:`~pythonforandroid.bootstrap.Bootstrap.list_bootstraps`
     returns the expected values, which should be: `empty", `service_only`,
     `webview` and `sdl2`
     """
     expected_bootstraps = {"empty", "service_only", "webview", "sdl2"}
     set_of_bootstraps = set(Bootstrap().list_bootstraps())
     self.assertEqual(
         expected_bootstraps, expected_bootstraps & set_of_bootstraps
     )
     self.assertEqual(len(expected_bootstraps), len(set_of_bootstraps))
Esempio n. 16
0
    def test_bootstrap_prepare_build_dir_with_java_src(
        self,
        mock_sh_rm,
        mock_sh_mkdir,
        mock_listdir,
        mock_sh_ln,
        mock_chdir,
        mock_open,
        mock_os_unlink,
        mock_os_path_exists,
        mock_os_path_isfile,
    ):
        """A test which will initialize a bootstrap and will check perform
        another test for method
        :meth:`~pythonforandroid.bootstrap.Bootstrap.prepare_build_dir`. In
        here we will simulate that we have `with_java_src` set to some value.
        """
        self.ctx.symlink_java_src = ["some_java_src"]
        mock_listdir.return_value = [
            "jnius",
            "kivy",
            "Kivy-1.11.0.dev0-py3.7.egg-info",
            "pyjnius-1.2.1.dev0-py3.7.egg",
        ]

        # prepare bootstrap
        bs = Bootstrap().get_bootstrap("sdl2", self.ctx)
        self.ctx.bootstrap = bs

        # test that prepare_build_dir runs (notice that we mock
        # any file/dir creation so we can speed up the tests)
        bs.prepare_build_dir()
        # make sure that the open command has been called only once
        mock_open.assert_called_with("project.properties", "w")

        # check that the symlink was made 4 times and that
        self.assertEqual(
            len(mock_sh_ln.call_args_list), len(mock_listdir.return_value)
        )
        for i, directory in enumerate(mock_listdir.return_value):
            self.assertTrue(
                mock_sh_ln.call_args_list[i][0][1].endswith(directory)
            )

        # check that the other mocks we made are actually called
        mock_sh_rm.assert_called()
        mock_sh_mkdir.assert_called()
        mock_chdir.assert_called()
        mock_os_unlink.assert_called()
        mock_os_path_exists.assert_called()
        mock_os_path_isfile.assert_called()
Esempio n. 17
0
 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.bootstrap = Bootstrap().get_bootstrap("sdl2", self.ctx)
     self.ctx.bootstrap.distribution = Distribution.get_distribution(
         self.ctx, name="sdl2", recipes=["python3", "kivy"])
     self.ctx.python_recipe = Recipe.get_recipe("python3", self.ctx)
     # Here we define the expected compiler, which, as per ndk >= r19,
     # should be the same for all the tests (no more gcc compiler)
     self.expected_compiler = ("/opt/android/android-ndk/toolchains/"
                               "llvm/prebuilt/linux-x86_64/bin/clang")
Esempio n. 18
0
 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()
Esempio n. 19
0
 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",
     )
Esempio n. 20
0
    def test_build_dist_dirs(self):
        """A test which will initialize a bootstrap and will check if the
        directories we set has the values that we expect. Here we test methods:

            - :meth:`~pythonforandroid.bootstrap.Bootstrap.get_build_dir`
            - :meth:`~pythonforandroid.bootstrap.Bootstrap.get_dist_dir`
            - :meth:`~pythonforandroid.bootstrap.Bootstrap.get_common_dir`
        """
        bs = Bootstrap().get_bootstrap("sdl2", self.ctx)

        self.assertTrue(
            bs.get_build_dir().endswith("build/bootstrap_builds/sdl2-python3")
        )
        self.assertTrue(bs.get_dist_dir("test_prj").endswith("dists/test_prj"))
        self.assertTrue(
            bs.get_common_dir().endswith("pythonforandroid/bootstraps/common")
        )
    def test_attributes(self):
        """A test which will initialize a bootstrap and will check if the
        values are the expected.
        """
        bs = Bootstrap().get_bootstrap("sdl2", self.ctx)
        self.assertEqual(bs.name, "sdl2")
        self.assertEqual(bs.jni_dir, "sdl2/jni")
        self.assertEqual(bs.get_build_dir_name(), "sdl2-python3")

        # test dist_dir error
        bs.distribution = None
        with self.assertRaises(SystemExit) as e:
            bs.dist_dir
        self.assertEqual(e.exception.args[0], 1)

        # test dist_dir success
        self.setUp_distribution_with_bootstrap(bs)
        self.assertTrue(bs.dist_dir.endswith("dists/test_prj"))
Esempio n. 22
0
    def test_attributes(self):
        """A test which will initialize a bootstrap and will check if the
        values are the expected.
        """
        bs = Bootstrap().get_bootstrap("sdl2", self.ctx)
        self.assertEqual(bs.name, "sdl2")
        self.assertEqual(bs.jni_dir, "sdl2/jni")
        self.assertEqual(bs.get_build_dir_name(), "sdl2-python3")

        # bs.dist_dir should raise an error if there is no distribution to query
        bs.distribution = None
        with self.assertRaises(BuildInterruptingException):
            bs.dist_dir

        # test dist_dir success
        self.setUp_distribution_with_bootstrap(bs)
        expected_folder_name = generate_dist_folder_name(
            'test_prj', [self.TEST_ARCH])
        self.assertTrue(bs.dist_dir.endswith(f"dists/{expected_folder_name}"))
Esempio n. 23
0
    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()
Esempio n. 24
0
 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"],
         arch_name=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)
    def test_bootstrap_prepare_build_dir(self, mock_os_makedirs,
                                         mock_shutil_copy, mock_chdir,
                                         mock_open):
        """A test which will initialize a bootstrap and will check if the
        method :meth:`~pythonforandroid.bootstrap.Bootstrap.prepare_build_dir`
        successfully calls the methods that we need to prepare a build dir.
        """

        # prepare bootstrap
        bs = Bootstrap().get_bootstrap("service_only", self.ctx)
        self.ctx.bootstrap = bs

        # test that prepare_build_dir runs (notice that we mock
        # any file/dir creation so we can speed up the tests)
        bs.prepare_build_dir()

        # make sure that the open command has been called only once
        mock_open.assert_called_once_with("project.properties", "w")

        # check that the other mocks we made are actually called
        mock_os_makedirs.assert_called()
        mock_shutil_copy.assert_called()
        mock_chdir.assert_called()
    def test_distribute_methods(self, mock_build_dir, mock_bs_dir, mock_glob,
                                mock_shprint):
        # prepare arch, bootstrap and distribution
        arch = ArchARMv7_a(self.ctx)
        bs = Bootstrap().get_bootstrap(self.bootstrap_name, self.ctx)
        self.setUp_distribution_with_bootstrap(bs)

        # a convenient method to reset mocks in one shot
        def reset_mocks():
            mock_glob.reset_mock()
            mock_shprint.reset_mock()
            mock_build_dir.reset_mock()
            mock_bs_dir.reset_mock()

        # test distribute_libs
        mock_glob.return_value = [
            "/fake_dir/libsqlite3.so",
            "/fake_dir/libpng16.so",
        ]
        bs.distribute_libs(arch, [self.ctx.get_libs_dir(arch.arch)])
        libs_dir = os.path.join("libs", arch.arch)
        # we expect two calls to glob/copy command via shprint
        self.assertEqual(len(mock_glob.call_args_list), 2)
        self.assertEqual(len(mock_shprint.call_args_list), 2)
        for i, lib in enumerate(mock_glob.return_value):
            self.assertEqual(
                mock_shprint.call_args_list[i],
                mock.call(sh.cp, "-a", lib, libs_dir),
            )
        mock_build_dir.assert_called()
        mock_bs_dir.assert_called_once_with(libs_dir)
        reset_mocks()

        # test distribute_javaclasses
        mock_glob.return_value = ["/fakedir/java_file.java"]
        bs.distribute_javaclasses(self.ctx.javaclass_dir)
        mock_glob.assert_called_once_with(self.ctx.javaclass_dir)
        mock_build_dir.assert_called_with(self.ctx.javaclass_dir)
        mock_bs_dir.assert_called_once_with("src")
        self.assertEqual(
            mock_shprint.call_args,
            mock.call(sh.cp, "-a", "/fakedir/java_file.java", "src"),
        )
        reset_mocks()

        # test distribute_aars
        mock_glob.return_value = ["/fakedir/file.aar"]
        bs.distribute_aars(arch)
        mock_build_dir.assert_called_with(self.ctx.aars_dir)
        # We expect three calls to shprint: unzip, cp, cp
        zip_call, kw = mock_shprint.call_args_list[0]
        self.assertEqual(zip_call[0], sh.unzip)
        self.assertEqual(zip_call[2], "/fakedir/file.aar")
        cp_java_call, kw = mock_shprint.call_args_list[1]
        self.assertEqual(cp_java_call[0], sh.cp)
        self.assertTrue(cp_java_call[2].endswith("classes.jar"))
        self.assertEqual(cp_java_call[3], "libs/file.jar")
        cp_libs_call, kw = mock_shprint.call_args_list[2]
        self.assertEqual(cp_libs_call[0], sh.cp)
        self.assertEqual(cp_libs_call[2], "/fakedir/file.aar")
        self.assertEqual(cp_libs_call[3], libs_dir)
        mock_bs_dir.assert_has_calls([mock.call("libs"), mock.call(libs_dir)])
        mock_glob.assert_called()
    def test_run_distribute(
        self,
        mock_sh_cp,
        mock_sh_rm,
        mock_listdir,
        mock_chdir,
        mock_ensure_dir,
        mock_strip_libraries,
        mock_create_python_bundle,
        mock_open_dist_files,
        mock_open_sdl2_files,
        mock_open_webview_files,
        mock_open_service_only_files,
    ):
        """
        A test for any overwritten method of
        `~pythonforandroid.bootstrap.Bootstrap.run_distribute`. Here we mock
        any file/dir operation that it could slow down our tests, and there is
        a lot to mock, because the `run_distribute` method it should take care
        of prepare all compiled files to generate the final `apk`. The targets
        of this test will be:

            - :meth:`~pythonforandroid.bootstraps.sdl2.BootstrapSdl2
              .run_distribute`
            - :meth:`~pythonforandroid.bootstraps.service_only
              .ServiceOnlyBootstrap.run_distribute`
            - :meth:`~pythonforandroid.bootstraps.webview.WebViewBootstrap
               .run_distribute`
            - :meth:`~pythonforandroid.bootstraps.empty.EmptyBootstrap.
              run_distribute`

        Here we will tests all those methods that are specific for each class.
        """
        # prepare bootstrap and distribution
        bs = Bootstrap().get_bootstrap(self.bootstrap_name, self.ctx)
        bs.build_dir = bs.get_build_dir()
        self.setUp_distribution_with_bootstrap(bs)

        self.ctx.hostpython = "/some/fake/hostpython3"
        self.ctx.python_recipe = Recipe.get_recipe("python3", self.ctx)
        self.ctx.python_modules = ["requests"]
        self.ctx.archs = [ArchARMv7_a(self.ctx)]

        bs.run_distribute()

        mock_open_dist_files.assert_called_once_with("dist_info.json", "w")
        mock_open_bootstraps = {
            "sdl2": mock_open_sdl2_files,
            "webview": mock_open_webview_files,
            "service_only": mock_open_service_only_files,
        }
        expected_open_calls = {
            "sdl2": [
                mock.call("local.properties", "w"),
                mock.call("blacklist.txt", "a"),
            ],
            "webview": [mock.call("local.properties", "w")],
            "service_only": [mock.call("local.properties", "w")],
        }
        mock_open_bs = mock_open_bootstraps[self.bootstrap_name]
        # test that the expected calls has been called
        for expected_call in expected_open_calls[self.bootstrap_name]:
            self.assertIn(expected_call, mock_open_bs.call_args_list)
        # test that the write function has been called with the expected args
        self.assertIn(
            mock.call().__enter__().write("sdk.dir=/opt/android/android-sdk"),
            mock_open_bs.mock_calls,
        )
        if self.bootstrap_name == "sdl2":
            self.assertIn(
                mock.call().__enter__().write(
                    "\nsqlite3/*\nlib-dynload/_sqlite3.so\n"),
                mock_open_bs.mock_calls,
            )

        # check that the other mocks we made are actually called
        mock_sh_rm.assert_called()
        mock_sh_cp.assert_called()
        mock_chdir.assert_called()
        mock_listdir.assert_called()
        mock_strip_libraries.assert_called()
        mock_create_python_bundle.assert_called()