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:
@@ -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',
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
Reference in New Issue
Block a user