1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
8 #include "tmpfile-util.h"
10 TEST_RET(bootspec_sort
) {
21 "machine-id dd235d00696545768f6f693bfd23b15f\n",
28 "machine-id dd235d00696545768f6f693bfd23b15f\n",
35 "machine-id b75451ad92f94feeab50b0b442768dbd\n",
43 "machine-id 309de666fd5044268a9a26541ac93176\n",
51 "machine-id 309de666fd5044268a9a26541ac93176\n",
59 "machine-id 81c6e3147cf544c19006af023e22b292\n",
63 _cleanup_(rm_rf_physical_and_freep
) char *d
= NULL
;
64 _cleanup_(boot_config_free
) BootConfig config
= BOOT_CONFIG_NULL
;
66 assert_se(mkdtemp_malloc("/tmp/bootspec-testXXXXXX", &d
) >= 0);
68 for (size_t i
= 0; i
< ELEMENTSOF(entries
); i
++) {
69 _cleanup_free_
char *j
= NULL
;
71 j
= path_join(d
, "/loader/entries/", entries
[i
].fname
);
74 assert_se(write_string_file(j
, entries
[i
].contents
, WRITE_STRING_FILE_CREATE
|WRITE_STRING_FILE_MKDIR_0755
) >= 0);
77 assert_se(boot_config_load(&config
, d
, NULL
) >= 0);
79 assert_se(config
.n_entries
== 6);
81 /* First, because has sort key, and its the lowest one */
82 assert_se(streq(config
.entries
[0].id
, "d.conf"));
84 /* These two have a sort key, and newest must be first */
85 assert_se(streq(config
.entries
[1].id
, "cx.conf"));
86 assert_se(streq(config
.entries
[2].id
, "c.conf"));
88 /* The following ones have no sort key, hence order by version compared ids, lowest first */
89 assert_se(streq(config
.entries
[3].id
, "b.conf"));
90 assert_se(streq(config
.entries
[4].id
, "a-10.conf"));
91 assert_se(streq(config
.entries
[5].id
, "a-5.conf"));
96 static void test_extract_tries_one(const char *fname
, int ret
, const char *stripped
, unsigned tries_left
, unsigned tries_done
) {
97 _cleanup_free_
char *p
= NULL
;
100 assert_se(boot_filename_extract_tries(fname
, &p
, &l
, &d
) == ret
);
104 assert_se(streq_ptr(p
, stripped
));
105 assert_se(l
== tries_left
);
106 assert_se(d
== tries_done
);
109 TEST_RET(bootspec_extract_tries
) {
110 test_extract_tries_one("foo.conf", 0, "foo.conf", UINT_MAX
, UINT_MAX
);
112 test_extract_tries_one("foo+0.conf", 0, "foo.conf", 0, UINT_MAX
);
113 test_extract_tries_one("foo+1.conf", 0, "foo.conf", 1, UINT_MAX
);
114 test_extract_tries_one("foo+2.conf", 0, "foo.conf", 2, UINT_MAX
);
115 test_extract_tries_one("foo+33.conf", 0, "foo.conf", 33, UINT_MAX
);
117 assert_cc(INT_MAX
== INT32_MAX
);
118 test_extract_tries_one("foo+2147483647.conf", 0, "foo.conf", 2147483647, UINT_MAX
);
119 test_extract_tries_one("foo+2147483648.conf", -ERANGE
, NULL
, UINT_MAX
, UINT_MAX
);
121 test_extract_tries_one("foo+33-0.conf", 0, "foo.conf", 33, 0);
122 test_extract_tries_one("foo+33-1.conf", 0, "foo.conf", 33, 1);
123 test_extract_tries_one("foo+33-107.conf", 0, "foo.conf", 33, 107);
124 test_extract_tries_one("foo+33-107.efi", 0, "foo.efi", 33, 107);
125 test_extract_tries_one("foo+33-2147483647.conf", 0, "foo.conf", 33, 2147483647);
126 test_extract_tries_one("foo+33-2147483648.conf", -ERANGE
, NULL
, UINT_MAX
, UINT_MAX
);
128 test_extract_tries_one("foo+007-000008.conf", 0, "foo.conf", 7, 8);
130 test_extract_tries_one("foo-1.conf", 0, "foo-1.conf", UINT_MAX
, UINT_MAX
);
131 test_extract_tries_one("foo-999.conf", 0, "foo-999.conf", UINT_MAX
, UINT_MAX
);
132 test_extract_tries_one("foo-.conf", 0, "foo-.conf", UINT_MAX
, UINT_MAX
);
134 test_extract_tries_one("foo+.conf", 0, "foo+.conf", UINT_MAX
, UINT_MAX
);
135 test_extract_tries_one("+.conf", 0, "+.conf", UINT_MAX
, UINT_MAX
);
136 test_extract_tries_one("-.conf", 0, "-.conf", UINT_MAX
, UINT_MAX
);
137 test_extract_tries_one("", 0, "", UINT_MAX
, UINT_MAX
);
139 test_extract_tries_one("+1.", 0, ".", 1, UINT_MAX
);
140 test_extract_tries_one("+1-7.", 0, ".", 1, 7);
142 test_extract_tries_one("some+name+24324-22.efi", 0, "some+name.efi", 24324, 22);
143 test_extract_tries_one("sels+2-3+7-6.", 0, "sels+2-3.", 7, 6);
144 test_extract_tries_one("a+1-2..", 0, "a+1-2..", UINT_MAX
, UINT_MAX
);
145 test_extract_tries_one("ses.sgesge.+4-1.efi", 0, "ses.sgesge..efi", 4, 1);
146 test_extract_tries_one("abc+0x4.conf", 0, "abc+0x4.conf", UINT_MAX
, UINT_MAX
);
147 test_extract_tries_one("def+1-0x3.conf", 0, "def+1-0x3.conf", UINT_MAX
, UINT_MAX
);
152 TEST_RET(bootspec_boot_config_find_entry
) {
154 static const struct {
156 const char *contents
;
159 .fname
= "a-10.conf",
163 "machine-id dd235d00696545768f6f693bfd23b15f\n",
166 .fname
= "a-05.conf",
170 "machine-id dd235d00696545768f6f693bfd23b15f\n",
174 _cleanup_(rm_rf_physical_and_freep
) char *d
= NULL
;
175 _cleanup_(boot_config_free
) BootConfig config
= BOOT_CONFIG_NULL
;
177 assert_se(mkdtemp_malloc("/tmp/bootspec-testXXXXXX", &d
) >= 0);
179 for (size_t i
= 0; i
< ELEMENTSOF(entries
); i
++) {
180 _cleanup_free_
char *j
= NULL
;
182 j
= path_join(d
, "/loader/entries/", entries
[i
].fname
);
185 assert_se(write_string_file(j
, entries
[i
].contents
, WRITE_STRING_FILE_CREATE
|WRITE_STRING_FILE_MKDIR_0755
) >= 0);
188 assert_se(boot_config_load(&config
, d
, NULL
) >= 0);
189 assert_se(config
.n_entries
== 2);
191 /* Test finding the first entry */
192 BootEntry
*entry
= boot_config_find_entry(&config
, "a-10.conf");
193 assert_se(entry
&& streq(entry
->id
, "a-10.conf"));
195 /* Test finding the second entry */
196 entry
= boot_config_find_entry(&config
, "a-05.conf");
197 assert_se(entry
&& streq(entry
->id
, "a-05.conf"));
199 /* Test finding a non-existent entry */
200 entry
= boot_config_find_entry(&config
, "nonexistent.conf");
201 assert_se(entry
== NULL
);
203 /* Test case-insensitivity */
204 entry
= boot_config_find_entry(&config
, "A-10.CONF");
205 assert_se(entry
&& streq(entry
->id
, "a-10.conf"));
210 DEFINE_TEST_MAIN(LOG_INFO
);