summaryrefslogtreecommitdiffstats
path: root/src/spdk/test/dd/posix.sh
blob: 15346d8d3f3ab403cff313e2e8f1e9b0999fb939 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#!/usr/bin/env bash
testdir=$(readlink -f "$(dirname "$0")")
rootdir=$(readlink -f "$testdir/../../")
source "$testdir/common.sh"

cleanup() {
	rm -f "$test_file0"{,.link}
	rm -f "$test_file1"{,.link}
}

append() {
	local dump0
	local dump1

	dump0=$(gen_bytes 32)
	dump1=$(gen_bytes 32)

	printf '%s' "$dump0" > "$test_file0"
	printf '%s' "$dump1" > "$test_file1"

	"${DD_APP[@]}" --if="$test_file0" --of="$test_file1" --oflag=append

	[[ $(< "$test_file1") == "${dump1}${dump0}" ]]
}

directory() {
	NOT "${DD_APP[@]}" --if="$test_file0" --iflag=directory --of="$test_file0"
	NOT "${DD_APP[@]}" --if="$test_file0" --of="$test_file0" --oflag=directory
}

nofollow() {
	local test_file0_link=$test_file0.link
	local test_file1_link=$test_file1.link

	ln -fs "$test_file0" "$test_file0_link"
	ln -fs "$test_file1" "$test_file1_link"

	NOT "${DD_APP[@]}" --if="$test_file0_link" --iflag=nofollow --of="$test_file1"
	NOT "${DD_APP[@]}" --if="$test_file0" --of="$test_file1_link" --oflag=nofollow

	# Do an extra step of checking if we actually can follow symlinks
	gen_bytes 512 > "$test_file0"

	"${DD_APP[@]}" --if="$test_file0_link" --of="$test_file1"
	[[ $(< "$test_file0") == "$(< "$test_file1")" ]]
}

noatime() {
	local atime_if
	local atime_of

	# It seems like spdk_dd doesn't update the atime in case 0 bytes are copied.
	# This differs from how standard dd works for instance
	gen_bytes 512 > "$test_file0"

	atime_if=$(stat --printf="%X" "$test_file0")
	atime_of=$(stat --printf="%X" "$test_file1")

	"${DD_APP[@]}" --if="$test_file0" --iflag=noatime --of="$test_file1"
	((atime_if == $(stat --printf="%X" "$test_file0")))
	((atime_of == $(stat --printf="%X" "$test_file1")))

	"${DD_APP[@]}" --if="$test_file0" --of="$test_file1"
	((atime_if < $(stat --printf="%X" "$test_file0")))
}

io() {
	local flags_ro flags_rw flag_ro flag_rw

	# O_NONBLOCK is actually a no-op, from a functional perspective, while
	# open()ing a regular file, but let's keep it just to test its usage.
	flags_ro=(direct nonblock)
	flags_rw=("${flags_ro[@]}" sync dsync)

	# simply check if data was correctly copied between files
	for flag_ro in "${flags_ro[@]}"; do
		gen_bytes 512 > "$test_file0"
		for flag_rw in "${flags_rw[@]}"; do
			"${DD_APP[@]}" \
				--if="$test_file0" \
				--iflag="$flag_ro" \
				--of="$test_file1" \
				--oflag="$flag_rw"
			[[ $(< "$test_file0") == "$(< "$test_file1")" ]]
		done
	done
}

tests() {
	printf '* First test run%s\n' \
		"${msg[liburing_in_use]}" >&2

	run_test "dd_flag_append" append
	run_test "dd_flag_directory" directory
	run_test "dd_flag_nofollow" nofollow
	run_test "dd_flag_noatime" noatime
	run_test "dd_flags_misc" io
}

tests_forced_aio() {
	printf '* Second test run%s\n' \
		"${msg[liburing_in_use ? 2 : 0]}" >&2

	DD_APP+=("--aio")
	run_test "dd_flag_append_forced_aio" append
	run_test "dd_flag_directory_forced_aio" directory
	run_test "dd_flag_nofollow_forced_aio" nofollow
	run_test "dd_flag_noatime_forced_aio" noatime
	run_test "dd_flags_misc_forced_aio" io
}

msg[0]=", using AIO"
msg[1]=", liburing in use"
msg[2]=", disabling liburing, forcing AIO"

trap "cleanup" EXIT

test_file0=$SPDK_TEST_STORAGE/dd.dump0
test_file1=$SPDK_TEST_STORAGE/dd.dump1

tests
tests_forced_aio