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