Merge pull request #26663 from poettering/vpick

add new "vpick" concept for automatically picking newest resource from .v/ dir containing versioned files
This commit is contained in:
Lennart Poettering
2024-01-03 22:17:32 +01:00
committed by GitHub
30 changed files with 2401 additions and 128 deletions
+1
View File
@@ -178,6 +178,7 @@ simple_tests += files(
'test-user-util.c',
'test-utf8.c',
'test-verbs.c',
'test-vpick.c',
'test-web-util.c',
'test-xattr-util.c',
'test-xml.c',
+15
View File
@@ -180,6 +180,21 @@ TEST(dir_is_empty) {
assert_se(dir_is_empty_at(AT_FDCWD, empty_dir, /* ignore_hidden_or_backup= */ false) > 0);
}
TEST(inode_type_from_string) {
static const mode_t types[] = {
S_IFREG,
S_IFDIR,
S_IFLNK,
S_IFCHR,
S_IFBLK,
S_IFIFO,
S_IFSOCK,
};
FOREACH_ARRAY(m, types, ELEMENTSOF(types))
assert_se(inode_type_from_string(inode_type_to_string(*m)) == *m);
}
static int intro(void) {
log_show_color(true);
return EXIT_SUCCESS;
+23
View File
@@ -1324,4 +1324,27 @@ TEST(strlevenshtein) {
assert_se(strlevenshtein("sunday", "saturday") == 3);
}
TEST(strrstr) {
assert_se(!strrstr(NULL, NULL));
assert_se(!strrstr("foo", NULL));
assert_se(!strrstr(NULL, "foo"));
const char *p = "foo";
assert_se(strrstr(p, "foo") == p);
assert_se(strrstr(p, "fo") == p);
assert_se(strrstr(p, "f") == p);
assert_se(strrstr(p, "oo") == p + 1);
assert_se(strrstr(p, "o") == p + 2);
assert_se(strrstr(p, "") == p + strlen(p));
assert_se(!strrstr(p, "bar"));
p = "xoxoxox";
assert_se(strrstr(p, "") == p + strlen(p));
assert_se(strrstr(p, "x") == p + 6);
assert_se(strrstr(p, "ox") == p + 5);
assert_se(strrstr(p, "xo") == p + 4);
assert_se(strrstr(p, "xox") == p + 4);
assert_se(!strrstr(p, "xx"));
}
DEFINE_TEST_MAIN(LOG_DEBUG);
+8
View File
@@ -1006,4 +1006,12 @@ TEST(strv_find_first_field) {
assert_se(streq_ptr(strv_find_first_field(STRV_MAKE("i", "k", "l", "m", "d", "c", "a", "b"), haystack), "j"));
}
TEST(strv_endswith) {
assert_se(streq_ptr(strv_endswith("waldo", STRV_MAKE("xxx", "yyy", "ldo", "zzz")), "ldo"));
assert_se(streq_ptr(strv_endswith("waldo", STRV_MAKE("xxx", "yyy", "zzz")), NULL));
assert_se(streq_ptr(strv_endswith("waldo", STRV_MAKE("waldo")), "waldo"));
assert_se(streq_ptr(strv_endswith("waldo", STRV_MAKE("w", "o", "ldo")), "o"));
assert_se(streq_ptr(strv_endswith("waldo", STRV_MAKE("knurz", "", "waldo")), ""));
}
DEFINE_TEST_MAIN(LOG_INFO);
+171
View File
@@ -0,0 +1,171 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "fd-util.h"
#include "fileio.h"
#include "fs-util.h"
#include "mkdir.h"
#include "path-util.h"
#include "rm-rf.h"
#include "tests.h"
#include "tmpfile-util.h"
#include "vpick.h"
TEST(path_pick) {
_cleanup_(rm_rf_physical_and_freep) char *p = NULL;
_cleanup_close_ int dfd = -EBADF, sub_dfd = -EBADF;
dfd = mkdtemp_open(NULL, O_DIRECTORY|O_CLOEXEC, &p);
assert(dfd >= 0);
sub_dfd = open_mkdir_at(dfd, "foo.v", O_CLOEXEC, 0777);
assert(sub_dfd >= 0);
assert_se(write_string_file_at(sub_dfd, "foo_5.5.raw", "5.5", WRITE_STRING_FILE_CREATE) >= 0);
assert_se(write_string_file_at(sub_dfd, "foo_55.raw", "55", WRITE_STRING_FILE_CREATE) >= 0);
assert_se(write_string_file_at(sub_dfd, "foo_5.raw", "5", WRITE_STRING_FILE_CREATE) >= 0);
assert_se(write_string_file_at(sub_dfd, "foo_5_ia64.raw", "5", WRITE_STRING_FILE_CREATE) >= 0);
assert_se(write_string_file_at(sub_dfd, "foo_7.raw", "7", WRITE_STRING_FILE_CREATE) >= 0);
assert_se(write_string_file_at(sub_dfd, "foo_7_x86-64.raw", "7 64bit", WRITE_STRING_FILE_CREATE) >= 0);
assert_se(write_string_file_at(sub_dfd, "foo_55_x86-64.raw", "55 64bit", WRITE_STRING_FILE_CREATE) >= 0);
assert_se(write_string_file_at(sub_dfd, "foo_55_x86.raw", "55 32bit", WRITE_STRING_FILE_CREATE) >= 0);
assert_se(write_string_file_at(sub_dfd, "foo_99_x86.raw", "99 32bit", WRITE_STRING_FILE_CREATE) >= 0);
/* Let's add an entry for sparc (which is a valid arch, but almost certainly not what we test
* on). This entry should hence always be ignored */
if (native_architecture() != ARCHITECTURE_SPARC)
assert_se(write_string_file_at(sub_dfd, "foo_100_sparc.raw", "100 sparc", WRITE_STRING_FILE_CREATE) >= 0);
assert_se(write_string_file_at(sub_dfd, "quux_1_s390.raw", "waldo1", WRITE_STRING_FILE_CREATE) >= 0);
assert_se(write_string_file_at(sub_dfd, "quux_2_s390+4-6.raw", "waldo2", WRITE_STRING_FILE_CREATE) >= 0);
assert_se(write_string_file_at(sub_dfd, "quux_3_s390+0-10.raw", "waldo3", WRITE_STRING_FILE_CREATE) >= 0);
_cleanup_free_ char *pp = NULL;
pp = path_join(p, "foo.v");
assert_se(pp);
_cleanup_(pick_result_done) PickResult result = PICK_RESULT_NULL;
PickFilter filter = {
.architecture = _ARCHITECTURE_INVALID,
.suffix = ".raw",
};
if (IN_SET(native_architecture(), ARCHITECTURE_X86, ARCHITECTURE_X86_64)) {
assert_se(path_pick(NULL, AT_FDCWD, pp, &filter, PICK_ARCHITECTURE|PICK_TRIES, &result) > 0);
assert_se(S_ISREG(result.st.st_mode));
assert_se(streq_ptr(result.version, "99"));
assert_se(result.architecture == ARCHITECTURE_X86);
assert_se(endswith(result.path, "/foo_99_x86.raw"));
pick_result_done(&result);
}
filter.architecture = ARCHITECTURE_X86_64;
assert_se(path_pick(NULL, AT_FDCWD, pp, &filter, PICK_ARCHITECTURE|PICK_TRIES, &result) > 0);
assert_se(S_ISREG(result.st.st_mode));
assert_se(streq_ptr(result.version, "55"));
assert_se(result.architecture == ARCHITECTURE_X86_64);
assert_se(endswith(result.path, "/foo_55_x86-64.raw"));
pick_result_done(&result);
filter.architecture = ARCHITECTURE_IA64;
assert_se(path_pick(NULL, AT_FDCWD, pp, &filter, PICK_ARCHITECTURE|PICK_TRIES, &result) > 0);
assert_se(S_ISREG(result.st.st_mode));
assert_se(streq_ptr(result.version, "5"));
assert_se(result.architecture == ARCHITECTURE_IA64);
assert_se(endswith(result.path, "/foo_5_ia64.raw"));
pick_result_done(&result);
filter.architecture = _ARCHITECTURE_INVALID;
filter.version = "5";
assert_se(path_pick(NULL, AT_FDCWD, pp, &filter, PICK_ARCHITECTURE|PICK_TRIES, &result) > 0);
assert_se(S_ISREG(result.st.st_mode));
assert_se(streq_ptr(result.version, "5"));
if (native_architecture() != ARCHITECTURE_IA64) {
assert_se(result.architecture == _ARCHITECTURE_INVALID);
assert_se(endswith(result.path, "/foo_5.raw"));
}
pick_result_done(&result);
filter.architecture = ARCHITECTURE_IA64;
assert_se(path_pick(NULL, AT_FDCWD, pp, &filter, PICK_ARCHITECTURE|PICK_TRIES, &result) > 0);
assert_se(S_ISREG(result.st.st_mode));
assert_se(streq_ptr(result.version, "5"));
assert_se(result.architecture == ARCHITECTURE_IA64);
assert_se(endswith(result.path, "/foo_5_ia64.raw"));
pick_result_done(&result);
filter.architecture = ARCHITECTURE_CRIS;
assert_se(path_pick(NULL, AT_FDCWD, pp, &filter, PICK_ARCHITECTURE|PICK_TRIES, &result) == 0);
assert_se(result.st.st_mode == MODE_INVALID);
assert_se(!result.version);
assert_se(result.architecture < 0);
assert_se(!result.path);
assert_se(unlinkat(sub_dfd, "foo_99_x86.raw", 0) >= 0);
filter.architecture = _ARCHITECTURE_INVALID;
filter.version = NULL;
if (IN_SET(native_architecture(), ARCHITECTURE_X86_64, ARCHITECTURE_X86)) {
assert_se(path_pick(NULL, AT_FDCWD, pp, &filter, PICK_ARCHITECTURE|PICK_TRIES, &result) > 0);
assert_se(S_ISREG(result.st.st_mode));
assert_se(streq_ptr(result.version, "55"));
if (native_architecture() == ARCHITECTURE_X86_64) {
assert_se(result.architecture == ARCHITECTURE_X86_64);
assert_se(endswith(result.path, "/foo_55_x86-64.raw"));
} else {
assert_se(result.architecture == ARCHITECTURE_X86);
assert_se(endswith(result.path, "/foo_55_x86.raw"));
}
pick_result_done(&result);
}
/* Test explicit patterns in last component of path not being .v */
free(pp);
pp = path_join(p, "foo.v/foo___.raw");
assert_se(pp);
if (IN_SET(native_architecture(), ARCHITECTURE_X86, ARCHITECTURE_X86_64)) {
assert_se(path_pick(NULL, AT_FDCWD, pp, &filter, PICK_ARCHITECTURE|PICK_TRIES, &result) > 0);
assert_se(S_ISREG(result.st.st_mode));
assert_se(streq_ptr(result.version, "55"));
assert_se(result.architecture == native_architecture());
assert_se(endswith(result.path, ".raw"));
assert_se(strrstr(result.path, "/foo_55_x86"));
pick_result_done(&result);
}
/* Specify an explicit path */
free(pp);
pp = path_join(p, "foo.v/foo_5.raw");
assert_se(pp);
filter.type_mask = UINT32_C(1) << DT_DIR;
assert_se(path_pick(NULL, AT_FDCWD, pp, &filter, PICK_ARCHITECTURE|PICK_TRIES, &result) == -ENOTDIR);
filter.type_mask = UINT32_C(1) << DT_REG;
assert_se(path_pick(NULL, AT_FDCWD, pp, &filter, PICK_ARCHITECTURE|PICK_TRIES, &result) > 0);
assert_se(S_ISREG(result.st.st_mode));
assert_se(!result.version);
assert_se(result.architecture == _ARCHITECTURE_INVALID);
assert_se(path_equal(result.path, pp));
pick_result_done(&result);
free(pp);
pp = path_join(p, "foo.v");
assert_se(pp);
filter.architecture = ARCHITECTURE_S390;
filter.basename = "quux";
assert_se(path_pick(NULL, AT_FDCWD, pp, &filter, PICK_ARCHITECTURE|PICK_TRIES, &result) > 0);
assert_se(S_ISREG(result.st.st_mode));
assert_se(streq_ptr(result.version, "2"));
assert_se(result.tries_left == 4);
assert_se(result.tries_done == 6);
assert_se(endswith(result.path, "quux_2_s390+4-6.raw"));
assert_se(result.architecture == ARCHITECTURE_S390);
}
DEFINE_TEST_MAIN(LOG_DEBUG);