blob: 8f3ea30f08a0c11538863677a08ff6b5eb22bc00 [file] [log] [blame]
Patrick Venture298930a2019-07-03 11:44:52 -07001#include "buildjson.hpp"
Patrick Venturecf066ac2019-08-06 09:03:47 -07002#include "general_systemd.hpp"
Patrick Ventured53d60a2020-04-07 09:01:34 -07003#include "skip_action.hpp"
Patrick Venture298930a2019-07-03 11:44:52 -07004
5#include <nlohmann/json.hpp>
6
7#include <gmock/gmock.h>
8#include <gtest/gtest.h>
9
10namespace ipmi_flash
11{
12namespace
13{
14using ::testing::IsEmpty;
15
16using json = nlohmann::json;
17
18TEST(FirmwareJsonTest, InvalidHandlerType)
19{
20 auto j2 = R"(
21 [{
22 "blob" : "/flash/image",
23 "handler" : {
24 "type" : "unsupported",
25 "path" : "/run/initramfs/bmc-image"
26 },
27 "actions" : {
28 "preparation" : {
29 "type" : "systemd",
30 "unit" : "phosphor-ipmi-flash-bmc-prepare.target"
31 },
32 "verification" : {
33 "type" : "fileSystemdVerify",
34 "unit" : "phosphor-ipmi-flash-bmc-verify.target",
35 "path" : "/tmp/bmc.verify"
36 },
37 "update" : {
38 "type" : "reboot"
39 }
40 }
41 }]
42 )"_json;
43
44 EXPECT_THAT(buildHandlerFromJson(j2), IsEmpty());
45}
46
47TEST(FirmwareJsonTest, InvalidPreparationType)
48{
49 auto j2 = R"(
50 [{
51 "blob" : "/flash/image",
52 "handler" : {
53 "type" : "file",
54 "path" : "/run/initramfs/bmc-image"
55 },
56 "actions" : {
57 "preparation" : {
58 "type" : "superfun",
59 "unit" : "phosphor-ipmi-flash-bmc-prepare.target"
60 },
61 "verification" : {
62 "type" : "fileSystemdVerify",
63 "unit" : "phosphor-ipmi-flash-bmc-verify.target",
64 "path" : "/tmp/bmc.verify"
65 },
66 "update" : {
67 "type" : "reboot"
68 }
69 }
70 }]
71 )"_json;
72
73 EXPECT_THAT(buildHandlerFromJson(j2), IsEmpty());
74}
75
76TEST(FirmwareJsonTest, InvalidVerificationType)
77{
78 auto j2 = R"(
79 [{
80 "blob" : "/flash/image",
81 "handler" : {
82 "type" : "file",
83 "path" : "/run/initramfs/bmc-image"
84 },
85 "actions" : {
86 "preparation" : {
87 "type" : "systemd",
88 "unit" : "phosphor-ipmi-flash-bmc-prepare.target"
89 },
90 "verification" : {
91 "type" : "funtimes",
92 "unit" : "phosphor-ipmi-flash-bmc-verify.target",
93 "path" : "/tmp/bmc.verify"
94 },
95 "update" : {
96 "type" : "reboot"
97 }
98 }
99 }]
100 )"_json;
101
102 EXPECT_THAT(buildHandlerFromJson(j2), IsEmpty());
103}
104
105TEST(FirmwareJsonTest, InvalidUpdateType)
106{
107 auto j2 = R"(
108 [{
109 "blob" : "/flash/image",
110 "handler" : {
111 "type" : "file",
112 "path" : "/run/initramfs/bmc-image"
113 },
114 "actions" : {
115 "preparation" : {
116 "type" : "systemd",
117 "unit" : "phosphor-ipmi-flash-bmc-prepare.target"
118 },
119 "verification" : {
120 "type" : "fileSystemdVerify",
121 "unit" : "phosphor-ipmi-flash-bmc-verify.target",
122 "path" : "/tmp/bmc.verify"
123 },
124 "update" : {
125 "type" : "systemd"
126 }
127 }
128 }]
129 )"_json;
130
131 EXPECT_THAT(buildHandlerFromJson(j2), IsEmpty());
132}
133
134TEST(FirmwareJsonTest, MissingHandler)
135{
136 auto j2 = R"(
137 [{
138 "blob" : "/flash/image",
139 "actions" : {
140 "preparation" : {
141 "type" : "systemd",
142 "unit" : "phosphor-ipmi-flash-bmc-prepare.target"
143 },
144 "verification" : {
145 "type" : "fileSystemdVerify",
146 "unit" : "phosphor-ipmi-flash-bmc-verify.target",
147 "path" : "/tmp/bmc.verify"
148 },
149 "update" : {
150 "type" : "reboot"
151 }
152 }
153 }]
154 )"_json;
155
156 EXPECT_THAT(buildHandlerFromJson(j2), IsEmpty());
157}
158
159TEST(FirmwareJsonTest, MissingActions)
160{
161 auto j2 = R"(
162 [{
163 "blob" : "/flash/image",
164 "handler" : {
165 "type" : "file",
166 "path" : "/run/initramfs/bmc-image"
167 }
168 }]
169 )"_json;
170
171 EXPECT_THAT(buildHandlerFromJson(j2), IsEmpty());
172}
173
174TEST(FirmwareJsonTest, MissingActionPreparation)
175{
176 auto j2 = R"(
177 [{
178 "blob" : "/flash/image",
179 "handler" : {
180 "type" : "file",
181 "path" : "/run/initramfs/bmc-image"
182 },
183 "actions" : {
184 "verification" : {
185 "type" : "fileSystemdVerify",
186 "unit" : "phosphor-ipmi-flash-bmc-verify.target",
187 "path" : "/tmp/bmc.verify"
188 },
189 "update" : {
190 "type" : "reboot"
191 }
192 }
193 }]
194 )"_json;
195
196 EXPECT_THAT(buildHandlerFromJson(j2), IsEmpty());
197}
198
199TEST(FirmwareJsonTest, MissingActionVerification)
200{
201 auto j2 = R"(
202 [{
203 "blob" : "/flash/image",
204 "handler" : {
205 "type" : "file",
206 "path" : "/run/initramfs/bmc-image"
207 },
208 "actions" : {
209 "preparation" : {
210 "type" : "systemd",
211 "unit" : "phosphor-ipmi-flash-bmc-prepare.target"
212 },
213 "update" : {
214 "type" : "reboot"
215 }
216 }
217 }]
218 )"_json;
219
220 EXPECT_THAT(buildHandlerFromJson(j2), IsEmpty());
221}
222
223TEST(FirmwareJsonTest, MissingActionUpdate)
224{
225 auto j2 = R"(
226 [{
227 "blob" : "/flash/image",
228 "handler" : {
229 "type" : "file",
230 "path" : "/run/initramfs/bmc-image"
231 },
232 "actions" : {
233 "preparation" : {
234 "type" : "systemd",
235 "unit" : "phosphor-ipmi-flash-bmc-prepare.target"
236 },
237 "verification" : {
238 "type" : "fileSystemdVerify",
239 "unit" : "phosphor-ipmi-flash-bmc-verify.target",
240 "path" : "/tmp/bmc.verify"
241 }
242 }
243 }]
244 )"_json;
245
246 EXPECT_THAT(buildHandlerFromJson(j2), IsEmpty());
247}
248
249TEST(FirmwareJsonTest, TwoConfigsOneInvalidReturnsValid)
250{
251 auto j2 = R"(
252 [{
253 "blob" : "/flash/image",
254 "actions" : {
255 "preparation" : {
256 "type" : "systemd",
257 "unit" : "phosphor-ipmi-flash-bmc-prepare.target"
258 },
259 "verification" : {
260 "type" : "fileSystemdVerify",
261 "unit" : "phosphor-ipmi-flash-bmc-verify.target",
262 "path" : "/tmp/bmc.verify"
263 },
264 "update" : {
265 "type" : "reboot"
266 }
267 }
268 },
269 {
270 "blob" : "/flash/image2",
271 "handler" : {
272 "type" : "file",
273 "path" : "/run/initramfs/bmc-image"
274 },
275 "actions" : {
276 "preparation" : {
277 "type" : "systemd",
278 "unit" : "phosphor-ipmi-flash-bmc-prepare.target"
279 },
280 "verification" : {
281 "type" : "fileSystemdVerify",
282 "unit" : "phosphor-ipmi-flash-bmc-verify.target",
283 "path" : "/tmp/bmc.verify"
284 },
285 "update" : {
286 "type" : "reboot"
287 }
288 }
289 }]
290 )"_json;
291
292 auto h = buildHandlerFromJson(j2);
293 EXPECT_EQ(h[0].blobId, "/flash/image2");
294 EXPECT_EQ(h.size(), 1);
295}
296
297/*
298 * TODO: It may be worth individually using builders per type, and testing
299 * those.
300 *
301 * TODO: Only allow unique handler blob paths (tested at a higher level).
302 */
303
Patrick Venture097435f2019-08-15 07:39:48 -0700304TEST(FirmwareJsonTest, VerifyBlobNameMatches)
305{
306 /* A perfect configuration except the blob name doesn't start with "/flash/"
307 */
308 auto j2 = R"(
309 [{
310 "blob" : "bmc-image-flash",
311 "handler" : {
312 "type" : "file",
313 "path" : "/run/initramfs/bmc-image"
314 },
315 "actions" : {
316 "preparation" : {
317 "type" : "systemd",
318 "unit" : "phosphor-ipmi-flash-bmc-prepare.target"
319 },
320 "verification" : {
321 "type" : "fileSystemdVerify",
322 "unit" : "phosphor-ipmi-flash-bmc-verify.target",
323 "path" : "/tmp/bmc.verify"
324 },
325 "update" : {
326 "type" : "reboot"
327 }
328 }
329 }]
330 )"_json;
331
332 EXPECT_THAT(buildHandlerFromJson(j2), IsEmpty());
333}
334
335TEST(FirmwareJsonTest, VerifyMinimumBlobNameLength)
336{
337 /* A perfect configuration except the blob name is effectively zero length.
338 */
339 auto j2 = R"(
340 [{
341 "blob" : "/flash/",
342 "handler" : {
343 "type" : "file",
344 "path" : "/run/initramfs/bmc-image"
345 },
346 "actions" : {
347 "preparation" : {
348 "type" : "systemd",
349 "unit" : "phosphor-ipmi-flash-bmc-prepare.target"
350 },
351 "verification" : {
352 "type" : "fileSystemdVerify",
353 "unit" : "phosphor-ipmi-flash-bmc-verify.target",
354 "path" : "/tmp/bmc.verify"
355 },
356 "update" : {
357 "type" : "reboot"
358 }
359 }
360 }]
361 )"_json;
362
363 EXPECT_THAT(buildHandlerFromJson(j2), IsEmpty());
364}
365
Patrick Venture298930a2019-07-03 11:44:52 -0700366TEST(FirmwareJsonTest, VerifySystemdWithReboot)
367{
368 auto j2 = R"(
369 [{
370 "blob" : "/flash/image",
371 "handler" : {
372 "type" : "file",
373 "path" : "/run/initramfs/bmc-image"
374 },
375 "actions" : {
376 "preparation" : {
377 "type" : "systemd",
378 "unit" : "phosphor-ipmi-flash-bmc-prepare.target"
379 },
380 "verification" : {
381 "type" : "fileSystemdVerify",
382 "unit" : "phosphor-ipmi-flash-bmc-verify.target",
383 "path" : "/tmp/bmc.verify"
384 },
385 "update" : {
386 "type" : "reboot"
387 }
388 }
389 }]
390 )"_json;
391
392 auto h = buildHandlerFromJson(j2);
393 EXPECT_EQ(h[0].blobId, "/flash/image");
394 EXPECT_FALSE(h[0].handler == nullptr);
395 EXPECT_FALSE(h[0].actions == nullptr);
396 EXPECT_FALSE(h[0].actions->preparation == nullptr);
397 EXPECT_FALSE(h[0].actions->verification == nullptr);
398 EXPECT_FALSE(h[0].actions->update == nullptr);
399}
400
401TEST(FirmwareJsonTest, VerifyMultipleHandlersReturned)
402{
403 auto j2 = R"(
404 [{
405 "blob" : "/flash/image",
406 "handler" : {
407 "type" : "file",
408 "path" : "/run/initramfs/bmc-image"
409 },
410 "actions" : {
411 "preparation" : {
412 "type" : "systemd",
413 "unit" : "phosphor-ipmi-flash-bmc-prepare.target"
414 },
415 "verification" : {
416 "type" : "fileSystemdVerify",
417 "unit" : "phosphor-ipmi-flash-bmc-verify.target",
418 "path" : "/tmp/bmc.verify"
419 },
420 "update" : {
421 "type" : "systemd",
422 "unit" : "phosphor-ipmi-flash-bmc-update.target"
423 }
424 }
425 },
426 {
427 "blob" : "/flash/bios",
428 "handler" : {
429 "type" : "file",
430 "path" : "/run/initramfs/bmc-image"
431 },
432 "actions" : {
433 "preparation" : {
434 "type" : "systemd",
435 "unit" : "phosphor-ipmi-flash-bmc-prepare.target"
436 },
437 "verification" : {
438 "type" : "fileSystemdVerify",
439 "unit" : "phosphor-ipmi-flash-bmc-verify.target",
440 "path" : "/tmp/bmc.verify"
441 },
442 "update" : {
443 "type" : "systemd",
444 "unit" : "phosphor-ipmi-flash-bmc-update.target"
445 }
446 }
447 }]
448 )"_json;
449
450 auto h = buildHandlerFromJson(j2);
451 EXPECT_EQ(h.size(), 2);
452 EXPECT_EQ(h[0].blobId, "/flash/image");
453 EXPECT_EQ(h[1].blobId, "/flash/bios");
454}
455
456TEST(FirmwareJsonTest, VerifyValidSingleNonReboot)
457{
458 auto j2 = R"(
459 [{
460 "blob" : "/flash/image",
461 "handler" : {
462 "type" : "file",
463 "path" : "/run/initramfs/bmc-image"
464 },
465 "actions" : {
466 "preparation" : {
467 "type" : "systemd",
468 "unit" : "phosphor-ipmi-flash-bmc-prepare.target"
469 },
470 "verification" : {
471 "type" : "fileSystemdVerify",
472 "unit" : "phosphor-ipmi-flash-bmc-verify.target",
473 "path" : "/tmp/bmc.verify"
474 },
475 "update" : {
476 "type" : "systemd",
477 "unit" : "phosphor-ipmi-flash-bmc-update.target"
478 }
479 }
480 }]
481 )"_json;
482
483 auto h = buildHandlerFromJson(j2);
484 EXPECT_EQ(h[0].blobId, "/flash/image");
485 EXPECT_FALSE(h[0].handler == nullptr);
486 EXPECT_FALSE(h[0].actions == nullptr);
487 EXPECT_FALSE(h[0].actions->preparation == nullptr);
488 EXPECT_FALSE(h[0].actions->verification == nullptr);
Patrick Venture29af1e32019-08-05 13:42:28 -0700489 auto verifier = reinterpret_cast<SystemdWithStatusFile*>(
Patrick Ventureee614ec2019-08-05 12:08:44 -0700490 h[0].actions->verification.get());
491 EXPECT_THAT(verifier->getMode(), "replace");
Patrick Venture298930a2019-07-03 11:44:52 -0700492 EXPECT_FALSE(h[0].actions->update == nullptr);
Patrick Venturee0216d22019-08-21 10:17:39 -0700493 auto updater = reinterpret_cast<SystemdNoFile*>(h[0].actions->update.get());
Patrick Venture0caec992019-08-05 09:58:27 -0700494 EXPECT_THAT(updater->getMode(), "replace");
495}
496
Patrick Venture984d94d2019-08-05 12:23:59 -0700497TEST(FirmwareJsonTest, VerifyValidWithModes)
Patrick Venture0caec992019-08-05 09:58:27 -0700498{
499 auto j2 = R"(
500 [{
501 "blob" : "/flash/image",
502 "handler" : {
503 "type" : "file",
504 "path" : "/run/initramfs/bmc-image"
505 },
506 "actions" : {
507 "preparation" : {
508 "type" : "systemd",
509 "unit" : "phosphor-ipmi-flash-bmc-prepare.target"
510 },
511 "verification" : {
512 "type" : "fileSystemdVerify",
513 "unit" : "phosphor-ipmi-flash-bmc-verify.target",
Patrick Venture984d94d2019-08-05 12:23:59 -0700514 "path" : "/tmp/bmc.verify",
515 "mode" : "replace-nope"
Patrick Venture0caec992019-08-05 09:58:27 -0700516 },
517 "update" : {
518 "type" : "systemd",
519 "mode" : "replace-fake",
520 "unit" : "phosphor-ipmi-flash-bmc-update.target"
521 }
522 }
523 }]
524 )"_json;
525
526 auto h = buildHandlerFromJson(j2);
527 EXPECT_EQ(h[0].blobId, "/flash/image");
528 EXPECT_FALSE(h[0].handler == nullptr);
529 EXPECT_FALSE(h[0].actions == nullptr);
530 EXPECT_FALSE(h[0].actions->preparation == nullptr);
531 EXPECT_FALSE(h[0].actions->verification == nullptr);
Patrick Venture29af1e32019-08-05 13:42:28 -0700532 auto verifier = reinterpret_cast<SystemdWithStatusFile*>(
Patrick Venture984d94d2019-08-05 12:23:59 -0700533 h[0].actions->verification.get());
534 EXPECT_THAT(verifier->getMode(), "replace-nope");
Patrick Venture0caec992019-08-05 09:58:27 -0700535 EXPECT_FALSE(h[0].actions->update == nullptr);
Patrick Venturee0216d22019-08-21 10:17:39 -0700536 auto updater = reinterpret_cast<SystemdNoFile*>(h[0].actions->update.get());
Patrick Venture0caec992019-08-05 09:58:27 -0700537 EXPECT_THAT(updater->getMode(), "replace-fake");
Patrick Venture298930a2019-07-03 11:44:52 -0700538}
539
Patrick Venturec2baac92019-08-05 13:30:38 -0700540TEST(FirmwareJsonTest, VerifyValidUpdateWithFilePath)
541{
542 auto j2 = R"(
543 [{
544 "blob" : "/flash/image",
545 "handler" : {
546 "type" : "file",
547 "path" : "/run/initramfs/bmc-image"
548 },
549 "actions" : {
550 "preparation" : {
551 "type" : "systemd",
552 "unit" : "phosphor-ipmi-flash-bmc-prepare.target"
553 },
554 "verification" : {
555 "type" : "fileSystemdVerify",
556 "unit" : "phosphor-ipmi-flash-bmc-verify.target",
557 "path" : "/tmp/bmc.verify",
558 "mode" : "replace-nope"
559 },
560 "update" : {
561 "type" : "fileSystemdUpdate",
562 "mode" : "replace-fake",
563 "unit" : "phosphor-ipmi-flash-bmc-update.target",
564 "path" : "/tmp/update.verify"
565 }
566 }
567 }]
568 )"_json;
569
570 auto h = buildHandlerFromJson(j2);
571 EXPECT_EQ(h[0].blobId, "/flash/image");
572 EXPECT_FALSE(h[0].handler == nullptr);
573 EXPECT_FALSE(h[0].actions == nullptr);
574 EXPECT_FALSE(h[0].actions->preparation == nullptr);
575 EXPECT_FALSE(h[0].actions->verification == nullptr);
Patrick Venture29af1e32019-08-05 13:42:28 -0700576 auto verifier = reinterpret_cast<SystemdWithStatusFile*>(
Patrick Venturec2baac92019-08-05 13:30:38 -0700577 h[0].actions->verification.get());
578 EXPECT_THAT(verifier->getMode(), "replace-nope");
579 EXPECT_FALSE(h[0].actions->update == nullptr);
580 auto updater =
Patrick Venture29af1e32019-08-05 13:42:28 -0700581 reinterpret_cast<SystemdWithStatusFile*>(h[0].actions->update.get());
Patrick Venturec2baac92019-08-05 13:30:38 -0700582 EXPECT_THAT(updater->getMode(), "replace-fake");
583}
584
Patrick Ventured53d60a2020-04-07 09:01:34 -0700585TEST(FirmwareJsonTest, VerifySkipFields)
586{
587 // In this configuration, nothing happens because all actions are set to
588 // skip.
589 auto j2 = R"(
590 [{
591 "blob" : "/flash/image",
592 "handler" : {
593 "type" : "file",
594 "path" : "/run/initramfs/bmc-image"
595 },
596 "actions" : {
597 "preparation" : {
598 "type" : "skip"
599 },
600 "verification" : {
601 "type" : "skip"
602 },
603 "update" : {
604 "type" : "skip"
605 }
606 }
607 }]
608 )"_json;
609
610 auto h = buildHandlerFromJson(j2);
611 EXPECT_EQ(h[0].blobId, "/flash/image");
612 EXPECT_FALSE(h[0].handler == nullptr);
613 EXPECT_FALSE(h[0].actions == nullptr);
614 EXPECT_FALSE(h[0].actions->preparation == nullptr);
615 EXPECT_FALSE(h[0].actions->verification == nullptr);
616 EXPECT_FALSE(h[0].actions->update == nullptr);
617}
618
Patrick Venture298930a2019-07-03 11:44:52 -0700619} // namespace
620} // namespace ipmi_flash