Skip to content

Commit

Permalink
secvar/test: add rudimentary secvar API unit testing
Browse files Browse the repository at this point in the history
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
erichte-ibm authored and oohal committed Nov 7, 2019
1 parent bc1f1e4 commit 127db3a
Show file tree
Hide file tree
Showing 7 changed files with 557 additions and 0 deletions.
47 changes: 47 additions & 0 deletions libstb/secvar/test/Makefile.check
@@ -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
148 changes: 148 additions & 0 deletions libstb/secvar/test/secvar-test-enqueue.c
@@ -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;

}
100 changes: 100 additions & 0 deletions libstb/secvar/test/secvar-test-getvar.c
@@ -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;
}

0 comments on commit 127db3a

Please sign in to comment.