Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(377)

Unified Diff: src/platform/vboot_reference/cgptlib/tests/cgpt_test.c

Issue 1729006: Add helper functions and files for gpt tests. (Closed)
Patch Set: fix for code review Created 10 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/platform/vboot_reference/cgptlib/tests/cgpt_test.c
diff --git a/src/platform/vboot_reference/cgptlib/tests/cgpt_test.c b/src/platform/vboot_reference/cgptlib/tests/cgpt_test.c
index b5b26e70f9ed4d91ad2b028bd542c989646a3ef4..a451838109c229db3c33dec0d68c818f3728af5f 100644
--- a/src/platform/vboot_reference/cgptlib/tests/cgpt_test.c
+++ b/src/platform/vboot_reference/cgptlib/tests/cgpt_test.c
@@ -3,12 +3,219 @@
* found in the LICENSE file.
*/
-#include "cgpt.h"
#include "cgpt_test.h"
+#include <string.h>
+#include "cgpt.h"
+#include "gpt.h"
+#include "utility.h"
+
+/* Testing partition layout (sector_bytes=512)
+ *
+ * LBA Size Usage
+ * 0 1 PMBR
+ * 1 1 primary partition header
+ * 2 32 primary partition entries (128B * 128)
+ * 34 100 kernel A
+ * 134 100 kernel B
+ * 234 100 root A
+ * 334 100 root B
+ * 434 32 secondary partition entries
+ * 466 1 secondary partition header
+ * 467
+ */
+#define DEFAULT_SECTOR_SIZE 512
+#define MAX_SECTOR_SIZE 4096
+#define DEFAULT_DRIVE_SECTORS 467
+#define PARTITION_ENTRIES_SIZE (16*1024)
#define TEST_CASE(func) #func, func
typedef int (*test_func)(void);
+/* NOT A REAL CRC32, it is fake before I call real one . FIXME */
+uint32_t CalculateCrc32(const uint8_t *start, size_t len) {
+ uint32_t buf = 0;
+ int i;
+ for (i = 0; i < len; i += 4, len -= 4) {
+ buf ^= *(uint32_t*)&start[i];
+ }
+ if (len >= 3) buf ^= start[i-2] << 16;
+ if (len >= 2) buf ^= start[i-3] << 8;
+ if (len >= 1) buf ^= start[i-4];
+ return buf;
+}
+
+/* Given a GptData pointer, first re-calculate entries CRC32 value,
+ * then reset header CRC32 value to 0, and calculate header CRC32 value.
+ * Both primary and secondary are updated. */
+void RefreshCrc32(struct GptData *gpt) {
+ GptHeader *header, *header2;
+ GptEntry *entries, *entries2;
+
+ header = (GptHeader*)gpt->primary_header;
+ entries = (GptEntry*)gpt->primary_entries;
+ header2 = (GptHeader*)gpt->secondary_header;
+ entries2 = (GptEntry*)gpt->secondary_entries;
+
+ header->entries_crc32 = CalculateCrc32((uint8_t*)entries,
+ sizeof(GptEntry));
+ header->header_crc32 = 0;
+ header->header_crc32 = CalculateCrc32((uint8_t*)header,
+ header->size);
+ header2->entries_crc32 = CalculateCrc32((uint8_t*)entries2,
+ sizeof(GptEntry));
+ header2->header_crc32 = 0;
+ header2->header_crc32 = CalculateCrc32((uint8_t*)header2,
+ header2->size);
+}
+
+/* Returns a pointer to a static GptData instance (no free is required).
+ * All fields are zero except 4 pointers linking to header and entries.
+ * All content of headers and entries are zero. */
+struct GptData* GetAClearGptData() {
+ static GptData_t gpt;
+ static uint8_t primary_header[MAX_SECTOR_SIZE];
+ static uint8_t primary_entries[PARTITION_ENTRIES_SIZE];
+ static uint8_t secondary_header[MAX_SECTOR_SIZE];
+ static uint8_t secondary_entries[PARTITION_ENTRIES_SIZE];
+
+ Memset(&gpt, 0, sizeof(gpt));
+ Memset(&primary_header, 0, sizeof(primary_header));
+ Memset(&primary_entries, 0, sizeof(primary_entries));
+ Memset(&secondary_header, 0, sizeof(secondary_header));
+ Memset(&secondary_entries, 0, sizeof(secondary_entries));
+
+ gpt.primary_header = primary_header;
+ gpt.primary_entries = primary_entries;
+ gpt.secondary_header = secondary_header;
+ gpt.secondary_entries = secondary_entries;
+
+ return &gpt;
+}
+
+/* Fills in most of fields and creates the layout described in the top of this
+ * file. */
+struct GptData*
+BuildTestGptData(uint32_t sector_bytes) {
+ GptData_t *gpt;
+ GptHeader *header, *header2;
+ GptEntry *entries, *entries2;
+ Guid chromeos_kernel = GPT_ENT_TYPE_CHROMEOS_KERNEL;
+
+ gpt = GetAClearGptData();
+ gpt->sector_bytes = sector_bytes;
+ gpt->drive_sectors = DEFAULT_DRIVE_SECTORS;
+
+ /* build primary */
+ header = (GptHeader*)gpt->primary_header;
+ entries = (GptEntry*)gpt->primary_entries;
+ Memcpy(header->signature, GPT_HEADER_SIGNATURE, sizeof(GPT_HEADER_SIGNATURE));
+ header->revision = GPT_HEADER_REVISION;
+ header->size = sizeof(GptHeader) - sizeof(header->padding);
+ header->my_lba = 1;
+ header->first_usable_lba = 34;
+ header->last_usable_lba = DEFAULT_DRIVE_SECTORS - 1 - 32 - 1; /* 433 */
+ header->entries_lba = 2;
+ header->number_of_entries = 128; /* 512B / 128B * 32sectors = 128 entries */
+ header->size_of_entry = 128; /* bytes */
+ Memcpy(&entries[0].type, &chromeos_kernel, sizeof(chromeos_kernel));
+ entries[0].starting_lba = 34;
+ entries[0].ending_lba = 133;
+ Memcpy(&entries[1].type, &chromeos_kernel, sizeof(chromeos_kernel));
+ entries[1].starting_lba = 134;
+ entries[1].ending_lba = 233;
+ Memcpy(&entries[2].type, &chromeos_kernel, sizeof(chromeos_kernel));
+ entries[2].starting_lba = 234;
+ entries[2].ending_lba = 333;
+ Memcpy(&entries[3].type, &chromeos_kernel, sizeof(chromeos_kernel));
+ entries[3].starting_lba = 334;
+ entries[3].ending_lba = 433;
+
+ /* build secondary */
+ header2 = (GptHeader*)gpt->secondary_header;
+ entries2 = (GptEntry*)gpt->secondary_entries;
+ Memcpy(header2, header, sizeof(header));
+ Memcpy(entries2, entries, sizeof(entries));
+ header2->my_lba = DEFAULT_DRIVE_SECTORS - 1; /* 466 */
+ header2->entries_lba = DEFAULT_DRIVE_SECTORS - 1 - 32; /* 434 */
+
+ RefreshCrc32(gpt);
+ return gpt;
+}
+
+/* Dumps memory starting from [vp] with [len] bytes.
+ * Prints [memo] if not NULL. Example output:
+ *
+ * 00 01 02 03 04 05 06 07 - 08 09 0a 0b 0c 0d 0e 0f
+ * 10 11 12 13 14 15 16 17 - 18 19 1a 1b 1c 1d 1e 1f
+ * ...
+ */
+static void dump(void *vp, int len, char* memo) {
+ uint8_t *start = vp;
+ int i;
+ if (memo) printf("--[%s]----------\n", memo);
+ for (i = 0; i < len; ++i) {
+ printf("%02x%s", start[i],
+ (!(~i & 15) ? "\n" :
+ !(~i & 7) ? " - ": " "));
+ }
+ if (i&15) printf("\n");
+}
+
+/* More formatted dump with GptData. */
+void DumpGptData(struct GptData *gpt) {
+ printf("DumpGptData(%p)...\n", gpt);
+ dump(gpt, sizeof(gpt), NULL);
+ dump(gpt->primary_header, sizeof(GptHeader), "Primary header");
+ dump(gpt->primary_entries, sizeof(GptEntry) * 8, "Primary entries");
+ dump(gpt->secondary_header, sizeof(GptHeader), "Secondary header");
+ dump(gpt->secondary_entries, sizeof(GptEntry) * 8,
+ "Secondary entries");
+}
+
+/* Tests if signature ("EFI PART") is checked. */
+int SignatureTest() {
+ int i;
+ GptData_t *gpt;
+ GptHeader *primary_header, *secondary_header;
+
+ gpt = BuildTestGptData(DEFAULT_SECTOR_SIZE);
+ primary_header = (GptHeader*)gpt->primary_header;
+ secondary_header = (GptHeader*)gpt->secondary_header;
+
+ EXPECT(GPT_SUCCESS == GptInit(gpt));
+
+ /* change every char in signature of primary. Secondary is still valid. */
+ for (i = 0; i < 8; ++i) {
+ gpt->primary_header[i] ^= 0xff;
+ RefreshCrc32(gpt);
+ EXPECT(GPT_SUCCESS == GptInit(gpt));
+ gpt->primary_header[i] ^= 0xff;
+ RefreshCrc32(gpt);
+ }
+
+ /* change every char in signature of secondary. Primary is still valid. */
+ for (i = 0; i < 8; ++i) {
+ gpt->secondary_header[i] ^= 0xff;
+ RefreshCrc32(gpt);
+ EXPECT(GPT_SUCCESS == GptInit(gpt));
+ gpt->secondary_header[i] ^= 0xff;
+ RefreshCrc32(gpt);
+ }
+
+ /* change every char in signature of primary and secondary. Expect fail. */
+ for (i = 0; i < 8; ++i) {
+ gpt->primary_header[i] ^= 0xff;
+ gpt->secondary_header[i] ^= 0xff;
+ RefreshCrc32(gpt);
+ EXPECT(GPT_ERROR_INVALID_HEADERS == GptInit(gpt));
+ gpt->primary_header[i] ^= 0xff;
+ gpt->secondary_header[i] ^= 0xff;
+ RefreshCrc32(gpt);
+ }
+
+ return TEST_OK;
+}
+
/* Tests if header CRC in two copies are calculated. */
int HeaderCrcTest() {
return TEST_FAIL;
@@ -45,7 +252,7 @@ int FirstUsableLbaAndLastUsableLbaTest() {
return TEST_FAIL;
}
-/* Tests if GPTInit() handles non-identical partition entries well.
+/* Tests if GptInit() handles non-identical partition entries well.
* Two copies of partition table entries must be identical. If not, we trust the
* primary table entries, and mark secondary as modified (see Caller's write-
* back order below). */
@@ -53,7 +260,7 @@ int IdenticalEntriesTest() {
return TEST_FAIL;
}
-/* Tests if GPTInit() handles non-identical headers well.
+/* Tests if GptInit() handles non-identical headers well.
* Two partition headers must be identical. If not, we trust the primary
* partition header, and mark secondary as modified (see Caller's write-back
* order below). */
@@ -84,7 +291,7 @@ int NoOverlappedPartitionTest() {
return TEST_FAIL;
}
-/* Tests if GPTNextKernelEntry() can survive in different corrupt header/entries
+/* Tests if GptNextKernelEntry() can survive in different corrupt header/entries
* combinations, like:
* primary GPT header - valid
* primary partition table - invalid
@@ -102,6 +309,8 @@ int main(int argc, char *argv[]) {
test_func fp;
int retval;
} test_cases[] = {
+ { TEST_CASE(SignatureTest), },
+#if 0
{ TEST_CASE(HeaderCrcTest), },
{ TEST_CASE(MyLbaTest), },
{ TEST_CASE(SizeOfPartitionEntryTest), },
@@ -114,6 +323,7 @@ int main(int argc, char *argv[]) {
{ TEST_CASE(ValidEntryTest), },
{ TEST_CASE(NoOverlappedPartitionTest), },
{ TEST_CASE(CorruptCombinationTest), },
+#endif
};
for (i = 0; i < sizeof(test_cases)/sizeof(test_cases[0]); ++i) {
« no previous file with comments | « src/platform/vboot_reference/cgptlib/tests/cgpt_test.h ('k') | src/platform/vboot_reference/common/include/utility.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698