* [PATCH] localedef: Add tests-container test for --no-hard-links. @ 2020-04-26 19:20 Carlos O'Donell 2020-04-28 18:28 ` DJ Delorie 0 siblings, 1 reply; 6+ messages in thread From: Carlos O'Donell @ 2020-04-26 19:20 UTC (permalink / raw) To: libc-alpha, DJ Delorie This test relies on the patch from here being applied: https://sourceware.org/pipermail/libc-alpha/2020-April/113168.html The test does what it says on the tin, and is the first time we actually test localedef's behaviour in this case in a container. I am always excited by extending our testing in this way to test previously untestable (hardlink code) which requires being installed in default paths :-) OK for master? 8< --- 8< --- 8< From 6d6e1e3346eca93731fc47df20ddcdf4b5f53b4e Mon Sep 17 00:00:00 2001 From: Carlos O'Donell <carlos@redhat.com> Date: Tue, 25 Feb 2020 10:15:30 -0500 Subject: [PATCH] localedef: Add tests-container test for --no-hard-links. The new tst-localedef-hardlinks 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. --- localedata/Makefile | 2 + localedata/tst-localedef-hardlinks.c | 130 ++++++++++++++++++ .../postclean.req | 0 .../tst-localedef-hardlinks.root/test1_locale | 3 + .../tst-localedef-hardlinks.root/test2_locale | 3 + .../tst-localedef-hardlinks.script | 10 ++ 6 files changed, 148 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 diff --git a/localedata/Makefile b/localedata/Makefile index e89bacc1aa..ccfcb0049f 100644 --- a/localedata/Makefile +++ b/localedata/Makefile @@ -167,6 +167,8 @@ tests-special += $(objpfx)mtrace-tst-leaks.out endif endif endif +tests-container = \ + tst-localedef-hardlinks # Files to install. ifeq ($(INSTALL_UNCOMPRESSED),yes) diff --git a/localedata/tst-localedef-hardlinks.c b/localedata/tst-localedef-hardlinks.c new file mode 100644 index 0000000000..672a03ad45 --- /dev/null +++ b/localedata/tst-localedef-hardlinks.c @@ -0,0 +1,130 @@ +/* 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> +#include <support/capture_subprocess.h> + +/* Each test compiles a locale to output, and has an expected link count for + LC_CTYPE. */ +struct test_data +{ + /* Arguments to localedef for this step. */ + const char * argv[16]; + /* Expected output file generated by running localedef. */ + const char *output; + /* Expected st_nlink count for the output. */ + int st_nlink; +}; + +/* Check for link count. */ +void +check_link (struct test_data step) +{ + struct stat64 locale; + char *output; + + output = xasprintf ("%s/%s", support_complocaledir_prefix, step.output); + xstat (output, &locale); + free (output); + TEST_COMPARE (locale.st_nlink, step.st_nlink); +} + +static void +run_localedef (void *step) +{ + const char *prog = xasprintf ("%s/localedef", support_bindir_prefix); + struct test_data *one = (struct test_data *) step; + + one->argv[0] = prog; + execv (prog, (char * const *) one->argv); + FAIL_EXIT1 ("execv: %m"); +} + +#define TEST1DIR "test1_locale.dir" +#define TEST2DIR "test2_locale.dir" + +/* The whole test has 4 steps described below. */ +static struct test_data step[4] = { + { .argv = { NULL, "--no-archive", "-i", "/test1_locale", TEST1DIR, NULL }, + .output = TEST1DIR "/LC_CTYPE", + .st_nlink = 1 }, + { .argv = { NULL, "--no-archive", "-i", "/test2_locale", TEST2DIR, NULL }, + .output = TEST2DIR "/LC_CTYPE", + .st_nlink = 2 }, + { .argv = { NULL, "--no-archive", "--no-hard-links", "-i", "/test1_locale", + TEST1DIR, NULL }, + .output = TEST1DIR "/LC_CTYPE", + .st_nlink = 1 }, + { .argv = { NULL, "--no-archive", "--no-hard-links", "-i", "/test2_locale", + TEST1DIR, NULL }, + .output = TEST2DIR "/LC_CTYPE", + .st_nlink = 1 }, +}; + +static int +do_test (void) +{ + struct support_capture_subprocess result; + + printf ("INFO: $complocaledir is %s\n", support_complocaledir_prefix); + /* Compile the first locale. */ + result = support_capture_subprocess (run_localedef, (void *) &step[0]); + support_capture_subprocess_check (&result, "execv", 1, sc_allow_stderr); + check_link (step[0]); + + /* This time around we should have link counts of 2 for the second + linked locale since categories are identical. */ + result = support_capture_subprocess (run_localedef, (void *) &step[1]); + support_capture_subprocess_check (&result, "execv", 1, sc_allow_stderr); + check_link (step[1]); + + /* Again with --no-hard-links (link count is always one). */ + result = support_capture_subprocess (run_localedef, (void *) &step[2]); + support_capture_subprocess_check (&result, "execv", 1, sc_allow_stderr); + check_link (step[2]); + + /* Again with --no-hard-links, and the link count must remain 1. */ + result = support_capture_subprocess (run_localedef, (void *) &step[3]); + support_capture_subprocess_check (&result, "execv", 1, sc_allow_stderr); + check_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..79f4c3aec4 --- /dev/null +++ b/localedata/tst-localedef-hardlinks.root/test1_locale @@ -0,0 +1,3 @@ +comment_char % +escape_char / +% Empty test locale. Must be identical to the other test 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..79f4c3aec4 --- /dev/null +++ b/localedata/tst-localedef-hardlinks.root/test2_locale @@ -0,0 +1,3 @@ +comment_char % +escape_char / +% Empty test locale. Must be identical to the other test 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..7c737aceb0 --- /dev/null +++ b/localedata/tst-localedef-hardlinks.root/tst-localedef-hardlinks.script @@ -0,0 +1,10 @@ +# Need root to write to $complocaledir when running localedef. +su + +# The container install ensures we have uncompressed charmaps so we don't +# need gzip, and we don't need to copy in the uncompressed charmap from +# the source tree. + +# We need to create all the parent directories to install the locales +# into. +mkdirp 0755 $complocaledir/ -- 2.21.1 -- Cheers, Carlos. ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] localedef: Add tests-container test for --no-hard-links. 2020-04-26 19:20 [PATCH] localedef: Add tests-container test for --no-hard-links Carlos O'Donell @ 2020-04-28 18:28 ` DJ Delorie 2020-04-29 16:17 ` [PATCHv2] " Carlos O'Donell 0 siblings, 1 reply; 6+ messages in thread From: DJ Delorie @ 2020-04-28 18:28 UTC (permalink / raw) To: Carlos O'Donell; +Cc: libc-alpha "Carlos O'Donell" <carlos@redhat.com> writes: > OK for master? Minor comments about comments but functionally OK. Reviewed-by: DJ Delorie <dj@redhat.com> > +tests-container = \ > + tst-localedef-hardlinks New test, ok. > +/* Test --no-hard-links option to localedef. > + Copyright (C) 2018 Free Software Foundation, Inc. 2018 ? > + <http://www.gnu.org/licenses/>. */ https > +/* Each test compiles a locale to output, and has an expected link count for > + LC_CTYPE. */ I don't see any cleanup between each step, do we rely on localedef to remove and replace any output files each time? And/or is that what we're testing? Either way, I suspect such expectations should be documented in the comment so that future test readers can share these expectations. > +struct test_data > +{ > + /* Arguments to localedef for this step. */ > + const char * argv[16]; Overkill ;-) > + /* Expected output file generated by running localedef. */ > + const char *output; Ok. > + /* Expected st_nlink count for the output. */ > + int st_nlink; Ok. > +/* Check for link count. */ > +void > +check_link (struct test_data step) > +{ > + struct stat64 locale; > + char *output; > + > + output = xasprintf ("%s/%s", support_complocaledir_prefix, step.output); > + xstat (output, &locale); > + free (output); > + TEST_COMPARE (locale.st_nlink, step.st_nlink); > +} Ok. > +static void > +run_localedef (void *step) > +{ > + const char *prog = xasprintf ("%s/localedef", support_bindir_prefix); > + struct test_data *one = (struct test_data *) step; > + > + one->argv[0] = prog; > + execv (prog, (char * const *) one->argv); > + FAIL_EXIT1 ("execv: %m"); > +} Ok. > +#define TEST1DIR "test1_locale.dir" > +#define TEST2DIR "test2_locale.dir" > + > +/* The whole test has 4 steps described below. */ > +static struct test_data step[4] = { > + { .argv = { NULL, "--no-archive", "-i", "/test1_locale", TEST1DIR, NULL }, > + .output = TEST1DIR "/LC_CTYPE", > + .st_nlink = 1 }, > + { .argv = { NULL, "--no-archive", "-i", "/test2_locale", TEST2DIR, NULL }, > + .output = TEST2DIR "/LC_CTYPE", > + .st_nlink = 2 }, > + { .argv = { NULL, "--no-archive", "--no-hard-links", "-i", "/test1_locale", > + TEST1DIR, NULL }, > + .output = TEST1DIR "/LC_CTYPE", > + .st_nlink = 1 }, > + { .argv = { NULL, "--no-archive", "--no-hard-links", "-i", "/test2_locale", > + TEST1DIR, NULL }, > + .output = TEST2DIR "/LC_CTYPE", > + .st_nlink = 1 }, > +}; Ok. Might want to add that the "NULL" will be filled in at runtime. > +static int > +do_test (void) > +{ > + struct support_capture_subprocess result; > + > + printf ("INFO: $complocaledir is %s\n", support_complocaledir_prefix); > + /* Compile the first locale. */ > + result = support_capture_subprocess (run_localedef, (void *) &step[0]); > + support_capture_subprocess_check (&result, "execv", 1, sc_allow_stderr); > + check_link (step[0]); > + > + /* This time around we should have link counts of 2 for the second > + linked locale since categories are identical. */ > + result = support_capture_subprocess (run_localedef, (void *) &step[1]); > + support_capture_subprocess_check (&result, "execv", 1, sc_allow_stderr); > + check_link (step[1]); > + > + /* Again with --no-hard-links (link count is always one). */ > + result = support_capture_subprocess (run_localedef, (void *) &step[2]); > + support_capture_subprocess_check (&result, "execv", 1, sc_allow_stderr); > + check_link (step[2]); > + > + /* Again with --no-hard-links, and the link count must remain 1. */ > + result = support_capture_subprocess (run_localedef, (void *) &step[3]); > + support_capture_subprocess_check (&result, "execv", 1, sc_allow_stderr); > + check_link (step[3]); > + > + /* Tested without and with --no-hard-links and link counts were > + consistent. */ > + return EXIT_SUCCESS; > +} Ok. > +#include <support/test-driver.c> Ok. > 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 I wonder if we should include a comment in this file (contents are otherwise ignored) saying why it's justified. In this case, I assume that having test locales hang around might influence future tests if they're loaded and matched by default? > diff --git a/localedata/tst-localedef-hardlinks.root/test1_locale b/localedata/tst-localedef-hardlinks.root/test1_locale > new file mode 100644 > index 0000000000..79f4c3aec4 > --- /dev/null > +++ b/localedata/tst-localedef-hardlinks.root/test1_locale > @@ -0,0 +1,3 @@ > +comment_char % > +escape_char / > +% Empty test locale. Must be identical to the other test locale. Ok. > diff --git a/localedata/tst-localedef-hardlinks.root/test2_locale b/localedata/tst-localedef-hardlinks.root/test2_locale > new file mode 100644 > index 0000000000..79f4c3aec4 > --- /dev/null > +++ b/localedata/tst-localedef-hardlinks.root/test2_locale > @@ -0,0 +1,3 @@ > +comment_char % > +escape_char / > +% Empty test locale. Must be identical to the other test locale. Ok. > 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..7c737aceb0 > --- /dev/null > +++ b/localedata/tst-localedef-hardlinks.root/tst-localedef-hardlinks.script > @@ -0,0 +1,10 @@ > +# Need root to write to $complocaledir when running localedef. > +su > + > +# The container install ensures we have uncompressed charmaps so we don't > +# need gzip, and we don't need to copy in the uncompressed charmap from > +# the source tree. > + > +# We need to create all the parent directories to install the locales > +# into. > +mkdirp 0755 $complocaledir/ Ok. ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCHv2] localedef: Add tests-container test for --no-hard-links. 2020-04-28 18:28 ` DJ Delorie @ 2020-04-29 16:17 ` Carlos O'Donell 2020-04-29 21:44 ` DJ Delorie 0 siblings, 1 reply; 6+ messages in thread From: Carlos O'Donell @ 2020-04-29 16:17 UTC (permalink / raw) To: DJ Delorie; +Cc: libc-alpha On 4/28/20 2:28 PM, DJ Delorie wrote: > > "Carlos O'Donell" <carlos@redhat.com> writes: >> OK for master? > > Minor comments about comments but functionally OK. > > Reviewed-by: DJ Delorie <dj@redhat.com> > >> +tests-container = \ >> + tst-localedef-hardlinks > > New test, ok. > >> +/* Test --no-hard-links option to localedef. >> + Copyright (C) 2018 Free Software Foundation, Inc. > > 2018 ? Fixed. > >> + <http://www.gnu.org/licenses/>. */ > > https Fixed. > >> +/* Each test compiles a locale to output, and has an expected link count for >> + LC_CTYPE. */ > > I don't see any cleanup between each step, do we rely on localedef to > remove and replace any output files each time? And/or is that what > we're testing? Either way, I suspect such expectations should be > documented in the comment so that future test readers can share these > expectations. Fixed. Yes, we expect localedef to remove the files and replace them. ~~~ -/* Each test compiles a locale to output, and has an expected link count for - LC_CTYPE. */ +/* Each test compiles a locale to output, and has an expected link count + for LC_CTYPE. This test expects that localedef removes the existing + files before installing new copies of the files, and we do not + cleanup between localedef runs. We can't cleanup between each pair + of runs since localedef must see the existing locale in order to + determine that space could be saved by using a hardlink. */ ~~~ >> +struct test_data >> +{ >> + /* Arguments to localedef for this step. */ >> + const char * argv[16]; > > Overkill ;-) Right, we're at 6 args, so I gave some room. We really need some dynamic APIs for writing test closures. I don't want ad-hoc methods for creating closures. > >> + /* Expected output file generated by running localedef. */ >> + const char *output; > > Ok. > >> + /* Expected st_nlink count for the output. */ >> + int st_nlink; > > Ok. > >> +/* Check for link count. */ >> +void >> +check_link (struct test_data step) >> +{ >> + struct stat64 locale; >> + char *output; >> + >> + output = xasprintf ("%s/%s", support_complocaledir_prefix, step.output); >> + xstat (output, &locale); >> + free (output); >> + TEST_COMPARE (locale.st_nlink, step.st_nlink); >> +} > > Ok. > >> +static void >> +run_localedef (void *step) >> +{ >> + const char *prog = xasprintf ("%s/localedef", support_bindir_prefix); >> + struct test_data *one = (struct test_data *) step; >> + >> + one->argv[0] = prog; >> + execv (prog, (char * const *) one->argv); >> + FAIL_EXIT1 ("execv: %m"); >> +} > > Ok. > >> +#define TEST1DIR "test1_locale.dir" >> +#define TEST2DIR "test2_locale.dir" >> + >> +/* The whole test has 4 steps described below. */ >> +static struct test_data step[4] = { >> + { .argv = { NULL, "--no-archive", "-i", "/test1_locale", TEST1DIR, NULL }, >> + .output = TEST1DIR "/LC_CTYPE", >> + .st_nlink = 1 }, >> + { .argv = { NULL, "--no-archive", "-i", "/test2_locale", TEST2DIR, NULL }, >> + .output = TEST2DIR "/LC_CTYPE", >> + .st_nlink = 2 }, >> + { .argv = { NULL, "--no-archive", "--no-hard-links", "-i", "/test1_locale", >> + TEST1DIR, NULL }, >> + .output = TEST1DIR "/LC_CTYPE", >> + .st_nlink = 1 }, >> + { .argv = { NULL, "--no-archive", "--no-hard-links", "-i", "/test2_locale", >> + TEST1DIR, NULL }, >> + .output = TEST2DIR "/LC_CTYPE", >> + .st_nlink = 1 }, >> +}; > > Ok. Might want to add that the "NULL" will be filled in at runtime. > Fixed. >> +static int >> +do_test (void) >> +{ >> + struct support_capture_subprocess result; >> + >> + printf ("INFO: $complocaledir is %s\n", support_complocaledir_prefix); >> + /* Compile the first locale. */ >> + result = support_capture_subprocess (run_localedef, (void *) &step[0]); >> + support_capture_subprocess_check (&result, "execv", 1, sc_allow_stderr); >> + check_link (step[0]); >> + >> + /* This time around we should have link counts of 2 for the second >> + linked locale since categories are identical. */ >> + result = support_capture_subprocess (run_localedef, (void *) &step[1]); >> + support_capture_subprocess_check (&result, "execv", 1, sc_allow_stderr); >> + check_link (step[1]); >> + >> + /* Again with --no-hard-links (link count is always one). */ >> + result = support_capture_subprocess (run_localedef, (void *) &step[2]); >> + support_capture_subprocess_check (&result, "execv", 1, sc_allow_stderr); >> + check_link (step[2]); >> + >> + /* Again with --no-hard-links, and the link count must remain 1. */ >> + result = support_capture_subprocess (run_localedef, (void *) &step[3]); >> + support_capture_subprocess_check (&result, "execv", 1, sc_allow_stderr); >> + check_link (step[3]); >> + >> + /* Tested without and with --no-hard-links and link counts were >> + consistent. */ >> + return EXIT_SUCCESS; >> +} > > Ok. > >> +#include <support/test-driver.c> > > Ok. > >> 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 > > I wonder if we should include a comment in this file (contents are > otherwise ignored) saying why it's justified. In this case, I assume > that having test locales hang around might influence future tests if > they're loaded and matched by default? Correct. Fixed. >> diff --git a/localedata/tst-localedef-hardlinks.root/test1_locale b/localedata/tst-localedef-hardlinks.root/test1_locale >> new file mode 100644 >> index 0000000000..79f4c3aec4 >> --- /dev/null >> +++ b/localedata/tst-localedef-hardlinks.root/test1_locale >> @@ -0,0 +1,3 @@ >> +comment_char % >> +escape_char / >> +% Empty test locale. Must be identical to the other test locale. > > Ok. > >> diff --git a/localedata/tst-localedef-hardlinks.root/test2_locale b/localedata/tst-localedef-hardlinks.root/test2_locale >> new file mode 100644 >> index 0000000000..79f4c3aec4 >> --- /dev/null >> +++ b/localedata/tst-localedef-hardlinks.root/test2_locale >> @@ -0,0 +1,3 @@ >> +comment_char % >> +escape_char / >> +% Empty test locale. Must be identical to the other test locale. > > Ok. > >> 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..7c737aceb0 >> --- /dev/null >> +++ b/localedata/tst-localedef-hardlinks.root/tst-localedef-hardlinks.script >> @@ -0,0 +1,10 @@ >> +# Need root to write to $complocaledir when running localedef. >> +su >> + >> +# The container install ensures we have uncompressed charmaps so we don't >> +# need gzip, and we don't need to copy in the uncompressed charmap from >> +# the source tree. >> + >> +# We need to create all the parent directories to install the locales >> +# into. >> +mkdirp 0755 $complocaledir/ > > Ok. > v2 - Fix date. - Fix https - Add extra comment about file overwrite expecatations. - Add comment about argv[0] getting filled in (it's dynamic and depends on bindir). - Add comment to postclean.req. OK for master? 8< --- 8< --- 8< From 67854155584856bab4849b01ecf51aab67048bbb Mon Sep 17 00:00:00 2001 From: Carlos O'Donell <carlos@redhat.com> Date: Tue, 25 Feb 2020 10:15:30 -0500 Subject: [PATCH] localedef: Add tests-container test for --no-hard-links. The new tst-localedef-hardlinks 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. Reviewed-by: DJ Delorie <dj@redhat.com> --- localedata/Makefile | 2 + localedata/tst-localedef-hardlinks.c | 135 ++++++++++++++++++ .../postclean.req | 2 + .../tst-localedef-hardlinks.root/test1_locale | 3 + .../tst-localedef-hardlinks.root/test2_locale | 3 + .../tst-localedef-hardlinks.script | 9 ++ 6 files changed, 154 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 diff --git a/localedata/Makefile b/localedata/Makefile index e89bacc1aa..ccfcb0049f 100644 --- a/localedata/Makefile +++ b/localedata/Makefile @@ -167,6 +167,8 @@ tests-special += $(objpfx)mtrace-tst-leaks.out endif endif endif +tests-container = \ + tst-localedef-hardlinks # Files to install. ifeq ($(INSTALL_UNCOMPRESSED),yes) diff --git a/localedata/tst-localedef-hardlinks.c b/localedata/tst-localedef-hardlinks.c new file mode 100644 index 0000000000..e8fda167be --- /dev/null +++ b/localedata/tst-localedef-hardlinks.c @@ -0,0 +1,135 @@ +/* Test --no-hard-links option to localedef. + Copyright (C) 2020 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 + <https://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> +#include <support/capture_subprocess.h> + +/* Each test compiles a locale to output, and has an expected link count + for LC_CTYPE. This test expects that localedef removes the existing + files before installing new copies of the files, and we do not + cleanup between localedef runs. We can't cleanup between each pair + of runs since localedef must see the existing locale in order to + determine that space could be saved by using a hardlink. */ +struct test_data +{ + /* Arguments to localedef for this step. */ + const char * argv[16]; + /* Expected output file generated by running localedef. */ + const char *output; + /* Expected st_nlink count for the output. */ + int st_nlink; +}; + +/* Check for link count. */ +void +check_link (struct test_data step) +{ + struct stat64 locale; + char *output; + + output = xasprintf ("%s/%s", support_complocaledir_prefix, step.output); + xstat (output, &locale); + free (output); + TEST_COMPARE (locale.st_nlink, step.st_nlink); +} + +static void +run_localedef (void *step) +{ + const char *prog = xasprintf ("%s/localedef", support_bindir_prefix); + struct test_data *one = (struct test_data *) step; + + one->argv[0] = prog; + execv (prog, (char * const *) one->argv); + FAIL_EXIT1 ("execv: %m"); +} + +#define TEST1DIR "test1_locale.dir" +#define TEST2DIR "test2_locale.dir" + +/* The whole test has 4 steps described below. Note the argv[0] NULL + will be filled in at runtime by run_localedef. */ +static struct test_data step[4] = { + { .argv = { NULL, "--no-archive", "-i", "/test1_locale", TEST1DIR, NULL }, + .output = TEST1DIR "/LC_CTYPE", + .st_nlink = 1 }, + { .argv = { NULL, "--no-archive", "-i", "/test2_locale", TEST2DIR, NULL }, + .output = TEST2DIR "/LC_CTYPE", + .st_nlink = 2 }, + { .argv = { NULL, "--no-archive", "--no-hard-links", "-i", "/test1_locale", + TEST1DIR, NULL }, + .output = TEST1DIR "/LC_CTYPE", + .st_nlink = 1 }, + { .argv = { NULL, "--no-archive", "--no-hard-links", "-i", "/test2_locale", + TEST1DIR, NULL }, + .output = TEST2DIR "/LC_CTYPE", + .st_nlink = 1 }, +}; + +static int +do_test (void) +{ + struct support_capture_subprocess result; + + printf ("INFO: $complocaledir is %s\n", support_complocaledir_prefix); + /* Compile the first locale. */ + result = support_capture_subprocess (run_localedef, (void *) &step[0]); + support_capture_subprocess_check (&result, "execv", 1, sc_allow_stderr); + check_link (step[0]); + + /* This time around we should have link counts of 2 for the second + linked locale since categories are identical. */ + result = support_capture_subprocess (run_localedef, (void *) &step[1]); + support_capture_subprocess_check (&result, "execv", 1, sc_allow_stderr); + check_link (step[1]); + + /* Again with --no-hard-links (link count is always one). */ + result = support_capture_subprocess (run_localedef, (void *) &step[2]); + support_capture_subprocess_check (&result, "execv", 1, sc_allow_stderr); + check_link (step[2]); + + /* Again with --no-hard-links, and the link count must remain 1. */ + result = support_capture_subprocess (run_localedef, (void *) &step[3]); + support_capture_subprocess_check (&result, "execv", 1, sc_allow_stderr); + check_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..48f3c4bd4e --- /dev/null +++ b/localedata/tst-localedef-hardlinks.root/postclean.req @@ -0,0 +1,2 @@ +# We do not want test locales to remain installed for future tests so +# we request that the testroot be cleaned after the test is complete. diff --git a/localedata/tst-localedef-hardlinks.root/test1_locale b/localedata/tst-localedef-hardlinks.root/test1_locale new file mode 100644 index 0000000000..79f4c3aec4 --- /dev/null +++ b/localedata/tst-localedef-hardlinks.root/test1_locale @@ -0,0 +1,3 @@ +comment_char % +escape_char / +% Empty test locale. Must be identical to the other test 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..79f4c3aec4 --- /dev/null +++ b/localedata/tst-localedef-hardlinks.root/test2_locale @@ -0,0 +1,3 @@ +comment_char % +escape_char / +% Empty test locale. Must be identical to the other test 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..dd88663530 --- /dev/null +++ b/localedata/tst-localedef-hardlinks.root/tst-localedef-hardlinks.script @@ -0,0 +1,9 @@ +# Need root to write to $complocaledir when running localedef. +su + +# The container install ensures we have uncompressed charmaps so we don't +# need gzip, and we don't need to copy in the uncompressed charmap from +# the source tree. + +# The container install ensures we have the compiled locale dirctory +# present for localedef to write to by default. -- 2.21.1 -- Cheers, Carlos. ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCHv2] localedef: Add tests-container test for --no-hard-links. 2020-04-29 16:17 ` [PATCHv2] " Carlos O'Donell @ 2020-04-29 21:44 ` DJ Delorie 2020-04-30 20:29 ` Carlos O'Donell 0 siblings, 1 reply; 6+ messages in thread From: DJ Delorie @ 2020-04-29 21:44 UTC (permalink / raw) To: Carlos O'Donell; +Cc: libc-alpha "Carlos O'Donell" <carlos@redhat.com> writes: > v2 > - Fix date. > - Fix https > - Add extra comment about file overwrite expecatations. > - Add comment about argv[0] getting filled in (it's dynamic and depends > on bindir). > - Add comment to postclean.req. > > OK for master? Ok. Be careful to not push this one before the one that adds the Makefile mkdirp patch ;-) Reviewed-by: DJ Delorie <dj@redhat.com> ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCHv2] localedef: Add tests-container test for --no-hard-links. 2020-04-29 21:44 ` DJ Delorie @ 2020-04-30 20:29 ` Carlos O'Donell 0 siblings, 0 replies; 6+ messages in thread From: Carlos O'Donell @ 2020-04-30 20:29 UTC (permalink / raw) To: DJ Delorie; +Cc: libc-alpha On 4/29/20 5:44 PM, DJ Delorie wrote: > "Carlos O'Donell" <carlos@redhat.com> writes: > >> v2 >> - Fix date. >> - Fix https >> - Add extra comment about file overwrite expecatations. >> - Add comment about argv[0] getting filled in (it's dynamic and depends >> on bindir). >> - Add comment to postclean.req. >> >> OK for master? > > Ok. Be careful to not push this one before the one that adds the > Makefile mkdirp patch ;-) > > Reviewed-by: DJ Delorie <dj@redhat.com> > Thanks! Pushed as #2 in sequence. -- Cheers, Carlos. ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH] localedef: Add tests-container test for --no-hard-links. @ 2018-12-11 1:30 Carlos O'Donell 0 siblings, 0 replies; 6+ messages in thread From: Carlos O'Donell @ 2018-12-11 1:30 UTC (permalink / raw) To: GNU C Library 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 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 -- 2.19.2 -- Cheers, Carlos. ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2020-04-30 20:29 UTC | newest] Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2020-04-26 19:20 [PATCH] localedef: Add tests-container test for --no-hard-links Carlos O'Donell 2020-04-28 18:28 ` DJ Delorie 2020-04-29 16:17 ` [PATCHv2] " Carlos O'Donell 2020-04-29 21:44 ` DJ Delorie 2020-04-30 20:29 ` Carlos O'Donell -- strict thread matches above, loose matches on Subject: below -- 2018-12-11 1:30 [PATCH] " Carlos O'Donell
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).