scripts: gconv_strip: process gconv-modules.d
New glibc versions moved most gconv module information into a
gconv-modules-extra.conf file in gconv-modules.d [1]. gconv_strip
currently only looks at the gconv-modules file. As a result,
gconv_strip isn't actually stripping much right now.
This change updates gconv_strip to search for additional files in
gconv-modules.d and process them in the exact same way as it processes
the gconv-modules file.
[1]: https://sourceware.org/git/?p=glibc.git;a=blob;f=NEWS;h=f976abccbd6ffe3c2d25b6d22bc9e042ab394fab;hb=7f079fdc16e88ebb8020e17b2fd900e8924da29a#l775
BUG=b:277779682
TEST=build a tatl image; check /usr/lib64/gconv for removed modules
Change-Id: Idce5cf6d4898e41759989f757e719ae63bbdebdd
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/chromite/+/4679252
Tested-by: Robert Kolchmeyer <rkolchmeyer@google.com>
Commit-Queue: Robert Kolchmeyer <rkolchmeyer@google.com>
Reviewed-by: Mike Frysinger <vapier@chromium.org>
Reviewed-by: Alex Klein <saklein@chromium.org>
diff --git a/scripts/gconv_strip_unittest.py b/scripts/gconv_strip_unittest.py
index 4d4048b..e633c90 100644
--- a/scripts/gconv_strip_unittest.py
+++ b/scripts/gconv_strip_unittest.py
@@ -2,8 +2,16 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-"""Test gconv_strip."""
+"""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
@@ -14,7 +22,7 @@
pytestmark = cros_test_lib.pytestmark_inside_only
-class GconvStriptTest(cros_test_lib.MockTempDirTestCase):
+class GconvStripTest(cros_test_lib.MockTempDirTestCase):
"""Tests for gconv_strip script."""
def testMultipleStringMatch(self):
@@ -43,7 +51,9 @@
"""
osutils.WriteFile(tmp_gconv_module, data)
- gmods = gconv_strip.GconvModules(tmp_gconv_module)
+ gmods = gconv_strip.GconvModules(
+ tmp_gconv_module, os.path.dirname(tmp_gconv_module)
+ )
self.assertEqual(
gmods.Load(),
[
@@ -81,3 +91,81 @@
content = osutils.ReadFile(tmp_gconv_module)
self.assertEqual(content, expected)
+
+ def testGconvStrip(self):
+ """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):
+ 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)