| # Copyright 2018 The ChromiumOS Authors |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| """Test gconv_strip. |
| |
| To run these tests, do the following inside the chroot: |
| $ pytest -c /dev/null scripts/gconv_strip_unittest.py |
| |
| Explicitly using an empty pytest config is necessary because chromite's |
| pytest.ini assumes pytest-xdist is installed, which it is not inside the chroot. |
| """ |
| |
| import glob |
| import os |
| |
| from chromite.lib import cros_test_lib |
| from chromite.lib import osutils |
| from chromite.scripts import gconv_strip |
| |
| |
| pytestmark = cros_test_lib.pytestmark_inside_only |
| |
| |
| class GconvStripTest(cros_test_lib.MockTempDirTestCase): |
| """Tests for gconv_strip script.""" |
| |
| def testMultipleStringMatch(self) -> None: |
| self.assertEqual( |
| gconv_strip.MultipleStringMatch( |
| [b"hell", b"a", b"z", b"k", b"spec"], |
| b"hello_from a very special place", |
| ), |
| [True, True, False, False, True], |
| ) |
| |
| def testModuleRewrite(self) -> None: |
| tmp_gconv_module = os.path.join(self.tempdir, "gconv-modules") |
| |
| data = """ |
| # from to module cost |
| alias FOO charset_foo |
| alias BAR charset_bar |
| module charset_foo charset_bar UNUSED_MODULE |
| |
| # from to module cost |
| alias CHAR_A charset_A |
| alias EUROPE charset_B |
| module charset_A charset_B USED_MODULE |
| module charset_foo charset_A USED_MODULE |
| """ |
| osutils.WriteFile(tmp_gconv_module, data) |
| |
| gmods = gconv_strip.GconvModules( |
| tmp_gconv_module, os.path.dirname(tmp_gconv_module) |
| ) |
| self.assertEqual( |
| gmods.Load(), |
| [ |
| "BAR", |
| "CHAR_A", |
| "EUROPE", |
| "FOO", |
| "charset_A", |
| "charset_B", |
| "charset_bar", |
| "charset_foo", |
| ], |
| ) |
| self.PatchObject(gconv_strip.lddtree, "ParseELF", return_value={}) |
| |
| class _StubStat: |
| """Fake for lstat.""" |
| |
| st_size = 0 |
| |
| self.PatchObject(gconv_strip.os, "lstat", return_value=_StubStat) |
| self.PatchObject(gconv_strip.os, "unlink") |
| gmods.Rewrite(["charset_A", "charset_B"], dryrun=False) |
| |
| expected = """ |
| # from to module cost |
| alias FOO charset_foo |
| |
| # from to module cost |
| alias CHAR_A charset_A |
| alias EUROPE charset_B |
| module charset_A charset_B USED_MODULE |
| module charset_foo charset_A USED_MODULE |
| """ |
| |
| content = osutils.ReadFile(tmp_gconv_module) |
| self.assertEqual(content, expected) |
| |
| def testGconvStrip(self) -> None: |
| """Tests GconvStrip end-to-end. |
| |
| Creates a fake root directory with fake gconv modules, and expects the |
| non-sticky modules to be deleted. |
| """ |
| modules_dir = os.path.join(self.tempdir, "usr", "lib64", "gconv") |
| extras_dir = os.path.join(modules_dir, "gconv-modules.d") |
| os.makedirs(extras_dir) |
| tmp_gconv_modules = os.path.join(modules_dir, "gconv-modules") |
| tmp_gconv_extras = os.path.join(extras_dir, "gconv-modules-extras.conf") |
| |
| gconv_data = """ |
| # from to module cost |
| alias UTF32// UTF-32// |
| module UTF-32// INTERNAL UTF-32 1 |
| module INTERNAL UTF-32// UTF-32 1 |
| |
| # from to module cost |
| alias UTF7// UTF-7// |
| module UTF-7// INTERNAL UTF-7 1 |
| module INTERNAL UTF-7// UTF-7 1 |
| """ |
| gconv_extras_data = """ |
| # from to module cost |
| alias UTF16// UTF-16// |
| module UTF-16// INTERNAL UTF-16 1 |
| module INTERNAL UTF-16// UTF-16 1 |
| |
| # from to module cost |
| alias EUCTW// EUC-TW// |
| alias OSF0005000a// EUC-TW// |
| module EUC-TW// INTERNAL EUC-TW 1 |
| module INTERNAL EUC-TW// EUC-TW 1 |
| """ |
| osutils.WriteFile(tmp_gconv_modules, gconv_data) |
| osutils.WriteFile(tmp_gconv_extras, gconv_extras_data) |
| for module in ["UTF-32.so", "UTF-7.so", "UTF-16.so", "EUC-TW.so"]: |
| osutils.Touch(os.path.join(modules_dir, module)) |
| |
| self.PatchObject(gconv_strip.lddtree, "ParseELF", return_value={}) |
| |
| class _StubOpts: |
| """Stub for GconvStrip args.""" |
| |
| def __init__(self, root) -> None: |
| self.root = root |
| self.dryrun = False |
| |
| gconv_strip.GconvStrip(_StubOpts(self.tempdir)) |
| |
| expected_gconv_data = """ |
| # from to module cost |
| alias UTF32// UTF-32// |
| module UTF-32// INTERNAL UTF-32 1 |
| module INTERNAL UTF-32// UTF-32 1 |
| |
| # from to module cost |
| """ |
| expected_gconv_extras_data = """ |
| # from to module cost |
| alias UTF16// UTF-16// |
| module UTF-16// INTERNAL UTF-16 1 |
| module INTERNAL UTF-16// UTF-16 1 |
| |
| # from to module cost |
| """ |
| expected_modules = ["UTF-16.so", "UTF-32.so"] |
| actual_gconv_data = osutils.ReadFile(tmp_gconv_modules) |
| actual_gconv_extras_data = osutils.ReadFile(tmp_gconv_extras) |
| actual_modules = glob.glob(os.path.join(modules_dir, "*.so")) |
| actual_modules_names = sorted( |
| os.path.basename(x) for x in actual_modules |
| ) |
| self.assertEqual(actual_gconv_data, expected_gconv_data) |
| self.assertEqual(actual_gconv_extras_data, expected_gconv_extras_data) |
| self.assertEqual(actual_modules_names, expected_modules) |