xref: /freebsd/contrib/netbsd-tests/sbin/gpt/t_gpt.sh (revision a4128aad8503277614f2d214011ef60a19447b83)
1# $NetBSD: t_gpt.sh,v 1.15 2016/03/08 08:04:48 joerg Exp $
2#
3# Copyright (c) 2015 The NetBSD Foundation, Inc.
4# All rights reserved.
5#
6# This code is derived from software contributed to The NetBSD Foundation
7# by Christos Zoulas
8#
9# Redistribution and use in source and binary forms, with or without
10# modification, are permitted provided that the following conditions
11# are met:
12# 1. Redistributions of source code must retain the above copyright
13#    notice, this list of conditions and the following disclaimer.
14# 2. Redistributions in binary form must reproduce the above copyright
15#    notice, this list of conditions and the following disclaimer in the
16#    documentation and/or other materials provided with the distribution.
17#
18# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
19# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
22# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28# POSSIBILITY OF SUCH DAMAGE.
29#
30
31bootblk=/usr/mdec/gptmbr.bin
32size=10240
33newsize=20480
34shdr=34
35disk=gpt.disk
36uuid="........-....-....-....-............"
37zero="00000000-0000-0000-0000-000000000000"
38src=$(atf_get_srcdir)
39
40silence() {
41	atf_check -s exit:0 -o empty -e empty "$@"
42}
43
44inline() {
45	local inline="$1"
46	shift
47	atf_check -s exit:0 -e empty -o inline:"$inline" "$@"
48}
49
50match() {
51	local match="$1"
52	shift
53	atf_check -s exit:0 -e empty -o match:"$match" "$@"
54}
55
56matcherr() {
57	local match="$1"
58	shift
59	atf_check -s exit:0 -o empty -e match:"$match" "$@"
60}
61
62file() {
63	local file="$1"
64	shift
65	atf_check -s exit:0 -e empty -o file:"$file" "$@"
66}
67
68save() {
69	local save="$1"
70	shift
71	atf_check -s exit:0 -e empty -o save:"$save" "$@"
72}
73
74zerodd() {
75	silence dd conv=notrunc msgfmt=quiet if=/dev/zero of="$disk" "$@"
76}
77
78prepare() {
79	rm -f "$disk"
80	zerodd seek="$size" count=1
81}
82
83prepare_2part() {
84	prepare
85	silence gpt create "$disk"
86	match "$(partaddmsg 1 34 1024)" gpt add -t efi -s 1024 "$disk"
87	match "$(partaddmsg 2 1058 9150)" gpt add "$disk"
88}
89
90# Calling this from tests does not work. BUG!
91check_2part() {
92	file "$src/gpt.2part.show.normal" gpt show "$disk"
93	file "$src/gpt.2part.show.uuid" gpt show -u "$disk"
94}
95
96partaddmsg() {
97	echo "^$disk: Partition $1 added: $uuid $2 $3\$"
98}
99
100partresmsg() {
101	echo "^$disk: Partition $1 resized: $2 $3\$"
102}
103
104partremmsg() {
105	echo "^$disk: Partition $1 removed\$"
106}
107
108partlblmsg() {
109	echo "^$disk: Partition $1 label changed\$"
110}
111
112partbootmsg() {
113	echo "^$disk: Partition $1 marked as bootable\$"
114}
115
116recovermsg() {
117	echo "^$disk: Recovered $1 GPT [a-z]* from $2\$"
118}
119
120migratemsg() {
121	echo -n "^gpt: $disk: Partition $1 unknown type MSDOS, "
122	echo 'using "Microsoft Basic Data"$'
123}
124
125attrmsg() {
126	echo "^$disk: Partition $1 attributes updated\$"
127}
128
129typemsg() {
130	echo "^$disk: Partition $1 type changed\$"
131}
132
133atf_test_case create_empty
134create_empty_head() {
135	atf_set "descr" "Create empty disk"
136}
137
138create_empty_body() {
139	prepare
140	silence gpt create "$disk"
141	file "$src/gpt.empty.show.normal" gpt show "$disk"
142}
143
144atf_test_case create_2part
145create_2part_head() {
146	atf_set "descr" "Create 2 partition disk"
147}
148
149create_2part_body() {
150	prepare_2part
151	check_2part
152}
153
154atf_test_case change_attr_2part
155change_attr_2part_head() {
156	atf_set "descr" "Change the attribute of 2 partition disk"
157}
158
159change_attr_2part_body() {
160	prepare_2part
161	match "$(attrmsg 1)" gpt set -i 1 -a biosboot,bootme "$disk"
162	save attr gpt show -i 1 "$disk"
163	match "^Attributes: biosboot, bootme\$" tail -1 attr
164	match "$(attrmsg 1)" gpt unset -i 1 -a biosboot,bootme "$disk"
165	save attr gpt show -i 1 "$disk"
166	match "^Attributes: None\$" tail -1 attr
167}
168
169atf_test_case change_type_2part
170change_type_2part_head() {
171	atf_set "descr" "Change the partition type type of 2 partition disk"
172}
173
174change_type_2part_body() {
175	prepare_2part
176	match "$(typemsg 1)" gpt type -i 1 -T apple "$disk"
177	save type gpt show -i 1 "$disk"
178	inline "Type: apple (48465300-0000-11aa-aa11-00306543ecac)\n" \
179	    grep "^Type:" type
180	match "$(typemsg 1)" gpt type -i 1 -T efi "$disk"
181	save type gpt show -i 1 "$disk"
182	inline "Type: efi (c12a7328-f81f-11d2-ba4b-00a0c93ec93b)\n" \
183	    grep "^Type:" type
184}
185
186atf_test_case backup_2part
187backup_2part_head() {
188	atf_set "descr" "Backup 2 partition disk"
189}
190
191backup_2part_body() {
192	prepare_2part
193	save test.backup gpt backup "$disk"
194	file "$src/gpt.backup" sed -e "s/$uuid/$zero/g" "test.backup"
195}
196
197atf_test_case restore_2part
198restore_2part_head() {
199	atf_set "descr" "Restore 2 partition disk"
200}
201
202restore_2part_body() {
203	prepare_2part
204	save test.backup gpt backup "$disk"
205	prepare
206	silence gpt restore -i test.backup "$disk"
207	check_2part
208}
209
210atf_test_case recover_backup
211recover_backup_head() {
212	atf_set "descr" "Recover the backup GPT header and table"
213}
214
215recover_backup_body() {
216	prepare_2part
217	zerodd seek="$((size - shdr))" count="$shdr"
218	match "$(recovermsg secondary primary)" gpt recover "$disk"
219	check_2part
220}
221
222atf_test_case recover_primary
223recover_primary_head() {
224	atf_set "descr" "Recover the primary GPT header and table"
225}
226
227recover_primary_body() {
228	prepare_2part
229	zerodd seek=1 count="$shdr"
230	match "$(recovermsg primary secondary)" gpt recover "$disk"
231	check_2part
232}
233
234atf_test_case resize_2part
235resize_2part_head() {
236	atf_set "descr" "Resize a 2 partition disk and partition"
237}
238
239resize_2part_body() {
240	prepare_2part
241	zerodd seek="$newsize" count=1
242	silence gpt resizedisk "$disk"
243	file "$src/gpt.resizedisk.show.normal" gpt show "$disk"
244	match "$(partresmsg 2 1058 19390)" gpt resize -i 2 "$disk"
245	file "$src/gpt.resizepart.show.normal" gpt show "$disk"
246}
247
248atf_test_case remove_2part
249remove_2part_head() {
250	atf_set "descr" "Remove a partition from a 2 partition disk"
251}
252
253remove_2part_body() {
254	prepare_2part
255	match "$(partremmsg 1)" -e empty gpt remove \
256	    -i 1 "$disk"
257	file "$src/gpt.removepart.show.normal" \
258	    gpt show "$disk"
259}
260
261atf_test_case label_2part
262label_2part_head() {
263	atf_set "descr" "Label partitions in a 2 partition disk"
264}
265
266label_2part_body() {
267	prepare_2part
268	match "$(partlblmsg 1)" gpt label -i 1 -l potato "$disk"
269	match "$(partlblmsg 2)" gpt label -i 2 -l tomato "$disk"
270	file "$src/gpt.2part.show.label" \
271	    gpt show -l "$disk"
272}
273
274atf_test_case bootable_2part
275bootable_2part_head() {
276	atf_set "descr" "Make partition 2 bootable in a 2 partition disk"
277	atf_set "require.files" "$bootblk"
278}
279
280bootable_2part_body() {
281	prepare_2part
282	match "$(partbootmsg 2)" gpt biosboot -i 2 "$disk"
283	local bootsz="$(ls -l "$bootblk" | awk '{ print $5 }')"
284	silence dd msgfmt=quiet if="$disk" of=bootblk bs=1 count="$bootsz"
285	silence cmp "$bootblk" bootblk
286	save bootattr gpt show -i 2 "$disk"
287	match "^Attributes: biosboot\$" tail -1 bootattr
288}
289
290atf_test_case migrate_disklabel
291migrate_disklabel_head() {
292	atf_set "descr" "Migrate an MBR+disklabel disk to GPT"
293}
294
295migrate_disklabel_body() {
296	prepare
297	silence fdisk -fi "$disk"
298	silence fdisk -fu0s "169/63/$((size / 10))" "$disk"
299	silence disklabel -R "$disk" "$src/gpt.disklabel"
300	matcherr "$(migratemsg 5)" gpt migrate "$disk"
301	file "$src/gpt.disklabel.show.normal" gpt show "$disk"
302}
303
304atf_init_test_cases() {
305	atf_add_test_case create_empty
306	atf_add_test_case create_2part
307	atf_add_test_case change_attr_2part
308	atf_add_test_case change_type_2part
309	atf_add_test_case backup_2part
310	atf_add_test_case remove_2part
311	atf_add_test_case restore_2part
312	atf_add_test_case recover_backup
313	atf_add_test_case recover_primary
314	atf_add_test_case resize_2part
315	atf_add_test_case label_2part
316	atf_add_test_case bootable_2part
317	atf_add_test_case migrate_disklabel
318}
319