mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-11-24 02:05:01 +00:00
Add kernel tests
BUG=chromium-os:38139 BRANCH=none TEST=make runtests Change-Id: Iee7c965d5c29063259c66d0ccb117c60f4f4a92e Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/42314
This commit is contained in:
committed by
ChromeBot
parent
c3d488d155
commit
49cb0d3471
5
Makefile
5
Makefile
@@ -425,6 +425,7 @@ TEST_NAMES = \
|
|||||||
vboot_common3_tests \
|
vboot_common3_tests \
|
||||||
vboot_display_tests \
|
vboot_display_tests \
|
||||||
vboot_firmware_tests \
|
vboot_firmware_tests \
|
||||||
|
vboot_kernel_tests \
|
||||||
vboot_nvstorage_test
|
vboot_nvstorage_test
|
||||||
|
|
||||||
# Grrr
|
# Grrr
|
||||||
@@ -952,6 +953,7 @@ runmisctests: test_setup
|
|||||||
${RUNTEST} ${BUILD_RUN}/tests/vboot_common3_tests ${TEST_KEYS}
|
${RUNTEST} ${BUILD_RUN}/tests/vboot_common3_tests ${TEST_KEYS}
|
||||||
${RUNTEST} ${BUILD_RUN}/tests/vboot_display_tests
|
${RUNTEST} ${BUILD_RUN}/tests/vboot_display_tests
|
||||||
${RUNTEST} ${BUILD_RUN}/tests/vboot_firmware_tests
|
${RUNTEST} ${BUILD_RUN}/tests/vboot_firmware_tests
|
||||||
|
${RUNTEST} ${BUILD_RUN}/tests/vboot_kernel_tests
|
||||||
${RUNTEST} ${BUILD_RUN}/tests/vboot_nvstorage_test
|
${RUNTEST} ${BUILD_RUN}/tests/vboot_nvstorage_test
|
||||||
|
|
||||||
.PHONY: runfutiltests
|
.PHONY: runfutiltests
|
||||||
@@ -993,7 +995,8 @@ coverage_html:
|
|||||||
|
|
||||||
# Generate addtional coverage stats just for firmware subdir, because the
|
# Generate addtional coverage stats just for firmware subdir, because the
|
||||||
# per-directory stats for the whole project don't include their own subdirs.
|
# per-directory stats for the whole project don't include their own subdirs.
|
||||||
lcov -e ${COV_INFO}.local '${SRCDIR}/firmware/*' \
|
lcov -r ${COV_INFO}.local '*/stub/*' -o ${COV_INFO}.nostub
|
||||||
|
lcov -e ${COV_INFO}.nostub '${SRCDIR}/firmware/*' \
|
||||||
-o ${COV_INFO}.firmware
|
-o ${COV_INFO}.firmware
|
||||||
|
|
||||||
.PHONY: coverage
|
.PHONY: coverage
|
||||||
|
|||||||
@@ -157,8 +157,7 @@ VbError_t LoadKernel(LoadKernelParams* params) {
|
|||||||
int recovery = VBNV_RECOVERY_LK_UNSPECIFIED;
|
int recovery = VBNV_RECOVERY_LK_UNSPECIFIED;
|
||||||
|
|
||||||
/* Sanity Checks */
|
/* Sanity Checks */
|
||||||
if (!params ||
|
if (!params->bytes_per_lba ||
|
||||||
!params->bytes_per_lba ||
|
|
||||||
!params->ending_lba) {
|
!params->ending_lba) {
|
||||||
VBDEBUG(("LoadKernel() called with invalid params\n"));
|
VBDEBUG(("LoadKernel() called with invalid params\n"));
|
||||||
retval = VBERROR_INVALID_PARAMETER;
|
retval = VBERROR_INVALID_PARAMETER;
|
||||||
@@ -210,27 +209,26 @@ VbError_t LoadKernel(LoadKernelParams* params) {
|
|||||||
kernel_subkey = &shared->kernel_subkey;
|
kernel_subkey = &shared->kernel_subkey;
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
|
||||||
/* Read GPT data */
|
/* Read GPT data */
|
||||||
gpt.sector_bytes = (uint32_t)blba;
|
gpt.sector_bytes = (uint32_t)blba;
|
||||||
gpt.drive_sectors = params->ending_lba + 1;
|
gpt.drive_sectors = params->ending_lba + 1;
|
||||||
if (0 != AllocAndReadGptData(params->disk_handle, &gpt)) {
|
if (0 != AllocAndReadGptData(params->disk_handle, &gpt)) {
|
||||||
VBDEBUG(("Unable to read GPT data\n"));
|
VBDEBUG(("Unable to read GPT data\n"));
|
||||||
shcall->check_result = VBSD_LKC_CHECK_GPT_READ_ERROR;
|
shcall->check_result = VBSD_LKC_CHECK_GPT_READ_ERROR;
|
||||||
break;
|
goto bad_gpt;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize GPT library */
|
/* Initialize GPT library */
|
||||||
if (GPT_SUCCESS != GptInit(&gpt)) {
|
if (GPT_SUCCESS != GptInit(&gpt)) {
|
||||||
VBDEBUG(("Error parsing GPT\n"));
|
VBDEBUG(("Error parsing GPT\n"));
|
||||||
shcall->check_result = VBSD_LKC_CHECK_GPT_PARSE_ERROR;
|
shcall->check_result = VBSD_LKC_CHECK_GPT_PARSE_ERROR;
|
||||||
break;
|
goto bad_gpt;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate kernel header buffers */
|
/* Allocate kernel header buffers */
|
||||||
kbuf = (uint8_t*)VbExMalloc(KBUF_SIZE);
|
kbuf = (uint8_t*)VbExMalloc(KBUF_SIZE);
|
||||||
if (!kbuf)
|
if (!kbuf)
|
||||||
break;
|
goto bad_gpt;
|
||||||
|
|
||||||
/* Loop over candidate kernel partitions */
|
/* Loop over candidate kernel partitions */
|
||||||
while (GPT_SUCCESS == GptNextKernelEntry(&gpt, &part_start, &part_size)) {
|
while (GPT_SUCCESS == GptNextKernelEntry(&gpt, &part_start, &part_size)) {
|
||||||
@@ -516,7 +514,8 @@ VbError_t LoadKernel(LoadKernelParams* params) {
|
|||||||
|
|
||||||
|
|
||||||
} /* while(GptNextKernelEntry) */
|
} /* while(GptNextKernelEntry) */
|
||||||
} while(0);
|
|
||||||
|
bad_gpt:
|
||||||
|
|
||||||
/* Free kernel buffer */
|
/* Free kernel buffer */
|
||||||
if (kbuf)
|
if (kbuf)
|
||||||
|
|||||||
203
tests/vboot_kernel_tests.c
Normal file
203
tests/vboot_kernel_tests.c
Normal file
@@ -0,0 +1,203 @@
|
|||||||
|
/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
|
||||||
|
* Use of this source code is governed by a BSD-style license that can be
|
||||||
|
* found in the LICENSE file.
|
||||||
|
*
|
||||||
|
* Tests for vboot_kernel.c
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "cgptlib.h"
|
||||||
|
#include "gbb_header.h"
|
||||||
|
#include "gpt.h"
|
||||||
|
#include "host_common.h"
|
||||||
|
#include "load_kernel_fw.h"
|
||||||
|
#include "test_common.h"
|
||||||
|
#include "vboot_api.h"
|
||||||
|
#include "vboot_common.h"
|
||||||
|
#include "vboot_kernel.h"
|
||||||
|
#include "vboot_nvstorage.h"
|
||||||
|
|
||||||
|
#define LOGCALL(fmt, args...) sprintf(call_log + strlen(call_log), fmt, ##args)
|
||||||
|
#define TEST_CALLS(expect_log) TEST_STR_EQ(call_log, expect_log, " calls")
|
||||||
|
|
||||||
|
/* Mock data */
|
||||||
|
static char call_log[4096];
|
||||||
|
static int disk_call_to_fail;
|
||||||
|
static int disk_calls;
|
||||||
|
static int gpt_init_fail;
|
||||||
|
|
||||||
|
static GoogleBinaryBlockHeader gbb;
|
||||||
|
static VbExDiskHandle_t handle;
|
||||||
|
static VbNvContext vnc;
|
||||||
|
static uint8_t shared_data[VB_SHARED_DATA_MIN_SIZE];
|
||||||
|
static VbSharedDataHeader *shared = (VbSharedDataHeader *)shared_data;
|
||||||
|
static LoadKernelParams lkp;
|
||||||
|
|
||||||
|
static void ResetCallLog(void)
|
||||||
|
{
|
||||||
|
*call_log = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset mock data (for use before each test)
|
||||||
|
*/
|
||||||
|
static void ResetMocks(void)
|
||||||
|
{
|
||||||
|
ResetCallLog();
|
||||||
|
|
||||||
|
disk_call_to_fail = 0;
|
||||||
|
disk_calls = 0;
|
||||||
|
|
||||||
|
gpt_init_fail = 0;
|
||||||
|
|
||||||
|
memset(&gbb, 0, sizeof(gbb));
|
||||||
|
gbb.major_version = GBB_MAJOR_VER;
|
||||||
|
gbb.minor_version = GBB_MINOR_VER;
|
||||||
|
gbb.flags = 0;
|
||||||
|
|
||||||
|
memset(&vnc, 0, sizeof(vnc));
|
||||||
|
VbNvSetup(&vnc);
|
||||||
|
VbNvTeardown(&vnc); /* So CRC gets generated */
|
||||||
|
|
||||||
|
memset(&shared_data, 0, sizeof(shared_data));
|
||||||
|
VbSharedDataInit(shared, sizeof(shared_data));
|
||||||
|
|
||||||
|
memset(&lkp, 0, sizeof(lkp));
|
||||||
|
lkp.nv_context = &vnc;
|
||||||
|
lkp.shared_data_blob = shared;
|
||||||
|
lkp.gbb_data = &gbb;
|
||||||
|
lkp.bytes_per_lba = 512;
|
||||||
|
lkp.ending_lba = 1023;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mocks */
|
||||||
|
|
||||||
|
VbError_t VbExDiskRead(VbExDiskHandle_t handle, uint64_t lba_start,
|
||||||
|
uint64_t lba_count, void *buffer)
|
||||||
|
{
|
||||||
|
LOGCALL("VbExDiskRead(h, %d, %d)\n", (int)lba_start, (int)lba_count);
|
||||||
|
|
||||||
|
if (++disk_calls == disk_call_to_fail)
|
||||||
|
return VBERROR_SIMULATED;
|
||||||
|
|
||||||
|
return VBERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
VbError_t VbExDiskWrite(VbExDiskHandle_t handle, uint64_t lba_start,
|
||||||
|
uint64_t lba_count, const void *buffer)
|
||||||
|
{
|
||||||
|
LOGCALL("VbExDiskWrite(h, %d, %d)\n", (int)lba_start, (int)lba_count);
|
||||||
|
|
||||||
|
if (++disk_calls == disk_call_to_fail)
|
||||||
|
return VBERROR_SIMULATED;
|
||||||
|
|
||||||
|
return VBERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GptInit(GptData *gpt)
|
||||||
|
{
|
||||||
|
return gpt_init_fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test reading/writing GPT
|
||||||
|
*/
|
||||||
|
static void ReadWriteGptTest(void)
|
||||||
|
{
|
||||||
|
GptData g;
|
||||||
|
GptHeader *h;
|
||||||
|
|
||||||
|
g.sector_bytes = 512;
|
||||||
|
g.drive_sectors = 1024;
|
||||||
|
|
||||||
|
ResetMocks();
|
||||||
|
TEST_EQ(AllocAndReadGptData(handle, &g), 0, "AllocAndRead");
|
||||||
|
TEST_CALLS("VbExDiskRead(h, 1, 1)\n"
|
||||||
|
"VbExDiskRead(h, 2, 32)\n"
|
||||||
|
"VbExDiskRead(h, 991, 32)\n"
|
||||||
|
"VbExDiskRead(h, 1023, 1)\n");
|
||||||
|
ResetCallLog();
|
||||||
|
TEST_EQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree");
|
||||||
|
TEST_CALLS("");
|
||||||
|
|
||||||
|
/* Data which is changed is written */
|
||||||
|
ResetMocks();
|
||||||
|
AllocAndReadGptData(handle, &g);
|
||||||
|
g.modified |= GPT_MODIFIED_HEADER1 | GPT_MODIFIED_ENTRIES1;
|
||||||
|
ResetCallLog();
|
||||||
|
TEST_EQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree mod 1");
|
||||||
|
TEST_CALLS("VbExDiskWrite(h, 1, 1)\n"
|
||||||
|
"VbExDiskWrite(h, 2, 32)\n");
|
||||||
|
|
||||||
|
/* Data which is changed is written */
|
||||||
|
ResetMocks();
|
||||||
|
AllocAndReadGptData(handle, &g);
|
||||||
|
g.modified = -1;
|
||||||
|
ResetCallLog();
|
||||||
|
TEST_EQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree mod all");
|
||||||
|
TEST_CALLS("VbExDiskWrite(h, 1, 1)\n"
|
||||||
|
"VbExDiskWrite(h, 2, 32)\n"
|
||||||
|
"VbExDiskWrite(h, 991, 32)\n"
|
||||||
|
"VbExDiskWrite(h, 1023, 1)\n");
|
||||||
|
|
||||||
|
/* If legacy signature, don't modify GPT header/entries 1 */
|
||||||
|
ResetMocks();
|
||||||
|
AllocAndReadGptData(handle, &g);
|
||||||
|
h = (GptHeader *)g.primary_header;
|
||||||
|
memcpy(h->signature, GPT_HEADER_SIGNATURE2, GPT_HEADER_SIGNATURE_SIZE);
|
||||||
|
g.modified = -1;
|
||||||
|
ResetCallLog();
|
||||||
|
TEST_EQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree mod all");
|
||||||
|
TEST_CALLS("VbExDiskWrite(h, 991, 32)\n"
|
||||||
|
"VbExDiskWrite(h, 1023, 1)\n");
|
||||||
|
|
||||||
|
/* Error reading */
|
||||||
|
ResetMocks();
|
||||||
|
disk_call_to_fail = 1;
|
||||||
|
TEST_NEQ(AllocAndReadGptData(handle, &g), 0, "AllocAndRead disk fail");
|
||||||
|
WriteAndFreeGptData(handle, &g);
|
||||||
|
|
||||||
|
/* Error writing */
|
||||||
|
ResetMocks();
|
||||||
|
disk_call_to_fail = 5;
|
||||||
|
AllocAndReadGptData(handle, &g);
|
||||||
|
g.modified = -1;
|
||||||
|
TEST_NEQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree disk fail");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Trivial invalid calls to LoadKernel()
|
||||||
|
*/
|
||||||
|
static void InvalidParamsTest(void)
|
||||||
|
{
|
||||||
|
ResetMocks();
|
||||||
|
lkp.bytes_per_lba = 0;
|
||||||
|
TEST_EQ(LoadKernel(&lkp), VBERROR_INVALID_PARAMETER, "Bad lba size");
|
||||||
|
|
||||||
|
ResetMocks();
|
||||||
|
lkp.ending_lba = 0;
|
||||||
|
TEST_EQ(LoadKernel(&lkp), VBERROR_INVALID_PARAMETER, "Bad lba count");
|
||||||
|
|
||||||
|
ResetMocks();
|
||||||
|
lkp.bytes_per_lba = 128*1024;
|
||||||
|
TEST_EQ(LoadKernel(&lkp), VBERROR_INVALID_PARAMETER, "Huge lba size");
|
||||||
|
|
||||||
|
ResetMocks();
|
||||||
|
disk_call_to_fail = 1;
|
||||||
|
TEST_EQ(LoadKernel(&lkp), VBERROR_NO_KERNEL_FOUND, "Can't read disk");
|
||||||
|
|
||||||
|
ResetMocks();
|
||||||
|
gpt_init_fail = 1;
|
||||||
|
TEST_EQ(LoadKernel(&lkp), VBERROR_NO_KERNEL_FOUND, "Bad GPT");
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
ReadWriteGptTest();
|
||||||
|
InvalidParamsTest();
|
||||||
|
|
||||||
|
return gTestSuccess ? 0 : 255;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user