]> git.proxmox.com Git - efi-boot-shim.git/blob - test-mock-variables.c
Switch to using gcc-12
[efi-boot-shim.git] / test-mock-variables.c
1 // SPDX-License-Identifier: BSD-2-Clause-Patent
2 /*
3 * test-mock-variables.c - test our mock variable implementation (irony)
4 * Copyright Peter Jones <pjones@redhat.com>
5 */
6
7 #include "shim.h"
8 #include "mock-variables.h"
9
10 #include <errno.h>
11 #include <efivar/efivar.h>
12 #include <stdio.h>
13 #include <sys/types.h>
14 #include <unistd.h>
15
16 #include "test-data-efivars-0.h"
17
18 #pragma GCC diagnostic ignored "-Wunused-label"
19
20 static const size_t guidstr_size = sizeof("8be4df61-93ca-11d2-aa0d-00e098032b8c");
21
22 void mock_print_guidname(EFI_GUID *guid, CHAR16 *name);
23 void mock_print_var_list(list_t *head);
24
25 static int
26 test_filter_out_helper(size_t nvars, const CHAR16 *varnames[nvars],
27 bool filter_out, UINTN expected_count)
28 {
29 const char *mok_rt_vars[n_mok_state_variables];
30 EFI_STATUS status;
31 EFI_GUID guid = SHIM_LOCK_GUID;
32 CHAR16 name[1024] = L"";
33 UINTN sz;
34 char asciiname[1024];
35 bool found = false;
36 int ret = 0;
37 UINTN count = 0;
38
39 for (size_t i = 0; i < n_mok_state_variables; i++) {
40 mok_rt_vars[i] = mok_state_variables[i].rtname8;
41 }
42
43 sz = sizeof(name);
44 status = RT->GetNextVariableName(&sz, name, &guid);
45 assert_equal_return(status, EFI_NOT_FOUND, -1, "got %lx, expected %lx");
46
47 mock_load_variables("test-data/efivars-1", mok_rt_vars, filter_out);
48
49 while (true) {
50 int rc = 0;
51
52 sz = sizeof(name);
53 status = RT->GetNextVariableName(&sz, name, &guid);
54 if (status == EFI_NOT_FOUND)
55 break;
56 if (EFI_ERROR(status))
57 return -1;
58
59 count += 1;
60 SetMem(asciiname, sizeof(asciiname), 0);
61 for (UINTN i = 0; i < sizeof(asciiname); i++)
62 asciiname[i] = name[i];
63 for (UINTN i = 0; varnames[i] != NULL; i++) {
64 if (sz == 0 || StrLen(varnames[i]) != sz-1)
65 continue;
66 if (StrCmp(name, varnames[i]) == 0) {
67 found = true;
68 if (filter_out) {
69 rc = assert_false_as_expr(found, -1,
70 "found=%u for undesired variable \"%s\"\n",
71 asciiname);
72 break;
73 }
74 }
75 }
76 if (!filter_out)
77 rc = assert_true_as_expr(found, -1,
78 "found=%u for undesired variable \"%s\"\n",
79 asciiname);
80 if (ret >= 0 && rc < 0)
81 ret = rc;
82 }
83
84 mock_reset_variables();
85 assert_equal_return(count, expected_count, -1, "%lu != %lu\n");
86 assert_true_return(list_empty(&mock_variables), -1, "%lu != %lu\n");
87
88 return ret;
89 }
90
91 static int
92 test_filter_out_true(void)
93 {
94 const CHAR16 *varnames[] = {
95 L"MokListRT",
96 L"MokListXRT",
97 L"SbatLevelRT",
98 NULL
99 };
100 size_t nvars = sizeof(varnames) / sizeof(varnames[0]);
101
102 return test_filter_out_helper(nvars, varnames, true, 3);
103 }
104
105 static int
106 test_filter_out_false(void)
107 {
108 const CHAR16 *varnames[] = {
109 L"MokListRT",
110 L"MokListXRT",
111 L"SbatLevelRT",
112 NULL
113 };
114 size_t nvars = sizeof(varnames) / sizeof(varnames[0]);
115
116 return test_filter_out_helper(nvars, varnames, false, 3);
117 }
118
119 static int
120 test_gnvn_buf_size_0(void)
121 {
122 UINTN size = 0;
123 CHAR16 buf[6] = { 0, };
124 EFI_STATUS status;
125 EFI_GUID empty_guid = { 0, };
126 int ret = -1;
127
128 status = RT->GetNextVariableName(&size, &buf[0], &GV_GUID);
129 assert_equal_return(status, EFI_INVALID_PARAMETER, -1, "0x%lx != 0x%lx\n");
130
131 size = 1;
132 status = RT->GetNextVariableName(&size, &buf[0], &GV_GUID);
133 assert_equal_return(status, EFI_NOT_FOUND, -1, "0x%lx != 0x%lx\n");
134
135 status = RT->SetVariable(L"test", &GV_GUID,
136 EFI_VARIABLE_BOOTSERVICE_ACCESS, 5, "test");
137 assert_equal_return(status, EFI_SUCCESS, -1, "0x%lx != 0x%lx\n");
138
139 size = 1;
140 status = RT->GetNextVariableName(&size, &buf[0], &empty_guid);
141 assert_equal_goto(status, EFI_NOT_FOUND, err, "0x%lx != 0x%lx\n");
142
143 size = 1;
144 status = RT->GetNextVariableName(&size, &buf[0], &GV_GUID);
145 assert_equal_goto(status, EFI_BUFFER_TOO_SMALL, err, "0x%lx != 0x%lx\n");
146 assert_equal_goto(size, StrSize(L"test"), err, "%zu != %zu\n");
147
148 size = StrSize(L"test");
149 status = RT->GetNextVariableName(&size, &buf[0], &GV_GUID);
150 assert_equal_goto(status, EFI_SUCCESS, err, "0x%lx != 0x%lx\n");
151
152 status = RT->SetVariable(L"testa", &GV_GUID,
153 EFI_VARIABLE_BOOTSERVICE_ACCESS, 5, "test");
154 assert_equal_return(status, EFI_SUCCESS, -1, "0x%lx != 0x%lx\n");
155
156 buf[0] = 0;
157 size = 1;
158 status = RT->GetNextVariableName(&size, &buf[0], &empty_guid);
159 assert_equal_goto(status, EFI_NOT_FOUND, err, "0x%lx != 0x%lx\n");
160
161 size = StrSize(L"test");
162 StrCpy(buf, L"test");
163 status = RT->GetNextVariableName(&size, &buf[0], &GV_GUID);
164 switch (mock_variable_sort_policy) {
165 case MOCK_SORT_DESCENDING:
166 case MOCK_SORT_PREPEND:
167 assert_equal_goto(status, EFI_NOT_FOUND, err, "0x%lx != 0x%lx\n");
168 break;
169 case MOCK_SORT_APPEND:
170 case MOCK_SORT_ASCENDING:
171 assert_equal_goto(status, EFI_BUFFER_TOO_SMALL, err, "0x%lx != 0x%lx\n");
172 break;
173 default:
174 break;
175 }
176
177 size = StrSize(L"testa");
178 StrCpy(buf, L"test");
179 status = RT->GetNextVariableName(&size, &buf[0], &GV_GUID);
180 switch (mock_variable_sort_policy) {
181 case MOCK_SORT_DESCENDING:
182 case MOCK_SORT_PREPEND:
183 assert_equal_goto(status, EFI_NOT_FOUND, err, "0x%lx != 0x%lx\n");
184 break;
185 case MOCK_SORT_APPEND:
186 case MOCK_SORT_ASCENDING:
187 assert_equal_goto(status, EFI_SUCCESS, err, "0x%lx != 0x%lx\n");
188 break;
189 default:
190 break;
191 }
192
193 ret = 0;
194 err:
195 mock_reset_variables();
196 return ret;
197 }
198
199 static int
200 test_gnvn_helper(char *testvars)
201 {
202 UINTN size = 0;
203 CHAR16 buf[8192] = { 0, };
204 EFI_STATUS status;
205 EFI_GUID empty_guid = { 0, };
206 int ret = -1;
207 const char *mok_rt_vars[n_mok_state_variables];
208
209 for (size_t i = 0; i < n_mok_state_variables; i++) {
210 mok_rt_vars[i] = mok_state_variables[i].rtname8;
211 }
212
213 mock_load_variables(testvars, mok_rt_vars, true);
214
215 size = sizeof(buf);
216 buf[0] = L'\0';
217 status = RT->GetNextVariableName(&size, buf, &GV_GUID);
218 assert_equal_goto(status, EFI_SUCCESS, err, "0x%lx != 0x%lx\n");
219
220 #if defined(SHIM_DEBUG) && SHIM_DEBUG != 0
221 dump_mock_variables(__FILE__, __LINE__, __func__);
222 #endif
223 switch (mock_variable_sort_policy) {
224 case MOCK_SORT_DESCENDING:
225 dump_mock_variables_if_wrong(__FILE__, __LINE__, __func__,
226 &GV_GUID, L"dbxDefault");
227 assert_zero_goto(StrCmp(buf, L"dbxDefault"), err, "0x%lx != 0x%lx\n");
228 break;
229 case MOCK_SORT_ASCENDING:
230 dump_mock_variables_if_wrong(__FILE__, __LINE__, __func__,
231 &GV_GUID, L"Boot0000");
232 assert_zero_goto(StrCmp(buf, L"Boot0000"), err, "0x%lx != 0x%lx buf:\"%s\"\n",
233 0, Str2str(buf));
234 break;
235 default:
236 break;
237 }
238
239 size = sizeof(buf);
240 buf[0] = 0;
241 status = RT->GetNextVariableName(&size, buf, &EFI_SECURE_BOOT_DB_GUID);
242 assert_equal_goto(status, EFI_SUCCESS, err, "0x%lx != 0x%lx\n");
243 switch (mock_variable_sort_policy) {
244 case MOCK_SORT_DESCENDING:
245 assert_zero_goto(StrCmp(buf, L"dbx"), err, "0x%lx != 0x%lx\n");
246 break;
247 case MOCK_SORT_ASCENDING:
248 assert_zero_goto(StrCmp(buf, L"db"), err, "0x%lx != 0x%lx\n");
249 break;
250 default:
251 break;
252 }
253
254 ret = 0;
255 err:
256 if (ret)
257 mock_print_var_list(&mock_variables);
258 mock_reset_variables();
259 return ret;
260 }
261
262 static int
263 test_gnvn_0(void)
264 {
265 return test_gnvn_helper("test-data/efivars-0");
266 }
267
268 static int
269 test_gnvn_1(void)
270 {
271 return test_gnvn_helper("test-data/efivars-1");
272 }
273
274 static int
275 test_get_variable_0(void)
276 {
277 UINTN size = 0;
278 uint8_t buf[8192] = { 0, };
279 EFI_STATUS status;
280 EFI_GUID empty_guid = { 0, };
281 UINT32 attrs = 0;
282 int ret = -1;
283 int cmp;
284 const char *mok_rt_vars[n_mok_state_variables];
285
286 for (size_t i = 0; i < n_mok_state_variables; i++) {
287 mok_rt_vars[i] = mok_state_variables[i].rtname8;
288 }
289
290 mock_load_variables("test-data/efivars-1", mok_rt_vars, true);
291
292 size = 0;
293 status = RT->GetVariable(L"Boot0000", &GV_GUID, &attrs, &size, buf);
294 assert_equal_goto(status, EFI_BUFFER_TOO_SMALL, err, "0x%lx != 0x%lx\n");
295
296 size = sizeof(buf);
297 status = RT->GetVariable(L"Boot0000", &GV_GUID, &attrs, &size, buf);
298 assert_equal_goto(status, EFI_SUCCESS, err, "0x%lx != 0x%lx\n");
299 assert_equal_goto(size, sizeof(test_data_efivars_0_Boot0000), err, "%zu != %zu\n");
300 assert_zero_goto(memcmp(buf, test_data_efivars_0_Boot0000, size), err, "%zu != %zu\n");
301
302 ret = 0;
303 err:
304 if (ret)
305 mock_print_var_list(&mock_variables);
306 mock_reset_variables();
307 return ret;
308 }
309
310 static int
311 test_set_variable_0(void)
312 {
313 UINTN size = 0;
314 uint8_t buf[8192] = { 0, };
315 EFI_STATUS status;
316 EFI_GUID empty_guid = { 0, };
317 UINT32 attrs = 0;
318 int ret = -1;
319 UINT32 bs_rt_nv = EFI_VARIABLE_BOOTSERVICE_ACCESS |
320 EFI_VARIABLE_RUNTIME_ACCESS |
321 EFI_VARIABLE_NON_VOLATILE;
322
323 size = 4;
324 strcpy(buf, "foo");
325 status = RT->SetVariable(L"tmp", &GV_GUID, bs_rt_nv, size, buf);
326 assert_equal_goto(status, EFI_SUCCESS, err, "0x%lx != 0x%lx\n");
327
328 size = sizeof(buf);
329 SetMem(buf, sizeof(buf), 0);
330 status = RT->GetVariable(L"tmp", &GV_GUID, &attrs, &size, buf);
331 assert_equal_goto(status, EFI_SUCCESS, err, "0x%lx != 0x%lx\n");
332 assert_equal_goto(size, 4, err, "%zu != %zu\n");
333 assert_zero_goto(memcmp(buf, "foo", 4), err, "0x%lx != 0x%lx\n");
334
335 size = 5;
336 strcpy(buf, "bang");
337 status = RT->SetVariable(L"tmp", &GV_GUID,
338 EFI_VARIABLE_NON_VOLATILE |
339 EFI_VARIABLE_BOOTSERVICE_ACCESS |
340 EFI_VARIABLE_RUNTIME_ACCESS,
341 size, buf);
342 size = sizeof(buf);
343 SetMem(buf, sizeof(buf), 0);
344 status = RT->GetVariable(L"tmp", &GV_GUID, &attrs, &size, buf);
345 assert_equal_goto(status, EFI_SUCCESS, err, "0x%lx != 0x%lx\n");
346 assert_equal_goto(size, 5, err, "%zu != %zu\n");
347 assert_zero_goto(memcmp(buf, "bang", 5), err, "%d != %d\n");
348
349 size = 5;
350 strcpy(buf, "foop");
351 status = RT->SetVariable(L"tmp", &GV_GUID, bs_rt_nv, size, buf);
352 assert_equal_goto(status, EFI_SUCCESS, err, "0x%lx != 0x%lx\n");
353
354 size = sizeof(buf);
355 SetMem(buf, sizeof(buf), 0);
356 status = RT->GetVariable(L"tmp", &GV_GUID, &attrs, &size, buf);
357 assert_equal_goto(status, EFI_SUCCESS, err, "0x%lx != 0x%lx\n");
358 assert_equal_goto(size, 5, err, "%zu != %zu\n");
359 assert_zero_goto(memcmp(buf, "foop", 5), err, "%d != %d\n");
360
361 size = 0;
362 strcpy(buf, "");
363 status = RT->SetVariable(L"tmp", &GV_GUID, bs_rt_nv | EFI_VARIABLE_APPEND_WRITE, size, buf);
364 assert_equal_goto(status, EFI_SUCCESS, err, "0x%lx != 0x%lx\n");
365
366 size = sizeof(buf);
367 SetMem(buf, sizeof(buf), 0);
368 status = RT->GetVariable(L"tmp", &GV_GUID, &attrs, &size, buf);
369 assert_equal_goto(status, EFI_SUCCESS, err, "0x%lx != 0x%lx\n");
370 assert_equal_goto(size, 5, err, "%zu != %zu\n");
371 assert_zero_goto(memcmp(buf, "foop", 5), err, "%d != %d\n");
372
373 size = 5;
374 strcpy(buf, "poof");
375 status = RT->SetVariable(L"tmp", &GV_GUID, bs_rt_nv | EFI_VARIABLE_APPEND_WRITE, size, buf);
376 assert_equal_goto(status, EFI_SUCCESS, err, "0x%lx != 0x%lx\n");
377
378 size = sizeof(buf);
379 SetMem(buf, sizeof(buf), 0);
380 status = RT->GetVariable(L"tmp", &GV_GUID, &attrs, &size, buf);
381 assert_equal_goto(status, EFI_SUCCESS, err, "0x%lx != 0x%lx\n");
382 assert_equal_goto(size, 10, err, "%zu != %zu\n");
383 assert_zero_goto(memcmp(buf, "foop\0poof", 10), err, "%d != %d\n");
384 ret = 0;
385 err:
386 if (ret)
387 mock_print_var_list(&mock_variables);
388 mock_reset_variables();
389 return ret;
390 }
391
392 static void
393 dump_config_table_if_wrong(const char * const func, int line, ...)
394 {
395 va_list alist, blist;
396 bool okay = true;
397 size_t n = 0, m = 0;
398
399 va_start(alist, line);
400 va_copy(blist, alist);
401
402 int idx = va_arg(alist, int);
403 EFI_GUID *guid = va_arg(alist, EFI_GUID *);
404 while (idx >= 0 && guid != NULL) {
405 EFI_CONFIGURATION_TABLE *entry;
406 if (idx < 0)
407 goto nexta;
408
409 n += 1;
410 if (idx >= (int)ST->NumberOfTableEntries) {
411 okay = false;
412 goto nexta;
413 }
414
415 entry = &ST->ConfigurationTable[idx];
416 if (CompareGuid(guid, &entry->VendorGuid) != 0)
417 okay = false;
418
419 nexta:
420 idx = va_arg(alist, int);
421 guid = va_arg(alist, EFI_GUID *);
422 }
423 va_end(alist);
424
425 if (okay)
426 return;
427
428 printf("%s:%d:%s(): %d entries:\n", __FILE__, line, func, ST->NumberOfTableEntries);
429 idx = va_arg(blist, int);
430 guid = va_arg(blist, EFI_GUID *);
431 while (idx >= 0 && guid != NULL) {
432 EFI_CONFIGURATION_TABLE *entry;
433
434 if (idx >= (int)ST->NumberOfTableEntries) {
435 printf("\t[%d]: invalid index for " GUID_FMT "\n",
436 idx, GUID_ARGS(*guid));
437 goto nexta;
438 }
439
440 if (idx < 0) {
441 printf("\t[%d]: " GUID_FMT "\n", idx, GUID_ARGS(*guid));
442 } else {
443 entry = &ST->ConfigurationTable[idx];
444 printf("\t[%d]: %p ", idx, entry);
445 printf("{.VendorGuid:" GUID_FMT ",", GUID_ARGS(entry->VendorGuid));
446 printf("&.VendorTable:%p}\n", entry->VendorTable);
447 if (CompareGuid(guid, &entry->VendorGuid) != 0)
448 printf("\t\t\t expected:" GUID_FMT "\n", GUID_ARGS(*guid));
449 }
450 next:
451 idx = va_arg(blist, int);
452 guid = va_arg(blist, EFI_GUID *);
453 }
454 va_end(blist);
455
456 if ((int)ST->NumberOfTableEntries - n == 0)
457 return;
458
459 printf("%d extra table entries:\n", ST->NumberOfTableEntries - n);
460 for (m = n; m < ST->NumberOfTableEntries; m++) {
461 EFI_CONFIGURATION_TABLE *entry;
462
463 entry = &ST->ConfigurationTable[m];
464
465 printf("\t[%d]: %p ", m, entry);
466 printf("{.VendorGuid:" GUID_FMT ",", GUID_ARGS(entry->VendorGuid));
467 printf("&.VendorTable:%p}\n", entry->VendorTable);
468 }
469 }
470
471 static int
472 test_install_config_table_0(void)
473 {
474 int ret = -1;
475 EFI_STATUS status;
476
477 /*
478 * These three guids are chosen on purpose: they start with "a",
479 * "b", and "c", respective to their variable names, so you can
480 * identify them when dumped.
481 */
482 EFI_GUID aguid = SECURITY_PROTOCOL_GUID;
483 char astr[guidstr_size];
484 void *astrp = &astr[0];
485 int aidx = -1;
486
487 EFI_GUID bguid = EFI_HTTP_BINDING_GUID;
488 char bstr[guidstr_size];
489 void *bstrp = &bstr[0];
490 int bidx = -1;
491
492 EFI_GUID cguid = MOK_VARIABLE_STORE;
493 char cstr[guidstr_size];
494 void *cstrp = &cstr[0];
495 int cidx = -1;
496
497 EFI_GUID lip = LOADED_IMAGE_PROTOCOL;
498
499 EFI_GUID guids[3];
500
501 char tmpstr[guidstr_size];
502
503 sprintf(astrp, GUID_FMT, GUID_ARGS(aguid));
504 sprintf(bstrp, GUID_FMT, GUID_ARGS(bguid));
505 sprintf(cstrp, GUID_FMT, GUID_ARGS(cguid));
506
507 assert_equal_return(ST->NumberOfTableEntries, 0, -1, "%lu != %lu\n");
508
509 /*
510 * test installing one
511 */
512 status = BS->InstallConfigurationTable(&bguid, bstrp);
513 assert_equal_return(status, EFI_SUCCESS, -1, "%lx != %lx\n");
514 assert_equal_goto(ST->NumberOfTableEntries, 1, err, "%lu != %lu\n");
515
516 sprintf(tmpstr, GUID_FMT, GUID_ARGS(ST->ConfigurationTable[0].VendorGuid));
517 assert_zero_goto(CompareGuid(&ST->ConfigurationTable[0].VendorGuid, &bguid),
518 err, "%d != 0 (%s != %s)\n", tmpstr, bstr);
519 assert_equal_goto(ST->ConfigurationTable[0].VendorTable,
520 bstrp, err, "%p != %p\n");
521
522 /*
523 * test re-installing the same one
524 */
525 status = BS->InstallConfigurationTable(&bguid, bstrp);
526 assert_equal_goto(status, EFI_SUCCESS, err, "%lx != %lx\n");
527 assert_equal_goto(ST->NumberOfTableEntries, 1, err, "%lu != %lu\n");
528
529 sprintf(tmpstr, GUID_FMT, GUID_ARGS(ST->ConfigurationTable[0].VendorGuid));
530 assert_zero_goto(CompareGuid(&ST->ConfigurationTable[0].VendorGuid, &bguid),
531 err, "%d != 0 (%s != %s)\n", tmpstr, bstr);
532 assert_equal_goto(ST->ConfigurationTable[0].VendorTable,
533 bstrp, err, "%p != %p\n");
534
535 /*
536 * Test installing a second one
537 */
538 status = BS->InstallConfigurationTable(&aguid, astrp);
539 assert_equal_goto(status, EFI_SUCCESS, err, "%lx != %lx\n");
540 assert_equal_goto(ST->NumberOfTableEntries, 2, err, "%lu != %lu\n");
541
542 switch (mock_config_table_sort_policy) {
543 case MOCK_SORT_DESCENDING:
544 aidx = 1;
545 bidx = 0;
546 break;
547 case MOCK_SORT_PREPEND:
548 aidx = 0;
549 bidx = 1;
550 break;
551 case MOCK_SORT_APPEND:
552 aidx = 1;
553 bidx = 0;
554 break;
555 case MOCK_SORT_ASCENDING:
556 aidx = 0;
557 bidx = 1;
558 break;
559 default:
560 break;
561 }
562
563 dump_config_table_if_wrong(__func__, __LINE__,
564 aidx, &aguid,
565 bidx, &bguid,
566 cidx, &cguid,
567 -1, NULL);
568
569 sprintf(tmpstr, GUID_FMT, GUID_ARGS(ST->ConfigurationTable[aidx].VendorGuid));
570 assert_zero_goto(CompareGuid(&ST->ConfigurationTable[aidx].VendorGuid, &aguid),
571 err, "%d != 0 (%s != %s)\n", tmpstr, astr);
572 assert_equal_goto(ST->ConfigurationTable[aidx].VendorTable, astrp,
573 err, "%p != %p\n");
574
575 sprintf(tmpstr, GUID_FMT, GUID_ARGS(ST->ConfigurationTable[bidx].VendorGuid));
576 assert_zero_goto(CompareGuid(&ST->ConfigurationTable[bidx].VendorGuid, &bguid),
577 err, "%d != 0 (%s != %s)\n", tmpstr, bstr);
578 assert_equal_goto(ST->ConfigurationTable[bidx].VendorTable, bstrp,
579 err, "%p != %p\n");
580
581 /*
582 * Test installing a third one
583 */
584 status = BS->InstallConfigurationTable(&cguid, cstrp);
585 assert_equal_goto(status, EFI_SUCCESS, err, "%lx != %lx\n");
586 assert_equal_goto(ST->NumberOfTableEntries, 3, err, "%lu != %lu\n");
587
588 switch (mock_config_table_sort_policy) {
589 case MOCK_SORT_DESCENDING:
590 aidx = 2;
591 bidx = 1;
592 cidx = 0;
593 break;
594 case MOCK_SORT_PREPEND:
595 aidx = 1;
596 bidx = 2;
597 cidx = 0;
598 break;
599 case MOCK_SORT_APPEND:
600 aidx = 1;
601 bidx = 0;
602 cidx = 2;
603 break;
604 case MOCK_SORT_ASCENDING:
605 aidx = 0;
606 bidx = 1;
607 cidx = 2;
608 break;
609 default:
610 break;
611 }
612
613 dump_config_table_if_wrong(__func__, __LINE__,
614 aidx, &aguid,
615 bidx, &bguid,
616 cidx, &cguid,
617 -1, NULL);
618
619 sprintf(tmpstr, GUID_FMT, GUID_ARGS(ST->ConfigurationTable[aidx].VendorGuid));
620 assert_zero_goto(CompareGuid(&ST->ConfigurationTable[aidx].VendorGuid, &aguid),
621 err, "%d != 0 (%s != %s)\n", tmpstr, astr);
622 assert_equal_goto(ST->ConfigurationTable[aidx].VendorTable, astrp,
623 err, "%p != %p\n");
624 memcpy(&guids[aidx], &aguid, sizeof(EFI_GUID));
625
626 sprintf(tmpstr, GUID_FMT, GUID_ARGS(ST->ConfigurationTable[bidx].VendorGuid));
627 assert_zero_goto(CompareGuid(&ST->ConfigurationTable[bidx].VendorGuid, &bguid),
628 err, "%d != 0 (%s != %s)\n", tmpstr, bstr);
629 assert_equal_goto(ST->ConfigurationTable[bidx].VendorTable, bstrp,
630 err, "%p != %p\n");
631 memcpy(&guids[bidx], &bguid, sizeof(EFI_GUID));
632
633 sprintf(tmpstr, GUID_FMT, GUID_ARGS(ST->ConfigurationTable[cidx].VendorGuid));
634 assert_zero_goto(CompareGuid(&ST->ConfigurationTable[cidx].VendorGuid, &cguid),
635 err, "%d != 0 (%s != %s)\n", tmpstr, cstr);
636 assert_equal_goto(ST->ConfigurationTable[cidx].VendorTable, cstrp,
637 err, "%p != %p\n");
638 memcpy(&guids[cidx], &cguid, sizeof(EFI_GUID));
639
640 /*
641 * Test removing NULL guid
642 */
643 status = BS->InstallConfigurationTable(NULL, NULL);
644 assert_equal_goto(status, EFI_INVALID_PARAMETER, err, "%lx != %lx\n");
645 assert_equal_goto(ST->NumberOfTableEntries, 3, err, "%lu != %lu\n");
646
647 /*
648 * Test removing a guid that's not present
649 */
650 status = BS->InstallConfigurationTable(&lip, NULL);
651 assert_equal_goto(status, EFI_NOT_FOUND, err, "%lx != %lx\n");
652 assert_equal_goto(ST->NumberOfTableEntries, 3, err, "%lu != %lu\n");
653
654 /*
655 * Test removing the middle one
656 */
657 status = BS->InstallConfigurationTable(&guids[1], NULL);
658 assert_equal_goto(status, EFI_SUCCESS, err, "%lx != %lx\n");
659 assert_equal_goto(ST->NumberOfTableEntries, 2, err, "%lu != %lu\n");
660
661 switch (mock_config_table_sort_policy) {
662 case MOCK_SORT_DESCENDING:
663 aidx = 1;
664 bidx = -1;
665 cidx = 0;
666 break;
667 case MOCK_SORT_PREPEND:
668 aidx = -1;
669 bidx = 1;
670 cidx = 0;
671 break;
672 case MOCK_SORT_APPEND:
673 aidx = -1;
674 bidx = 0;
675 cidx = 1;
676 break;
677 case MOCK_SORT_ASCENDING:
678 aidx = 0;
679 bidx = -1;
680 cidx = 1;
681 break;
682 default:
683 break;
684 }
685
686 dump_config_table_if_wrong(__func__, __LINE__,
687 aidx, &aguid,
688 bidx, &bguid,
689 cidx, &cguid,
690 -1, NULL);
691
692 if (aidx >= 0) {
693 sprintf(tmpstr, GUID_FMT, GUID_ARGS(ST->ConfigurationTable[aidx].VendorGuid));
694 assert_zero_goto(CompareGuid(&ST->ConfigurationTable[aidx].VendorGuid, &aguid),
695 err, "%d != 0 (%s != %s)\n", tmpstr, astr);
696 assert_equal_goto(ST->ConfigurationTable[aidx].VendorTable, astrp,
697 err, "%p != %p\n");
698 memcpy(&guids[aidx], &aguid, sizeof(EFI_GUID));
699 }
700
701 if (bidx >= 0) {
702 sprintf(tmpstr, GUID_FMT, GUID_ARGS(ST->ConfigurationTable[bidx].VendorGuid));
703 assert_zero_goto(CompareGuid(&ST->ConfigurationTable[bidx].VendorGuid, &bguid),
704 err, "%d != 0 (%s != %s)\n", tmpstr, bstr);
705 assert_equal_goto(ST->ConfigurationTable[bidx].VendorTable, bstrp,
706 err, "%p != %p\n");
707 memcpy(&guids[bidx], &bguid, sizeof(EFI_GUID));
708 }
709
710 if (cidx >= 0) {
711 sprintf(tmpstr, GUID_FMT, GUID_ARGS(ST->ConfigurationTable[cidx].VendorGuid));
712 assert_zero_goto(CompareGuid(&ST->ConfigurationTable[cidx].VendorGuid, &cguid),
713 err, "%d != 0 (%s != %s)\n", tmpstr, cstr);
714 assert_equal_goto(ST->ConfigurationTable[cidx].VendorTable, cstrp,
715 err, "%p != %p\n");
716 memcpy(&guids[cidx], &cguid, sizeof(EFI_GUID));
717 }
718
719 /*
720 * Test removing the lowest one
721 */
722 status = BS->InstallConfigurationTable(&guids[0], NULL);
723 assert_equal_goto(status, EFI_SUCCESS, err, "%lx != %lx\n");
724 assert_equal_goto(ST->NumberOfTableEntries, 1, err, "%lu != %lu\n");
725
726 switch (mock_config_table_sort_policy) {
727 case MOCK_SORT_DESCENDING:
728 aidx = 0;
729 bidx = -1;
730 cidx = -1;
731 break;
732 case MOCK_SORT_PREPEND:
733 aidx = -1;
734 bidx = 0;
735 cidx = -1;
736 break;
737 case MOCK_SORT_APPEND:
738 aidx = -1;
739 bidx = -1;
740 cidx = 0;
741 break;
742 case MOCK_SORT_ASCENDING:
743 aidx = -1;
744 bidx = -1;
745 cidx = 0;
746 break;
747 default:
748 break;
749 }
750
751 dump_config_table_if_wrong(__func__, __LINE__,
752 aidx, &aguid,
753 bidx, &bguid,
754 cidx, &cguid,
755 -1, NULL);
756
757 if (aidx >= 0) {
758 sprintf(tmpstr, GUID_FMT, GUID_ARGS(ST->ConfigurationTable[aidx].VendorGuid));
759 assert_zero_goto(CompareGuid(&ST->ConfigurationTable[aidx].VendorGuid, &aguid),
760 err, "%d != 0 (%s != %s)\n", tmpstr, astr);
761 assert_equal_goto(ST->ConfigurationTable[aidx].VendorTable, astrp,
762 err, "%p != %p\n");
763 memcpy(&guids[aidx], &aguid, sizeof(EFI_GUID));
764 }
765
766 if (bidx >= 0) {
767 sprintf(tmpstr, GUID_FMT, GUID_ARGS(ST->ConfigurationTable[bidx].VendorGuid));
768 assert_zero_goto(CompareGuid(&ST->ConfigurationTable[bidx].VendorGuid, &bguid),
769 err, "%d != 0 (%s != %s)\n", tmpstr, bstr);
770 assert_equal_goto(ST->ConfigurationTable[bidx].VendorTable, bstrp,
771 err, "%p != %p\n");
772 memcpy(&guids[bidx], &bguid, sizeof(EFI_GUID));
773 }
774
775 if (cidx >= 0) {
776 sprintf(tmpstr, GUID_FMT, GUID_ARGS(ST->ConfigurationTable[cidx].VendorGuid));
777 assert_zero_goto(CompareGuid(&ST->ConfigurationTable[cidx].VendorGuid, &cguid),
778 err, "%d != 0 (%s != %s)\n", tmpstr, cstr);
779 assert_equal_goto(ST->ConfigurationTable[cidx].VendorTable, cstrp,
780 err, "%p != %p\n");
781 memcpy(&guids[cidx], &cguid, sizeof(EFI_GUID));
782 }
783
784 /*
785 * Test removing the last one
786 */
787 status = BS->InstallConfigurationTable(&guids[0], NULL);
788 assert_equal_goto(status, EFI_SUCCESS, err, "%lx != %lx\n");
789 assert_equal_goto(ST->NumberOfTableEntries, 0, err, "%lu != %lu\n");
790
791 /*
792 * Test removing it again
793 */
794 status = BS->InstallConfigurationTable(&guids[0], NULL);
795 assert_equal_goto(status, EFI_NOT_FOUND, err, "%lx != %lx\n");
796 assert_equal_goto(ST->NumberOfTableEntries, 0, err, "%lu != %lu\n");
797
798 ret = 0;
799 err:
800 while (ST->NumberOfTableEntries)
801 BS->InstallConfigurationTable(&ST->ConfigurationTable[0].VendorGuid, NULL);
802 mock_reset_config_table();
803
804 return ret;
805 }
806
807 int
808 main(void)
809 {
810 int status = 0;
811 setbuf(stdout, NULL);
812
813 const char *policies[] = {
814 "MOCK_SORT_DESCENDING",
815 "MOCK_SORT_PREPEND",
816 "MOCK_SORT_APPEND",
817 "MOCK_SORT_ASCENDING",
818 "MOCK_SORT_MAX_SENTINEL"
819 };
820
821 test(test_filter_out_true);
822 test(test_filter_out_false);
823
824 for (int i = 0; i < MOCK_SORT_MAX_SENTINEL; i++) {
825 mock_variable_sort_policy = i;
826 mock_config_table_sort_policy = i;
827 printf("%s: setting variable sort policy to %s\n",
828 program_invocation_short_name, policies[i]);
829
830 test(test_gnvn_buf_size_0);
831 test(test_gnvn_0);
832 test(test_gnvn_1);
833
834 test(test_install_config_table_0);
835 }
836
837 test(test_get_variable_0);
838 test(test_set_variable_0);
839 return status;
840 }
841
842 // vim:fenc=utf-8:tw=75:noet