vboot_display_tests.c revision 8fa13ad6f727d44fdc0ae1d2bde5f54b32dab9b9
1/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved. 2 * Use of this source code is governed by a BSD-style license that can be 3 * found in the LICENSE file. 4 * 5 * Tests for firmware display library. 6 */ 7 8#include <stdint.h> 9#include <stdio.h> 10#include <stdlib.h> 11#include <string.h> 12 13#include "bmpblk_font.h" 14#include "gbb_header.h" 15#include "host_common.h" 16#include "test_common.h" 17#include "vboot_common.h" 18#include "vboot_display.h" 19#include "vboot_nvstorage.h" 20 21/* Mock data */ 22static VbCommonParams cparams; 23static VbNvContext vnc; 24static uint8_t shared_data[VB_SHARED_DATA_MIN_SIZE]; 25static VbSharedDataHeader *shared = (VbSharedDataHeader *)shared_data; 26static char gbb_data[4096 + sizeof(GoogleBinaryBlockHeader)]; 27static GoogleBinaryBlockHeader *gbb = (GoogleBinaryBlockHeader *)gbb_data; 28static BmpBlockHeader *bhdr; 29static char debug_info[4096]; 30 31/* Reset mock data (for use before each test) */ 32static void ResetMocks(void) 33{ 34 int gbb_used; 35 36 Memset(gbb_data, 0, sizeof(gbb_data)); 37 gbb->major_version = GBB_MAJOR_VER; 38 gbb->minor_version = GBB_MINOR_VER; 39 gbb->flags = 0; 40 gbb_used = sizeof(GoogleBinaryBlockHeader); 41 42 gbb->hwid_offset = gbb_used; 43 strcpy(gbb_data + gbb->hwid_offset, "Test HWID"); 44 gbb->hwid_size = strlen(gbb_data + gbb->hwid_offset) + 1; 45 gbb_used = (gbb_used + gbb->hwid_size + 7) & ~7; 46 47 gbb->bmpfv_offset = gbb_used; 48 bhdr = (BmpBlockHeader *)(gbb_data + gbb->bmpfv_offset); 49 gbb->bmpfv_size = sizeof(BmpBlockHeader); 50 gbb_used = (gbb_used + gbb->bmpfv_size + 7) & ~7; 51 memcpy(bhdr->signature, BMPBLOCK_SIGNATURE, BMPBLOCK_SIGNATURE_SIZE); 52 bhdr->major_version = BMPBLOCK_MAJOR_VERSION; 53 bhdr->minor_version = BMPBLOCK_MINOR_VERSION; 54 bhdr->number_of_localizations = 3; 55 56 Memset(&cparams, 0, sizeof(cparams)); 57 cparams.shared_data_size = sizeof(shared_data); 58 cparams.shared_data_blob = shared_data; 59 cparams.gbb_data = gbb; 60 cparams.gbb_size = sizeof(gbb_data); 61 62 Memset(&vnc, 0, sizeof(vnc)); 63 VbNvSetup(&vnc); 64 VbNvTeardown(&vnc); /* So CRC gets generated */ 65 66 Memset(&shared_data, 0, sizeof(shared_data)); 67 VbSharedDataInit(shared, sizeof(shared_data)); 68 69 *debug_info = 0; 70} 71 72/* Mocks */ 73 74VbError_t VbExDisplayDebugInfo(const char *info_str) 75{ 76 strncpy(debug_info, info_str, sizeof(debug_info)); 77 debug_info[sizeof(debug_info) - 1] = '\0'; 78 return VBERROR_SUCCESS; 79} 80 81/* Test displaying debug info */ 82static void DebugInfoTest(void) 83{ 84 int i; 85 86 /* Recovery string should be non-null for any code */ 87 for (i = 0; i < 0x100; i++) 88 TEST_PTR_NEQ(RecoveryReasonString(i), NULL, "Non-null reason"); 89 90 /* HWID should come from the gbb */ 91 ResetMocks(); 92 TEST_EQ(strcmp(VbHWID(&cparams), "Test HWID"), 0, "HWID"); 93 94 ResetMocks(); 95 cparams.gbb_size = 0; 96 TEST_EQ(strcmp(VbHWID(&cparams), "{INVALID}"), 0, "HWID bad gbb"); 97 98 ResetMocks(); 99 gbb->hwid_size = 0; 100 TEST_EQ(strcmp(VbHWID(&cparams), "{INVALID}"), 0, "HWID missing"); 101 102 ResetMocks(); 103 gbb->hwid_offset = cparams.gbb_size + 1; 104 TEST_EQ(strcmp(VbHWID(&cparams), "{INVALID}"), 0, "HWID past end"); 105 106 ResetMocks(); 107 gbb->hwid_size = cparams.gbb_size; 108 TEST_EQ(strcmp(VbHWID(&cparams), "{INVALID}"), 0, "HWID overflow"); 109 110 /* Display debug info */ 111 ResetMocks(); 112 VbDisplayDebugInfo(&cparams, &vnc); 113 TEST_NEQ(*debug_info, '\0', "Some debug info was displayed"); 114} 115 116/* Test localization */ 117static void LocalizationTest(void) 118{ 119 uint32_t count = 6; 120 121 ResetMocks(); 122 gbb->bmpfv_size = 0; 123 TEST_EQ(VbGetLocalizationCount(&cparams, &count), 124 VBERROR_INVALID_GBB, "VbGetLocalizationCount bad gbb"); 125 TEST_EQ(count, 0, " count"); 126 127 ResetMocks(); 128 bhdr->signature[0] ^= 0x5a; 129 TEST_EQ(VbGetLocalizationCount(&cparams, &count), 130 VBERROR_INVALID_BMPFV, "VbGetLocalizationCount bad bmpfv"); 131 132 ResetMocks(); 133 TEST_EQ(VbGetLocalizationCount(&cparams, &count), 0, 134 "VbGetLocalizationCount()"); 135 TEST_EQ(count, 3, " count"); 136 137} 138 139/* Test display key checking */ 140static void DisplayKeyTest(void) 141{ 142 uint32_t u; 143 144 ResetMocks(); 145 VbCheckDisplayKey(&cparams, 'q', &vnc); 146 TEST_EQ(*debug_info, '\0', "DisplayKey q = does nothing"); 147 148 ResetMocks(); 149 VbCheckDisplayKey(&cparams, '\t', &vnc); 150 TEST_NEQ(*debug_info, '\0', "DisplayKey tab = display"); 151 152 /* Toggle localization */ 153 ResetMocks(); 154 VbNvSet(&vnc, VBNV_LOCALIZATION_INDEX, 0); 155 VbNvTeardown(&vnc); 156 VbCheckDisplayKey(&cparams, VB_KEY_DOWN, &vnc); 157 VbNvGet(&vnc, VBNV_LOCALIZATION_INDEX, &u); 158 TEST_EQ(u, 2, "DisplayKey up"); 159 VbCheckDisplayKey(&cparams, VB_KEY_LEFT, &vnc); 160 VbNvGet(&vnc, VBNV_LOCALIZATION_INDEX, &u); 161 TEST_EQ(u, 1, "DisplayKey left"); 162 VbCheckDisplayKey(&cparams, VB_KEY_RIGHT, &vnc); 163 VbNvGet(&vnc, VBNV_LOCALIZATION_INDEX, &u); 164 TEST_EQ(u, 2, "DisplayKey right"); 165 VbCheckDisplayKey(&cparams, VB_KEY_UP, &vnc); 166 VbNvGet(&vnc, VBNV_LOCALIZATION_INDEX, &u); 167 TEST_EQ(u, 0, "DisplayKey up"); 168 169 /* Reset localization if localization count is invalid */ 170 ResetMocks(); 171 VbNvSet(&vnc, VBNV_LOCALIZATION_INDEX, 1); 172 VbNvTeardown(&vnc); 173 bhdr->signature[0] ^= 0x5a; 174 VbCheckDisplayKey(&cparams, VB_KEY_UP, &vnc); 175 VbNvGet(&vnc, VBNV_LOCALIZATION_INDEX, &u); 176 TEST_EQ(u, 0, "DisplayKey invalid"); 177 178} 179 180static void FontTest(void) 181{ 182 FontArrayHeader h; 183 FontArrayEntryHeader eh[3] = { 184 { 185 .ascii = 'A', 186 .info.original_size = 10, 187 }, 188 { 189 .ascii = 'B', 190 .info.original_size = 20, 191 }, 192 { 193 .ascii = 'C', 194 .info.original_size = 30, 195 }, 196 }; 197 FontArrayEntryHeader *eptr; 198 uint8_t buf[sizeof(h) + sizeof(eh)]; 199 VbFont_t *fptr; 200 void *bufferptr; 201 uint32_t buffersize; 202 203 /* Create font data */ 204 h.num_entries = ARRAY_SIZE(eh); 205 Memcpy(buf, &h, sizeof(h)); 206 eptr = (FontArrayEntryHeader *)(buf + sizeof(h)); 207 Memcpy(eptr, eh, sizeof(eh)); 208 209 fptr = VbInternalizeFontData((FontArrayHeader *)buf); 210 TEST_PTR_EQ(fptr, buf, "Internalize"); 211 212 TEST_PTR_EQ(VbFindFontGlyph(fptr, 'B', &bufferptr, &buffersize), 213 &eptr[1].info, "Glyph found"); 214 TEST_EQ(buffersize, eptr[1].info.original_size, " size"); 215 TEST_PTR_EQ(VbFindFontGlyph(fptr, 'X', &bufferptr, &buffersize), 216 &eptr[0].info, "Glyph not found"); 217 TEST_EQ(buffersize, eptr[0].info.original_size, " size"); 218 219 /* Test invalid rendering params */ 220 VbRenderTextAtPos(NULL, 0, 0, 0, fptr); 221 VbRenderTextAtPos("ABC", 0, 0, 0, NULL); 222 223 VbDoneWithFontForNow(fptr); 224 225} 226 227int main(void) 228{ 229 DebugInfoTest(); 230 LocalizationTest(); 231 DisplayKeyTest(); 232 FontTest(); 233 234 return gTestSuccess ? 0 : 255; 235} 236