diff options
Diffstat (limited to 'localedata/tst-localedef-hardlinks.c')
-rw-r--r-- | localedata/tst-localedef-hardlinks.c | 135 |
1 files changed, 135 insertions, 0 deletions
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> |