blob: c1743dd23a789bcfe00336bab91726399cbf8649 [file] [log] [blame]
Brad Bishop099543e2020-11-09 15:37:58 -05001// SPDX-License-Identifier: Apache-2.0
2
3#include "../functions.hpp"
4
5#include <stdlib.h>
6
7#include <array>
8#include <cerrno>
9#include <filesystem>
10#include <fstream>
11#include <map>
12#include <string>
13#include <vector>
14
15#include <gtest/gtest.h>
16
17using namespace std::string_literals;
18
19TEST(GetExtensionsForIbmCompatibleSystem, testSingleMatch)
20{
21 std::map<std::string, std::vector<std::string>> extensionMap{{
22 {"system-foo"s, {".EXT"s}},
23 }};
24 std::vector<std::string> compatibleSystem{"system-foo"s}, extensions;
25 auto found =
26 functions::process_hostfirmware::getExtensionsForIbmCompatibleSystem(
27 extensionMap, compatibleSystem, extensions);
28 EXPECT_TRUE(found);
29 EXPECT_EQ(extensions, std::vector<std::string>{".EXT"s});
30}
31
32TEST(GetExtensionsForIbmCompatibleSystem, testSingleNoMatchNoModify)
33{
34 std::map<std::string, std::vector<std::string>> extensionMap{{
35 {"system-bar"s, {".EXT"s}},
36 }};
37 std::vector<std::string> compatibleSystem{"system-foo"s},
38 extensions{"foo"s};
39 auto found =
40 functions::process_hostfirmware::getExtensionsForIbmCompatibleSystem(
41 extensionMap, compatibleSystem, extensions);
42 EXPECT_FALSE(found);
43 EXPECT_EQ(extensions, std::vector<std::string>{"foo"s});
44}
45
46TEST(GetExtensionsForIbmCompatibleSystem, testMatchModify)
47{
48 std::map<std::string, std::vector<std::string>> extensionMap{{
49 {"system-bar"s, {".BAR"s}},
50 {"system-foo"s, {".FOO"s}},
51 }};
52 std::vector<std::string> compatibleSystem{"system-foo"s},
53 extensions{"foo"s};
54 auto found =
55 functions::process_hostfirmware::getExtensionsForIbmCompatibleSystem(
56 extensionMap, compatibleSystem, extensions);
57 EXPECT_TRUE(found);
58 EXPECT_EQ(extensions, std::vector<std::string>{".FOO"s});
59}
60
61TEST(GetExtensionsForIbmCompatibleSystem, testEmpty)
62{
63 std::map<std::string, std::vector<std::string>> extensionMap;
64 std::vector<std::string> compatibleSystem{"system-foo"s},
65 extensions{"foo"s};
66 auto found =
67 functions::process_hostfirmware::getExtensionsForIbmCompatibleSystem(
68 extensionMap, compatibleSystem, extensions);
69 EXPECT_FALSE(found);
70 EXPECT_EQ(extensions, std::vector<std::string>{"foo"s});
71}
72
73TEST(GetExtensionsForIbmCompatibleSystem, testEmptyEmpty)
74{
75 std::map<std::string, std::vector<std::string>> extensionMap;
76 std::vector<std::string> compatibleSystem, extensions{"foo"s};
77 auto found =
78 functions::process_hostfirmware::getExtensionsForIbmCompatibleSystem(
79 extensionMap, compatibleSystem, extensions);
80 EXPECT_FALSE(found);
81 EXPECT_EQ(extensions, std::vector<std::string>{"foo"s});
82}
83
84TEST(GetExtensionsForIbmCompatibleSystem, testMatchMultiCompat)
85{
86 std::map<std::string, std::vector<std::string>> extensionMap{{
87 {"system-bar"s, {".BAR"s}},
88 {"system-foo"s, {".FOO"s}},
89 }};
90 std::vector<std::string> compatibleSystem{"system-foo"s, "system"},
91 extensions;
92 auto found =
93 functions::process_hostfirmware::getExtensionsForIbmCompatibleSystem(
94 extensionMap, compatibleSystem, extensions);
95 EXPECT_TRUE(found);
96 EXPECT_EQ(extensions, std::vector<std::string>{".FOO"s});
97}
98
99TEST(GetExtensionsForIbmCompatibleSystem, testMultiMatchMultiCompat)
100{
101 std::map<std::string, std::vector<std::string>> extensionMap{{
102 {"system-bar"s, {".BAR"s}},
103 {"system-foo"s, {".FOO"s}},
104 }};
105 std::vector<std::string> compatibleSystem{"system-foo"s, "system-bar"},
106 extensions;
107 auto found =
108 functions::process_hostfirmware::getExtensionsForIbmCompatibleSystem(
109 extensionMap, compatibleSystem, extensions);
110 EXPECT_TRUE(found);
111 EXPECT_EQ(extensions, std::vector<std::string>{".FOO"s});
112}
113
114TEST(GetExtensionsForIbmCompatibleSystem, testMultiMatchMultiCompat2)
115{
116 std::map<std::string, std::vector<std::string>> extensionMap{{
117 {"system-foo"s, {".FOO"s}},
118 {"system-bar"s, {".BAR"s}},
119 }};
120 std::vector<std::string> compatibleSystem{"system-foo"s, "system-bar"},
121 extensions;
122 auto found =
123 functions::process_hostfirmware::getExtensionsForIbmCompatibleSystem(
124 extensionMap, compatibleSystem, extensions);
125 EXPECT_TRUE(found);
126 EXPECT_EQ(extensions, std::vector<std::string>{".FOO"s});
127}
128
129TEST(GetExtensionsForIbmCompatibleSystem, testMultiMatchMultiCompat3)
130{
131 std::map<std::string, std::vector<std::string>> extensionMap{{
132 {"system-bar"s, {".BAR"s}},
133 {"system-foo"s, {".FOO"s}},
134 }};
135 std::vector<std::string> compatibleSystem{"system-bar", "system-foo"s},
136 extensions;
137 auto found =
138 functions::process_hostfirmware::getExtensionsForIbmCompatibleSystem(
139 extensionMap, compatibleSystem, extensions);
140 EXPECT_TRUE(found);
141 EXPECT_EQ(extensions, std::vector<std::string>{".BAR"s});
142}
143
144TEST(GetExtensionsForIbmCompatibleSystem, testMultiMatchMultiCompat4)
145{
146 std::map<std::string, std::vector<std::string>> extensionMap{{
147 {"system-foo"s, {".FOO"s}},
148 {"system-bar"s, {".BAR"s}},
149 }};
150 std::vector<std::string> compatibleSystem{"system-bar", "system-foo"s},
151 extensions;
152 auto found =
153 functions::process_hostfirmware::getExtensionsForIbmCompatibleSystem(
154 extensionMap, compatibleSystem, extensions);
155 EXPECT_TRUE(found);
156 EXPECT_EQ(extensions, std::vector<std::string>{".BAR"s});
157}
158
159TEST(MaybeCall, noMatch)
160{
161 bool called = false;
162 auto callback = [&called](const auto&) { called = true; };
163 std::map<std::string,
164 std::map<std::string, std::variant<std::vector<std::string>>>>
165 interfaces{{
166 {"foo"s, {{"bar"s, std::vector<std::string>{"foo"s}}}},
167 }};
168 auto found = functions::process_hostfirmware::maybeCall(
169 interfaces, std::move(callback));
170 EXPECT_FALSE(found);
171 EXPECT_FALSE(called);
172}
173
174TEST(MaybeCall, match)
175{
176 bool called = false;
177 std::vector<std::string> sys;
178 auto callback = [&called, &sys](const auto& system) {
179 sys = system;
180 called = true;
181 };
182 std::map<std::string,
183 std::map<std::string, std::variant<std::vector<std::string>>>>
184 interfaces{{
Adriana Kobylak749bdcc2024-01-17 12:56:00 -0600185 {"xyz.openbmc_project.Inventory.Decorator.Compatible"s,
Brad Bishop099543e2020-11-09 15:37:58 -0500186 {{"Names"s, std::vector<std::string>{"foo"s}}}},
187 }};
188 auto found = functions::process_hostfirmware::maybeCall(
189 interfaces, std::move(callback));
190 EXPECT_TRUE(found);
191 EXPECT_TRUE(called);
192 EXPECT_EQ(sys, std::vector<std::string>{"foo"s});
193}
194
195TEST(MaybeCall, missingNames)
196{
197 bool called = false;
198 auto callback = [&called](const auto&) { called = true; };
199 std::map<std::string,
200 std::map<std::string, std::variant<std::vector<std::string>>>>
201 interfaces{{
Adriana Kobylak749bdcc2024-01-17 12:56:00 -0600202 {"xyz.openbmc_project.Inventory.Decorator.Compatible"s, {}},
Brad Bishop099543e2020-11-09 15:37:58 -0500203 }};
204 auto found = functions::process_hostfirmware::maybeCall(
205 interfaces, std::move(callback));
206 EXPECT_TRUE(found);
207 EXPECT_FALSE(called);
208}
209
210TEST(MaybeCall, emptyCallbackFound)
211{
212 std::map<std::string,
213 std::map<std::string, std::variant<std::vector<std::string>>>>
214 interfaces{{
Adriana Kobylak749bdcc2024-01-17 12:56:00 -0600215 {"xyz.openbmc_project.Inventory.Decorator.Compatible"s,
Brad Bishop099543e2020-11-09 15:37:58 -0500216 {{"Names"s, std::vector<std::string>{"foo"s}}}},
217 }};
218 auto found = functions::process_hostfirmware::maybeCall(
219 interfaces, std::function<void(std::vector<std::string>)>());
220 EXPECT_TRUE(found);
221}
222
223TEST(MaybeCall, emptyCallbackNotFound)
224{
225 std::map<std::string,
226 std::map<std::string, std::variant<std::vector<std::string>>>>
227 interfaces{{
228 {"foo"s, {{"Names"s, std::vector<std::string>{"foo"s}}}},
229 }};
230 auto found = functions::process_hostfirmware::maybeCall(
231 interfaces, std::function<void(std::vector<std::string>)>());
232 EXPECT_FALSE(found);
233}
234
235TEST(MaybeCall, emptyInterfaces)
236{
237 bool called = false;
238 auto callback = [&called](const auto&) { called = true; };
239 std::map<std::string,
240 std::map<std::string, std::variant<std::vector<std::string>>>>
241 interfaces;
242 auto found = functions::process_hostfirmware::maybeCall(
243 interfaces, std::move(callback));
244 EXPECT_FALSE(found);
245 EXPECT_FALSE(called);
246}
247
248TEST(MaybeCall, emptyInterfacesEmptyCallback)
249{
250 std::map<std::string,
251 std::map<std::string, std::variant<std::vector<std::string>>>>
252 interfaces;
253 auto found = functions::process_hostfirmware::maybeCall(
254 interfaces, std::function<void(std::vector<std::string>)>());
255 EXPECT_FALSE(found);
256}
257
258TEST(WriteLink, testLinkNoDelete)
259{
260 std::array<char, 15> tmpl{"/tmp/tmpXXXXXX"};
261 std::filesystem::path workdir = mkdtemp(&tmpl[0]);
262 bool called = false;
263 auto callback = [&called](const auto&, auto&) { called = true; };
264 std::filesystem::path linkPath = workdir / "link";
265 std::filesystem::path targetPath = workdir / "target";
266 std::ofstream link{linkPath};
267 functions::process_hostfirmware::writeLink(linkPath.filename(), targetPath,
268 callback);
269 std::filesystem::remove_all(workdir);
270 EXPECT_FALSE(called);
271}
272
273TEST(WriteLink, testLinkDelete)
274{
275 std::array<char, 15> tmpl{"/tmp/tmpXXXXXX"};
276 std::filesystem::path workdir = mkdtemp(&tmpl[0]);
277 bool called = false;
278 auto callback = [&called](const auto&, auto&) { called = true; };
279 auto linkPath = workdir / "link";
280 auto targetPath = workdir / "target";
281 std::ofstream link{linkPath}, target{targetPath};
282 functions::process_hostfirmware::writeLink(linkPath.filename(), targetPath,
283 callback);
284 std::filesystem::remove_all(workdir);
285 EXPECT_FALSE(called);
286}
287
288TEST(WriteLink, testLinkFailDeleteDir)
289{
290 std::array<char, 15> tmpl{"/tmp/tmpXXXXXX"};
291 std::filesystem::path workdir = mkdtemp(&tmpl[0]);
292 std::error_code ec;
293 std::filesystem::path callbackPath;
294 auto callback = [&ec, &callbackPath](const auto& p, auto& _ec) {
295 ec = _ec;
296 callbackPath = p;
297 };
298 auto targetPath = workdir / "target";
299 std::filesystem::create_directory(targetPath);
300 auto linkPath = workdir / "link";
301 auto filePath = targetPath / "file";
302 std::ofstream link{linkPath}, file{filePath};
303 functions::process_hostfirmware::writeLink(linkPath.filename(), targetPath,
304 callback);
305 std::filesystem::remove_all(workdir);
306 EXPECT_EQ(ec.value(), ENOTEMPTY);
307 EXPECT_EQ(callbackPath, targetPath);
308}
309
310TEST(WriteLink, testLinkPathNotExist)
311{
312 std::array<char, 15> tmpl{"/tmp/tmpXXXXXX"};
313 std::filesystem::path workdir = mkdtemp(&tmpl[0]);
314 std::error_code ec;
315 std::filesystem::path callbackPath;
316 auto callback = [&ec, &callbackPath](const auto& p, auto& _ec) {
317 ec = _ec;
318 callbackPath = p;
319 };
320 auto linkPath = workdir / "baz";
321 auto targetPath = workdir / "foo/bar/foo";
322 functions::process_hostfirmware::writeLink(linkPath.filename(), targetPath,
323 callback);
324 std::filesystem::remove_all(workdir);
325 EXPECT_EQ(ec.value(), ENOENT);
326 EXPECT_EQ(callbackPath, targetPath);
327}
328
329TEST(FindLinks, testNoLinks)
330{
331 std::array<char, 15> tmpl{"/tmp/tmpXXXXXX"};
332 std::filesystem::path workdir = mkdtemp(&tmpl[0]);
333
334 bool callbackCalled = false, errorCallbackCalled = false;
335 auto callback = [&callbackCalled](const auto&, const auto&, const auto&) {
336 callbackCalled = true;
337 };
338 auto errorCallback = [&errorCallbackCalled](const auto&, auto&) {
339 errorCallbackCalled = true;
340 };
341
342 std::vector<std::string> extensions;
343 functions::process_hostfirmware::findLinks(workdir, extensions,
344 errorCallback, callback);
345 std::filesystem::remove_all(workdir);
346 EXPECT_FALSE(errorCallbackCalled);
347 EXPECT_FALSE(callbackCalled);
348}
349
350TEST(FindLinks, testOneFound)
351{
352 std::array<char, 15> tmpl{"/tmp/tmpXXXXXX"};
353 std::filesystem::path workdir = mkdtemp(&tmpl[0]);
354 std::filesystem::path callbackPath, callbackLink;
355
356 bool errorCallbackCalled = false;
357 auto callback = [&callbackPath, &callbackLink](
358 const auto& p1, const auto& p2, const auto&) {
359 callbackPath = p1;
360 callbackLink = p2;
361 };
362 auto errorCallback = [&errorCallbackCalled](const auto&, auto&) {
363 errorCallbackCalled = true;
364 };
365
366 auto filePath = workdir / "foo.foo";
367 std::ofstream file{filePath};
368 std::vector<std::string> extensions{".foo"s};
369 functions::process_hostfirmware::findLinks(workdir, extensions,
370 errorCallback, callback);
371 std::filesystem::remove_all(workdir);
372 EXPECT_FALSE(errorCallbackCalled);
373 EXPECT_EQ(callbackLink, workdir / "foo");
374 EXPECT_EQ(callbackPath, filePath.filename());
375}
376
377TEST(FindLinks, testNoExtensions)
378{
379 std::array<char, 15> tmpl{"/tmp/tmpXXXXXX"};
380 std::filesystem::path workdir = mkdtemp(&tmpl[0]);
381 std::filesystem::path callbackPath, callbackLink;
382
383 bool errorCallbackCalled = false, callbackCalled = false;
384 auto callback = [&callbackCalled](const auto&, const auto&, const auto&) {
385 callbackCalled = true;
386 };
387 auto errorCallback = [&errorCallbackCalled](const auto&, auto&) {
388 errorCallbackCalled = true;
389 };
390
391 auto filePath = workdir / "foo.foo";
392 std::ofstream file{filePath};
393 std::vector<std::string> extensions;
394 functions::process_hostfirmware::findLinks(workdir, extensions,
395 errorCallback, callback);
396 std::filesystem::remove_all(workdir);
397 EXPECT_FALSE(errorCallbackCalled);
398 EXPECT_FALSE(callbackCalled);
399}
400
401TEST(FindLinks, testEnoent)
402{
403 std::array<char, 15> tmpl{"/tmp/tmpXXXXXX"};
404 std::filesystem::path workdir = mkdtemp(&tmpl[0]);
405
406 std::error_code ec;
407 bool called = false;
408 std::filesystem::path callbackPath;
409 auto callback = [&called](const auto&, const auto&, const auto&) {
410 called = true;
411 };
412 auto errorCallback = [&ec, &callbackPath](const auto& p, auto& _ec) {
413 ec = _ec;
414 callbackPath = p;
415 };
416
417 std::vector<std::string> extensions;
418 auto dir = workdir / "baz";
419 functions::process_hostfirmware::findLinks(dir, extensions, errorCallback,
420 callback);
421 std::filesystem::remove_all(workdir);
422 EXPECT_EQ(ec.value(), ENOENT);
423 EXPECT_EQ(callbackPath, dir);
424 EXPECT_FALSE(called);
425}
426
427TEST(FindLinks, testEmptyCallback)
428{
429 std::array<char, 15> tmpl{"/tmp/tmpXXXXXX"};
430 std::filesystem::path workdir = mkdtemp(&tmpl[0]);
431
432 bool called = false;
433 std::filesystem::path callbackPath;
434 auto errorCallback = [&called](const auto&, auto&) { called = true; };
435
436 auto filePath = workdir / "foo.foo";
437 std::ofstream file{filePath};
438
439 std::vector<std::string> extensions{".foo"s};
440 functions::process_hostfirmware::findLinks(
441 workdir, extensions, errorCallback,
442 functions::process_hostfirmware::LinkCallbackType());
443 std::filesystem::remove_all(workdir);
444 EXPECT_FALSE(called);
445 EXPECT_NO_THROW();
446}
447
448TEST(FindLinks, testEmptyErrorCallback)
449{
450 std::array<char, 15> tmpl{"/tmp/tmpXXXXXX"};
451 std::filesystem::path workdir = mkdtemp(&tmpl[0]);
452
453 bool called = false;
454 auto callback = [&called](const auto&, const auto&, const auto&) {
455 called = true;
456 };
457
458 std::vector<std::string> extensions;
459 auto dir = workdir / "baz";
460 functions::process_hostfirmware::findLinks(
461 dir, extensions, functions::process_hostfirmware::ErrorCallbackType(),
462 callback);
463 std::filesystem::remove_all(workdir);
464 EXPECT_FALSE(called);
465 EXPECT_NO_THROW();
466}