Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
secvar/test: add rudimentary secvar API unit testing
This patch adds an initial port of the userspace unit tests for exercising the API that were originally developed out of tree. Future revisions will adjust the naming schemes and general formatting to match that of other tests within skiboot. Signed-off-by: Eric Richter <erichte@linux.ibm.com> [oliver: Use SPDX headers] Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
- Loading branch information
1 parent
bc1f1e4
commit 127db3a
Showing
7 changed files
with
557 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
# SPDX-License-Identifier: Apache-2.0 | ||
# -*-Makefile-*- | ||
SECVAR_TEST_DIR = libstb/secvar/test | ||
#SUBDIRS = $(SECVAR_TEST_DIR) | ||
|
||
SECVAR_TEST = $(patsubst %.c, %, $(wildcard $(SECVAR_TEST_DIR)/secvar-test-*.c)) | ||
|
||
HOSTCFLAGS+=-I . -I include | ||
|
||
.PHONY : secvar-check | ||
secvar-check: $(SECVAR_TEST:%=%-check) $(SECVAR_TEST:%=%-gcov-run) | ||
secvar-check: $(SECVAR_TEST_NOSTUB:%=%-check) $(SECVAR_TEST_NOSTUB:%=%-gcov-run) | ||
|
||
.PHONY : secvar-coverage | ||
secvar-coverage: $(SECVAR_TEST:%=%-gcov-run) | ||
secvar-coverage: $(SECVAR_TEST_NOSTUB:%=%-gcov-run) | ||
|
||
check: secvar-check | ||
coverage: secvar-coverage | ||
|
||
# TODO: create pnor image for only tests that need it | ||
$(SECVAR_TEST:%=%-gcov-run) : %-run: % | ||
@dd if=/dev/zero of=secboot.img bs=128k count=1 2> /dev/null | ||
$(call QTEST, TEST-COVERAGE ,$< , $<) | ||
@$(RM) -f secboot.img | ||
|
||
$(SECVAR_TEST:%=%-check) : %-check: % | ||
@dd if=/dev/zero of=secboot.img bs=128k count=1 2> /dev/null | ||
$(call QTEST, RUN-TEST ,$(VALGRIND) $<, $<) | ||
@$(RM) -f secboot.img | ||
|
||
$(SECVAR_TEST) : core/test/stubs.o | ||
|
||
$(SECVAR_TEST) : % : %.c | ||
$(call Q, HOSTCC ,$(HOSTCC) $(HOSTCFLAGS) -O0 -g -I include -I . -I libfdt -o $@ $< core/test/stubs.o, $<) | ||
|
||
$(SECVAR_TEST:%=%-gcov): %-gcov : %.c % | ||
$(call Q, HOSTCC ,$(HOSTCC) $(HOSTCFLAGS) $(HOSTGCOVCFLAGS) -I include -I . -I libfdt -lgcov -o $@ $< core/test/stubs.o, $<) | ||
|
||
-include $(wildcard libstb/secvar/test/*.d) | ||
|
||
clean: secvar-test-clean | ||
|
||
secvar-test-clean: | ||
$(RM) -f libstb/secvar/test/*.[od] $(SECVAR_TEST) $(SECVAR_TEST:%=%-gcov) | ||
$(RM) -f libstb/secvar/test/*.gcda libstb/secvar/test/*.gcno | ||
$(RM) -f secboot.img |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
/* Copyright 2019 IBM Corp. */ | ||
|
||
#include "secvar_api_test.c" | ||
|
||
const char *secvar_test_name = "enqueue"; | ||
|
||
// Stub storage function, enqueue only cares that this succeeds | ||
static int temp_write_bank(struct list_head *bank, int section) | ||
{ | ||
(void) bank, (void) section; | ||
return OPAL_SUCCESS; | ||
} | ||
|
||
int run_test(void) | ||
{ | ||
int64_t rc; | ||
|
||
struct secvar_node *node; | ||
char key[1024] = {0}; | ||
|
||
uint64_t data_size = 128; | ||
char *data = zalloc(data_size); | ||
|
||
secvar_storage.max_var_size = 1024; | ||
|
||
/*** Bad cases first this time ***/ | ||
// No write bank hook set | ||
secvar_storage.write_bank = NULL; | ||
memcpy(key, "meow", 4); // ascii | ||
rc = secvar_enqueue(key, 4, data, data_size); | ||
ASSERT(rc == OPAL_HARDWARE); | ||
|
||
// Set a stub bank writer, so the rest runs ok | ||
secvar_storage.write_bank = temp_write_bank; | ||
|
||
// Parameter checks | ||
// null key | ||
rc = secvar_enqueue(NULL, 5, data, data_size); | ||
ASSERT(rc == OPAL_PARAMETER); | ||
ASSERT(list_empty(&update_bank)); | ||
|
||
// key is empty | ||
memset(key, 0, sizeof(key)); | ||
rc = secvar_enqueue(key, 5, data, data_size); | ||
ASSERT(rc == OPAL_PARAMETER); | ||
ASSERT(list_empty(&update_bank)); | ||
|
||
// keylen is zero | ||
rc = secvar_enqueue(key, 0, data, data_size); | ||
ASSERT(rc == OPAL_PARAMETER); | ||
ASSERT(list_empty(&update_bank)); | ||
|
||
// keylen is excessive | ||
rc = secvar_enqueue(key, 5000, data, data_size); | ||
ASSERT(rc == OPAL_PARAMETER); | ||
ASSERT(list_empty(&update_bank)); | ||
|
||
// null data | ||
rc = secvar_enqueue(key, 5, NULL, data_size); | ||
ASSERT(rc == OPAL_PARAMETER); | ||
ASSERT(list_empty(&update_bank)); | ||
|
||
// data_size is excessive | ||
rc = secvar_enqueue(key, 5, data, 50000); | ||
ASSERT(rc == OPAL_PARAMETER); | ||
ASSERT(list_empty(&update_bank)); | ||
|
||
// data_size is zero | ||
rc = secvar_enqueue(key, 5, data, 0); | ||
ASSERT(rc == OPAL_PARAMETER); | ||
ASSERT(list_empty(&update_bank)); | ||
|
||
// secvar is disabled | ||
secvar_enabled = 0; | ||
rc = secvar_enqueue(key, 5, data, data_size); | ||
ASSERT(rc == OPAL_UNSUPPORTED); | ||
secvar_enabled = 1; | ||
|
||
// secvar is not ready | ||
secvar_ready = 0; | ||
rc = secvar_enqueue(key, 5, data, data_size); | ||
ASSERT(rc == OPAL_RESOURCE); | ||
secvar_ready = 1; | ||
|
||
|
||
/*** Good cases ***/ | ||
// TODO: add data? | ||
memcpy(key, "test", 4); // ascii | ||
rc = secvar_enqueue(key, 4, data, data_size); | ||
ASSERT(rc == OPAL_SUCCESS); | ||
ASSERT(list_length(&update_bank) == 1); | ||
|
||
memcpy(key, "f\0o\0o\0b\0a\0r\0", 6*2); // "unicode" | ||
rc = secvar_enqueue(key, 6*2, data, data_size); | ||
ASSERT(rc == OPAL_SUCCESS); | ||
ASSERT(list_length(&update_bank) == 2); | ||
|
||
memcpy(key, "meep", 4); | ||
rc = secvar_enqueue(key, 4, data, data_size); | ||
ASSERT(rc == OPAL_SUCCESS); | ||
ASSERT(list_length(&update_bank) == 3); // should not increase | ||
|
||
// Re-add the same variable | ||
memcpy(key, "meep", 4); | ||
rc = secvar_enqueue(key, 4, data, data_size); | ||
ASSERT(rc == OPAL_SUCCESS); | ||
ASSERT(list_length(&update_bank) == 3); // should not increase | ||
node = list_tail(&update_bank, struct secvar_node, link); | ||
ASSERT(!memcmp(node->var->key, key, 4)) // should be at end | ||
|
||
// Unstage the variable update | ||
rc = secvar_enqueue(key, 4, NULL, 0); | ||
ASSERT(rc == OPAL_SUCCESS); | ||
ASSERT(list_length(&update_bank) == 2); | ||
|
||
// Unstage a bogus variable update | ||
rc = secvar_enqueue("nada", 4, NULL, 0); | ||
ASSERT(rc == OPAL_EMPTY); | ||
ASSERT(list_length(&update_bank) == 2); | ||
|
||
|
||
// Empty the in-memory cache, and reload from "pnor" | ||
// Removed to drop dependency on a storage backend | ||
// Probably not actually necessary to test, that's the | ||
// job of the storage backend tests | ||
/* | ||
clear_bank_list(&update_bank); | ||
ASSERT(list_empty(&update_bank)); | ||
secvar_storage.load_bank(&update_bank, SECVAR_UPDATE_BANK); | ||
printf("list_length = %d\n", list_length(&update_bank)); | ||
ASSERT(list_length(&update_bank) == 2); | ||
node = list_top(&update_bank, struct secvar_node, link); | ||
ASSERT(node); | ||
ASSERT(!memcmp(node->var->key, "test", 4)); | ||
node = list_next(&update_bank, node, link); | ||
ASSERT(node); | ||
ASSERT(!memcmp(node->var->key, "f\0o\0o\0b\0a\0r\0", 6*2)); | ||
*/ | ||
|
||
/*** ONE more bad case... ***/ | ||
|
||
free(data); | ||
|
||
return 0; | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
/* Copyright 2019 IBM Corp. */ | ||
|
||
#include "secvar_api_test.c" | ||
|
||
const char *secvar_test_name = "getvar"; | ||
|
||
// Run tests on the less obvious features of secvar_get | ||
// Includes: | ||
// - Partial reads | ||
// - Size queries (NULL buffer) | ||
//int run_test_helper(uint64_t bank_enum) | ||
int run_test(void) | ||
{ | ||
int64_t rc; | ||
|
||
uint64_t size = 4; | ||
char *temp = zalloc(100); | ||
char key[1024] = {0}; | ||
|
||
struct secvar_node *node = zalloc(sizeof(struct secvar_node)); | ||
struct secvar *var = zalloc(sizeof(struct secvar) + 1024); // over-allocate for now, this should be rewritten | ||
size_t data_size = sizeof("foobar"); | ||
char *data = zalloc(data_size); | ||
uint64_t key_len = 4; | ||
memcpy(data, "foobar", data_size); | ||
|
||
memcpy(key, "test", 4); | ||
|
||
// List should be empty at start | ||
rc = secvar_get(key, key_len, data, &data_size); | ||
ASSERT(rc == OPAL_EMPTY); | ||
ASSERT(list_length(&variable_bank) == 0); | ||
|
||
// Manually add variables, and check get_variable call | ||
var->key_len = key_len; | ||
memcpy(var->key, key, key_len); | ||
var->data_size = data_size; | ||
memcpy(var->data, data, data_size); | ||
|
||
node->var = var; | ||
list_add_tail(&variable_bank, &node->link); | ||
|
||
ASSERT(list_length(&variable_bank) == 1); | ||
|
||
// TEST ONLY DATA | ||
// Test actual variable get | ||
size = data_size; | ||
rc = secvar_get(key, key_len, temp, &size); | ||
ASSERT(rc == OPAL_SUCCESS); | ||
ASSERT(0 == memcmp("foobar", var->data, size)); | ||
|
||
// Test buffer too small | ||
size = data_size / 2; | ||
memset(temp, 0, 100); | ||
rc = secvar_get(key, key_len, temp, &size); | ||
ASSERT(rc == OPAL_PARTIAL); | ||
|
||
size = 0; | ||
rc = secvar_get(key, key_len, temp, &size); | ||
ASSERT(rc == OPAL_PARTIAL); | ||
ASSERT(size == data_size); | ||
|
||
// Test size query w/ no data | ||
size = 0; | ||
rc = secvar_get(key, key_len, NULL, &size); | ||
ASSERT(rc == OPAL_SUCCESS); | ||
ASSERT(size == data_size); | ||
|
||
/**** Error/Bad param cases ****/ | ||
// NULL key | ||
rc = secvar_get(NULL, key_len, data, &data_size); | ||
ASSERT(rc == OPAL_PARAMETER); | ||
// zero key_len | ||
rc = secvar_get(key, 0, data, &data_size); | ||
ASSERT(rc == OPAL_PARAMETER); | ||
// NULL size, valid data | ||
rc = secvar_get(key, key_len, data, NULL); | ||
ASSERT(rc == OPAL_PARAMETER); | ||
|
||
secvar_enabled = 0; | ||
rc = secvar_get(key, key_len, data, &data_size); | ||
ASSERT(rc == OPAL_UNSUPPORTED); | ||
secvar_enabled = 1; | ||
|
||
secvar_ready = 0; | ||
rc = secvar_get(key, key_len, data, &data_size); | ||
ASSERT(rc == OPAL_RESOURCE); | ||
secvar_ready = 1; | ||
|
||
list_del(&node->link); | ||
|
||
free(var); | ||
free(node); | ||
free(data); | ||
free(temp); | ||
|
||
return 0; | ||
} | ||
|
Oops, something went wrong.