run_cgpt_tests.sh 11 KB

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