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

Side by Side Diff: src/platform/vboot_reference/cgptlib/tests/cgpt_test.c

Issue 1701017: Add more test cases for GptInit() and fixed some bugs (Closed)
Patch Set: refine for code review Created 10 years, 7 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 unified diff | Download patch
OLDNEW
1 /* Copyright (c) 2010 The Chromium OS Authors. All rights reserved. 1 /* Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
2 * Use of this source code is governed by a BSD-style license that can be 2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file. 3 * found in the LICENSE file.
4 */ 4 */
5 5
6 #include "cgpt_test.h" 6 #include "cgpt_test.h"
7 #include <string.h> 7 #include <string.h>
8 #include "cgpt.h" 8 #include "cgpt.h"
9 #include "cgpt_internal.h"
10 #include "crc32.h"
9 #include "gpt.h" 11 #include "gpt.h"
12 #include "quick_sort_test.h"
10 #include "utility.h" 13 #include "utility.h"
11 14
12 /* Testing partition layout (sector_bytes=512) 15 /* Testing partition layout (sector_bytes=512)
13 * 16 *
14 * LBA Size Usage 17 * LBA Size Usage
15 * 0 1 PMBR 18 * 0 1 PMBR
16 * 1 1 primary partition header 19 * 1 1 primary partition header
17 * 2 32 primary partition entries (128B * 128) 20 * 2 32 primary partition entries (128B * 128)
18 * 34 100 kernel A 21 * 34 100 kernel A
19 * 134 100 kernel B 22 * 134 100 kernel B
20 * 234 100 root A 23 * 234 100 root A
21 * 334 100 root B 24 * 334 100 root B
22 * 434 32 secondary partition entries 25 * 434 32 secondary partition entries
23 * 466 1 secondary partition header 26 * 466 1 secondary partition header
24 * 467 27 * 467
25 */ 28 */
26 #define DEFAULT_SECTOR_SIZE 512 29 #define DEFAULT_SECTOR_SIZE 512
27 #define MAX_SECTOR_SIZE 4096 30 #define MAX_SECTOR_SIZE 4096
28 #define DEFAULT_DRIVE_SECTORS 467 31 #define DEFAULT_DRIVE_SECTORS 467
29 #define PARTITION_ENTRIES_SIZE (16*1024) 32 #define PARTITION_ENTRIES_SIZE TOTAL_ENTRIES_SIZE /* 16384 */
30
31 #define TEST_CASE(func) #func, func
32 typedef int (*test_func)(void);
33
34 /* NOT A REAL CRC32, it is fake before I call real one . FIXME */
35 uint32_t CalculateCrc32(const uint8_t *start, size_t len) {
36 uint32_t buf = 0;
37 int i;
38 for (i = 0; i < len; i += 4, len -= 4) {
39 buf ^= *(uint32_t*)&start[i];
40 }
41 if (len >= 3) buf ^= start[i-2] << 16;
42 if (len >= 2) buf ^= start[i-3] << 8;
43 if (len >= 1) buf ^= start[i-4];
44 return buf;
45 }
46 33
47 /* Given a GptData pointer, first re-calculate entries CRC32 value, 34 /* Given a GptData pointer, first re-calculate entries CRC32 value,
48 * then reset header CRC32 value to 0, and calculate header CRC32 value. 35 * then reset header CRC32 value to 0, and calculate header CRC32 value.
49 * Both primary and secondary are updated. */ 36 * Both primary and secondary are updated. */
50 void RefreshCrc32(struct GptData *gpt) { 37 void RefreshCrc32(GptData *gpt) {
51 GptHeader *header, *header2; 38 GptHeader *header, *header2;
52 GptEntry *entries, *entries2; 39 GptEntry *entries, *entries2;
53 40
54 header = (GptHeader*)gpt->primary_header; 41 header = (GptHeader*)gpt->primary_header;
55 entries = (GptEntry*)gpt->primary_entries; 42 entries = (GptEntry*)gpt->primary_entries;
56 header2 = (GptHeader*)gpt->secondary_header; 43 header2 = (GptHeader*)gpt->secondary_header;
57 entries2 = (GptEntry*)gpt->secondary_entries; 44 entries2 = (GptEntry*)gpt->secondary_entries;
58 45
59 header->entries_crc32 = CalculateCrc32((uint8_t*)entries, 46 header->entries_crc32 =
60 sizeof(GptEntry)); 47 Crc32((uint8_t*)entries,
48 header->number_of_entries * header->size_of_entry);
61 header->header_crc32 = 0; 49 header->header_crc32 = 0;
62 header->header_crc32 = CalculateCrc32((uint8_t*)header, 50 header->header_crc32 = Crc32((uint8_t*)header, header->size);
63 header->size); 51 header2->entries_crc32 =
64 header2->entries_crc32 = CalculateCrc32((uint8_t*)entries2, 52 Crc32((uint8_t*)entries2,
65 sizeof(GptEntry)); 53 header2->number_of_entries * header2->size_of_entry);
66 header2->header_crc32 = 0; 54 header2->header_crc32 = 0;
67 header2->header_crc32 = CalculateCrc32((uint8_t*)header2, 55 header2->header_crc32 = Crc32((uint8_t*)header2, header2->size);
68 header2->size); 56 }
57
58 void ZeroHeaders(GptData* gpt) {
59 Memset(gpt->primary_header, 0, MAX_SECTOR_SIZE);
60 Memset(gpt->secondary_header, 0, MAX_SECTOR_SIZE);
61 }
62
63 void ZeroEntries(GptData* gpt) {
64 Memset(gpt->primary_entries, 0, PARTITION_ENTRIES_SIZE);
65 Memset(gpt->secondary_entries, 0, PARTITION_ENTRIES_SIZE);
66 }
67
68 void ZeroHeadersEntries(GptData* gpt) {
69 ZeroHeaders(gpt);
70 ZeroEntries(gpt);
69 } 71 }
70 72
71 /* Returns a pointer to a static GptData instance (no free is required). 73 /* Returns a pointer to a static GptData instance (no free is required).
72 * All fields are zero except 4 pointers linking to header and entries. 74 * All fields are zero except 4 pointers linking to header and entries.
73 * All content of headers and entries are zero. */ 75 * All content of headers and entries are zero. */
74 struct GptData* GetAClearGptData() { 76 GptData* GetEmptyGptData() {
75 static GptData_t gpt; 77 static GptData gpt;
76 static uint8_t primary_header[MAX_SECTOR_SIZE]; 78 static uint8_t primary_header[MAX_SECTOR_SIZE];
77 static uint8_t primary_entries[PARTITION_ENTRIES_SIZE]; 79 static uint8_t primary_entries[PARTITION_ENTRIES_SIZE];
78 static uint8_t secondary_header[MAX_SECTOR_SIZE]; 80 static uint8_t secondary_header[MAX_SECTOR_SIZE];
79 static uint8_t secondary_entries[PARTITION_ENTRIES_SIZE]; 81 static uint8_t secondary_entries[PARTITION_ENTRIES_SIZE];
80 82
81 Memset(&gpt, 0, sizeof(gpt)); 83 Memset(&gpt, 0, sizeof(gpt));
82 Memset(&primary_header, 0, sizeof(primary_header));
83 Memset(&primary_entries, 0, sizeof(primary_entries));
84 Memset(&secondary_header, 0, sizeof(secondary_header));
85 Memset(&secondary_entries, 0, sizeof(secondary_entries));
86
87 gpt.primary_header = primary_header; 84 gpt.primary_header = primary_header;
88 gpt.primary_entries = primary_entries; 85 gpt.primary_entries = primary_entries;
89 gpt.secondary_header = secondary_header; 86 gpt.secondary_header = secondary_header;
90 gpt.secondary_entries = secondary_entries; 87 gpt.secondary_entries = secondary_entries;
88 ZeroHeadersEntries(&gpt);
91 89
92 return &gpt; 90 return &gpt;
93 } 91 }
94 92
95 /* Fills in most of fields and creates the layout described in the top of this 93 /* Fills in most of fields and creates the layout described in the top of this
96 * file. */ 94 * file. Before calling this function, primary/secondary header/entries must
97 struct GptData* 95 * have been pointed to the buffer, say, a gpt returned from GetEmptyGptData().
98 BuildTestGptData(uint32_t sector_bytes) { 96 * This function returns a good (valid) copy of GPT layout described in top of
99 GptData_t *gpt; 97 * this file. */
98 void BuildTestGptData(GptData *gpt) {
100 GptHeader *header, *header2; 99 GptHeader *header, *header2;
101 GptEntry *entries, *entries2; 100 GptEntry *entries, *entries2;
102 Guid chromeos_kernel = GPT_ENT_TYPE_CHROMEOS_KERNEL; 101 Guid chromeos_kernel = GPT_ENT_TYPE_CHROMEOS_KERNEL;
103 102
104 gpt = GetAClearGptData(); 103 gpt->sector_bytes = DEFAULT_SECTOR_SIZE;
105 gpt->sector_bytes = sector_bytes;
106 gpt->drive_sectors = DEFAULT_DRIVE_SECTORS; 104 gpt->drive_sectors = DEFAULT_DRIVE_SECTORS;
107 105
108 /* build primary */ 106 /* build primary */
109 header = (GptHeader*)gpt->primary_header; 107 header = (GptHeader*)gpt->primary_header;
110 entries = (GptEntry*)gpt->primary_entries; 108 entries = (GptEntry*)gpt->primary_entries;
111 Memcpy(header->signature, GPT_HEADER_SIGNATURE, sizeof(GPT_HEADER_SIGNATURE)); 109 Memcpy(header->signature, GPT_HEADER_SIGNATURE, sizeof(GPT_HEADER_SIGNATURE));
112 header->revision = GPT_HEADER_REVISION; 110 header->revision = GPT_HEADER_REVISION;
113 header->size = sizeof(GptHeader) - sizeof(header->padding); 111 header->size = sizeof(GptHeader) - sizeof(header->padding);
112 header->reserved = 0;
114 header->my_lba = 1; 113 header->my_lba = 1;
115 header->first_usable_lba = 34; 114 header->first_usable_lba = 34;
116 header->last_usable_lba = DEFAULT_DRIVE_SECTORS - 1 - 32 - 1; /* 433 */ 115 header->last_usable_lba = DEFAULT_DRIVE_SECTORS - 1 - 32 - 1; /* 433 */
117 header->entries_lba = 2; 116 header->entries_lba = 2;
118 header->number_of_entries = 128; /* 512B / 128B * 32sectors = 128 entries */ 117 header->number_of_entries = 128; /* 512B / 128B * 32sectors = 128 entries */
119 header->size_of_entry = 128; /* bytes */ 118 header->size_of_entry = 128; /* bytes */
120 Memcpy(&entries[0].type, &chromeos_kernel, sizeof(chromeos_kernel)); 119 Memcpy(&entries[0].type, &chromeos_kernel, sizeof(chromeos_kernel));
121 entries[0].starting_lba = 34; 120 entries[0].starting_lba = 34;
122 entries[0].ending_lba = 133; 121 entries[0].ending_lba = 133;
123 Memcpy(&entries[1].type, &chromeos_kernel, sizeof(chromeos_kernel)); 122 Memcpy(&entries[1].type, &chromeos_kernel, sizeof(chromeos_kernel));
124 entries[1].starting_lba = 134; 123 entries[1].starting_lba = 134;
125 entries[1].ending_lba = 233; 124 entries[1].ending_lba = 233;
126 Memcpy(&entries[2].type, &chromeos_kernel, sizeof(chromeos_kernel)); 125 Memcpy(&entries[2].type, &chromeos_kernel, sizeof(chromeos_kernel));
127 entries[2].starting_lba = 234; 126 entries[2].starting_lba = 234;
128 entries[2].ending_lba = 333; 127 entries[2].ending_lba = 333;
129 Memcpy(&entries[3].type, &chromeos_kernel, sizeof(chromeos_kernel)); 128 Memcpy(&entries[3].type, &chromeos_kernel, sizeof(chromeos_kernel));
130 entries[3].starting_lba = 334; 129 entries[3].starting_lba = 334;
131 entries[3].ending_lba = 433; 130 entries[3].ending_lba = 433;
131 header->padding = 0;
132 132
133 /* build secondary */ 133 /* build secondary */
134 header2 = (GptHeader*)gpt->secondary_header; 134 header2 = (GptHeader*)gpt->secondary_header;
135 entries2 = (GptEntry*)gpt->secondary_entries; 135 entries2 = (GptEntry*)gpt->secondary_entries;
136 Memcpy(header2, header, sizeof(header)); 136 Memcpy(header2, header, sizeof(GptHeader));
137 Memcpy(entries2, entries, sizeof(entries)); 137 Memcpy(entries2, entries, PARTITION_ENTRIES_SIZE);
138 header2->my_lba = DEFAULT_DRIVE_SECTORS - 1; /* 466 */ 138 header2->my_lba = DEFAULT_DRIVE_SECTORS - 1; /* 466 */
139 header2->entries_lba = DEFAULT_DRIVE_SECTORS - 1 - 32; /* 434 */ 139 header2->entries_lba = DEFAULT_DRIVE_SECTORS - 1 - 32; /* 434 */
140 140
141 RefreshCrc32(gpt); 141 RefreshCrc32(gpt);
142 return gpt;
143 } 142 }
144 143
145 /* Dumps memory starting from [vp] with [len] bytes. 144 /* Dumps memory starting from [vp] with [len] bytes.
146 * Prints [memo] if not NULL. Example output: 145 * Prints [memo] if not NULL. Example output:
147 * 146 *
148 * 00 01 02 03 04 05 06 07 - 08 09 0a 0b 0c 0d 0e 0f 147 * 00 01 02 03 04 05 06 07 - 08 09 0a 0b 0c 0d 0e 0f
149 * 10 11 12 13 14 15 16 17 - 18 19 1a 1b 1c 1d 1e 1f 148 * 10 11 12 13 14 15 16 17 - 18 19 1a 1b 1c 1d 1e 1f
150 * ... 149 * ...
151 */ 150 */
152 static void dump(void *vp, int len, char* memo) { 151 static void Dump(void *vp, int len, char* memo) {
153 uint8_t *start = vp; 152 uint8_t *start = vp;
154 int i; 153 int i;
155 if (memo) printf("--[%s]----------\n", memo); 154 if (memo) printf("--[%s]----------\n", memo);
156 for (i = 0; i < len; ++i) { 155 for (i = 0; i < len; ++i) {
157 printf("%02x%s", start[i], 156 printf("%02x%s", start[i],
158 (!(~i & 15) ? "\n" : 157 (!(~i & 15) ? "\n" :
159 !(~i & 7) ? " - ": " ")); 158 !(~i & 7) ? " - ": " "));
160 } 159 }
161 if (i&15) printf("\n"); 160 if (i&15) printf("\n");
162 } 161 }
163 162
164 /* More formatted dump with GptData. */ 163 /* More formatted dump with GptData. */
165 void DumpGptData(struct GptData *gpt) { 164 void DumpGptData(GptData *gpt) {
166 printf("DumpGptData(%p)...\n", gpt); 165 printf("DumpGptData(%p)...\n", gpt);
167 dump(gpt, sizeof(gpt), NULL); 166 Dump(gpt, sizeof(gpt), NULL);
168 dump(gpt->primary_header, sizeof(GptHeader), "Primary header"); 167 Dump(gpt->primary_header, sizeof(GptHeader), "Primary header");
169 dump(gpt->primary_entries, sizeof(GptEntry) * 8, "Primary entries"); 168 Dump(gpt->primary_entries, sizeof(GptEntry) * 8, "Primary entries");
170 dump(gpt->secondary_header, sizeof(GptHeader), "Secondary header"); 169 Dump(gpt->secondary_header, sizeof(GptHeader), "Secondary header");
171 dump(gpt->secondary_entries, sizeof(GptEntry) * 8, 170 Dump(gpt->secondary_entries, sizeof(GptEntry) * 8,
172 "Secondary entries"); 171 "Secondary entries");
173 } 172 }
174 173
174 /* Tests if the default structure returned by BuildTestGptData() is good. */
175 int TestBuildTestGptData() {
176 GptData *gpt;
177 gpt = GetEmptyGptData();
178 BuildTestGptData(gpt);
179 EXPECT(GPT_SUCCESS == GptInit(gpt));
180 return TEST_OK;
181 }
182
183 /* Tests if wrong sector_bytes or drive_sectors is detected by GptInit().
184 * Currently we only support 512 bytes per sector.
185 * In the future, we may support other sizes.
186 * A too small drive_sectors should be rejected by GptInit(). */
187 int ParameterTests() {
188 GptData *gpt;
189 struct {
190 uint32_t sector_bytes;
191 uint64_t drive_sectors;
192 int expected_retval;
193 } cases[] = {
194 {512, DEFAULT_DRIVE_SECTORS, GPT_SUCCESS},
195 {520, DEFAULT_DRIVE_SECTORS, GPT_ERROR_INVALID_SECTOR_SIZE},
196 {512, 0, GPT_ERROR_INVALID_SECTOR_NUMBER},
197 {512, 66, GPT_ERROR_INVALID_SECTOR_NUMBER},
198 {512, GPT_PMBR_SECTOR + GPT_HEADER_SECTOR * 2 + GPT_ENTRIES_SECTORS * 2,
199 GPT_SUCCESS},
200 {4096, DEFAULT_DRIVE_SECTORS, GPT_ERROR_INVALID_SECTOR_SIZE},
201 };
202 int i;
203
204 gpt = GetEmptyGptData();
205 for (i = 0; i < ARRAY_SIZE(cases); ++i) {
206 BuildTestGptData(gpt);
207 gpt->sector_bytes = cases[i].sector_bytes;
208 gpt->drive_sectors = cases[i].drive_sectors;
209 EXPECT(cases[i].expected_retval == CheckParameters(gpt));
210 }
211
212 return TEST_OK;
213 }
214
175 /* Tests if signature ("EFI PART") is checked. */ 215 /* Tests if signature ("EFI PART") is checked. */
176 int SignatureTest() { 216 int SignatureTest() {
177 int i; 217 int i;
178 GptData_t *gpt; 218 GptData *gpt;
219 int test_mask;
220 GptHeader *headers[2];
221
222 gpt = GetEmptyGptData();
223 headers[PRIMARY] = (GptHeader*)gpt->primary_header;
224 headers[SECONDARY] = (GptHeader*)gpt->secondary_header;
225
226 for (test_mask = MASK_PRIMARY; test_mask <= MASK_BOTH; ++test_mask) {
227 for (i = 0; i < 8; ++i) {
228 BuildTestGptData(gpt);
229 if (test_mask & MASK_PRIMARY)
230 headers[PRIMARY]->signature[i] ^= 0xff;
231 if (test_mask & MASK_SECONDARY)
232 headers[SECONDARY]->signature[i] ^= 0xff;
233 EXPECT((MASK_BOTH ^ test_mask) == CheckHeaderSignature(gpt));
234 }
235 }
236
237 return TEST_OK;
238 }
239
240 /* The revision we currently support is GPT_HEADER_REVISION.
241 * If the revision in header is not that, we expect the header is invalid. */
242 int RevisionTest() {
243 GptData *gpt;
244 struct {
245 uint32_t value_to_test;
246 int is_valid_value;
247 } cases[] = {
248 {0x01000000, 0},
249 {0x00010000, 1}, /* GPT_HEADER_REVISION */
250 {0x00000100, 0},
251 {0x00000001, 0},
252 {0x23010456, 0},
253 };
254 int i;
255 int test_mask;
256 GptHeader *headers[2];
257 uint32_t valid_headers;
258
259 gpt = GetEmptyGptData();
260 headers[PRIMARY] = (GptHeader*)gpt->primary_header;
261 headers[SECONDARY] = (GptHeader*)gpt->secondary_header;
262
263 for (i = 0; i < ARRAY_SIZE(cases); ++i) {
264 for (test_mask = MASK_PRIMARY; test_mask <= MASK_BOTH; ++test_mask) {
265 BuildTestGptData(gpt);
266 if (test_mask & MASK_PRIMARY)
267 headers[PRIMARY]->revision = cases[i].value_to_test;
268 if (test_mask & MASK_SECONDARY)
269 headers[SECONDARY]->revision = cases[i].value_to_test;
270 valid_headers = CheckRevision(gpt);
271 if (cases[i].is_valid_value)
272 EXPECT(MASK_BOTH == valid_headers);
273 else
274 EXPECT((MASK_BOTH ^ test_mask) == valid_headers);
275 }
276 }
277 return TEST_OK;
278 }
279
280 int SizeTest() {
281 GptData *gpt;
282 struct {
283 uint32_t value_to_test;
284 int is_valid_value;
285 } cases[] = {
286 {91, 0},
287 {92, 1},
288 {93, 1},
289 {511, 1},
290 {512, 1},
291 {513, 0},
292 };
293 int i;
294 int test_mask;
295 GptHeader *headers[2];
296 uint32_t valid_headers;
297
298 gpt = GetEmptyGptData();
299 headers[PRIMARY] = (GptHeader*)gpt->primary_header;
300 headers[SECONDARY] = (GptHeader*)gpt->secondary_header;
301
302 for (i = 0; i < ARRAY_SIZE(cases); ++i) {
303 for (test_mask = MASK_PRIMARY; test_mask <= MASK_BOTH; ++test_mask) {
304 BuildTestGptData(gpt);
305 if (test_mask & MASK_PRIMARY)
306 headers[PRIMARY]->size = cases[i].value_to_test;
307 if (test_mask & MASK_SECONDARY)
308 headers[SECONDARY]->size = cases[i].value_to_test;
309 valid_headers = CheckSize(gpt);
310 if (cases[i].is_valid_value)
311 EXPECT(MASK_BOTH == valid_headers);
312 else
313 EXPECT((MASK_BOTH ^ test_mask) == valid_headers);
314 }
315 }
316 return TEST_OK;
317 }
318
319 /* Tests if reserved fields are checked.
320 * We'll try non-zero values to test. */
321 int ReservedFieldsTest() {
322 GptData *gpt;
179 GptHeader *primary_header, *secondary_header; 323 GptHeader *primary_header, *secondary_header;
180 324
181 gpt = BuildTestGptData(DEFAULT_SECTOR_SIZE); 325 gpt = GetEmptyGptData();
182 primary_header = (GptHeader*)gpt->primary_header; 326 primary_header = (GptHeader*)gpt->primary_header;
183 secondary_header = (GptHeader*)gpt->secondary_header; 327 secondary_header = (GptHeader*)gpt->secondary_header;
184 328
185 EXPECT(GPT_SUCCESS == GptInit(gpt)); 329 /* expect secondary is still valid. */
186 330 BuildTestGptData(gpt);
187 /* change every char in signature of primary. Secondary is still valid. */ 331 primary_header->reserved ^= 0x12345678; /* whatever random */
188 for (i = 0; i < 8; ++i) { 332 EXPECT(MASK_SECONDARY == CheckReservedFields(gpt));
189 gpt->primary_header[i] ^= 0xff; 333
190 RefreshCrc32(gpt); 334 /* expect secondary is still valid. */
191 EXPECT(GPT_SUCCESS == GptInit(gpt)); 335 BuildTestGptData(gpt);
192 gpt->primary_header[i] ^= 0xff; 336 primary_header->padding ^= 0x12345678; /* whatever random */
193 RefreshCrc32(gpt); 337 EXPECT(MASK_SECONDARY == CheckReservedFields(gpt));
194 } 338
195 339 /* expect primary is still valid. */
196 /* change every char in signature of secondary. Primary is still valid. */ 340 BuildTestGptData(gpt);
197 for (i = 0; i < 8; ++i) { 341 secondary_header->reserved ^= 0x12345678; /* whatever random */
198 gpt->secondary_header[i] ^= 0xff; 342 EXPECT(MASK_PRIMARY == CheckReservedFields(gpt));
199 RefreshCrc32(gpt); 343
200 EXPECT(GPT_SUCCESS == GptInit(gpt)); 344 /* expect primary is still valid. */
201 gpt->secondary_header[i] ^= 0xff; 345 BuildTestGptData(gpt);
202 RefreshCrc32(gpt); 346 secondary_header->padding ^= 0x12345678; /* whatever random */
203 } 347 EXPECT(MASK_PRIMARY == CheckReservedFields(gpt));
204 348
205 /* change every char in signature of primary and secondary. Expect fail. */ 349 return TEST_OK;
206 for (i = 0; i < 8; ++i) {
207 gpt->primary_header[i] ^= 0xff;
208 gpt->secondary_header[i] ^= 0xff;
209 RefreshCrc32(gpt);
210 EXPECT(GPT_ERROR_INVALID_HEADERS == GptInit(gpt));
211 gpt->primary_header[i] ^= 0xff;
212 gpt->secondary_header[i] ^= 0xff;
213 RefreshCrc32(gpt);
214 }
215
216 return TEST_OK;
217 }
218
219 /* Tests if header CRC in two copies are calculated. */
220 int HeaderCrcTest() {
221 return TEST_FAIL;
222 } 350 }
223 351
224 /* Tests if myLBA field is checked (1 for primary, last for secondary). */ 352 /* Tests if myLBA field is checked (1 for primary, last for secondary). */
225 int MyLbaTest() { 353 int MyLbaTest() {
226 return TEST_FAIL; 354 GptData *gpt;
355 int test_mask;
356 GptHeader *headers[2];
357 uint32_t valid_headers;
358
359 gpt = GetEmptyGptData();
360 headers[PRIMARY] = (GptHeader*)gpt->primary_header;
361 headers[SECONDARY] = (GptHeader*)gpt->secondary_header;
362
363 for (test_mask = MASK_PRIMARY; test_mask <= MASK_BOTH; ++test_mask) {
364 BuildTestGptData(gpt);
365 if (test_mask & MASK_PRIMARY)
366 ++headers[PRIMARY]->my_lba;
367 if (test_mask & MASK_SECONDARY)
368 --headers[SECONDARY]->my_lba;
369 valid_headers = CheckMyLba(gpt);
370 EXPECT((MASK_BOTH ^ test_mask) == valid_headers);
371 }
372 return TEST_OK;
227 } 373 }
228 374
229 /* Tests if SizeOfPartitionEntry is checked. SizeOfPartitionEntry must be 375 /* Tests if SizeOfPartitionEntry is checked. SizeOfPartitionEntry must be
230 * between 128 and 512, and a multiple of 8. */ 376 * between 128 and 512, and a multiple of 8. */
231 int SizeOfPartitionEntryTest() { 377 int SizeOfPartitionEntryTest() {
232 return TEST_FAIL; 378 GptData *gpt;
379 struct {
380 uint32_t value_to_test;
381 int is_valid_value;
382 } cases[] = {
383 {127, 0},
384 {128, 1},
385 {129, 0},
386 {130, 0},
387 {131, 0},
388 {132, 0},
389 {133, 0},
390 {134, 0},
391 {135, 0},
392 {136, 1},
393 {144, 1},
394 {160, 1},
395 {192, 1},
396 {256, 1},
397 {384, 1},
398 {504, 1},
399 {512, 1},
400 {513, 0},
401 {520, 0},
402 };
403 int i;
404 int test_mask;
405 GptHeader *headers[2];
406 uint32_t valid_headers;
407
408 gpt = GetEmptyGptData();
409 headers[PRIMARY] = (GptHeader*)gpt->primary_header;
410 headers[SECONDARY] = (GptHeader*)gpt->secondary_header;
411
412 for (i = 0; i < ARRAY_SIZE(cases); ++i) {
413 for (test_mask = MASK_PRIMARY; test_mask <= MASK_BOTH; ++test_mask) {
414 BuildTestGptData(gpt);
415 if (test_mask & MASK_PRIMARY) {
416 headers[PRIMARY]->size_of_entry = cases[i].value_to_test;
417 headers[PRIMARY]->number_of_entries =
418 TOTAL_ENTRIES_SIZE / cases[i].value_to_test;
419 }
420 if (test_mask & MASK_SECONDARY) {
421 headers[SECONDARY]->size_of_entry = cases[i].value_to_test;
422 headers[SECONDARY]->number_of_entries =
423 TOTAL_ENTRIES_SIZE / cases[i].value_to_test;
424 }
425 valid_headers = CheckSizeOfPartitionEntry(gpt);
426 if (cases[i].is_valid_value)
427 EXPECT(MASK_BOTH == valid_headers);
428 else
429 EXPECT((MASK_BOTH ^ test_mask) == valid_headers);
430 }
431 }
432 return TEST_OK;
233 } 433 }
234 434
235 /* Tests if NumberOfPartitionEntries is checes. NumberOfPartitionEntries must 435 /* Tests if NumberOfPartitionEntries is checes. NumberOfPartitionEntries must
236 * be between 32 and 512, and SizeOfPartitionEntry * NumberOfPartitionEntries 436 * be between 32 and 512, and SizeOfPartitionEntry * NumberOfPartitionEntries
237 * must be 16384. */ 437 * must be 16384. */
238 int NumberOfPartitionEntriesTest() { 438 int NumberOfPartitionEntriesTest() {
239 return TEST_FAIL; 439 GptData *gpt;
440 struct {
441 uint32_t size_of_entry;
442 uint32_t number_of_entries;
443 int is_valid_value;
444 } cases[] = {
445 {111, 147, 0},
446 {111, 149, 0},
447 {128, 32, 0},
448 {128, 64, 0},
449 {128, 127, 0},
450 {128, 128, 1},
451 {128, 129, 0},
452 {128, 256, 0},
453 {256, 32, 0},
454 {256, 64, 1},
455 {256, 128, 0},
456 {256, 256, 0},
457 {512, 32, 1},
458 {512, 64, 0},
459 {512, 128, 0},
460 {512, 256, 0},
461 {1024, 128, 0},
462 };
463 int i;
464 int test_mask;
465 GptHeader *headers[2];
466 uint32_t valid_headers;
467
468 gpt = GetEmptyGptData();
469 headers[PRIMARY] = (GptHeader*)gpt->primary_header;
470 headers[SECONDARY] = (GptHeader*)gpt->secondary_header;
471
472 for (i = 0; i < ARRAY_SIZE(cases); ++i) {
473 for (test_mask = MASK_PRIMARY; test_mask <= MASK_BOTH; ++test_mask) {
474 BuildTestGptData(gpt);
475 if (test_mask & MASK_PRIMARY) {
476 headers[PRIMARY]->size_of_entry = cases[i].size_of_entry;
477 headers[PRIMARY]->number_of_entries = cases[i].number_of_entries;
478 }
479 if (test_mask & MASK_SECONDARY) {
480 headers[SECONDARY]->size_of_entry = cases[i].size_of_entry;
481 headers[SECONDARY]->number_of_entries = cases[i].number_of_entries;
482 }
483 valid_headers = CheckNumberOfEntries(gpt);
484 if (cases[i].is_valid_value)
485 EXPECT(MASK_BOTH == valid_headers);
486 else
487 EXPECT((MASK_BOTH ^ test_mask) == valid_headers);
488 }
489 }
490 return TEST_OK;
240 } 491 }
241 492
242 /* Tests if PartitionEntryLBA in primary/secondary headers is checked. */ 493 /* Tests if PartitionEntryLBA in primary/secondary headers is checked. */
243 int PartitionEntryLbaTest() { 494 int PartitionEntryLbaTest() {
244 return TEST_FAIL; 495 GptData *gpt;
496 int test_mask;
497 GptHeader *headers[2];
498 uint32_t valid_headers;
499
500 gpt = GetEmptyGptData();
501 headers[PRIMARY] = (GptHeader*)gpt->primary_header;
502 headers[SECONDARY] = (GptHeader*)gpt->secondary_header;
503
504 for (test_mask = MASK_PRIMARY; test_mask <= MASK_BOTH; ++test_mask) {
505 BuildTestGptData(gpt);
506 if (test_mask & MASK_PRIMARY)
507 headers[PRIMARY]->entries_lba = 0;
508 if (test_mask & MASK_SECONDARY)
509 headers[SECONDARY]->entries_lba = DEFAULT_DRIVE_SECTORS - 31 - 1;
510 valid_headers = CheckEntriesLba(gpt);
511 EXPECT((MASK_BOTH ^ test_mask) == valid_headers);
512 }
513 return TEST_OK;
245 } 514 }
246 515
247 /* Tests if FirstUsableLBA and LastUsableLBA are checked. 516 /* Tests if FirstUsableLBA and LastUsableLBA are checked.
248 * FirstUsableLBA must be after the end of the primary GPT table array. 517 * FirstUsableLBA must be after the end of the primary GPT table array.
249 * LastUsableLBA must be before the start of the secondary GPT table array. 518 * LastUsableLBA must be before the start of the secondary GPT table array.
250 * FirstUsableLBA <= LastUsableLBA. */ 519 * FirstUsableLBA <= LastUsableLBA. */
251 int FirstUsableLbaAndLastUsableLbaTest() { 520 int FirstUsableLbaAndLastUsableLbaTest() {
252 return TEST_FAIL; 521 GptData *gpt;
522 GptHeader *primary_header, *secondary_header;
523 uint32_t valid_headers;
524 int i;
525 struct {
526 uint64_t primary_entries_lba;
527 uint64_t primary_first_usable_lba;
528 uint64_t primary_last_usable_lba;
529 uint64_t secondary_first_usable_lba;
530 uint64_t secondary_last_usable_lba;
531 uint64_t secondary_entries_lba;
532 int expected_masks;
533 } cases[] = {
534 {2, 34, 433, 34, 433, 434, MASK_BOTH},
535 {2, 34, 432, 34, 430, 434, MASK_BOTH},
536 {2, 33, 433, 33, 433, 434, MASK_NONE},
537 {3, 34, 433, 35, 433, 434, MASK_SECONDARY},
538 {3, 35, 433, 33, 433, 434, MASK_PRIMARY},
539 {2, 34, 434, 34, 433, 434, MASK_SECONDARY},
540 {2, 34, 433, 34, 434, 434, MASK_PRIMARY},
541 {2, 35, 433, 35, 433, 434, MASK_BOTH},
542 {2, 433, 433, 433, 433, 434, MASK_BOTH},
543 {2, 434, 433, 434, 434, 434, MASK_NONE},
544 {2, 433, 34, 34, 433, 434, MASK_SECONDARY},
545 {2, 34, 433, 433, 34, 434, MASK_PRIMARY},
546 };
547
548 gpt = GetEmptyGptData();
549 primary_header = (GptHeader*)gpt->primary_header;
550 secondary_header = (GptHeader*)gpt->secondary_header;
551
552 for (i = 0; i < ARRAY_SIZE(cases); ++i) {
553 BuildTestGptData(gpt);
554 primary_header->entries_lba = cases[i].primary_entries_lba;
555 primary_header->first_usable_lba = cases[i].primary_first_usable_lba;
556 primary_header->last_usable_lba = cases[i].primary_last_usable_lba;
557 secondary_header->entries_lba = cases[i].secondary_entries_lba;
558 secondary_header->first_usable_lba = cases[i].secondary_first_usable_lba;
559 secondary_header->last_usable_lba = cases[i].secondary_last_usable_lba;
560 valid_headers = CheckValidUsableLbas(gpt);
561 EXPECT(cases[i].expected_masks == valid_headers);
562 }
563
564 return TEST_OK;
253 } 565 }
254 566
255 /* Tests if GptInit() handles non-identical partition entries well. 567 /* Tests if header CRC in two copies are calculated. */
256 * Two copies of partition table entries must be identical. If not, we trust the 568 int HeaderCrcTest() {
257 * primary table entries, and mark secondary as modified (see Caller's write- 569 GptData *gpt;
258 * back order below). */ 570 GptHeader *primary_header, *secondary_header;
259 int IdenticalEntriesTest() {
260 return TEST_FAIL;
261 }
262 571
263 /* Tests if GptInit() handles non-identical headers well. 572 gpt = GetEmptyGptData();
264 * Two partition headers must be identical. If not, we trust the primary 573 primary_header = (GptHeader*)gpt->primary_header;
265 * partition header, and mark secondary as modified (see Caller's write-back 574 secondary_header = (GptHeader*)gpt->secondary_header;
266 * order below). */ 575
267 int IdenticalHeaderTest() { 576 /* Modify the first byte of primary header, and expect the CRC is wrong. */
268 return TEST_FAIL; 577 BuildTestGptData(gpt);
578 gpt->primary_header[0] ^= 0xa5; /* just XOR a non-zero value */
579 EXPECT(MASK_SECONDARY == CheckHeaderCrc(gpt));
580
581 /* Modify the last byte of secondary header, and expect the CRC is wrong. */
582 BuildTestGptData(gpt);
583 gpt->secondary_header[secondary_header->size-1] ^= 0x5a;
584 EXPECT(MASK_PRIMARY == CheckHeaderCrc(gpt));
585
586 /* Modify out of CRC range, expect CRC is still right. */
587 BuildTestGptData(gpt);
588 gpt->primary_header[primary_header->size] ^= 0x87;
589 EXPECT(MASK_BOTH == CheckHeaderCrc(gpt));
590
591 return TEST_OK;
269 } 592 }
270 593
271 /* Tests if PartitionEntryArrayCRC32 is checked. 594 /* Tests if PartitionEntryArrayCRC32 is checked.
272 * PartitionEntryArrayCRC32 must be calculated over SizeOfPartitionEntry * 595 * PartitionEntryArrayCRC32 must be calculated over SizeOfPartitionEntry *
273 * NumberOfPartitionEntries bytes. 596 * NumberOfPartitionEntries bytes.
274 */ 597 */
275 int EntriesCrcTest() { 598 int EntriesCrcTest() {
276 return TEST_FAIL; 599 GptData *gpt;
600
601 gpt = GetEmptyGptData();
602
603 /* Modify the first byte of primary entries, and expect the CRC is wrong. */
604 BuildTestGptData(gpt);
605 gpt->primary_entries[0] ^= 0xa5; /* just XOR a non-zero value */
606 EXPECT(MASK_SECONDARY == CheckEntriesCrc(gpt));
607
608 /* Modify the last byte of secondary entries, and expect the CRC is wrong. */
609 BuildTestGptData(gpt);
610 gpt->secondary_entries[TOTAL_ENTRIES_SIZE-1] ^= 0x5a;
611 EXPECT(MASK_PRIMARY == CheckEntriesCrc(gpt));
612
613 return TEST_OK;
614 }
615
616 /* Tests if GptInit() handles non-identical partition entries well.
617 * Two copies of partition table entries must be identical. If not, we trust the
618 * primary table entries, and mark secondary as modified. */
619 int IdenticalEntriesTest() {
620 GptData *gpt;
621
622 gpt = GetEmptyGptData();
623
624 /* Tests RepairEntries() first. */
625 BuildTestGptData(gpt);
626 EXPECT(0 == RepairEntries(gpt, MASK_BOTH));
627 gpt->secondary_entries[0] ^= 0xa5; /* XOR any number */
628 EXPECT(GPT_MODIFIED_ENTRIES2 == RepairEntries(gpt, MASK_BOTH));
629 EXPECT(GPT_MODIFIED_ENTRIES2 == RepairEntries(gpt, MASK_PRIMARY));
630 EXPECT(GPT_MODIFIED_ENTRIES1 == RepairEntries(gpt, MASK_SECONDARY));
631 EXPECT(0 == RepairEntries(gpt, MASK_NONE));
632
633 /* The first byte is different. We expect secondary entries is marked as
634 * modified. */
635 BuildTestGptData(gpt);
636 gpt->primary_entries[0] ^= 0xff;
637 RefreshCrc32(gpt);
638 EXPECT(GPT_SUCCESS == GptInit(gpt));
639 EXPECT(GPT_MODIFIED_ENTRIES2 == gpt->modified);
640 EXPECT(0 == Memcmp(gpt->primary_entries, gpt->secondary_entries,
641 TOTAL_ENTRIES_SIZE));
642
643 /* The last byte is different, but the primary entries CRC is bad.
644 * We expect primary entries is marked as modified. */
645 BuildTestGptData(gpt);
646 gpt->primary_entries[TOTAL_ENTRIES_SIZE-1] ^= 0xff;
647 EXPECT(GPT_SUCCESS == GptInit(gpt));
648 EXPECT(GPT_MODIFIED_ENTRIES1 == gpt->modified);
649 EXPECT(0 == Memcmp(gpt->primary_entries, gpt->secondary_entries,
650 TOTAL_ENTRIES_SIZE));
651
652 return TEST_OK;
653 }
654
655 /* Tests if GptInit() handles synonymous headers well.
656 * Note that two partition headers are NOT bit-swise identical.
657 * For exmaple, my_lba must be different (pointing to respective self).
658 * So in normal case, they are synonymous, not identical.
659 * If not synonymous, we trust the primary partition header, and
660 * overwrite secondary, then mark secondary as modified.*/
661 int SynonymousHeaderTest() {
662 GptData *gpt;
663 GptHeader *primary_header, *secondary_header;
664
665 gpt = GetEmptyGptData();
666 primary_header = (GptHeader*)gpt->primary_header;
667 secondary_header = (GptHeader*)gpt->secondary_header;
668
669 /* Tests RepairHeader() for synonymous cases first. */
670 BuildTestGptData(gpt);
671 EXPECT(0 == RepairHeader(gpt, MASK_BOTH));
672 EXPECT(GPT_MODIFIED_HEADER2 == RepairHeader(gpt, MASK_PRIMARY));
673 EXPECT(GPT_MODIFIED_HEADER1 == RepairHeader(gpt, MASK_SECONDARY));
674 EXPECT(0 == RepairHeader(gpt, MASK_NONE));
675 /* Then tests non-synonymous cases. */
676 BuildTestGptData(gpt);
677 ++secondary_header->first_usable_lba; /* chnage any bit */
678 EXPECT(GPT_MODIFIED_HEADER2 == RepairHeader(gpt, MASK_BOTH));
679 EXPECT(primary_header->first_usable_lba ==
680 secondary_header->first_usable_lba);
681 /* ---- */
682 BuildTestGptData(gpt);
683 --secondary_header->last_usable_lba;
684 EXPECT(GPT_MODIFIED_HEADER2 == RepairHeader(gpt, MASK_BOTH));
685 EXPECT(primary_header->last_usable_lba == secondary_header->last_usable_lba);
686 /* ---- */
687 BuildTestGptData(gpt);
688 ++secondary_header->number_of_entries;
689 EXPECT(GPT_MODIFIED_HEADER2 == RepairHeader(gpt, MASK_BOTH));
690 EXPECT(primary_header->number_of_entries ==
691 secondary_header->number_of_entries);
692 /* ---- */
693 BuildTestGptData(gpt);
694 --secondary_header->size_of_entry;
695 EXPECT(GPT_MODIFIED_HEADER2 == RepairHeader(gpt, MASK_BOTH));
696 EXPECT(primary_header->size_of_entry ==
697 secondary_header->size_of_entry);
698 /* ---- */
699 BuildTestGptData(gpt);
700 secondary_header->disk_uuid.u.raw[0] ^= 0x56;
701 EXPECT(GPT_MODIFIED_HEADER2 == RepairHeader(gpt, MASK_BOTH));
702 EXPECT(0 == Memcmp(&primary_header->disk_uuid,
703 &secondary_header->disk_uuid, sizeof(Guid)));
704
705 /* Consider header repairing in GptInit(). */
706 BuildTestGptData(gpt);
707 ++secondary_header->first_usable_lba;
708 RefreshCrc32(gpt);
709 EXPECT(GPT_SUCCESS == GptInit(gpt));
710 EXPECT(GPT_MODIFIED_HEADER2 == gpt->modified);
711 EXPECT(primary_header->first_usable_lba ==
712 secondary_header->first_usable_lba);
713
714 return TEST_OK;
277 } 715 }
278 716
279 /* Tests if partition geometry is checked. 717 /* Tests if partition geometry is checked.
280 * All active (non-zero PartitionTypeGUID) partition entries should have: 718 * All active (non-zero PartitionTypeGUID) partition entries should have:
281 * entry.StartingLBA >= header.FirstUsableLBA 719 * entry.StartingLBA >= header.FirstUsableLBA
282 * entry.EndingLBA <= header.LastUsableLBA 720 * entry.EndingLBA <= header.LastUsableLBA
283 * entry.StartingLBA <= entry.EndingLBA 721 * entry.StartingLBA <= entry.EndingLBA
284 */ 722 */
285 int ValidEntryTest() { 723 int ValidEntryTest() {
286 return TEST_FAIL; 724 GptData *gpt;
725 GptHeader *primary_header, *secondary_header;
726 GptEntry *primary_entries, *secondary_entries;
727
728 gpt = GetEmptyGptData();
729 primary_header = (GptHeader*)gpt->primary_header;
730 secondary_header = (GptHeader*)gpt->secondary_header;
731 primary_entries = (GptEntry*)gpt->primary_entries;
732 secondary_entries = (GptEntry*)gpt->secondary_entries;
733
734 /* error case: entry.StartingLBA < header.FirstUsableLBA */
735 BuildTestGptData(gpt);
736 primary_entries[0].starting_lba = primary_header->first_usable_lba - 1;
737 EXPECT(MASK_SECONDARY == CheckValidEntries(gpt));
738 secondary_entries[1].starting_lba = secondary_header->first_usable_lba - 1;
739 EXPECT(MASK_NONE == CheckValidEntries(gpt));
740
741 /* error case: entry.EndingLBA > header.LastUsableLBA */
742 BuildTestGptData(gpt);
743 primary_entries[2].ending_lba = primary_header->last_usable_lba + 1;
744 EXPECT(MASK_SECONDARY == CheckValidEntries(gpt));
745 secondary_entries[3].ending_lba = secondary_header->last_usable_lba + 1;
746 EXPECT(MASK_NONE == CheckValidEntries(gpt));
747
748 /* error case: entry.StartingLBA > entry.EndingLBA */
749 BuildTestGptData(gpt);
750 primary_entries[3].starting_lba = primary_entries[3].ending_lba + 1;
751 EXPECT(MASK_SECONDARY == CheckValidEntries(gpt));
752 secondary_entries[1].starting_lba = secondary_entries[1].ending_lba + 1;
753 EXPECT(MASK_NONE == CheckValidEntries(gpt));
754
755 /* case: non active entry should be ignored. */
756 BuildTestGptData(gpt);
757 Memset(&primary_entries[1].type, 0, sizeof(primary_entries[1].type));
758 primary_entries[1].starting_lba = primary_entries[1].ending_lba + 1;
759 EXPECT(MASK_BOTH == CheckValidEntries(gpt));
760 Memset(&secondary_entries[2].type, 0, sizeof(secondary_entries[2].type));
761 secondary_entries[2].starting_lba = secondary_entries[2].ending_lba + 1;
762 EXPECT(MASK_BOTH == CheckValidEntries(gpt));
763
764 return TEST_OK;
287 } 765 }
288 766
289 /* Tests if overlapped partition tables can be detected. */ 767 /* Tests if overlapped partition tables can be detected. */
290 int NoOverlappedPartitionTest() { 768 int OverlappedPartitionTest() {
291 return TEST_FAIL; 769 GptData *gpt;
292 } 770 struct {
293 771 int overlapped;
294 /* Tests if GptNextKernelEntry() can survive in different corrupt header/entries 772 struct {
773 int active;
774 uint64_t starting_lba;
775 uint64_t ending_lba;
776 } entries[16]; /* enough for testing. */
777 } cases[] = {
778 {0, {{0, 100, 199}, {0, 0, 0}}},
779 {0, {{1, 100, 199}, {0, 0, 0}}},
780 {0, {{1, 100, 150}, {1, 200, 250}, {1, 300, 350}, {0, 0, 0}}},
781 {1, {{1, 200, 299}, {1, 100, 199}, {1, 100, 100}, {0, 0, 0}}},
782 {1, {{1, 200, 299}, {1, 100, 199}, {1, 299, 299}, {0, 0, 0}}},
783 {0, {{1, 300, 399}, {1, 200, 299}, {1, 100, 199}, {0, 0, 0}}},
784 {1, {{1, 100, 199}, {1, 199, 299}, {1, 299, 399}, {0, 0, 0}}},
785 {1, {{1, 100, 199}, {1, 200, 299}, {1, 75, 399}, {0, 0, 0}}},
786 {1, {{1, 100, 199}, {1, 75, 250}, {1, 200, 299}, {0, 0, 0}}},
787 {1, {{1, 75, 150}, {1, 100, 199}, {1, 200, 299}, {0, 0, 0}}},
788 {1, {{1, 200, 299}, {1, 100, 199}, {1, 300, 399}, {1, 100, 399},
789 {0, 0, 0}}},
790 {0, {{1, 200, 299}, {1, 100, 199}, {1, 300, 399}, {0, 100, 399},
791 {0, 0, 0}}},
792 {1, {{1, 200, 300}, {1, 100, 200}, {1, 100, 400}, {1, 300, 400},
793 {0, 0, 0}}},
794 {1, {{0, 200, 300}, {1, 100, 200}, {1, 100, 400}, {1, 300, 400},
795 {0, 0, 0}}},
796 {0, {{1, 200, 300}, {1, 100, 199}, {0, 100, 400}, {0, 300, 400},
797 {0, 0, 0}}},
798 {1, {{1, 200, 299}, {1, 100, 199}, {1, 199, 199}, {0, 0, 0}}},
799 {0, {{1, 200, 299}, {0, 100, 199}, {1, 199, 199}, {0, 0, 0}}},
800 {0, {{1, 200, 299}, {1, 100, 199}, {0, 199, 199}, {0, 0, 0}}},
801 {1, {{1, 199, 199}, {1, 200, 200}, {1, 201, 201}, {1, 202, 202},
802 {1, 203, 203}, {1, 204, 204}, {1, 205, 205}, {1, 206, 206},
803 {1, 207, 207}, {1, 208, 208}, {1, 199, 199}, {0, 0, 0}}},
804 {0, {{1, 199, 199}, {1, 200, 200}, {1, 201, 201}, {1, 202, 202},
805 {1, 203, 203}, {1, 204, 204}, {1, 205, 205}, {1, 206, 206},
806 {1, 207, 207}, {1, 208, 208}, {0, 199, 199}, {0, 0, 0}}},
807 };
808 Guid any_type = GPT_ENT_TYPE_CHROMEOS_KERNEL;
809 int i, j;
810 int test_mask;
811 GptEntry *entries[2];
812
813 gpt = GetEmptyGptData();
814 entries[PRIMARY] = (GptEntry*)gpt->primary_entries;
815 entries[SECONDARY] = (GptEntry*)gpt->secondary_entries;
816
817 for (i = 0; i < ARRAY_SIZE(cases); ++i) {
818 for (test_mask = MASK_PRIMARY; test_mask <= MASK_BOTH; ++test_mask) {
819 BuildTestGptData(gpt);
820 ZeroEntries(gpt);
821 for(j = 0; j < ARRAY_SIZE(cases[0].entries); ++j) {
822 if (!cases[i].entries[j].starting_lba) break;
823 if (test_mask & MASK_PRIMARY) {
824 if (cases[i].entries[j].active)
825 Memcpy(&entries[PRIMARY][j].type, &any_type, sizeof(any_type));
826 entries[PRIMARY][j].starting_lba = cases[i].entries[j].starting_lba;
827 entries[PRIMARY][j].ending_lba = cases[i].entries[j].ending_lba;
828 }
829 if (test_mask & MASK_SECONDARY) {
830 if (cases[i].entries[j].active)
831 Memcpy(&entries[SECONDARY][j].type, &any_type, sizeof(any_type));
832 entries[SECONDARY][j].starting_lba = cases[i].entries[j].starting_lba;
833 entries[SECONDARY][j].ending_lba = cases[i].entries[j].ending_lba;
834 }
835 }
836 EXPECT((cases[i].overlapped * test_mask) ==
837 (OverlappedEntries(entries[PRIMARY], j) |
838 (OverlappedEntries(entries[SECONDARY], j) << SECONDARY))
839 );
840
841 EXPECT((MASK_BOTH ^ (cases[i].overlapped * test_mask)) ==
842 CheckOverlappedPartition(gpt));
843 }
844 }
845 return TEST_OK;
846 }
847
848 /* Tests if GptInit() can survive in different corrupt header/entries
295 * combinations, like: 849 * combinations, like:
296 * primary GPT header - valid 850 * primary GPT header - valid
297 * primary partition table - invalid 851 * primary partition table - invalid
852 * secondary GPT header - invalid
298 * secondary partition table - valid 853 * secondary partition table - valid
299 * secondary GPT header - invalid
300 */ 854 */
301 int CorruptCombinationTest() { 855 int CorruptCombinationTest() {
302 return TEST_FAIL; 856 GptData *gpt;
857 GptHeader *primary_header, *secondary_header;
858 GptEntry *primary_entries, *secondary_entries;
859
860 gpt = GetEmptyGptData();
861 primary_header = (GptHeader*)gpt->primary_header;
862 secondary_header = (GptHeader*)gpt->secondary_header;
863 primary_entries = (GptEntry*)gpt->primary_entries;
864 secondary_entries = (GptEntry*)gpt->secondary_entries;
865
866 /* Make primary entries and secondary header invalid, we expect GptInit()
867 * can recover them (returns GPT_SUCCESS and MODIFIED flasgs). */
868 BuildTestGptData(gpt);
869 primary_entries[0].type.u.raw[0] ^= 0x33;
870 secondary_header->header_crc32 ^= 0x55;
871 EXPECT(GPT_SUCCESS == GptInit(gpt));
872 EXPECT((GPT_MODIFIED_HEADER2 | GPT_MODIFIED_ENTRIES1) == gpt->modified);
873 EXPECT(0 == Memcmp(primary_entries, secondary_entries, TOTAL_ENTRIES_SIZE));
874 /* We expect the modified header/entries can pass GptInit(). */
875 EXPECT(GPT_SUCCESS == GptInit(gpt));
876 EXPECT(0 == gpt->modified);
877
878 /* Make primary header invalid (the entries is not damaged actually). */
879 BuildTestGptData(gpt);
880 primary_header->entries_crc32 ^= 0x73;
881 EXPECT(GPT_SUCCESS == GptInit(gpt));
882 /* After header is repaired, the entries are valid actually. */
883 EXPECT((GPT_MODIFIED_HEADER1) == gpt->modified);
884 /* We expect the modified header/entries can pass GptInit(). */
885 EXPECT(GPT_SUCCESS == GptInit(gpt));
886 EXPECT(0 == gpt->modified);
887
888 return TEST_OK;
303 } 889 }
304 890
305 int main(int argc, char *argv[]) { 891 int main(int argc, char *argv[]) {
306 int i; 892 int i;
893 int error_count = 0;
307 struct { 894 struct {
308 char *name; 895 char *name;
309 test_func fp; 896 test_func fp;
310 int retval; 897 int retval;
311 } test_cases[] = { 898 } test_cases[] = {
899 { TEST_CASE(TestBuildTestGptData), },
900 { TEST_CASE(ParameterTests), },
312 { TEST_CASE(SignatureTest), }, 901 { TEST_CASE(SignatureTest), },
313 #if 0 902 { TEST_CASE(RevisionTest), },
314 { TEST_CASE(HeaderCrcTest), }, 903 { TEST_CASE(SizeTest), },
904 { TEST_CASE(ReservedFieldsTest), },
315 { TEST_CASE(MyLbaTest), }, 905 { TEST_CASE(MyLbaTest), },
316 { TEST_CASE(SizeOfPartitionEntryTest), }, 906 { TEST_CASE(SizeOfPartitionEntryTest), },
317 { TEST_CASE(NumberOfPartitionEntriesTest), }, 907 { TEST_CASE(NumberOfPartitionEntriesTest), },
318 { TEST_CASE(PartitionEntryLbaTest), }, 908 { TEST_CASE(PartitionEntryLbaTest), },
319 { TEST_CASE(FirstUsableLbaAndLastUsableLbaTest), }, 909 { TEST_CASE(FirstUsableLbaAndLastUsableLbaTest), },
910 { TEST_CASE(HeaderCrcTest), },
911 { TEST_CASE(EntriesCrcTest), },
320 { TEST_CASE(IdenticalEntriesTest), }, 912 { TEST_CASE(IdenticalEntriesTest), },
321 { TEST_CASE(IdenticalHeaderTest), }, 913 { TEST_CASE(SynonymousHeaderTest), },
322 { TEST_CASE(EntriesCrcTest), },
323 { TEST_CASE(ValidEntryTest), }, 914 { TEST_CASE(ValidEntryTest), },
324 { TEST_CASE(NoOverlappedPartitionTest), }, 915 { TEST_CASE(OverlappedPartitionTest), },
325 { TEST_CASE(CorruptCombinationTest), }, 916 { TEST_CASE(CorruptCombinationTest), },
326 #endif 917 { TEST_CASE(TestQuickSortFixed), },
918 { TEST_CASE(TestQuickSortRandom), },
327 }; 919 };
328 920
329 for (i = 0; i < sizeof(test_cases)/sizeof(test_cases[0]); ++i) { 921 for (i = 0; i < sizeof(test_cases)/sizeof(test_cases[0]); ++i) {
330 printf("Running %s() ...\n", test_cases[i].name); 922 printf("Running %s() ...\n", test_cases[i].name);
331 test_cases[i].retval = test_cases[i].fp(); 923 test_cases[i].retval = test_cases[i].fp();
332 if (test_cases[i].retval) 924 if (test_cases[i].retval) {
333 printf(COL_RED "[ERROR]" COL_STOP " %s()\n\n", test_cases[i].name); 925 printf(COL_RED "[ERROR]\n\n" COL_STOP);
334 else 926 ++error_count;
335 printf(COL_GREEN "[PASS]" COL_STOP " %s()\n\n", test_cases[i].name); 927 } else {
928 printf(COL_GREEN "[PASS]\n\n" COL_STOP);
929 }
336 } 930 }
337 931
338 printf("\n--------------------------------------------------\n"); 932 if (error_count) {
339 printf("The following test cases are failed:\n"); 933 printf("\n--------------------------------------------------\n");
340 for (i = 0; i < sizeof(test_cases)/sizeof(test_cases[0]); ++i) { 934 printf(COL_RED "The following %d test cases are failed:\n" COL_STOP,
341 if (test_cases[i].retval) 935 error_count);
342 printf(" %s()\n", test_cases[i].name); 936 for (i = 0; i < sizeof(test_cases)/sizeof(test_cases[0]); ++i) {
937 if (test_cases[i].retval)
938 printf(" %s()\n", test_cases[i].name);
939 }
343 } 940 }
344 941
345 return 0; 942 return (error_count) ? 1 : 0;
346 } 943 }
OLDNEW
« no previous file with comments | « src/platform/vboot_reference/cgptlib/tests/cgpt_test.h ('k') | src/platform/vboot_reference/cgptlib/tests/quick_sort_test.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698