1 #!/bin/bash -eu 2 3 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. 4 # Use of this source code is governed by a BSD-style license that can be 5 # found in the LICENSE file. 6 # 7 # Run tests for cgpt utility. 8 9 # Load common constants and variables. 10 . "$(dirname "$0")/common.sh" 11 12 CGPT=$(readlink -f "$1") 13 [ -x "$CGPT" ] || error "Can't execute $CGPT" 14 15 MTD="${@:2}" 16 17 # Run tests in a dedicated directory for easy cleanup or debugging. 18 DIR="${TEST_DIR}/cgpt_test_dir" 19 [ -d "$DIR" ] || mkdir -p "$DIR" 20 warning "testing $CGPT in $DIR" 21 cd "$DIR" 22 23 assert_fail() { 24 set +e 25 "$@" 2>/dev/null 26 if [ $? == 0 ]; then 27 error "$*" " should have failed but did not" 28 fi 29 set -e 30 } 31 32 # Test failure on non existing file. 33 assert_fail ${CGPT} show $MTD blah_404_haha 34 35 echo "Create an empty file to use as the device..." 36 NUM_SECTORS=1000 37 DEV=fake_dev.bin 38 rm -f ${DEV} 39 dd if=/dev/zero of=${DEV} conv=notrunc bs=512 count=${NUM_SECTORS} 2>/dev/null 40 41 42 echo "Create a bunch of partitions, using the real GUID types..." 43 DATA_START=100 44 DATA_SIZE=20 45 DATA_LABEL="data stuff" 46 DATA_GUID='ebd0a0a2-b9e5-4433-87c0-68b6b72699c7' 47 DATA_NUM=1 48 49 KERN_START=200 50 KERN_SIZE=30 51 KERN_LABEL="kernel stuff" 52 KERN_GUID='fe3a2a5d-4f32-41a7-b725-accc3285a309' 53 KERN_NUM=2 54 55 ROOTFS_START=300 56 ROOTFS_SIZE=40 57 ROOTFS_LABEL="rootfs stuff" 58 ROOTFS_GUID='3cb8e202-3b7e-47dd-8a3c-7ff2a13cfcec' 59 ROOTFS_NUM=3 60 61 ESP_START=400 62 ESP_SIZE=50 63 ESP_LABEL="ESP stuff" 64 ESP_GUID='c12a7328-f81f-11d2-ba4b-00a0c93ec93b' 65 ESP_NUM=4 66 67 FUTURE_START=500 68 FUTURE_SIZE=60 69 FUTURE_LABEL="future stuff" 70 FUTURE_GUID='2e0a753d-9e48-43b0-8337-b15192cb1b5e' 71 FUTURE_NUM=5 72 73 RANDOM_START=600 74 RANDOM_SIZE=70 75 RANDOM_LABEL="random stuff" 76 RANDOM_GUID='2364a860-bf63-42fb-a83d-9ad3e057fcf5' 77 RANDOM_NUM=6 78 79 $CGPT create $MTD ${DEV} 80 81 $CGPT add $MTD -b ${DATA_START} -s ${DATA_SIZE} -t ${DATA_GUID} \ 82 -l "${DATA_LABEL}" ${DEV} 83 $CGPT add $MTD -b ${KERN_START} -s ${KERN_SIZE} -t ${KERN_GUID} \ 84 -l "${KERN_LABEL}" ${DEV} 85 $CGPT add $MTD -b ${ROOTFS_START} -s ${ROOTFS_SIZE} -t ${ROOTFS_GUID} \ 86 -l "${ROOTFS_LABEL}" ${DEV} 87 $CGPT add $MTD -b ${ESP_START} -s ${ESP_SIZE} -t ${ESP_GUID} \ 88 -l "${ESP_LABEL}" ${DEV} 89 $CGPT add $MTD -b ${FUTURE_START} -s ${FUTURE_SIZE} -t ${FUTURE_GUID} \ 90 -l "${FUTURE_LABEL}" ${DEV} 91 $CGPT add $MTD -b ${RANDOM_START} -s ${RANDOM_SIZE} -t ${RANDOM_GUID} \ 92 -l "${RANDOM_LABEL}" ${DEV} 93 94 95 echo "Extract the start and size of given partitions..." 96 97 X=$($CGPT show $MTD -b -i $DATA_NUM ${DEV}) 98 Y=$($CGPT show $MTD -s -i $DATA_NUM ${DEV}) 99 [ "$X $Y" = "$DATA_START $DATA_SIZE" ] || error 100 101 X=$($CGPT show $MTD -b -i $KERN_NUM ${DEV}) 102 Y=$($CGPT show $MTD -s -i $KERN_NUM ${DEV}) 103 [ "$X $Y" = "$KERN_START $KERN_SIZE" ] || error 104 105 X=$($CGPT show $MTD -b -i $ROOTFS_NUM ${DEV}) 106 Y=$($CGPT show $MTD -s -i $ROOTFS_NUM ${DEV}) 107 [ "$X $Y" = "$ROOTFS_START $ROOTFS_SIZE" ] || error 108 109 X=$($CGPT show $MTD -b -i $ESP_NUM ${DEV}) 110 Y=$($CGPT show $MTD -s -i $ESP_NUM ${DEV}) 111 [ "$X $Y" = "$ESP_START $ESP_SIZE" ] || error 112 113 X=$($CGPT show $MTD -b -i $FUTURE_NUM ${DEV}) 114 Y=$($CGPT show $MTD -s -i $FUTURE_NUM ${DEV}) 115 [ "$X $Y" = "$FUTURE_START $FUTURE_SIZE" ] || error 116 117 X=$($CGPT show $MTD -b -i $RANDOM_NUM ${DEV}) 118 Y=$($CGPT show $MTD -s -i $RANDOM_NUM ${DEV}) 119 [ "$X $Y" = "$RANDOM_START $RANDOM_SIZE" ] || error 120 121 122 echo "Change the beginning..." 123 DATA_START=$((DATA_START + 10)) 124 $CGPT add $MTD -i 1 -b ${DATA_START} ${DEV} || error 125 X=$($CGPT show $MTD -b -i 1 ${DEV}) 126 [ "$X" = "$DATA_START" ] || error 127 128 echo "Change the size..." 129 DATA_SIZE=$((DATA_SIZE + 10)) 130 $CGPT add $MTD -i 1 -s ${DATA_SIZE} ${DEV} || error 131 X=$($CGPT show $MTD -s -i 1 ${DEV}) 132 [ "$X" = "$DATA_SIZE" ] || error 133 134 echo "Change the type..." 135 $CGPT add $MTD -i 1 -t reserved ${DEV} || error 136 X=$($CGPT show $MTD -t -i 1 ${DEV} | tr 'A-Z' 'a-z') 137 [ "$X" = "$FUTURE_GUID" ] || error 138 # arbitrary value 139 $CGPT add $MTD -i 1 -t 610a563a-a55c-4ae0-ab07-86e5bb9db67f ${DEV} || error 140 X=$($CGPT show $MTD -t -i 1 ${DEV}) 141 [ "$X" = "610A563A-A55C-4AE0-AB07-86E5BB9DB67F" ] || error 142 143 $CGPT add $MTD -i 1 -t data ${DEV} || error 144 X=$($CGPT show $MTD -t -i 1 ${DEV} | tr 'A-Z' 'a-z') 145 [ "$X" = "$DATA_GUID" ] || error 146 147 148 echo "Set the boot partition.." 149 $CGPT boot $MTD -i ${KERN_NUM} ${DEV} >/dev/null 150 151 echo "Check the PMBR's idea of the boot partition..." 152 X=$($CGPT boot $MTD ${DEV}) 153 Y=$($CGPT show $MTD -u -i $KERN_NUM $DEV) 154 [ "$X" = "$Y" ] || error 155 156 echo "Test the cgpt prioritize command..." 157 158 # Input: sequence of priorities 159 # Output: ${DEV} has kernel partitions with the given priorities 160 make_pri() { 161 local idx=0 162 $CGPT create $MTD ${DEV} 163 for pri in "$@"; do 164 idx=$((idx+1)) 165 $CGPT add $MTD -t kernel -l "kern$idx" -b $((100 + 2 * $idx)) -s 1 -P $pri ${DEV} 166 done 167 } 168 169 # Output: returns string containing priorities of all kernels 170 get_pri() { 171 echo $( 172 for idx in $($CGPT find $MTD -t kernel ${DEV} | sed -e s@${DEV}@@); do 173 $CGPT show $MTD -i $idx -P ${DEV} 174 done 175 ) 176 } 177 178 # Input: list of priorities 179 # Operation: expects ${DEV} to contain those kernel priorities 180 assert_pri() { 181 local expected="$*" 182 local actual=$(get_pri) 183 [ "$actual" = "$expected" ] || \ 184 error 1 "expected priority \"$expected\", actual priority \"$actual\"" 185 } 186 187 # no kernels at all. This should do nothing. 188 $CGPT create $MTD ${DEV} 189 $CGPT add $MTD -t rootfs -b 100 -s 1 ${DEV} 190 $CGPT prioritize $MTD ${DEV} 191 assert_pri "" 192 193 # common install/upgrade sequence 194 make_pri 2 0 0 195 $CGPT prioritize $MTD -i 1 ${DEV} 196 assert_pri 1 0 0 197 $CGPT prioritize $MTD -i 2 ${DEV} 198 assert_pri 1 2 0 199 $CGPT prioritize $MTD -i 1 ${DEV} 200 assert_pri 2 1 0 201 $CGPT prioritize $MTD -i 2 ${DEV} 202 assert_pri 1 2 0 203 # lots of kernels, all same starting priority, should go to priority 1 204 make_pri 8 8 8 8 8 8 8 8 8 8 8 0 0 8 205 $CGPT prioritize $MTD ${DEV} 206 assert_pri 1 1 1 1 1 1 1 1 1 1 1 0 0 1 207 208 # now raise them all up again 209 $CGPT prioritize $MTD -P 4 ${DEV} 210 assert_pri 4 4 4 4 4 4 4 4 4 4 4 0 0 4 211 212 # set one of them higher, should leave the rest alone 213 $CGPT prioritize $MTD -P 5 -i 3 ${DEV} 214 assert_pri 4 4 5 4 4 4 4 4 4 4 4 0 0 4 215 216 # set one of them lower, should bring the rest down 217 $CGPT prioritize $MTD -P 3 -i 4 ${DEV} 218 assert_pri 1 1 2 3 1 1 1 1 1 1 1 0 0 1 219 220 # raise a group by including the friends of one partition 221 $CGPT prioritize $MTD -P 6 -i 1 -f ${DEV} 222 assert_pri 6 6 4 5 6 6 6 6 6 6 6 0 0 6 223 224 # resurrect one, should not affect the others 225 make_pri 0 0 0 0 0 0 0 0 0 0 0 0 0 0 226 $CGPT prioritize $MTD -i 2 ${DEV} 227 assert_pri 0 1 0 0 0 0 0 0 0 0 0 0 0 0 228 229 # resurrect one and all its friends 230 make_pri 0 0 0 0 0 0 0 0 1 2 0 0 0 0 231 $CGPT prioritize $MTD -P 5 -i 2 -f ${DEV} 232 assert_pri 5 5 5 5 5 5 5 5 3 4 5 5 5 5 233 234 # no options should maintain the same order 235 $CGPT prioritize $MTD ${DEV} 236 assert_pri 3 3 3 3 3 3 3 3 1 2 3 3 3 3 237 238 # squish all the ranks 239 make_pri 1 1 2 2 3 3 4 4 5 5 0 6 7 7 240 $CGPT prioritize $MTD -P 6 ${DEV} 241 assert_pri 1 1 1 1 2 2 3 3 4 4 0 5 6 6 242 243 # squish the ranks by not leaving room 244 make_pri 1 1 2 2 3 3 4 4 5 5 0 6 7 7 245 $CGPT prioritize $MTD -P 7 -i 3 ${DEV} 246 assert_pri 1 1 7 1 2 2 3 3 4 4 0 5 6 6 247 248 # squish the ranks while bringing the friends along 249 make_pri 1 1 2 2 3 3 4 4 5 5 0 6 7 7 250 $CGPT prioritize $MTD -P 6 -i 3 -f ${DEV} 251 assert_pri 1 1 6 6 1 1 2 2 3 3 0 4 5 5 252 253 # squish them pretty hard 254 make_pri 1 1 2 2 3 3 4 4 5 5 0 6 7 7 255 $CGPT prioritize $MTD -P 2 ${DEV} 256 assert_pri 1 1 1 1 1 1 1 1 1 1 0 1 2 2 257 258 # squish them really really hard (nobody gets reduced to zero, though) 259 make_pri 1 1 2 2 3 3 4 4 5 5 0 6 7 7 260 $CGPT prioritize $MTD -P 1 -i 3 ${DEV} 261 assert_pri 1 1 1 1 1 1 1 1 1 1 0 1 1 1 262 263 make_pri 15 15 14 14 13 13 12 12 11 11 10 10 9 9 8 8 7 7 6 6 5 5 4 4 3 3 2 2 1 1 0 264 $CGPT prioritize $MTD -i 3 ${DEV} 265 assert_pri 14 14 15 13 12 12 11 11 10 10 9 9 8 8 7 7 6 6 5 5 4 4 3 3 2 2 1 1 1 1 0 266 $CGPT prioritize $MTD -i 5 ${DEV} 267 assert_pri 13 13 14 12 15 11 10 10 9 9 8 8 7 7 6 6 5 5 4 4 3 3 2 2 1 1 1 1 1 1 0 268 # but if I bring friends I don't have to squish 269 $CGPT prioritize $MTD -i 1 -f ${DEV} 270 assert_pri 15 15 13 12 14 11 10 10 9 9 8 8 7 7 6 6 5 5 4 4 3 3 2 2 1 1 1 1 1 1 0 271 272 # Now make sure that we don't need write access if we're just looking. 273 echo "Test read vs read-write access..." 274 chmod 0444 ${DEV} 275 276 # These should fail 277 $CGPT create $MTD -z ${DEV} 2>/dev/null && error 278 $CGPT add $MTD -i 2 -P 3 ${DEV} 2>/dev/null && error 279 $CGPT repair $MTD ${DEV} 2>/dev/null && error 280 $CGPT prioritize $MTD -i 3 ${DEV} 2>/dev/null && error 281 282 # Most 'boot' usage should fail too. 283 $CGPT boot $MTD -p ${DEV} 2>/dev/null && error 284 dd if=/dev/zero of=fake_mbr.bin bs=100 count=1 2>/dev/null 285 $CGPT boot $MTD -b fake_mbr.bin ${DEV} 2>/dev/null && error 286 $CGPT boot $MTD -i 2 ${DEV} 2>/dev/null && error 287 288 $CGPT boot $MTD ${DEV} >/dev/null 289 $CGPT show $MTD ${DEV} >/dev/null 290 $CGPT find $MTD -t kernel ${DEV} >/dev/null 291 292 # Enable write access again to test boundary in off device storage 293 chmod 600 ${DEV} 294 # GPT too small 295 dd if=/dev/zero of=${DEV} bs=5632 count=1 296 assert_fail $CGPT create -D 1024 ${DEV} 297 # GPT is just right for 16 entries (512 + 512 + 16 * 128) * 2 = 6144 298 dd if=/dev/zero of=${DEV} bs=6144 count=1 299 $CGPT create -D 1024 ${DEV} 300 # Create a small 8K file to simulate Flash NOR section 301 dd if=/dev/zero of=${DEV} bs=8K count=1 302 # Drive size is not multiple of 512 303 assert_fail $CGPT create -D 511 ${DEV} 304 assert_fail $CGPT create -D 513 ${DEV} 305 MTD="-D 1024" 306 # Create a GPT table for a device of 1024 bytes (2 sectors) 307 $CGPT create $MTD ${DEV} 308 # Make sure number of entries is reasonable for 8KiB GPT 309 X=$($CGPT show -D 1024 -d ${DEV} | grep -c "Number of entries: 24") 310 [ "$X" = "2" ] || error 311 # This fails because header verification is off due to different drive size 312 assert_fail $CGPT show ${DEV} 313 # But this passes because we pass in correct drive size 314 $CGPT show $MTD ${DEV} 315 # This fails because beginning sector is over the size of the device 316 assert_fail $CGPT add $MTD -b 2 -s 1 -t data ${DEV} 317 # This fails because partition size is over the size of the device 318 assert_fail $CGPT add $MTD -b 0 -s 3 -t data ${DEV} 319 320 321 echo "Done." 322 323 happy "All tests passed." 324