1 // Copyright 2018 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that be be
3 // found in the LICENSE file.
4 
5 #include <fcntl.h>
6 #include <lib/cksum.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <sys/param.h>
11 #include <unistd.h>
12 
13 #include <fbl/unique_fd.h>
14 #include <lib/fdio/util.h>
15 #include <lib/zx/vmo.h>
16 #include <zircon/device/block.h>
17 #include <zircon/syscalls.h>
18 
19 #include <chromeos-disk-setup/chromeos-disk-setup.h>
20 #include <gpt/cros.h>
21 #include <gpt/gpt.h>
22 #include <lib/zxio/null.h>
23 #include <lib/zxio/ops.h>
24 
25 #include <unittest/unittest.h>
26 
27 #define TOTAL_BLOCKS 244277248 // roughly 116GB
28 #define BLOCK_SIZE 512
29 #define SZ_FW_PART (8 * ((uint64_t)1) << 20)
30 #define SZ_EFI_PART (32 * ((uint64_t)1) << 20)
31 #define SZ_KERN_PART (16 * ((uint64_t)1) << 20)
32 #define SZ_FVM_PART (8 * ((uint64_t)1) << 30)
33 #define SZ_SYSCFG_PART (1<<20)
34 
35 namespace {
36 
37 const uint8_t kStateGUID[GPT_GUID_LEN] = GUID_CROS_STATE_VALUE;
38 const uint8_t kCrosKernGUID[GPT_GUID_LEN] = GUID_CROS_KERNEL_VALUE;
39 const uint8_t kCrosRootGUID[GPT_GUID_LEN] = GUID_CROS_ROOT_VALUE;
40 const uint8_t kGenDataGUID[GPT_GUID_LEN] = GUID_GEN_DATA_VALUE;
41 const uint8_t kFwGUID[GPT_GUID_LEN] = GUID_CROS_FIRMWARE_VALUE;
42 const uint8_t kEfiGUID[GPT_GUID_LEN] = GUID_EFI_VALUE;
43 const uint8_t kFvmGUID[GPT_GUID_LEN] = GUID_FVM_VALUE;
44 const uint64_t kCPartsInitSize = 1;
45 
46 const block_info_t kDefaultBlockInfo = {
47     .block_count = TOTAL_BLOCKS,
48     .block_size = BLOCK_SIZE,
49     .max_transfer_size = BLOCK_MAX_TRANSFER_UNBOUNDED,
50     .flags = 0,
51     .reserved = 0,
52 };
53 
mock_read(zxio_t * io,void * buffer,size_t capacity,size_t * out_actual)54 static zx_status_t mock_read(zxio_t* io, void* buffer, size_t capacity, size_t* out_actual) {
55     memset(buffer, 0, capacity);
56     *out_actual = capacity;
57     return ZX_OK;
58 }
59 
mock_write(zxio_t * io,const void * buffer,size_t capacity,size_t * out_actual)60 static zx_status_t mock_write(zxio_t* io, const void* buffer, size_t capacity, size_t* out_actual) {
61     *out_actual = capacity;
62     return ZX_OK;
63 }
64 
mock_seek(zxio_t * io,size_t offset,zxio_seek_origin_t start,size_t * out_offset)65 static zx_status_t mock_seek(zxio_t* io, size_t offset, zxio_seek_origin_t start, size_t* out_offset) {
66     if (start != fuchsia_io_SeekOrigin_START) {
67         return ZX_ERR_NOT_SUPPORTED;
68     }
69     *out_offset = offset;
70     return ZX_OK;
71 }
72 
__anon5791c0ef0202() 73 constexpr zxio_ops_t mock_ops = []() {
74     zxio_ops_t ops = zxio_default_ops;
75     ops.read = &mock_read;
76     ops.write = &mock_write;
77     ops.seek = &mock_seek;
78     return ops;
79 }();
80 
81 class TestState {
82 public:
83     DISALLOW_COPY_ASSIGN_AND_MOVE(TestState);
84 
TestState(block_info_t info=kDefaultBlockInfo)85     TestState(block_info_t info = kDefaultBlockInfo) : device_(nullptr) {
86         Initialize(info);
87     }
88 
Initialize(block_info_t info)89     void Initialize(block_info_t info) {
90         ReleaseGpt();
91         blk_sz_root_ = howmany(SZ_ROOT_PART, info.block_size);
92         blk_sz_kern_ = howmany(SZ_KERN_PART, info.block_size);
93         blk_sz_fw_ = howmany(SZ_FW_PART, info.block_size);
94         blk_sz_efi_ = howmany(SZ_EFI_PART, info.block_size);
95         blk_sz_fvm_ = howmany(SZ_FVM_PART, info.block_size);
96         blk_sz_kernc_ = howmany(SZ_ZX_PART, info.block_size);
97         blk_sz_rootc_ = howmany(SZ_ROOT_PART, info.block_size);
98         block_info_ = info;
99         device_ = nullptr;
100     }
101 
BlockCount() const102     uint64_t BlockCount() const {
103         return block_info_.block_count;
104     }
105 
BlockSize() const106     uint64_t BlockSize() const {
107         return block_info_.block_size;
108     }
109 
PrepareGpt()110     bool PrepareGpt() {
111         BEGIN_HELPER;
112         ASSERT_EQ(device_, nullptr);
113 
114         zxio_storage_t* storage;
115         fdio_t* io = fdio_zxio_create(&storage);
116         ASSERT_NE(io, nullptr);
117         zxio_init(&storage->io, &mock_ops);
118         fd_.reset(fdio_bind_to_fd(io, -1, 0));
119         ASSERT_TRUE(fd_);
120         zx_status_t rc = gpt_device_init(fd_.get(), static_cast<uint32_t>(BlockSize()),
121                                          BlockCount(), &device_);
122         ASSERT_GE(rc, 0, "Could not initialize gpt");
123         rc = gpt_device_finalize(device_);
124         ASSERT_GE(rc, 0, "Could not finalize gpt");
125         END_HELPER;
126     }
127 
Device()128     gpt_device_t* Device() {
129         return device_;
130     }
131 
Info() const132     const block_info_t* Info() const {
133         return &block_info_;
134     }
135 
ReleaseGpt()136     void ReleaseGpt() {
137         if (device_ != nullptr) {
138             gpt_device_release(device_);
139             device_ = nullptr;
140         }
141     }
142 
~TestState()143     ~TestState() {
144         ReleaseGpt();
145     }
146 
RootBlks() const147     uint64_t RootBlks() const { return blk_sz_root_; }
KernBlks() const148     uint64_t KernBlks() const { return blk_sz_kern_; }
RwfwBlks() const149     uint64_t RwfwBlks() const { return blk_sz_fw_; }
EfiBlks() const150     uint64_t EfiBlks() const { return blk_sz_efi_; }
FvmBlks() const151     uint64_t FvmBlks() const { return blk_sz_fvm_; }
KernCBlks() const152     uint64_t KernCBlks() const { return blk_sz_kernc_; }
RootCBlks() const153     uint64_t RootCBlks() const { return blk_sz_rootc_; }
154 
155 private:
156     uint64_t blk_sz_root_;
157     uint64_t blk_sz_kern_;
158     uint64_t blk_sz_fw_;
159     uint64_t blk_sz_efi_;
160     uint64_t blk_sz_fvm_;
161     uint64_t blk_sz_kernc_;
162     uint64_t blk_sz_rootc_;
163     block_info_t block_info_;
164     gpt_device_t* device_;
165     fbl::unique_fd fd_;
166 };
167 
168 typedef struct {
169     uint64_t start;
170     uint64_t len;
171 } partition_t;
172 
part_size_gte(const gpt_partition_t * part,uint64_t size,uint64_t block_size)173 bool part_size_gte(const gpt_partition_t *part, uint64_t size,
174                    uint64_t block_size) {
175     if (part == NULL) {
176         return false;
177     }
178     uint64_t size_in_blocks = part->last - part->first + 1;
179     return size_in_blocks * block_size >= size;
180 }
181 
find_by_type_and_name(const gpt_device_t * gpt,const uint8_t type_guid[GPT_GUID_LEN],const char * name)182 gpt_partition_t* find_by_type_and_name(const gpt_device_t* gpt,
183                                        const uint8_t type_guid[GPT_GUID_LEN],
184                                        const char *name) {
185     for(size_t i = 0; i < PARTITIONS_COUNT; ++i) {
186         gpt_partition_t* p = gpt->partitions[i];
187         if (p == NULL) {
188             continue;
189         }
190         char buf[GPT_NAME_LEN] = {0};
191         utf16_to_cstring(&buf[0], (const uint16_t*)p->name, GPT_NAME_LEN/2);
192         if(!strncmp(buf, name, GPT_NAME_LEN)) {
193             return p;
194         }
195     }
196     return NULL;
197 }
198 
create_partition(gpt_device_t * d,const char * name,const uint8_t * type,partition_t * p)199 bool create_partition(gpt_device_t* d, const char* name, const uint8_t* type,
200                       partition_t* p) {
201     BEGIN_HELPER;
202     uint8_t guid_buf[GPT_GUID_LEN];
203     zx_cprng_draw(guid_buf, GPT_GUID_LEN);
204 
205     ASSERT_EQ(gpt_partition_add(d, name, type, guid_buf, p->start, p->len, 0),
206               0, "Partition could not be added.");
207     END_HELPER;
208 }
209 
210 // create the KERN-A, KERN-B, ROOT-A, ROOT-B and state partitions
create_kern_roots_state(TestState * test)211 bool create_kern_roots_state(TestState* test) {
212     BEGIN_HELPER;
213     partition_t part_defs[5];
214 
215     // this layout is patterned off observed layouts of ChromeOS devices
216     // KERN-A
217     part_defs[1].start = 20480;
218     part_defs[1].len = test->KernBlks();
219 
220     // ROOT-A
221     part_defs[2].start = 315392;
222     part_defs[2].len = test->RootBlks();
223 
224     // KERN-B
225     part_defs[3].start = part_defs[1].start + part_defs[1].len;
226     part_defs[3].len = test->KernBlks();
227 
228     // ROOT-B
229     part_defs[4].start = part_defs[2].start + part_defs[2].len;
230     part_defs[4].len = test->RootBlks();
231 
232     part_defs[0].start = part_defs[4].start + part_defs[4].len;
233 
234     gpt_device_t* device = test->Device();
235 
236     // first the rest of the disk with STATE
237     uint64_t disk_start, disk_end;
238     ASSERT_EQ(gpt_device_range(device, &disk_start, &disk_end), 0,
239               "Retrieval of device range failed.");
240     part_defs[0].len = disk_end - part_defs[0].start;
241 
242     ASSERT_TRUE(create_partition(device, "STATE", kStateGUID, &part_defs[0]));
243     ASSERT_TRUE(create_partition(device, "KERN-A", kCrosKernGUID,
244                                  &part_defs[1]));
245     ASSERT_TRUE(create_partition(device, "ROOT-A", kCrosRootGUID,
246                                  &part_defs[2]));
247     ASSERT_TRUE(create_partition(device, "KERN-B", kCrosKernGUID,
248                                  &part_defs[3]));
249     ASSERT_TRUE(create_partition(device, "ROOT-B", kCrosRootGUID,
250                                  &part_defs[4]));
251     END_HELPER;
252 }
253 
create_default_c_parts(TestState * test)254 bool create_default_c_parts(TestState* test) {
255     BEGIN_HELPER;
256 
257     gpt_device_t* device = test->Device();
258     uint64_t begin, end;
259     gpt_device_range(device, &begin, &end);
260 
261     partition_t part_defs[2];
262     part_defs[0].start = begin;
263     part_defs[0].len = kCPartsInitSize;
264 
265     part_defs[1].start = part_defs[0].start + part_defs[0].len;
266     part_defs[1].len = kCPartsInitSize;
267 
268     ASSERT_TRUE(create_partition(device, "KERN-C", kCrosKernGUID,
269                                  &part_defs[0]));
270     ASSERT_TRUE(create_partition(device, "ROOT-C", kCrosRootGUID,
271                                  &part_defs[1]));
272 
273     END_HELPER;
274 }
275 
create_misc_parts(TestState * test)276 bool create_misc_parts(TestState* test) {
277     BEGIN_HELPER;
278     partition_t part_defs[5];
279     // "OEM"
280     part_defs[0].start = 86016;
281     part_defs[0].len = test->KernBlks();
282 
283     // "reserved"
284     part_defs[1].start = 16450;
285     part_defs[1].len = 1;
286 
287     // "reserved"
288     part_defs[2].start = part_defs[0].start + part_defs[0].len;
289     part_defs[2].len = 1;
290 
291     // "RWFW"
292     part_defs[3].start = 64;
293     part_defs[3].len = test->RwfwBlks();
294 
295     // "EFI-SYSTEM"
296     part_defs[4].start = 249856;
297     part_defs[4].len = test->EfiBlks();
298 
299     gpt_device_t* device = test->Device();
300     ASSERT_TRUE(create_partition(device, "OEM", kGenDataGUID, &part_defs[0]));
301     ASSERT_TRUE(create_partition(device, "reserved", kGenDataGUID,
302                                  &part_defs[1]));
303     ASSERT_TRUE(create_partition(device, "reserved", kGenDataGUID,
304                                  &part_defs[2]));
305     ASSERT_TRUE(create_partition(device, "RWFW", kFwGUID, &part_defs[3]));
306     ASSERT_TRUE(create_partition(device, "EFI-SYSTEM", kEfiGUID, &part_defs[4]));
307     END_HELPER;
308 }
309 
create_test_layout(TestState * test)310 bool create_test_layout(TestState* test) {
311     BEGIN_HELPER;
312     ASSERT_TRUE(create_kern_roots_state(test));
313     ASSERT_TRUE(create_default_c_parts(test));
314     ASSERT_TRUE(create_misc_parts(test));
315     END_HELPER;
316 }
317 
add_fvm_part(TestState * test,gpt_partition_t * state)318 bool add_fvm_part(TestState* test, gpt_partition_t* state) {
319     BEGIN_HELPER;
320     partition_t fvm_part;
321     fvm_part.start = state->first;
322     fvm_part.len = test->FvmBlks();
323     state->first += test->FvmBlks();
324 
325     gpt_device_t* device = test->Device();
326     ASSERT_TRUE(create_partition(device, "fvm", kFvmGUID, &fvm_part));
327 
328     END_HELPER;
329 }
330 
resize_kernc_from_state(TestState * test,gpt_partition_t * kernc,gpt_partition_t * state)331 void resize_kernc_from_state(TestState* test, gpt_partition_t* kernc,
332                              gpt_partition_t* state) {
333     kernc->first = state->first;
334     kernc->last = kernc->first + test->KernCBlks() - 1;
335     state->first = kernc->last + 1;
336 }
337 
resize_rootc_from_state(TestState * test,gpt_partition_t * rootc,gpt_partition_t * state)338 void resize_rootc_from_state(TestState* test, gpt_partition_t* rootc,
339                              gpt_partition_t* state) {
340     rootc->first = state->first;
341     rootc->last = rootc->first + test->RootCBlks() - 1;
342     state->first = rootc->last + 1;
343 }
344 
345 // assumes that the base layout contains 12 partitions and that
346 // partition 0 is the resizable state partition
347 // the fvm partition will be created as the 13th partition
create_test_layout_with_fvm(TestState * test)348 bool create_test_layout_with_fvm(TestState* test) {
349     BEGIN_HELPER;
350     ASSERT_TRUE(create_test_layout(test));
351     ASSERT_TRUE(add_fvm_part(test, test->Device()->partitions[0]));
352     END_HELPER;
353 }
354 
assert_required_partitions(gpt_device_t * gpt)355 bool assert_required_partitions(gpt_device_t* gpt) {
356     BEGIN_HELPER;
357     gpt_partition_t* part;
358     part = find_by_type_and_name(gpt, kFvmGUID, "fvm");
359     ASSERT_NOT_NULL(part);
360     ASSERT_TRUE(part_size_gte(part, SZ_FVM_PART, BLOCK_SIZE), "FVM size");
361 
362     part = find_by_type_and_name(gpt, kCrosKernGUID, "ZIRCON-A");
363     ASSERT_NOT_NULL(part);
364     ASSERT_TRUE(part_size_gte(part, SZ_KERN_PART, BLOCK_SIZE), "ZIRCON-A size");
365 
366     part = find_by_type_and_name(gpt, kCrosKernGUID, "ZIRCON-B");
367     ASSERT_NOT_NULL(part);
368     ASSERT_TRUE(part_size_gte(part, SZ_KERN_PART, BLOCK_SIZE), "ZIRCON-B size");
369 
370     part = find_by_type_and_name(gpt, kCrosKernGUID, "ZIRCON-R");
371     ASSERT_NOT_NULL(part);
372     ASSERT_TRUE(part_size_gte(part, SZ_KERN_PART, BLOCK_SIZE), "ZIRCON-R size");
373 
374     part = find_by_type_and_name(gpt, kCrosKernGUID, "SYSCFG");
375     ASSERT_NOT_NULL(part);
376     ASSERT_TRUE(part_size_gte(part, SZ_SYSCFG_PART, BLOCK_SIZE), "SYSCFG size");
377     END_HELPER;
378 }
379 
TestDefaultConfig(void)380 bool TestDefaultConfig(void) {
381     BEGIN_TEST;
382     TestState test;
383     ASSERT_TRUE(test.PrepareGpt());
384     gpt_device_t* dev = test.Device();
385 
386     ASSERT_TRUE(create_test_layout(&test), "Test layout creation failed.");
387 
388     ASSERT_FALSE(is_ready_to_pave(dev, test.Info(), SZ_ZX_PART),
389                  "Device SHOULD NOT be ready to pave.");
390     ASSERT_EQ(config_cros_for_fuchsia(dev, test.Info(), SZ_ZX_PART),
391               ZX_OK, "Configuration failed.");
392     ASSERT_TRUE(is_ready_to_pave(dev, test.Info(), SZ_ZX_PART),
393                 "Device SHOULD be ready to pave.");
394 
395     assert_required_partitions(dev);
396 
397     END_TEST;
398 }
399 
TestAlreadyConfigured(void)400 bool TestAlreadyConfigured(void) {
401     BEGIN_TEST;
402     TestState test;
403     ASSERT_TRUE(test.PrepareGpt());
404     gpt_device_t* dev = test.Device();
405 
406     ASSERT_TRUE(create_test_layout(&test), "Test layout creation failed.");
407     ASSERT_TRUE(add_fvm_part(&test, dev->partitions[0]),
408                 "Could not add FVM partition record");
409     resize_kernc_from_state(&test, dev->partitions[5], dev->partitions[0]);
410     resize_rootc_from_state(&test, dev->partitions[6], dev->partitions[0]);
411 
412     ASSERT_FALSE(is_ready_to_pave(dev, test.Info(), SZ_ZX_PART),
413                 "Device SHOULD NOT be ready to pave.");
414 
415     // TODO verify that nothing changed
416     ASSERT_EQ(config_cros_for_fuchsia(dev, test.Info(), SZ_ZX_PART),
417               ZX_OK, "Config failed.");
418 
419     ASSERT_TRUE(is_ready_to_pave(dev, test.Info(), SZ_ZX_PART),
420                 "Device SHOULD be ready to pave.");
421 
422     assert_required_partitions(dev);
423 
424     END_TEST;
425 }
426 
TestNoCParts(void)427 bool TestNoCParts(void) {
428     BEGIN_TEST;
429     TestState test;
430     ASSERT_TRUE(test.PrepareGpt());
431     gpt_device_t* dev = test.Device();
432 
433     ASSERT_TRUE(create_kern_roots_state(&test),
434                 "Couldn't create A/B kern and root parts");
435 
436     ASSERT_TRUE(create_misc_parts(&test), "Couldn't create misc parts");
437 
438     ASSERT_FALSE(is_ready_to_pave(dev, test.Info(), SZ_ZX_PART),
439                  "Should not initially be ready to pave");
440 
441     ASSERT_EQ(config_cros_for_fuchsia(dev, test.Info(), SZ_ZX_PART),
442               ZX_OK, "Configure failed");
443 
444     ASSERT_TRUE(is_ready_to_pave(dev, test.Info(), SZ_ZX_PART),
445                 "Device should now be ready to pave, but isn't");
446 
447     assert_required_partitions(dev);
448     END_TEST;
449 }
450 
TestNoRootc(void)451 bool TestNoRootc(void) {
452     BEGIN_TEST;
453     TestState test;
454     ASSERT_TRUE(test.PrepareGpt());
455     gpt_device_t* dev = test.Device();
456 
457     ASSERT_TRUE(create_kern_roots_state(&test),
458                 "Couldn't make A&B kern/root parts");
459 
460     ASSERT_TRUE(create_misc_parts(&test), "Couldn't create misc parts");
461 
462     ASSERT_TRUE(create_default_c_parts(&test), "Couldn't create c parts\n");
463 
464     ASSERT_EQ(gpt_partition_remove(dev, dev->partitions[11]->guid), 0,
465               "Failed to remove ROOT-C partition");
466 
467     ASSERT_FALSE(is_ready_to_pave(dev, test.Info(), SZ_ZX_PART),
468                  "Should not initially be ready to pave");
469 
470     ASSERT_EQ(config_cros_for_fuchsia(dev, test.Info(), SZ_ZX_PART),
471               ZX_OK, "Configure failed");
472 
473     ASSERT_TRUE(is_ready_to_pave(dev, test.Info(), SZ_ZX_PART),
474                 "Device should now be ready to pave, but isn't");
475 
476     assert_required_partitions(dev);
477     END_TEST;
478 }
479 
TestNoKernc(void)480 bool TestNoKernc(void) {
481     BEGIN_TEST;
482     TestState test;
483     ASSERT_TRUE(test.PrepareGpt());
484     gpt_device_t* dev = test.Device();
485 
486     ASSERT_TRUE(create_kern_roots_state(&test),
487                 "Couldn't make A&B kern/root parts");
488 
489     ASSERT_TRUE(create_misc_parts(&test), "Couldn't create misc parts");
490 
491     ASSERT_TRUE(create_default_c_parts(&test), "Couldn't create c parts\n");
492 
493     ASSERT_EQ(gpt_partition_remove(dev, dev->partitions[10]->guid), 0,
494               "Failed to remove ROOT-C partition");
495 
496     ASSERT_FALSE(is_ready_to_pave(dev, test.Info(), SZ_ZX_PART),
497                  "Should not initially be ready to pave");
498 
499     ASSERT_EQ(config_cros_for_fuchsia(dev, test.Info(), SZ_ZX_PART),
500               ZX_OK, "Configure failed");
501 
502     ASSERT_TRUE(is_ready_to_pave(dev, test.Info(), SZ_ZX_PART),
503                 "Device should now be ready to pave, but isn't");
504 
505     assert_required_partitions(dev);
506 
507     END_TEST;
508 }
509 
TestDiskTooSmall(void)510 bool TestDiskTooSmall(void) {
511     BEGIN_TEST;
512 
513     // first setup the device as though it is a normal test so we can compute
514     // the blocks required
515     TestState test;
516     ASSERT_TRUE(test.PrepareGpt());
517     gpt_device_t* dev = test.Device();
518 
519     ASSERT_TRUE(create_test_layout(&test), "Failed creating initial test layout");
520 
521     uint64_t reserved, unused;
522     gpt_device_range(dev, &reserved, &unused);
523 
524     // this is the size we need the STATE partition to be if we are to resize
525     // it to make room for the partitions we want to add and expand
526     uint64_t needed_blks = howmany(SZ_ZX_PART + MIN_SZ_STATE,
527                                    test.BlockSize()) + reserved;
528     // now remove a few blocks so we can't satisfy all constraints
529     needed_blks--;
530 
531     block_info_t info;
532     memcpy(&info, &kDefaultBlockInfo, sizeof(block_info_t));
533     info.block_count = dev->partitions[0]->first + needed_blks - 1;
534 
535     // now that we've calculated the block count, create a device with that
536     // smaller count
537 
538     test.Initialize(info);
539     ASSERT_TRUE(test.PrepareGpt());
540     dev = test.Device();
541 
542     ASSERT_TRUE(create_test_layout(&test), "Failed creating real test layout");
543 
544     ASSERT_FALSE(is_ready_to_pave(dev, test.Info(), SZ_ZX_PART),
545                  "Should not initially be ready to pave");
546 
547     ASSERT_NE(config_cros_for_fuchsia(dev, test.Info(), SZ_ZX_PART),
548               ZX_OK, "Configure reported success, but should have failed.");
549     ASSERT_FALSE(is_ready_to_pave(dev, test.Info(), SZ_ZX_PART),
550                  "Device should still not be paveable");
551     END_TEST;
552 }
553 
TestIsCrosDevice(void)554 bool TestIsCrosDevice(void) {
555     BEGIN_TEST;
556     TestState test;
557     ASSERT_TRUE(test.PrepareGpt());
558     gpt_device_t* dev = test.Device();
559 
560     ASSERT_TRUE(create_test_layout(&test), "Failed to create test layout");
561 
562     ASSERT_TRUE(is_cros(dev), "This should be recognized as a chromeos layout");
563     zx_cprng_draw(dev->partitions[1]->type, GPT_GUID_LEN);
564     zx_cprng_draw(dev->partitions[4]->type, GPT_GUID_LEN);
565     ASSERT_FALSE(is_cros(dev), "This should NOT be recognized as a chromos layout");
566     END_TEST;
567 }
568 
569 } // namespace
570 
571 BEGIN_TEST_CASE(disk_wizard_tests)
RUN_TEST(TestDefaultConfig)572 RUN_TEST(TestDefaultConfig)
573 RUN_TEST(TestAlreadyConfigured)
574 RUN_TEST(TestNoCParts)
575 RUN_TEST(TestNoRootc)
576 RUN_TEST(TestNoKernc)
577 RUN_TEST(TestDiskTooSmall)
578 RUN_TEST(TestIsCrosDevice)
579 END_TEST_CASE(disk_wizard_tests)
580 
581 int main(int argc, char** argv) {
582     return unittest_run_all_tests(argc, argv) ? 0 : -1;
583 }
584