LCOV - code coverage report
Current view: top level - spdk/test/unit/lib/bdev/gpt/gpt.c - gpt_ut.c (source / functions) Hit Total Coverage
Test: Combined Lines: 211 211 100.0 %
Date: 2024-07-15 19:03:29 Functions: 6 6 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 5 10 50.0 %

           Branch data     Line data    Source code
       1                 :            : /*   SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  *   Copyright (C) 2017 Intel Corporation.
       3                 :            :  *   All rights reserved.
       4                 :            :  */
       5                 :            : 
       6                 :            : #include "spdk_internal/cunit.h"
       7                 :            : 
       8                 :            : #include "common/lib/test_env.c"
       9                 :            : 
      10                 :            : #include "bdev/gpt/gpt.c"
      11                 :            : 
      12                 :            : static void
      13                 :          3 : test_check_mbr(void)
      14                 :            : {
      15                 :            :         struct spdk_gpt *gpt;
      16                 :            :         struct spdk_mbr *mbr;
      17                 :          3 :         unsigned char a[SPDK_GPT_BUFFER_SIZE];
      18                 :            :         int re;
      19                 :            : 
      20                 :            :         /* Set gpt is NULL */
      21                 :          3 :         re = gpt_parse_mbr(NULL);
      22                 :          3 :         CU_ASSERT(re == -1);
      23                 :            : 
      24                 :            :         /* Set gpt->buf is NULL */
      25                 :          3 :         gpt = calloc(1, sizeof(*gpt));
      26         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(gpt != NULL);
      27                 :          3 :         re = gpt_parse_mbr(gpt);
      28                 :          3 :         CU_ASSERT(re == -1);
      29                 :            : 
      30                 :            :         /* Set *gpt is "aaa...", all are mismatch include mbr_signature */
      31                 :          3 :         memset(a, 'a', sizeof(a));
      32                 :          3 :         gpt->buf = &a[0];
      33                 :          3 :         re = gpt_check_mbr(gpt);
      34                 :          3 :         CU_ASSERT(re == -1);
      35                 :            : 
      36                 :            :         /* Set mbr->mbr_signature matched, start lba mismatch */
      37                 :          3 :         mbr = (struct spdk_mbr *)gpt->buf;
      38                 :          3 :         mbr->mbr_signature = 0xAA55;
      39                 :          3 :         re = gpt_check_mbr(gpt);
      40                 :          3 :         CU_ASSERT(re == -1);
      41                 :            : 
      42                 :            :         /* Set mbr->partitions[0].start lba matched, os_type mismatch */
      43                 :          3 :         mbr->partitions[0].start_lba = 1;
      44                 :          3 :         re = gpt_check_mbr(gpt);
      45                 :          3 :         CU_ASSERT(re == -1);
      46                 :            : 
      47                 :            :         /* Set mbr->partitions[0].os_type matched, size_lba mismatch */
      48                 :          3 :         mbr->partitions[0].os_type = 0xEE;
      49                 :          3 :         re = gpt_check_mbr(gpt);
      50                 :          3 :         CU_ASSERT(re == -1);
      51                 :            : 
      52                 :            :         /* Set mbr->partitions[0].size_lba matched, passing case */
      53                 :          3 :         mbr->partitions[0].size_lba = 0xFFFFFFFF;
      54                 :          3 :         re = gpt_check_mbr(gpt);
      55                 :          3 :         CU_ASSERT(re == 0);
      56                 :            : 
      57                 :          3 :         free(gpt);
      58                 :          3 : }
      59                 :            : 
      60                 :            : static void
      61                 :          3 : test_read_header(void)
      62                 :            : {
      63                 :            :         struct spdk_gpt *gpt;
      64                 :            :         struct spdk_gpt_header *head;
      65                 :          3 :         unsigned char a[SPDK_GPT_BUFFER_SIZE];
      66                 :            :         int re;
      67                 :            : 
      68                 :            :         /* gpt_read_header(NULL) does not exist, NULL is filtered out in gpt_parse_mbr() */
      69                 :          3 :         gpt = calloc(1, sizeof(*gpt));
      70         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(gpt != NULL);
      71                 :          3 :         gpt->parse_phase = SPDK_GPT_PARSE_PHASE_PRIMARY;
      72                 :          3 :         gpt->sector_size = 512;
      73                 :            : 
      74                 :            :         /* Set *gpt is "aaa..." */
      75                 :          3 :         memset(a, 'a', sizeof(a));
      76                 :          3 :         gpt->buf = &a[0];
      77                 :          3 :         gpt->buf_size = sizeof(a);
      78                 :            : 
      79                 :            :         /* Set header_size mismatch */
      80                 :          3 :         gpt->sector_size = 512;
      81                 :          3 :         head = (struct spdk_gpt_header *)(gpt->buf + GPT_PRIMARY_PARTITION_TABLE_LBA * gpt->sector_size);
      82                 :          3 :         to_le32(&head->header_size, 0x258);
      83                 :          3 :         re = gpt_read_header(gpt);
      84                 :          3 :         CU_ASSERT(re == -1);
      85                 :            : 
      86                 :            :         /* Set head->header_size matched, header_crc32 mismatch */
      87                 :          3 :         head->header_size = sizeof(*head);
      88                 :          3 :         to_le32(&head->header_crc32, 0x22D18C80);
      89                 :          3 :         re = gpt_read_header(gpt);
      90                 :          3 :         CU_ASSERT(re == -1);
      91                 :            : 
      92                 :            :         /* Set head->header_crc32 matched, gpt_signature mismatch */
      93                 :          3 :         to_le32(&head->header_crc32, 0xC5B2117E);
      94                 :          3 :         re = gpt_read_header(gpt);
      95                 :          3 :         CU_ASSERT(re == -1);
      96                 :            : 
      97                 :            :         /* Set head->gpt_signature matched, head->my_lba mismatch */
      98                 :          3 :         to_le32(&head->header_crc32, 0xD637335A);
      99                 :          3 :         head->gpt_signature[0] = 'E';
     100                 :          3 :         head->gpt_signature[1] = 'F';
     101                 :          3 :         head->gpt_signature[2] = 'I';
     102                 :          3 :         head->gpt_signature[3] = ' ';
     103                 :          3 :         head->gpt_signature[4] = 'P';
     104                 :          3 :         head->gpt_signature[5] = 'A';
     105                 :          3 :         head->gpt_signature[6] = 'R';
     106                 :          3 :         head->gpt_signature[7] = 'T';
     107                 :          3 :         re = gpt_read_header(gpt);
     108                 :          3 :         CU_ASSERT(re == -1);
     109                 :            : 
     110                 :            :         /* Set head->my_lba matched, lba_end usable_lba mismatch */
     111                 :          3 :         to_le32(&head->header_crc32, 0xB3CDB2D2);
     112                 :          3 :         to_le64(&head->my_lba, 0x1);
     113                 :          3 :         re = gpt_read_header(gpt);
     114                 :          3 :         CU_ASSERT(re == -1);
     115                 :            : 
     116                 :            :         /* Set gpt->lba_end usable_lba matched, passing case */
     117                 :          3 :         to_le32(&head->header_crc32, 0x5531F2F0);
     118                 :          3 :         to_le64(&gpt->lba_start, 0x0);
     119                 :          3 :         to_le64(&gpt->lba_end, 0x2E935FFE);
     120                 :          3 :         to_le64(&head->first_usable_lba, 0xA);
     121                 :          3 :         to_le64(&head->last_usable_lba, 0xF4240);
     122                 :          3 :         re = gpt_read_header(gpt);
     123                 :          3 :         CU_ASSERT(re == 0);
     124                 :            : 
     125                 :          3 :         free(gpt);
     126                 :          3 : }
     127                 :            : 
     128                 :            : static void
     129                 :          3 : test_read_partitions(void)
     130                 :            : {
     131                 :            :         struct spdk_gpt *gpt;
     132                 :            :         struct spdk_gpt_header *head;
     133                 :          3 :         unsigned char a[SPDK_GPT_BUFFER_SIZE];
     134                 :            :         int re;
     135                 :            : 
     136                 :            :         /* gpt_read_partitions(NULL) does not exist, NULL is filtered out in gpt_parse_mbr() */
     137                 :          3 :         gpt = calloc(1, sizeof(*gpt));
     138         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(gpt != NULL);
     139                 :          3 :         gpt->parse_phase = SPDK_GPT_PARSE_PHASE_PRIMARY;
     140                 :          3 :         gpt->sector_size = 512;
     141                 :            : 
     142                 :            :         /* Set *gpt is "aaa..." */
     143                 :          3 :         memset(a, 'a', sizeof(a));
     144                 :          3 :         gpt->buf = &a[0];
     145                 :          3 :         gpt->buf_size = sizeof(a);
     146                 :            : 
     147                 :            :         /* Set num_partition_entries exceeds Max value of entries GPT supported */
     148                 :          3 :         gpt->sector_size = 512;
     149                 :          3 :         head = (struct spdk_gpt_header *)(gpt->buf + GPT_PRIMARY_PARTITION_TABLE_LBA * gpt->sector_size);
     150                 :          3 :         gpt->header = head;
     151                 :          3 :         to_le32(&head->num_partition_entries, 0x100);
     152                 :          3 :         re = gpt_read_partitions(gpt);
     153                 :          3 :         CU_ASSERT(re == -1);
     154                 :            : 
     155                 :            :         /* Set num_partition_entries within Max value, size_of_partition_entry mismatch */
     156                 :          3 :         to_le32(&head->header_crc32, 0x573857BE);
     157                 :          3 :         to_le32(&head->num_partition_entries, 0x40);
     158                 :          3 :         to_le32(&head->size_of_partition_entry, 0x0);
     159                 :          3 :         re = gpt_read_partitions(gpt);
     160                 :          3 :         CU_ASSERT(re == -1);
     161                 :            : 
     162                 :            :         /* Set size_of_partition_entry matched, partition_entry_lba mismatch */
     163                 :          3 :         to_le32(&head->header_crc32, 0x5279B712);
     164                 :          3 :         to_le32(&head->size_of_partition_entry, 0x80);
     165                 :          3 :         to_le64(&head->partition_entry_lba, 0x64);
     166                 :          3 :         re = gpt_read_partitions(gpt);
     167                 :          3 :         CU_ASSERT(re == -1);
     168                 :            : 
     169                 :            :         /* Set partition_entry_lba matched, partition_entry_array_crc32 mismatch */
     170                 :          3 :         to_le32(&head->header_crc32, 0xEC093B43);
     171                 :          3 :         to_le64(&head->partition_entry_lba, 0x20);
     172                 :          3 :         to_le32(&head->partition_entry_array_crc32, 0x0);
     173                 :          3 :         re = gpt_read_partitions(gpt);
     174                 :          3 :         CU_ASSERT(re == -1);
     175                 :            : 
     176                 :            :         /* Set partition_entry_array_crc32 matched, passing case */
     177                 :          3 :         to_le32(&head->header_crc32, 0xE1A08822);
     178                 :          3 :         to_le32(&head->partition_entry_array_crc32, 0xEBEE44FB);
     179                 :          3 :         to_le32(&head->num_partition_entries, 0x80);
     180                 :          3 :         re = gpt_read_partitions(gpt);
     181                 :          3 :         CU_ASSERT(re == 0);
     182                 :            : 
     183                 :          3 :         free(gpt);
     184                 :          3 : }
     185                 :            : 
     186                 :            : static void
     187                 :          3 : test_parse_mbr_and_primary(void)
     188                 :            : {
     189                 :            :         struct spdk_gpt *gpt;
     190                 :            :         struct spdk_mbr *mbr;
     191                 :            :         struct spdk_gpt_header *head;
     192                 :          3 :         unsigned char a[SPDK_GPT_BUFFER_SIZE];
     193                 :            :         int re;
     194                 :            : 
     195                 :            :         /* Set gpt is NULL */
     196                 :          3 :         re = gpt_parse_mbr(NULL);
     197                 :          3 :         CU_ASSERT(re == -1);
     198                 :            : 
     199                 :            :         /* Set gpt->buf is NULL */
     200                 :          3 :         gpt = calloc(1, sizeof(*gpt));
     201         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(gpt != NULL);
     202                 :          3 :         gpt->parse_phase = SPDK_GPT_PARSE_PHASE_PRIMARY;
     203                 :          3 :         gpt->sector_size = 512;
     204                 :          3 :         re = gpt_parse_mbr(gpt);
     205                 :          3 :         CU_ASSERT(re == -1);
     206                 :            : 
     207                 :            :         /* Set *gpt is "aaa...", check_mbr failed */
     208                 :          3 :         memset(a, 'a', sizeof(a));
     209                 :          3 :         gpt->buf = &a[0];
     210                 :          3 :         gpt->buf_size = sizeof(a);
     211                 :          3 :         re = gpt_parse_mbr(gpt);
     212                 :          3 :         CU_ASSERT(re == -1);
     213                 :            : 
     214                 :            :         /* Set check_mbr passed */
     215                 :          3 :         mbr = (struct spdk_mbr *)gpt->buf;
     216                 :          3 :         mbr->mbr_signature = 0xAA55;
     217                 :          3 :         mbr->partitions[0].start_lba = 1;
     218                 :          3 :         mbr->partitions[0].os_type = 0xEE;
     219                 :          3 :         mbr->partitions[0].size_lba = 0xFFFFFFFF;
     220                 :          3 :         re = gpt_parse_mbr(gpt);
     221                 :          3 :         CU_ASSERT(re == 0);
     222                 :            : 
     223                 :            :         /* Expect read_header failed */
     224                 :          3 :         re = gpt_parse_partition_table(gpt);
     225                 :          3 :         CU_ASSERT(re == -1);
     226                 :            : 
     227                 :            :         /* Set read_header passed, read_partitions failed */
     228                 :          3 :         head = (struct spdk_gpt_header *)(gpt->buf + GPT_PRIMARY_PARTITION_TABLE_LBA * gpt->sector_size);
     229                 :          3 :         head->header_size = sizeof(*head);
     230                 :          3 :         head->gpt_signature[0] = 'E';
     231                 :          3 :         head->gpt_signature[1] = 'F';
     232                 :          3 :         head->gpt_signature[2] = 'I';
     233                 :          3 :         head->gpt_signature[3] = ' ';
     234                 :          3 :         head->gpt_signature[4] = 'P';
     235                 :          3 :         head->gpt_signature[5] = 'A';
     236                 :          3 :         head->gpt_signature[6] = 'R';
     237                 :          3 :         head->gpt_signature[7] = 'T';
     238                 :          3 :         to_le32(&head->header_crc32, 0x5531F2F0);
     239                 :          3 :         to_le64(&head->my_lba, 0x1);
     240                 :          3 :         to_le64(&gpt->lba_start, 0x0);
     241                 :          3 :         to_le64(&gpt->lba_end, 0x2E935FFE);
     242                 :          3 :         to_le64(&head->first_usable_lba, 0xA);
     243                 :          3 :         to_le64(&head->last_usable_lba, 0xF4240);
     244                 :          3 :         re = gpt_parse_partition_table(gpt);
     245                 :          3 :         CU_ASSERT(re == -1);
     246                 :            : 
     247                 :            :         /* Set read_partitions passed, all passed */
     248                 :          3 :         to_le32(&head->size_of_partition_entry, 0x80);
     249                 :          3 :         to_le64(&head->partition_entry_lba, 0x20);
     250                 :          3 :         to_le32(&head->header_crc32, 0x845A09AA);
     251                 :          3 :         to_le32(&head->partition_entry_array_crc32, 0xEBEE44FB);
     252                 :          3 :         to_le32(&head->num_partition_entries, 0x80);
     253                 :          3 :         re = gpt_parse_partition_table(gpt);
     254                 :          3 :         CU_ASSERT(re == 0);
     255                 :            : 
     256                 :          3 :         free(gpt);
     257                 :          3 : }
     258                 :            : 
     259                 :            : static void
     260                 :          3 : test_parse_secondary(void)
     261                 :            : {
     262                 :            :         struct spdk_gpt *gpt;
     263                 :            :         struct spdk_gpt_header *head;
     264                 :          3 :         unsigned char a[SPDK_GPT_BUFFER_SIZE];
     265                 :            :         int re;
     266                 :            : 
     267                 :            :         /* gpt_parse_partition_table(NULL) does not exist, NULL is filtered out in gpt_parse_mbr() */
     268                 :          3 :         gpt = calloc(1, sizeof(*gpt));
     269         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(gpt != NULL);
     270                 :          3 :         gpt->parse_phase = SPDK_GPT_PARSE_PHASE_SECONDARY;
     271                 :          3 :         gpt->sector_size = 512;
     272                 :            : 
     273                 :            :         /* Set *gpt is "aaa...", read_header failed */
     274                 :          3 :         memset(a, 'a', sizeof(a));
     275                 :          3 :         gpt->buf = &a[0];
     276                 :          3 :         gpt->buf_size = sizeof(a);
     277                 :          3 :         re = gpt_parse_partition_table(gpt);
     278                 :          3 :         CU_ASSERT(re == -1);
     279                 :            : 
     280                 :            :         /* Set read_header passed, read_partitions failed */
     281                 :          3 :         head = (struct spdk_gpt_header *)(gpt->buf + gpt->buf_size - gpt->sector_size);
     282                 :          3 :         head->header_size = sizeof(*head);
     283                 :          3 :         head->gpt_signature[0] = 'E';
     284                 :          3 :         head->gpt_signature[1] = 'F';
     285                 :          3 :         head->gpt_signature[2] = 'I';
     286                 :          3 :         head->gpt_signature[3] = ' ';
     287                 :          3 :         head->gpt_signature[4] = 'P';
     288                 :          3 :         head->gpt_signature[5] = 'A';
     289                 :          3 :         head->gpt_signature[6] = 'R';
     290                 :          3 :         head->gpt_signature[7] = 'T';
     291                 :          3 :         to_le32(&head->header_crc32, 0xAA68A167);
     292                 :          3 :         to_le64(&head->my_lba, 0x63FFFFF);
     293                 :          3 :         to_le64(&gpt->lba_start, 0x0);
     294                 :          3 :         to_le64(&gpt->lba_end, 0x63FFFFF);
     295                 :          3 :         to_le64(&gpt->total_sectors, 0x6400000);
     296                 :          3 :         to_le64(&head->first_usable_lba, 0xA);
     297                 :          3 :         to_le64(&head->last_usable_lba, 0x63FFFDE);
     298                 :          3 :         re = gpt_parse_partition_table(gpt);
     299                 :          3 :         CU_ASSERT(re == -1);
     300                 :            : 
     301                 :            :         /* Set read_partitions passed, all passed */
     302                 :          3 :         to_le32(&head->size_of_partition_entry, 0x80);
     303                 :          3 :         to_le64(&head->partition_entry_lba, 0x63FFFDF);
     304                 :          3 :         to_le32(&head->header_crc32, 0x204129E8);
     305                 :          3 :         to_le32(&head->partition_entry_array_crc32, 0xEBEE44FB);
     306                 :          3 :         to_le32(&head->num_partition_entries, 0x80);
     307                 :          3 :         re = gpt_parse_partition_table(gpt);
     308                 :          3 :         CU_ASSERT(re == 0);
     309                 :            : 
     310                 :          3 :         free(gpt);
     311                 :          3 : }
     312                 :            : 
     313                 :            : int
     314                 :          3 : main(int argc, char **argv)
     315                 :            : {
     316                 :          3 :         CU_pSuite       suite = NULL;
     317                 :            :         unsigned int    num_failures;
     318                 :            : 
     319                 :          3 :         CU_initialize_registry();
     320                 :            : 
     321                 :          3 :         suite = CU_add_suite("gpt_parse", NULL, NULL);
     322                 :            : 
     323                 :          3 :         CU_ADD_TEST(suite, test_parse_mbr_and_primary);
     324                 :          3 :         CU_ADD_TEST(suite, test_parse_secondary);
     325                 :          3 :         CU_ADD_TEST(suite, test_check_mbr);
     326                 :          3 :         CU_ADD_TEST(suite, test_read_header);
     327                 :          3 :         CU_ADD_TEST(suite, test_read_partitions);
     328                 :            : 
     329                 :          3 :         num_failures = spdk_ut_run_tests(argc, argv, NULL);
     330                 :          3 :         CU_cleanup_registry();
     331                 :          3 :         return num_failures;
     332                 :            : }

Generated by: LCOV version 1.14