localedef: Add tests-container test for --no-hard-links.

Message ID 31daeb24-f07b-23cc-bb81-5f972b90d0cd@redhat.com
State New, archived
Headers

Commit Message

Carlos O'Donell Dec. 11, 2018, 1:24 a.m. UTC
  Depends on:
https://www.sourceware.org/ml/libc-alpha/2018-12/msg00340.html

The new tests-container test verifies that when compiling
two locales (with default output directory) one with
--no-hard-links and one without the option, results in the
expected behaviour.  When --no-hard-links is used the link
counts on LC_CTYPE is 1, indicating that even thoug the two
locale are identical (though different named source files and
output direcotry) the localedef did not carry out the hard
link optimization.  Then when --no-hard-links is omitted the
localedef hard link optimization is correctly carried out and
for 2 compiled locales the link count for LC_CTYPE is 2.

Signed-off-by: Carlos O'Donell <carlos@redhat.com>
---
 ChangeLog                                     |   9 ++
 localedata/Makefile                           |   2 +
 localedata/tst-localedef-hardlinks.c          | 111 ++++++++++++++++++
 .../postclean.req                             |   0
 .../tst-localedef-hardlinks.root/test1_locale |   3 +
 .../tst-localedef-hardlinks.root/test2_locale |   3 +
 .../tst-localedef-hardlinks.script            |  14 +++
 7 files changed, 142 insertions(+)
 create mode 100644 localedata/tst-localedef-hardlinks.c
 create mode 100644 localedata/tst-localedef-hardlinks.root/postclean.req
 create mode 100644 localedata/tst-localedef-hardlinks.root/test1_locale
 create mode 100644 localedata/tst-localedef-hardlinks.root/test2_locale
 create mode 100644 localedata/tst-localedef-hardlinks.root/tst-localedef-hardlinks.script
  

Patch

diff --git a/ChangeLog b/ChangeLog
index e538327f59..539a377b8a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@ 
+2018-12-10  Carlos O'Donell  <carlos@redhat.com>
+
+	* localedata/Makefile (tests-container): Add tst-localedef-hardlinks.
+	* localedata/tst-localedef-hardlinks.c: New file.
+	* localedata/tst-localedef-hardlinks.root/postclean.req: Likewise.
+	* localedata/tst-localedef-hardlinks.root/test1_locale: Likewise.
+	* localedata/tst-localedef-hardlinks.root/test2_locale: Likewise.
+	* localedata/tst-localedef-hardlinks.root/tst-localedef-hardlinks.script: Likewise
+
 2018-12-10  Carlos O'Donell  <carlos@redhat.com>
 
 	* support/Makefile (CFLAGS-support_paths.c): Add -DI18NDIR_PATH
diff --git a/localedata/Makefile b/localedata/Makefile
index b245f0ff54..ecc0bd611e 100644
--- a/localedata/Makefile
+++ b/localedata/Makefile
@@ -165,6 +165,8 @@  tests-special += $(objpfx)mtrace-tst-leaks.out
 endif
 endif
 endif
+tests-container = \
+			tst-localedef-hardlinks
 
 # Files to install.
 install-others := $(addprefix $(inst_i18ndir)/, \
diff --git a/localedata/tst-localedef-hardlinks.c b/localedata/tst-localedef-hardlinks.c
new file mode 100644
index 0000000000..48baa425cd
--- /dev/null
+++ b/localedata/tst-localedef-hardlinks.c
@@ -0,0 +1,111 @@ 
+/* Test --no-hard-links option to localedef.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* The test is designed to run in a container and execute localedef
+   once without --no-hard-links, verify that there are 2 hard links to
+   LC_CTYPE, and then run again *with* --no-hard-links and verify there
+   are no hard links and link counts remain at 1.  The expectation here
+   is that LC_CTYPE is identical for both locales because they are same
+   empty locale but with a different name.  We use tests-container in
+   this test because the hard link optimziation is only carried out for
+   the default locale installation directory, and to write to that we
+   need write access to that directory, enabled by 'su' via
+   tests-container framework.  */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <support/check.h>
+#include <support/support.h>
+#include <support/xunistd.h>
+
+/* Each step of the test compiles a locale to output, and has an expected
+   link count for LC_CTYPE.  */
+struct step_data
+{
+  const char *compile;
+  const char *output;
+  int expected_link;
+};
+
+/* Carry out one step of compile and test for link count.  */
+void
+compile_and_test_link (struct step_data step)
+{
+  int ret;
+  struct stat64 locale;
+  char *output;
+
+  ret = system (step.compile);
+
+  /* The source locales are empty and so localedef exists with error
+     code 1 from the warnings, but that's OK.  We want to look at
+     the produced files and their link counts only.  */
+  if (WEXITSTATUS(ret) == 1)
+    {
+      output = xasprintf ("%s/%s", support_complocaledir_prefix, step.output);
+      xstat (output, &locale);
+      free (output);
+      TEST_COMPARE (locale.st_nlink, step.expected_link);
+    }
+  else
+    FAIL_EXIT1 ("system: %d\n", ret);
+
+}
+
+#define TEST1DIR "test1_locale.dir"
+#define TEST2DIR "test2_locale.dir"
+
+/* The whole test has 4 steps described below.  */
+static struct step_data step[] = {
+  { "/usr/bin/localedef --no-archive -i /test1_locale " TEST1DIR,
+    TEST1DIR "/LC_CTYPE", 1 },
+  { "/usr/bin/localedef --no-archive -i /test2_locale " TEST2DIR,
+    TEST2DIR "/LC_CTYPE", 2 },
+  { "/usr/bin/localedef --no-archive " \
+    "--no-hard-links -i /test1_locale " TEST1DIR,
+    TEST1DIR "/LC_CTYPE", 1 },
+  { "/usr/bin/localedef --no-archive " \
+    "--no-hard-links -i /test2_locale " TEST1DIR,
+    TEST2DIR "/LC_CTYPE", 1 },
+};
+
+static int
+do_test (void)
+{
+  /* Compile the first locale.  */
+  compile_and_test_link (step[0]);
+
+  /* This time around we should have link counts of 2 for the second
+     linked locale since categories are identical.  */
+  compile_and_test_link (step[1]);
+
+  /* Again with --no-hard-links (link count is always one).  */
+  compile_and_test_link (step[2]);
+
+  /* Again with --no-hard-links, and the link count must remain 1.  */
+  compile_and_test_link (step[3]);
+
+  /* Tested without and with --no-hard-links and link counts were
+     consistent.  */
+  return EXIT_SUCCESS;
+}
+
+#include <support/test-driver.c>
diff --git a/localedata/tst-localedef-hardlinks.root/postclean.req b/localedata/tst-localedef-hardlinks.root/postclean.req
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/localedata/tst-localedef-hardlinks.root/test1_locale b/localedata/tst-localedef-hardlinks.root/test1_locale
new file mode 100644
index 0000000000..acaa15e288
--- /dev/null
+++ b/localedata/tst-localedef-hardlinks.root/test1_locale
@@ -0,0 +1,3 @@ 
+comment_char %
+escape_char /
+% Empty test1 locale.  Must be identical to test2 locale.
diff --git a/localedata/tst-localedef-hardlinks.root/test2_locale b/localedata/tst-localedef-hardlinks.root/test2_locale
new file mode 100644
index 0000000000..a46fed97f2
--- /dev/null
+++ b/localedata/tst-localedef-hardlinks.root/test2_locale
@@ -0,0 +1,3 @@ 
+comment_char %
+escape_char /
+% Empty test2 locale.  Must be identical to test1 locale.
diff --git a/localedata/tst-localedef-hardlinks.root/tst-localedef-hardlinks.script b/localedata/tst-localedef-hardlinks.root/tst-localedef-hardlinks.script
new file mode 100644
index 0000000000..2f33d333a6
--- /dev/null
+++ b/localedata/tst-localedef-hardlinks.root/tst-localedef-hardlinks.script
@@ -0,0 +1,14 @@ 
+# Need root to write to $i18ndir and $complocaledir when running localedef.
+su
+
+# A default install compresses charmaps with gzip.  This means that to
+# load a charmap you need gzip installed.  To avoid this we copy the
+# uncompressed charmap into place and use that instead.  This minimizes
+# the rootfs requirements.
+cp $S/localedata/charmaps/ANSI_X3.4-1968 $i18ndir/charmaps/ANSI_X3.4-1968
+
+# Create both compiled locale directories, this is required
+# by localedef, it won't create new directories to install
+# compiled files into.
+mkdirp 0755 $complocaledir/test1_locale.dir
+mkdirp 0755 $complocaledir/test2_locale.dir