source: mainline/uspace/lib/label/test/label.c@ bec18a9

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since bec18a9 was 3bacee1, checked in by Jiri Svoboda <jiri@…>, 7 years ago

Make ccheck-fix again and commit more good files.

  • Property mode set to 100644
File size: 14.9 KB
Line 
1/*
2 * Copyright (c) 2017 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <label/label.h>
30#include <mem.h>
31#include <pcut/pcut.h>
32#include <stddef.h>
33#include <stdlib.h>
34
35PCUT_INIT;
36
37PCUT_TEST_SUITE(label);
38
39static errno_t label_test_get_bsize(void *, size_t *);
40static errno_t label_test_get_nblocks(void *, aoff64_t *);
41static errno_t label_test_read(void *, aoff64_t, size_t, void *);
42static errno_t label_test_write(void *, aoff64_t, size_t, const void *);
43
44label_bd_ops_t label_test_ops = {
45 .get_bsize = label_test_get_bsize,
46 .get_nblocks = label_test_get_nblocks,
47 .read = label_test_read,
48 .write = label_test_write
49};
50
51/** Pretended block device for testing */
52typedef struct {
53 char *data;
54 size_t bsize;
55 aoff64_t nblocks;
56} test_bd_t;
57
58enum {
59 test_block_size = 512,
60 test_nblocks = 1024
61};
62
63/** Create pretended block device.
64 *
65 * @param bsize Block size
66 * @param nblocks Number of blocks
67 * @param rbd Place to store pointer to new pretended block device
68 */
69static errno_t test_bd_create(size_t bsize, aoff64_t nblocks, test_bd_t **rbd)
70{
71 test_bd_t *bd;
72
73 bd = calloc(1, sizeof(test_bd_t));
74 if (bd == NULL)
75 return ENOMEM;
76
77 bd->data = calloc(bsize, nblocks);
78 if (bd->data == NULL) {
79 free(bd);
80 return ENOMEM;
81 }
82
83 bd->bsize = bsize;
84 bd->nblocks = nblocks;
85 *rbd = bd;
86
87 return EOK;
88}
89
90/** Destroy pretended block device.
91 *
92 * @param bd Pretended block device
93 */
94static void test_bd_destroy(test_bd_t *bd)
95{
96 free(bd->data);
97 free(bd);
98}
99
100/** Get block size wrapper for liblabel */
101static errno_t label_test_get_bsize(void *arg, size_t *bsize)
102{
103 test_bd_t *bd = (test_bd_t *)arg;
104
105 *bsize = bd->bsize;
106 return EOK;
107}
108
109/** Get number of blocks wrapper for liblabel */
110static errno_t label_test_get_nblocks(void *arg, aoff64_t *nblocks)
111{
112 test_bd_t *bd = (test_bd_t *)arg;
113
114 *nblocks = bd->nblocks;
115 return EOK;
116}
117
118/** Read blocks wrapper for liblabel */
119static errno_t label_test_read(void *arg, aoff64_t ba, size_t cnt, void *buf)
120{
121 test_bd_t *bd = (test_bd_t *)arg;
122
123 if (ba >= bd->nblocks)
124 return EINVAL;
125
126 memcpy(buf, bd->data + ba * bd->bsize, bd->bsize);
127 return EOK;
128}
129
130/** Write blocks wrapper for liblabel */
131static errno_t label_test_write(void *arg, aoff64_t ba, size_t cnt, const void *data)
132{
133 test_bd_t *bd = (test_bd_t *)arg;
134
135 if (ba >= bd->nblocks)
136 return EINVAL;
137
138 memcpy(bd->data + ba * bd->bsize, data, bd->bsize);
139 return EOK;
140}
141
142PCUT_TEST(open_empty)
143{
144 label_t *label;
145 label_bd_t lbd;
146 label_info_t linfo;
147 label_part_t *part;
148 test_bd_t *bd = NULL;
149 errno_t rc;
150
151 rc = test_bd_create(test_block_size, test_nblocks, &bd);
152 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
153
154 lbd.ops = &label_test_ops;
155 lbd.arg = (void *)bd;
156
157 rc = label_open(&lbd, &label);
158 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
159
160 rc = label_get_info(label, &linfo);
161 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
162
163 PCUT_ASSERT_INT_EQUALS(lt_none, linfo.ltype);
164 PCUT_ASSERT_INT_EQUALS(0, linfo.flags);
165
166 /* There should be exactly one pseudo partition */
167 part = label_part_first(label);
168 PCUT_ASSERT_NOT_NULL(part);
169
170 part = label_part_next(part);
171 PCUT_ASSERT_NULL(part);
172
173 label_close(label);
174
175 test_bd_destroy(bd);
176}
177
178PCUT_TEST(create_destroy_mbr)
179{
180 label_t *label;
181 label_bd_t lbd;
182 label_info_t linfo;
183 label_part_t *part;
184 test_bd_t *bd = NULL;
185 errno_t rc;
186
187 rc = test_bd_create(test_block_size, test_nblocks, &bd);
188 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
189
190 lbd.ops = &label_test_ops;
191 lbd.arg = (void *)bd;
192
193 rc = label_create(&lbd, lt_mbr, &label);
194 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
195
196 rc = label_get_info(label, &linfo);
197 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
198
199 PCUT_ASSERT_INT_EQUALS(lt_mbr, linfo.ltype);
200 PCUT_ASSERT_INT_EQUALS(lf_ext_supp | lf_can_create_pri |
201 lf_can_create_ext, linfo.flags);
202
203 /* There should be no partitions */
204 part = label_part_first(label);
205 PCUT_ASSERT_NULL(part);
206
207 /* Close and reopen */
208 label_close(label);
209
210 rc = label_open(&lbd, &label);
211 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
212
213 rc = label_get_info(label, &linfo);
214 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
215
216 /* Everything should still be the same */
217 PCUT_ASSERT_INT_EQUALS(lt_mbr, linfo.ltype);
218 PCUT_ASSERT_INT_EQUALS(lf_ext_supp | lf_can_create_pri |
219 lf_can_create_ext, linfo.flags);
220
221 rc = label_destroy(label);
222 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
223
224 /* There should be no label now */
225
226 rc = label_open(&lbd, &label);
227 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
228
229 rc = label_get_info(label, &linfo);
230 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
231
232 PCUT_ASSERT_INT_EQUALS(lt_none, linfo.ltype);
233 PCUT_ASSERT_INT_EQUALS(0, linfo.flags);
234
235 label_close(label);
236
237 test_bd_destroy(bd);
238}
239
240PCUT_TEST(create_destroy_gpt)
241{
242 label_t *label;
243 label_bd_t lbd;
244 label_info_t linfo;
245 label_part_t *part;
246 test_bd_t *bd = NULL;
247 errno_t rc;
248
249 rc = test_bd_create(test_block_size, test_nblocks, &bd);
250 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
251
252 lbd.ops = &label_test_ops;
253 lbd.arg = (void *)bd;
254
255 rc = label_create(&lbd, lt_gpt, &label);
256 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
257
258 rc = label_get_info(label, &linfo);
259 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
260
261 PCUT_ASSERT_INT_EQUALS(lt_gpt, linfo.ltype);
262 PCUT_ASSERT_INT_EQUALS(lf_can_create_pri | lf_ptype_uuid, linfo.flags);
263
264 /* There should be no partitions */
265 part = label_part_first(label);
266 PCUT_ASSERT_NULL(part);
267
268 /* Close and reopen */
269 label_close(label);
270
271 rc = label_open(&lbd, &label);
272 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
273
274 rc = label_get_info(label, &linfo);
275 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
276
277 /* Everything should still be the same */
278 PCUT_ASSERT_INT_EQUALS(lt_gpt, linfo.ltype);
279 PCUT_ASSERT_INT_EQUALS(lf_can_create_pri | lf_ptype_uuid, linfo.flags);
280
281 rc = label_destroy(label);
282 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
283
284 /* There should be no label now */
285
286 rc = label_open(&lbd, &label);
287 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
288
289 rc = label_get_info(label, &linfo);
290 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
291
292 PCUT_ASSERT_INT_EQUALS(lt_none, linfo.ltype);
293 PCUT_ASSERT_INT_EQUALS(0, linfo.flags);
294
295 label_close(label);
296
297 test_bd_destroy(bd);
298}
299
300PCUT_TEST(mbr_primary_part)
301{
302 label_t *label;
303 label_bd_t lbd;
304 label_info_t linfo;
305 label_part_t *part;
306 label_part_spec_t pspec;
307 label_part_info_t pinfo;
308 label_ptype_t ptype;
309 test_bd_t *bd = NULL;
310 errno_t rc;
311
312 rc = test_bd_create(test_block_size, test_nblocks, &bd);
313 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
314
315 lbd.ops = &label_test_ops;
316 lbd.arg = (void *)bd;
317
318 rc = label_create(&lbd, lt_mbr, &label);
319 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
320
321 rc = label_get_info(label, &linfo);
322 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
323
324 /* There should be no partitions */
325 part = label_part_first(label);
326 PCUT_ASSERT_NULL(part);
327
328 rc = label_suggest_ptype(label, lpc_ext4, &ptype);
329 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
330
331 memset(&pspec, 0, sizeof(pspec));
332 pspec.index = 1;
333 pspec.block0 = linfo.ablock0;
334 pspec.nblocks = linfo.anblocks;
335 pspec.hdr_blocks = 0;
336 pspec.pkind = lpk_primary;
337 pspec.ptype = ptype;
338
339 rc = label_part_create(label, &pspec, &part);
340 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
341
342 label_part_get_info(part, &pinfo);
343 PCUT_ASSERT_INT_EQUALS(1, pinfo.index);
344 PCUT_ASSERT_INT_EQUALS(lpk_primary, pinfo.pkind);
345 PCUT_ASSERT_INT_EQUALS(linfo.ablock0, pinfo.block0);
346 PCUT_ASSERT_INT_EQUALS(linfo.anblocks, pinfo.nblocks);
347
348 /* Close and reopen */
349 label_close(label);
350
351 rc = label_open(&lbd, &label);
352 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
353
354 rc = label_get_info(label, &linfo);
355 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
356
357 PCUT_ASSERT_INT_EQUALS(lt_mbr, linfo.ltype);
358 PCUT_ASSERT_INT_EQUALS(lf_ext_supp | lf_can_create_pri |
359 lf_can_create_ext | lf_can_delete_part, linfo.flags);
360
361 part = label_part_first(label);
362 PCUT_ASSERT_NOT_NULL(part);
363 PCUT_ASSERT_NULL(label_part_next(part));
364
365 label_part_get_info(part, &pinfo);
366 PCUT_ASSERT_INT_EQUALS(1, pinfo.index);
367 PCUT_ASSERT_INT_EQUALS(lpk_primary, pinfo.pkind);
368 PCUT_ASSERT_INT_EQUALS(linfo.ablock0, pinfo.block0);
369 PCUT_ASSERT_INT_EQUALS(linfo.anblocks, pinfo.nblocks);
370
371 /* Destroy the partition */
372 rc = label_part_destroy(part);
373 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
374
375 /* Close and reopen */
376 label_close(label);
377
378 rc = label_open(&lbd, &label);
379 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
380
381 /* There should be no partitions */
382 part = label_part_first(label);
383 PCUT_ASSERT_NULL(part);
384
385 label_close(label);
386
387 test_bd_destroy(bd);
388}
389
390PCUT_TEST(mbr_logical_part)
391{
392 label_t *label;
393 label_bd_t lbd;
394 label_info_t linfo;
395 label_part_t *part, *lpart, *epart;
396 label_part_spec_t pspec;
397 label_ptype_t ptype;
398 label_part_info_t pinfo, lpinfo, epinfo;
399 test_bd_t *bd = NULL;
400 errno_t rc;
401
402 rc = test_bd_create(test_block_size, test_nblocks, &bd);
403 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
404
405 lbd.ops = &label_test_ops;
406 lbd.arg = (void *)bd;
407
408 rc = label_create(&lbd, lt_mbr, &label);
409 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
410
411 rc = label_get_info(label, &linfo);
412 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
413
414 /* There should be no partitions */
415 part = label_part_first(label);
416 PCUT_ASSERT_NULL(part);
417
418 memset(&pspec, 0, sizeof(pspec));
419 pspec.index = 1;
420 pspec.block0 = linfo.ablock0;
421 pspec.nblocks = linfo.anblocks;
422 pspec.hdr_blocks = 0;
423 pspec.pkind = lpk_extended;
424
425 rc = label_part_create(label, &pspec, &epart);
426 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
427
428 label_part_get_info(epart, &epinfo);
429 PCUT_ASSERT_INT_EQUALS(1, epinfo.index);
430 PCUT_ASSERT_INT_EQUALS(lpk_extended, epinfo.pkind);
431 PCUT_ASSERT_INT_EQUALS(linfo.ablock0, epinfo.block0);
432 PCUT_ASSERT_INT_EQUALS(linfo.anblocks, epinfo.nblocks);
433
434 /* Close and reopen */
435 label_close(label);
436
437 rc = label_open(&lbd, &label);
438 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
439
440 rc = label_get_info(label, &linfo);
441 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
442
443 PCUT_ASSERT_INT_EQUALS(lt_mbr, linfo.ltype);
444 PCUT_ASSERT_INT_EQUALS(lf_ext_supp | lf_can_create_pri |
445 lf_can_create_log | lf_can_delete_part, linfo.flags);
446
447 epart = label_part_first(label);
448 PCUT_ASSERT_NOT_NULL(epart);
449 PCUT_ASSERT_NULL(label_part_next(epart));
450
451 label_part_get_info(epart, &epinfo);
452 PCUT_ASSERT_INT_EQUALS(1, epinfo.index);
453 PCUT_ASSERT_INT_EQUALS(lpk_extended, epinfo.pkind);
454 PCUT_ASSERT_INT_EQUALS(linfo.ablock0, epinfo.block0);
455 PCUT_ASSERT_INT_EQUALS(linfo.anblocks, epinfo.nblocks);
456
457 /* Create logical partition */
458 rc = label_suggest_ptype(label, lpc_ext4, &ptype);
459 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
460
461 memset(&pspec, 0, sizeof(pspec));
462 pspec.index = 0;
463 pspec.block0 = epinfo.block0 + 1;
464 pspec.nblocks = epinfo.nblocks - 1;
465 pspec.hdr_blocks = 1;
466 pspec.pkind = lpk_logical;
467 pspec.ptype = ptype;
468
469 rc = label_part_create(label, &pspec, &lpart);
470 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
471
472 label_part_get_info(lpart, &lpinfo);
473 PCUT_ASSERT_INT_EQUALS(5, lpinfo.index);
474 PCUT_ASSERT_INT_EQUALS(lpk_logical, lpinfo.pkind);
475 PCUT_ASSERT_INT_EQUALS(epinfo.block0 + 1, lpinfo.block0);
476 PCUT_ASSERT_INT_EQUALS(epinfo.nblocks - 1, lpinfo.nblocks);
477
478 /* Close and reopen */
479 label_close(label);
480
481 rc = label_open(&lbd, &label);
482 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
483
484 /* Find the extended and the logical partition */
485
486 epart = NULL;
487 lpart = NULL;
488
489 part = label_part_first(label);
490 while (part != NULL) {
491 label_part_get_info(part, &pinfo);
492 if (pinfo.pkind == lpk_extended) {
493 epart = part;
494 } else {
495 PCUT_ASSERT_INT_EQUALS(lpk_logical, pinfo.pkind);
496 lpart = part;
497 }
498
499 part = label_part_next(part);
500 }
501
502 PCUT_ASSERT_NOT_NULL(epart);
503 PCUT_ASSERT_NOT_NULL(lpart);
504
505 /* Destroy the logical partition */
506 rc = label_part_destroy(lpart);
507 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
508
509 /* Destroy the extended partition */
510 rc = label_part_destroy(epart);
511 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
512
513 /* Close and reopen */
514 label_close(label);
515
516 rc = label_open(&lbd, &label);
517 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
518
519 /* There should be no partitions */
520 part = label_part_first(label);
521 PCUT_ASSERT_NULL(part);
522
523 label_close(label);
524
525 test_bd_destroy(bd);
526}
527
528
529PCUT_TEST(gpt_part)
530{
531 label_t *label;
532 label_bd_t lbd;
533 label_info_t linfo;
534 label_part_t *part;
535 label_part_spec_t pspec;
536 label_part_info_t pinfo;
537 label_ptype_t ptype;
538 test_bd_t *bd = NULL;
539 errno_t rc;
540
541 rc = test_bd_create(test_block_size, test_nblocks, &bd);
542 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
543
544 lbd.ops = &label_test_ops;
545 lbd.arg = (void *)bd;
546
547 rc = label_create(&lbd, lt_gpt, &label);
548 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
549
550 rc = label_get_info(label, &linfo);
551 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
552
553 /* There should be no partitions */
554 part = label_part_first(label);
555 PCUT_ASSERT_NULL(part);
556
557 rc = label_suggest_ptype(label, lpc_ext4, &ptype);
558 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
559
560 memset(&pspec, 0, sizeof(pspec));
561 pspec.index = 1;
562 pspec.block0 = linfo.ablock0;
563 pspec.nblocks = linfo.anblocks;
564 pspec.hdr_blocks = 0;
565 pspec.pkind = lpk_primary;
566 pspec.ptype = ptype;
567
568 rc = label_part_create(label, &pspec, &part);
569 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
570
571 label_part_get_info(part, &pinfo);
572 PCUT_ASSERT_INT_EQUALS(1, pinfo.index);
573 PCUT_ASSERT_INT_EQUALS(lpk_primary, pinfo.pkind);
574 PCUT_ASSERT_INT_EQUALS(linfo.ablock0, pinfo.block0);
575 PCUT_ASSERT_INT_EQUALS(linfo.anblocks, pinfo.nblocks);
576
577 /* Close and reopen */
578 label_close(label);
579
580 rc = label_open(&lbd, &label);
581 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
582
583 rc = label_get_info(label, &linfo);
584 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
585
586 PCUT_ASSERT_INT_EQUALS(lt_gpt, linfo.ltype);
587 PCUT_ASSERT_INT_EQUALS(lf_can_create_pri | lf_ptype_uuid |
588 lf_can_delete_part, linfo.flags);
589
590 part = label_part_first(label);
591 PCUT_ASSERT_NOT_NULL(part);
592 PCUT_ASSERT_NULL(label_part_next(part));
593
594 label_part_get_info(part, &pinfo);
595 PCUT_ASSERT_INT_EQUALS(1, pinfo.index);
596 PCUT_ASSERT_INT_EQUALS(lpk_primary, pinfo.pkind);
597 PCUT_ASSERT_INT_EQUALS(linfo.ablock0, pinfo.block0);
598 PCUT_ASSERT_INT_EQUALS(linfo.anblocks, pinfo.nblocks);
599
600 /* Destroy the partition */
601 rc = label_part_destroy(part);
602 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
603
604 /* Close and reopen */
605 label_close(label);
606
607 rc = label_open(&lbd, &label);
608 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
609
610 /* There should be no partitions */
611 part = label_part_first(label);
612 PCUT_ASSERT_NULL(part);
613
614 label_close(label);
615
616 test_bd_destroy(bd);
617}
618
619PCUT_EXPORT(label);
Note: See TracBrowser for help on using the repository browser.