diff options
| author | Steve McIntyre <steve@einval.com> | 2022-04-27 22:41:59 +0100 |
|---|---|---|
| committer | Steve McIntyre <steve@einval.com> | 2022-04-27 22:41:59 +0100 |
| commit | acb8d1ffbca46190a934a5b27185a95ba4451fda (patch) | |
| tree | dc4a7291fa6dff3855f012b74ee779fa49ce8e94 /test-mock-variables.c | |
| parent | 39c311d6773b915df277a62425a6715b2d977ab6 (diff) | |
| parent | 8529e0f7f70f427a7202815061362eceba6bfc50 (diff) | |
| download | efi-boot-shim-acb8d1ffbca46190a934a5b27185a95ba4451fda.tar.gz efi-boot-shim-acb8d1ffbca46190a934a5b27185a95ba4451fda.zip | |
Update upstream source from tag 'upstream/15.5'
Update to upstream version '15.5'
with Debian dir 3ac353daa3d32301e3b225b2b6f446200a2c682f
Diffstat (limited to 'test-mock-variables.c')
| -rw-r--r-- | test-mock-variables.c | 842 |
1 files changed, 842 insertions, 0 deletions
diff --git a/test-mock-variables.c b/test-mock-variables.c new file mode 100644 index 00000000..c7e42b05 --- /dev/null +++ b/test-mock-variables.c @@ -0,0 +1,842 @@ +// SPDX-License-Identifier: BSD-2-Clause-Patent +/* + * test-mock-variables.c - test our mock variable implementation (irony) + * Copyright Peter Jones <pjones@redhat.com> + */ + +#include "shim.h" +#include "mock-variables.h" + +#include <errno.h> +#include <efivar/efivar.h> +#include <stdio.h> +#include <sys/types.h> +#include <unistd.h> + +#include "test-data-efivars-0.h" + +#pragma GCC diagnostic ignored "-Wunused-label" + +static const size_t guidstr_size = sizeof("8be4df61-93ca-11d2-aa0d-00e098032b8c"); + +void mock_print_guidname(EFI_GUID *guid, CHAR16 *name); +void mock_print_var_list(list_t *head); + +static int +test_filter_out_helper(size_t nvars, const CHAR16 *varnames[nvars], + bool filter_out, UINTN expected_count) +{ + const char *mok_rt_vars[n_mok_state_variables]; + EFI_STATUS status; + EFI_GUID guid = SHIM_LOCK_GUID; + CHAR16 name[1024] = L""; + UINTN sz; + char asciiname[1024]; + bool found = false; + int ret = 0; + UINTN count = 0; + + for (size_t i = 0; i < n_mok_state_variables; i++) { + mok_rt_vars[i] = mok_state_variables[i].rtname8; + } + + sz = sizeof(name); + status = RT->GetNextVariableName(&sz, name, &guid); + assert_equal_return(status, EFI_NOT_FOUND, -1, "got %lx, expected %lx"); + + mock_load_variables("test-data/efivars-1", mok_rt_vars, filter_out); + + while (true) { + int rc = 0; + + sz = sizeof(name); + status = RT->GetNextVariableName(&sz, name, &guid); + if (status == EFI_NOT_FOUND) + break; + if (EFI_ERROR(status)) + return -1; + + count += 1; + SetMem(asciiname, sizeof(asciiname), 0); + for (UINTN i = 0; i < sizeof(asciiname); i++) + asciiname[i] = name[i]; + for (UINTN i = 0; varnames[i] != NULL; i++) { + if (sz == 0 || StrLen(varnames[i]) != sz-1) + continue; + if (StrCmp(name, varnames[i]) == 0) { + found = true; + if (filter_out) { + rc = assert_false_as_expr(found, -1, + "found=%u for undesired variable \"%s\"\n", + asciiname); + break; + } + } + } + if (!filter_out) + rc = assert_true_as_expr(found, -1, + "found=%u for undesired variable \"%s\"\n", + asciiname); + if (ret >= 0 && rc < 0) + ret = rc; + } + + mock_reset_variables(); + assert_equal_return(count, expected_count, -1, "%lu != %lu\n"); + assert_true_return(list_empty(&mock_variables), -1, "%lu != %lu\n"); + + return ret; +} + +static int +test_filter_out_true(void) +{ + const CHAR16 *varnames[] = { + L"MokListRT", + L"MokListXRT", + L"SbatLevelRT", + NULL + }; + size_t nvars = sizeof(varnames) / sizeof(varnames[0]); + + return test_filter_out_helper(nvars, varnames, true, 3); +} + +static int +test_filter_out_false(void) +{ + const CHAR16 *varnames[] = { + L"MokListRT", + L"MokListXRT", + L"SbatLevelRT", + NULL + }; + size_t nvars = sizeof(varnames) / sizeof(varnames[0]); + + return test_filter_out_helper(nvars, varnames, false, 3); +} + +static int +test_gnvn_buf_size_0(void) +{ + UINTN size = 0; + CHAR16 buf[6] = { 0, }; + EFI_STATUS status; + EFI_GUID empty_guid = { 0, }; + int ret = -1; + + status = RT->GetNextVariableName(&size, &buf[0], &GV_GUID); + assert_equal_return(status, EFI_INVALID_PARAMETER, -1, "0x%lx != 0x%lx\n"); + + size = 1; + status = RT->GetNextVariableName(&size, &buf[0], &GV_GUID); + assert_equal_return(status, EFI_NOT_FOUND, -1, "0x%lx != 0x%lx\n"); + + status = RT->SetVariable(L"test", &GV_GUID, + EFI_VARIABLE_BOOTSERVICE_ACCESS, 5, "test"); + assert_equal_return(status, EFI_SUCCESS, -1, "0x%lx != 0x%lx\n"); + + size = 1; + status = RT->GetNextVariableName(&size, &buf[0], &empty_guid); + assert_equal_goto(status, EFI_NOT_FOUND, err, "0x%lx != 0x%lx\n"); + + size = 1; + status = RT->GetNextVariableName(&size, &buf[0], &GV_GUID); + assert_equal_goto(status, EFI_BUFFER_TOO_SMALL, err, "0x%lx != 0x%lx\n"); + assert_equal_goto(size, StrSize(L"test"), err, "%zu != %zu\n"); + + size = StrSize(L"test"); + status = RT->GetNextVariableName(&size, &buf[0], &GV_GUID); + assert_equal_goto(status, EFI_SUCCESS, err, "0x%lx != 0x%lx\n"); + + status = RT->SetVariable(L"testa", &GV_GUID, + EFI_VARIABLE_BOOTSERVICE_ACCESS, 5, "test"); + assert_equal_return(status, EFI_SUCCESS, -1, "0x%lx != 0x%lx\n"); + + buf[0] = 0; + size = 1; + status = RT->GetNextVariableName(&size, &buf[0], &empty_guid); + assert_equal_goto(status, EFI_NOT_FOUND, err, "0x%lx != 0x%lx\n"); + + size = StrSize(L"test"); + StrCpy(buf, L"test"); + status = RT->GetNextVariableName(&size, &buf[0], &GV_GUID); + switch (mock_variable_sort_policy) { + case MOCK_SORT_DESCENDING: + case MOCK_SORT_PREPEND: + assert_equal_goto(status, EFI_NOT_FOUND, err, "0x%lx != 0x%lx\n"); + break; + case MOCK_SORT_APPEND: + case MOCK_SORT_ASCENDING: + assert_equal_goto(status, EFI_BUFFER_TOO_SMALL, err, "0x%lx != 0x%lx\n"); + break; + default: + break; + } + + size = StrSize(L"testa"); + StrCpy(buf, L"test"); + status = RT->GetNextVariableName(&size, &buf[0], &GV_GUID); + switch (mock_variable_sort_policy) { + case MOCK_SORT_DESCENDING: + case MOCK_SORT_PREPEND: + assert_equal_goto(status, EFI_NOT_FOUND, err, "0x%lx != 0x%lx\n"); + break; + case MOCK_SORT_APPEND: + case MOCK_SORT_ASCENDING: + assert_equal_goto(status, EFI_SUCCESS, err, "0x%lx != 0x%lx\n"); + break; + default: + break; + } + + ret = 0; +err: + mock_reset_variables(); + return ret; +} + +static int +test_gnvn_helper(char *testvars) +{ + UINTN size = 0; + CHAR16 buf[8192] = { 0, }; + EFI_STATUS status; + EFI_GUID empty_guid = { 0, }; + int ret = -1; + const char *mok_rt_vars[n_mok_state_variables]; + + for (size_t i = 0; i < n_mok_state_variables; i++) { + mok_rt_vars[i] = mok_state_variables[i].rtname8; + } + + mock_load_variables(testvars, mok_rt_vars, true); + + size = sizeof(buf); + buf[0] = L'\0'; + status = RT->GetNextVariableName(&size, buf, &GV_GUID); + assert_equal_goto(status, EFI_SUCCESS, err, "0x%lx != 0x%lx\n"); + +#if defined(SHIM_DEBUG) && SHIM_DEBUG != 0 + dump_mock_variables(__FILE__, __LINE__, __func__); +#endif + switch (mock_variable_sort_policy) { + case MOCK_SORT_DESCENDING: + dump_mock_variables_if_wrong(__FILE__, __LINE__, __func__, + &GV_GUID, L"dbxDefault"); + assert_zero_goto(StrCmp(buf, L"dbxDefault"), err, "0x%lx != 0x%lx\n"); + break; + case MOCK_SORT_ASCENDING: + dump_mock_variables_if_wrong(__FILE__, __LINE__, __func__, + &GV_GUID, L"Boot0000"); + assert_zero_goto(StrCmp(buf, L"Boot0000"), err, "0x%lx != 0x%lx buf:\"%s\"\n", + 0, Str2str(buf)); + break; + default: + break; + } + + size = sizeof(buf); + buf[0] = 0; + status = RT->GetNextVariableName(&size, buf, &EFI_SECURE_BOOT_DB_GUID); + assert_equal_goto(status, EFI_SUCCESS, err, "0x%lx != 0x%lx\n"); + switch (mock_variable_sort_policy) { + case MOCK_SORT_DESCENDING: + assert_zero_goto(StrCmp(buf, L"dbx"), err, "0x%lx != 0x%lx\n"); + break; + case MOCK_SORT_ASCENDING: + assert_zero_goto(StrCmp(buf, L"db"), err, "0x%lx != 0x%lx\n"); + break; + default: + break; + } + + ret = 0; +err: + if (ret) + mock_print_var_list(&mock_variables); + mock_reset_variables(); + return ret; +} + +static int +test_gnvn_0(void) +{ + return test_gnvn_helper("test-data/efivars-0"); +} + +static int +test_gnvn_1(void) +{ + return test_gnvn_helper("test-data/efivars-1"); +} + +static int +test_get_variable_0(void) +{ + UINTN size = 0; + uint8_t buf[8192] = { 0, }; + EFI_STATUS status; + EFI_GUID empty_guid = { 0, }; + UINT32 attrs = 0; + int ret = -1; + int cmp; + const char *mok_rt_vars[n_mok_state_variables]; + + for (size_t i = 0; i < n_mok_state_variables; i++) { + mok_rt_vars[i] = mok_state_variables[i].rtname8; + } + + mock_load_variables("test-data/efivars-1", mok_rt_vars, true); + + size = 0; + status = RT->GetVariable(L"Boot0000", &GV_GUID, &attrs, &size, buf); + assert_equal_goto(status, EFI_BUFFER_TOO_SMALL, err, "0x%lx != 0x%lx\n"); + + size = sizeof(buf); + status = RT->GetVariable(L"Boot0000", &GV_GUID, &attrs, &size, buf); + assert_equal_goto(status, EFI_SUCCESS, err, "0x%lx != 0x%lx\n"); + assert_equal_goto(size, sizeof(test_data_efivars_0_Boot0000), err, "%zu != %zu\n"); + assert_zero_goto(memcmp(buf, test_data_efivars_0_Boot0000, size), err, "%zu != %zu\n"); + + ret = 0; +err: + if (ret) + mock_print_var_list(&mock_variables); + mock_reset_variables(); + return ret; +} + +static int +test_set_variable_0(void) +{ + UINTN size = 0; + uint8_t buf[8192] = { 0, }; + EFI_STATUS status; + EFI_GUID empty_guid = { 0, }; + UINT32 attrs = 0; + int ret = -1; + UINT32 bs_rt_nv = EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS | + EFI_VARIABLE_NON_VOLATILE; + + size = 4; + strcpy(buf, "foo"); + status = RT->SetVariable(L"tmp", &GV_GUID, bs_rt_nv, size, buf); + assert_equal_goto(status, EFI_SUCCESS, err, "0x%lx != 0x%lx\n"); + + size = sizeof(buf); + SetMem(buf, sizeof(buf), 0); + status = RT->GetVariable(L"tmp", &GV_GUID, &attrs, &size, buf); + assert_equal_goto(status, EFI_SUCCESS, err, "0x%lx != 0x%lx\n"); + assert_equal_goto(size, 4, err, "%zu != %zu\n"); + assert_zero_goto(memcmp(buf, "foo", 4), err, "0x%lx != 0x%lx\n"); + + size = 5; + strcpy(buf, "bang"); + status = RT->SetVariable(L"tmp", &GV_GUID, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + size, buf); + size = sizeof(buf); + SetMem(buf, sizeof(buf), 0); + status = RT->GetVariable(L"tmp", &GV_GUID, &attrs, &size, buf); + assert_equal_goto(status, EFI_SUCCESS, err, "0x%lx != 0x%lx\n"); + assert_equal_goto(size, 5, err, "%zu != %zu\n"); + assert_zero_goto(memcmp(buf, "bang", 5), err, "%d != %d\n"); + + size = 5; + strcpy(buf, "foop"); + status = RT->SetVariable(L"tmp", &GV_GUID, bs_rt_nv, size, buf); + assert_equal_goto(status, EFI_SUCCESS, err, "0x%lx != 0x%lx\n"); + + size = sizeof(buf); + SetMem(buf, sizeof(buf), 0); + status = RT->GetVariable(L"tmp", &GV_GUID, &attrs, &size, buf); + assert_equal_goto(status, EFI_SUCCESS, err, "0x%lx != 0x%lx\n"); + assert_equal_goto(size, 5, err, "%zu != %zu\n"); + assert_zero_goto(memcmp(buf, "foop", 5), err, "%d != %d\n"); + + size = 0; + strcpy(buf, ""); + status = RT->SetVariable(L"tmp", &GV_GUID, bs_rt_nv | EFI_VARIABLE_APPEND_WRITE, size, buf); + assert_equal_goto(status, EFI_SUCCESS, err, "0x%lx != 0x%lx\n"); + + size = sizeof(buf); + SetMem(buf, sizeof(buf), 0); + status = RT->GetVariable(L"tmp", &GV_GUID, &attrs, &size, buf); + assert_equal_goto(status, EFI_SUCCESS, err, "0x%lx != 0x%lx\n"); + assert_equal_goto(size, 5, err, "%zu != %zu\n"); + assert_zero_goto(memcmp(buf, "foop", 5), err, "%d != %d\n"); + + size = 5; + strcpy(buf, "poof"); + status = RT->SetVariable(L"tmp", &GV_GUID, bs_rt_nv | EFI_VARIABLE_APPEND_WRITE, size, buf); + assert_equal_goto(status, EFI_SUCCESS, err, "0x%lx != 0x%lx\n"); + + size = sizeof(buf); + SetMem(buf, sizeof(buf), 0); + status = RT->GetVariable(L"tmp", &GV_GUID, &attrs, &size, buf); + assert_equal_goto(status, EFI_SUCCESS, err, "0x%lx != 0x%lx\n"); + assert_equal_goto(size, 10, err, "%zu != %zu\n"); + assert_zero_goto(memcmp(buf, "foop\0poof", 10), err, "%d != %d\n"); + ret = 0; +err: + if (ret) + mock_print_var_list(&mock_variables); + mock_reset_variables(); + return ret; +} + +static void +dump_config_table_if_wrong(const char * const func, int line, ...) +{ + va_list alist, blist; + bool okay = true; + size_t n = 0, m = 0; + + va_start(alist, line); + va_copy(blist, alist); + + int idx = va_arg(alist, int); + EFI_GUID *guid = va_arg(alist, EFI_GUID *); + while (idx >= 0 && guid != NULL) { + EFI_CONFIGURATION_TABLE *entry; + if (idx < 0) + goto nexta; + + n += 1; + if (idx >= (int)ST->NumberOfTableEntries) { + okay = false; + goto nexta; + } + + entry = &ST->ConfigurationTable[idx]; + if (CompareGuid(guid, &entry->VendorGuid) != 0) + okay = false; + +nexta: + idx = va_arg(alist, int); + guid = va_arg(alist, EFI_GUID *); + } + va_end(alist); + + if (okay) + return; + + printf("%s:%d:%s(): %d entries:\n", __FILE__, line, func, ST->NumberOfTableEntries); + idx = va_arg(blist, int); + guid = va_arg(blist, EFI_GUID *); + while (idx >= 0 && guid != NULL) { + EFI_CONFIGURATION_TABLE *entry; + + if (idx >= (int)ST->NumberOfTableEntries) { + printf("\t[%d]: invalid index for " GUID_FMT "\n", + idx, GUID_ARGS(*guid)); + goto nexta; + } + + if (idx < 0) { + printf("\t[%d]: " GUID_FMT "\n", idx, GUID_ARGS(*guid)); + } else { + entry = &ST->ConfigurationTable[idx]; + printf("\t[%d]: %p ", idx, entry); + printf("{.VendorGuid:" GUID_FMT ",", GUID_ARGS(entry->VendorGuid)); + printf("&.VendorTable:%p}\n", entry->VendorTable); + if (CompareGuid(guid, &entry->VendorGuid) != 0) + printf("\t\t\t expected:" GUID_FMT "\n", GUID_ARGS(*guid)); + } +next: + idx = va_arg(blist, int); + guid = va_arg(blist, EFI_GUID *); + } + va_end(blist); + + if ((int)ST->NumberOfTableEntries - n == 0) + return; + + printf("%d extra table entries:\n", ST->NumberOfTableEntries - n); + for (m = n; m < ST->NumberOfTableEntries; m++) { + EFI_CONFIGURATION_TABLE *entry; + + entry = &ST->ConfigurationTable[m]; + + printf("\t[%d]: %p ", m, entry); + printf("{.VendorGuid:" GUID_FMT ",", GUID_ARGS(entry->VendorGuid)); + printf("&.VendorTable:%p}\n", entry->VendorTable); + } +} + +static int +test_install_config_table_0(void) +{ + int ret = -1; + EFI_STATUS status; + + /* + * These three guids are chosen on purpose: they start with "a", + * "b", and "c", respective to their variable names, so you can + * identify them when dumped. + */ + EFI_GUID aguid = SECURITY_PROTOCOL_GUID; + char astr[guidstr_size]; + void *astrp = &astr[0]; + int aidx = -1; + + EFI_GUID bguid = EFI_HTTP_BINDING_GUID; + char bstr[guidstr_size]; + void *bstrp = &bstr[0]; + int bidx = -1; + + EFI_GUID cguid = MOK_VARIABLE_STORE; + char cstr[guidstr_size]; + void *cstrp = &cstr[0]; + int cidx = -1; + + EFI_GUID lip = LOADED_IMAGE_PROTOCOL; + + EFI_GUID guids[3]; + + char tmpstr[guidstr_size]; + + sprintf(astrp, GUID_FMT, GUID_ARGS(aguid)); + sprintf(bstrp, GUID_FMT, GUID_ARGS(bguid)); + sprintf(cstrp, GUID_FMT, GUID_ARGS(cguid)); + + assert_equal_return(ST->NumberOfTableEntries, 0, -1, "%lu != %lu\n"); + + /* + * test installing one + */ + status = BS->InstallConfigurationTable(&bguid, bstrp); + assert_equal_return(status, EFI_SUCCESS, -1, "%lx != %lx\n"); + assert_equal_goto(ST->NumberOfTableEntries, 1, err, "%lu != %lu\n"); + + sprintf(tmpstr, GUID_FMT, GUID_ARGS(ST->ConfigurationTable[0].VendorGuid)); + assert_zero_goto(CompareGuid(&ST->ConfigurationTable[0].VendorGuid, &bguid), + err, "%d != 0 (%s != %s)\n", tmpstr, bstr); + assert_equal_goto(ST->ConfigurationTable[0].VendorTable, + bstrp, err, "%p != %p\n"); + + /* + * test re-installing the same one + */ + status = BS->InstallConfigurationTable(&bguid, bstrp); + assert_equal_goto(status, EFI_SUCCESS, err, "%lx != %lx\n"); + assert_equal_goto(ST->NumberOfTableEntries, 1, err, "%lu != %lu\n"); + + sprintf(tmpstr, GUID_FMT, GUID_ARGS(ST->ConfigurationTable[0].VendorGuid)); + assert_zero_goto(CompareGuid(&ST->ConfigurationTable[0].VendorGuid, &bguid), + err, "%d != 0 (%s != %s)\n", tmpstr, bstr); + assert_equal_goto(ST->ConfigurationTable[0].VendorTable, + bstrp, err, "%p != %p\n"); + + /* + * Test installing a second one + */ + status = BS->InstallConfigurationTable(&aguid, astrp); + assert_equal_goto(status, EFI_SUCCESS, err, "%lx != %lx\n"); + assert_equal_goto(ST->NumberOfTableEntries, 2, err, "%lu != %lu\n"); + + switch (mock_config_table_sort_policy) { + case MOCK_SORT_DESCENDING: + aidx = 1; + bidx = 0; + break; + case MOCK_SORT_PREPEND: + aidx = 0; + bidx = 1; + break; + case MOCK_SORT_APPEND: + aidx = 1; + bidx = 0; + break; + case MOCK_SORT_ASCENDING: + aidx = 0; + bidx = 1; + break; + default: + break; + } + + dump_config_table_if_wrong(__func__, __LINE__, + aidx, &aguid, + bidx, &bguid, + cidx, &cguid, + -1, NULL); + + sprintf(tmpstr, GUID_FMT, GUID_ARGS(ST->ConfigurationTable[aidx].VendorGuid)); + assert_zero_goto(CompareGuid(&ST->ConfigurationTable[aidx].VendorGuid, &aguid), + err, "%d != 0 (%s != %s)\n", tmpstr, astr); + assert_equal_goto(ST->ConfigurationTable[aidx].VendorTable, astrp, + err, "%p != %p\n"); + + sprintf(tmpstr, GUID_FMT, GUID_ARGS(ST->ConfigurationTable[bidx].VendorGuid)); + assert_zero_goto(CompareGuid(&ST->ConfigurationTable[bidx].VendorGuid, &bguid), + err, "%d != 0 (%s != %s)\n", tmpstr, bstr); + assert_equal_goto(ST->ConfigurationTable[bidx].VendorTable, bstrp, + err, "%p != %p\n"); + + /* + * Test installing a third one + */ + status = BS->InstallConfigurationTable(&cguid, cstrp); + assert_equal_goto(status, EFI_SUCCESS, err, "%lx != %lx\n"); + assert_equal_goto(ST->NumberOfTableEntries, 3, err, "%lu != %lu\n"); + + switch (mock_config_table_sort_policy) { + case MOCK_SORT_DESCENDING: + aidx = 2; + bidx = 1; + cidx = 0; + break; + case MOCK_SORT_PREPEND: + aidx = 1; + bidx = 2; + cidx = 0; + break; + case MOCK_SORT_APPEND: + aidx = 1; + bidx = 0; + cidx = 2; + break; + case MOCK_SORT_ASCENDING: + aidx = 0; + bidx = 1; + cidx = 2; + break; + default: + break; + } + + dump_config_table_if_wrong(__func__, __LINE__, + aidx, &aguid, + bidx, &bguid, + cidx, &cguid, + -1, NULL); + + sprintf(tmpstr, GUID_FMT, GUID_ARGS(ST->ConfigurationTable[aidx].VendorGuid)); + assert_zero_goto(CompareGuid(&ST->ConfigurationTable[aidx].VendorGuid, &aguid), + err, "%d != 0 (%s != %s)\n", tmpstr, astr); + assert_equal_goto(ST->ConfigurationTable[aidx].VendorTable, astrp, + err, "%p != %p\n"); + memcpy(&guids[aidx], &aguid, sizeof(EFI_GUID)); + + sprintf(tmpstr, GUID_FMT, GUID_ARGS(ST->ConfigurationTable[bidx].VendorGuid)); + assert_zero_goto(CompareGuid(&ST->ConfigurationTable[bidx].VendorGuid, &bguid), + err, "%d != 0 (%s != %s)\n", tmpstr, bstr); + assert_equal_goto(ST->ConfigurationTable[bidx].VendorTable, bstrp, + err, "%p != %p\n"); + memcpy(&guids[bidx], &bguid, sizeof(EFI_GUID)); + + sprintf(tmpstr, GUID_FMT, GUID_ARGS(ST->ConfigurationTable[cidx].VendorGuid)); + assert_zero_goto(CompareGuid(&ST->ConfigurationTable[cidx].VendorGuid, &cguid), + err, "%d != 0 (%s != %s)\n", tmpstr, cstr); + assert_equal_goto(ST->ConfigurationTable[cidx].VendorTable, cstrp, + err, "%p != %p\n"); + memcpy(&guids[cidx], &cguid, sizeof(EFI_GUID)); + + /* + * Test removing NULL guid + */ + status = BS->InstallConfigurationTable(NULL, NULL); + assert_equal_goto(status, EFI_INVALID_PARAMETER, err, "%lx != %lx\n"); + assert_equal_goto(ST->NumberOfTableEntries, 3, err, "%lu != %lu\n"); + + /* + * Test removing a guid that's not present + */ + status = BS->InstallConfigurationTable(&lip, NULL); + assert_equal_goto(status, EFI_NOT_FOUND, err, "%lx != %lx\n"); + assert_equal_goto(ST->NumberOfTableEntries, 3, err, "%lu != %lu\n"); + + /* + * Test removing the middle one + */ + status = BS->InstallConfigurationTable(&guids[1], NULL); + assert_equal_goto(status, EFI_SUCCESS, err, "%lx != %lx\n"); + assert_equal_goto(ST->NumberOfTableEntries, 2, err, "%lu != %lu\n"); + + switch (mock_config_table_sort_policy) { + case MOCK_SORT_DESCENDING: + aidx = 1; + bidx = -1; + cidx = 0; + break; + case MOCK_SORT_PREPEND: + aidx = -1; + bidx = 1; + cidx = 0; + break; + case MOCK_SORT_APPEND: + aidx = -1; + bidx = 0; + cidx = 1; + break; + case MOCK_SORT_ASCENDING: + aidx = 0; + bidx = -1; + cidx = 1; + break; + default: + break; + } + + dump_config_table_if_wrong(__func__, __LINE__, + aidx, &aguid, + bidx, &bguid, + cidx, &cguid, + -1, NULL); + + if (aidx >= 0) { + sprintf(tmpstr, GUID_FMT, GUID_ARGS(ST->ConfigurationTable[aidx].VendorGuid)); + assert_zero_goto(CompareGuid(&ST->ConfigurationTable[aidx].VendorGuid, &aguid), + err, "%d != 0 (%s != %s)\n", tmpstr, astr); + assert_equal_goto(ST->ConfigurationTable[aidx].VendorTable, astrp, + err, "%p != %p\n"); + memcpy(&guids[aidx], &aguid, sizeof(EFI_GUID)); + } + + if (bidx >= 0) { + sprintf(tmpstr, GUID_FMT, GUID_ARGS(ST->ConfigurationTable[bidx].VendorGuid)); + assert_zero_goto(CompareGuid(&ST->ConfigurationTable[bidx].VendorGuid, &bguid), + err, "%d != 0 (%s != %s)\n", tmpstr, bstr); + assert_equal_goto(ST->ConfigurationTable[bidx].VendorTable, bstrp, + err, "%p != %p\n"); + memcpy(&guids[bidx], &bguid, sizeof(EFI_GUID)); + } + + if (cidx >= 0) { + sprintf(tmpstr, GUID_FMT, GUID_ARGS(ST->ConfigurationTable[cidx].VendorGuid)); + assert_zero_goto(CompareGuid(&ST->ConfigurationTable[cidx].VendorGuid, &cguid), + err, "%d != 0 (%s != %s)\n", tmpstr, cstr); + assert_equal_goto(ST->ConfigurationTable[cidx].VendorTable, cstrp, + err, "%p != %p\n"); + memcpy(&guids[cidx], &cguid, sizeof(EFI_GUID)); + } + + /* + * Test removing the lowest one + */ + status = BS->InstallConfigurationTable(&guids[0], NULL); + assert_equal_goto(status, EFI_SUCCESS, err, "%lx != %lx\n"); + assert_equal_goto(ST->NumberOfTableEntries, 1, err, "%lu != %lu\n"); + + switch (mock_config_table_sort_policy) { + case MOCK_SORT_DESCENDING: + aidx = 0; + bidx = -1; + cidx = -1; + break; + case MOCK_SORT_PREPEND: + aidx = -1; + bidx = 0; + cidx = -1; + break; + case MOCK_SORT_APPEND: + aidx = -1; + bidx = -1; + cidx = 0; + break; + case MOCK_SORT_ASCENDING: + aidx = -1; + bidx = -1; + cidx = 0; + break; + default: + break; + } + + dump_config_table_if_wrong(__func__, __LINE__, + aidx, &aguid, + bidx, &bguid, + cidx, &cguid, + -1, NULL); + + if (aidx >= 0) { + sprintf(tmpstr, GUID_FMT, GUID_ARGS(ST->ConfigurationTable[aidx].VendorGuid)); + assert_zero_goto(CompareGuid(&ST->ConfigurationTable[aidx].VendorGuid, &aguid), + err, "%d != 0 (%s != %s)\n", tmpstr, astr); + assert_equal_goto(ST->ConfigurationTable[aidx].VendorTable, astrp, + err, "%p != %p\n"); + memcpy(&guids[aidx], &aguid, sizeof(EFI_GUID)); + } + + if (bidx >= 0) { + sprintf(tmpstr, GUID_FMT, GUID_ARGS(ST->ConfigurationTable[bidx].VendorGuid)); + assert_zero_goto(CompareGuid(&ST->ConfigurationTable[bidx].VendorGuid, &bguid), + err, "%d != 0 (%s != %s)\n", tmpstr, bstr); + assert_equal_goto(ST->ConfigurationTable[bidx].VendorTable, bstrp, + err, "%p != %p\n"); + memcpy(&guids[bidx], &bguid, sizeof(EFI_GUID)); + } + + if (cidx >= 0) { + sprintf(tmpstr, GUID_FMT, GUID_ARGS(ST->ConfigurationTable[cidx].VendorGuid)); + assert_zero_goto(CompareGuid(&ST->ConfigurationTable[cidx].VendorGuid, &cguid), + err, "%d != 0 (%s != %s)\n", tmpstr, cstr); + assert_equal_goto(ST->ConfigurationTable[cidx].VendorTable, cstrp, + err, "%p != %p\n"); + memcpy(&guids[cidx], &cguid, sizeof(EFI_GUID)); + } + + /* + * Test removing the last one + */ + status = BS->InstallConfigurationTable(&guids[0], NULL); + assert_equal_goto(status, EFI_SUCCESS, err, "%lx != %lx\n"); + assert_equal_goto(ST->NumberOfTableEntries, 0, err, "%lu != %lu\n"); + + /* + * Test removing it again + */ + status = BS->InstallConfigurationTable(&guids[0], NULL); + assert_equal_goto(status, EFI_NOT_FOUND, err, "%lx != %lx\n"); + assert_equal_goto(ST->NumberOfTableEntries, 0, err, "%lu != %lu\n"); + + ret = 0; +err: + while (ST->NumberOfTableEntries) + BS->InstallConfigurationTable(&ST->ConfigurationTable[0].VendorGuid, NULL); + mock_reset_config_table(); + + return ret; +} + +int +main(void) +{ + int status = 0; + setbuf(stdout, NULL); + + const char *policies[] = { + "MOCK_SORT_DESCENDING", + "MOCK_SORT_PREPEND", + "MOCK_SORT_APPEND", + "MOCK_SORT_ASCENDING", + "MOCK_SORT_MAX_SENTINEL" + }; + + test(test_filter_out_true); + test(test_filter_out_false); + + for (int i = 0; i < MOCK_SORT_MAX_SENTINEL; i++) { + mock_variable_sort_policy = i; + mock_config_table_sort_policy = i; + printf("%s: setting variable sort policy to %s\n", + program_invocation_short_name, policies[i]); + + test(test_gnvn_buf_size_0); + test(test_gnvn_0); + test(test_gnvn_1); + + test(test_install_config_table_0); + } + + test(test_get_variable_0); + test(test_set_variable_0); + return status; +} + +// vim:fenc=utf-8:tw=75:noet |
