forked from xen-project/xen
-
Notifications
You must be signed in to change notification settings - Fork 2
/
check-xl-vcpupin-parse
executable file
·294 lines (261 loc) · 9.04 KB
/
check-xl-vcpupin-parse
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
#!/bin/bash
set -e
if [ -x ./xl ] ; then
export LD_LIBRARY_PATH=.:../libxc:../xenstore:
XL=./xl
else
XL=xl
fi
fprefix=tmp.check-xl-vcpupin-parse
outfile=check-xl-vcpupin-parse.data
usage () {
cat <<END
usage: $0 [options]
Tests various vcpu-pinning strings. If run without arguments acts
as follows:
- generates some test data and saves them in $outfile;
- tests all the generated configurations (reading them back from
$outfile).
An example of a test vector file is provided in ${outfile}-example.
Options:
-h prints this message
-r seed uses seed for initializing the rundom number generator
(default: the script PID)
-s string tries using string as a vcpu pinning configuration and
reports whether that succeeds or not
-o ofile save the test data in ofile (default: $outfile)
-i ifile read test data from ifile
END
}
expected () {
cat >$fprefix.expected
}
# by default, re-seed with our PID
seed=$$
failures=0
# Execute one test and check the result against the provided
# rc value and output
one () {
expected_rc=$1; shift
printf "test case %s...\n" "$*"
set +e
${XL} -N vcpu-pin 0 all "$@" </dev/null >$fprefix.actual 2>/dev/null
actual_rc=$?
if [ $actual_rc != $expected_rc ]; then
diff -u $fprefix.expected $fprefix.actual
echo >&2 "test case \`$*' failed ($actual_rc $diff_rc)"
failures=$(( $failures + 1 ))
fi
set -e
}
# Write an entry in the test vector file. Format is as follows:
# test-string*expected-rc*expected-output
write () {
printf "$1*$2*$3\n" >> $outfile
}
complete () {
if [ "$failures" = 0 ]; then
echo all ok.; exit 0
else
echo "$failures tests failed."; exit 1
fi
}
# Test a specific pinning string
string () {
expected_rc=$1; shift
printf "test case %s...\n" "$*"
set +e
${XL} -N vcpu-pin 0 all "$@" &> /dev/null
actual_rc=$?
set -e
if [ $actual_rc != $expected_rc ]; then
echo >&2 "test case \`$*' failed ($actual_rc)"
else
echo >&2 "test case \`$*' succeeded"
fi
exit 0
}
# Read a test vector file (provided as $1) line by line and
# test all the entries it contains
run ()
{
while read line
do
if [ ${line:0:1} != '#' ]; then
test_string="`echo $line | cut -f1 -d'*'`"
exp_rc="`echo $line | cut -f2 -d'*'`"
exp_output="`echo $line | cut -f3 -d'*'`"
expected <<END
$exp_output
END
one $exp_rc "$test_string"
fi
done < $1
complete
exit 0
}
while getopts "hr:s:o:i:" option
do
case $option in
h)
usage
exit 0
;;
r)
seed=$OPTARG
;;
s)
string 0 "$OPTARG"
;;
o)
outfile=$OPTARG
;;
i)
run $OPTARG
;;
esac
done
#---------- test data ----------
#
nr_cpus=`xl info | grep nr_cpus | cut -f2 -d':'`
nr_nodes=`xl info | grep nr_nodes | cut -f2 -d':'`
nr_cpus_per_node=`xl info -n | sed '/cpu:/,/numa_info/!d' | head -n -1 | \
awk '{print $4}' | uniq -c | tail -1 | awk '{print $1}'`
cat >$outfile <<END
# WARNING: some of these tests are topology based tests.
# Expect failures if the topology is not detected correctly
# detected topology: $nr_cpus CPUs, $nr_nodes nodes, $nr_cpus_per_node CPUs per node.
#
# seed used for random number generation: seed=${seed}.
#
# Format is as follows:
# test-string*expected-return-code*expected-output
#
END
# Re-seed the random number generator
RANDOM=$seed
echo "# Testing a wrong configuration" >> $outfile
write foo 1 ""
echo "# Testing the 'all' syntax" >> $outfile
write "all" 0 "cpumap: all"
write "nodes:all" 0 "cpumap: all"
write "all,nodes:all" 0 "cpumap: all"
write "all,^nodes:0,all" 0 "cpumap: all"
echo "# Testing the empty cpumap case" >> $outfile
write "^0" 0 "cpumap: none"
echo "# A few attempts of pinning to just one random cpu" >> $outfile
if [ $nr_cpus -gt 1 ]; then
for i in `seq 0 3`; do
cpu=$(($RANDOM % nr_cpus))
write "$cpu" 0 "cpumap: $cpu"
done
fi
echo "# A few attempts of pinning to all but one random cpu" >> $outfile
if [ $nr_cpus -gt 2 ]; then
for i in `seq 0 3`; do
cpu=$(($RANDOM % nr_cpus))
if [ $cpu -eq 0 ]; then
expected_range="1-$((nr_cpus - 1))"
elif [ $cpu -eq 1 ]; then
expected_range="0,2-$((nr_cpus - 1))"
elif [ $cpu -eq $((nr_cpus - 2)) ]; then
expected_range="0-$((cpu - 1)),$((nr_cpus - 1))"
elif [ $cpu -eq $((nr_cpus - 1)) ]; then
expected_range="0-$((nr_cpus - 2))"
else
expected_range="0-$((cpu - 1)),$((cpu + 1))-$((nr_cpus - 1))"
fi
write "all,^$cpu" 0 "cpumap: $expected_range"
done
fi
echo "# A few attempts of pinning to a random range of cpus" >> $outfile
if [ $nr_cpus -gt 2 ]; then
for i in `seq 0 3`; do
cpua=$(($RANDOM % nr_cpus))
range=$((nr_cpus - cpua))
cpub=$(($RANDOM % range))
cpubb=$((cpua + cpub))
if [ $cpua -eq $cpubb ]; then
expected_range="$cpua"
else
expected_range="$cpua-$cpubb"
fi
write "$expected_range" 0 "cpumap: $expected_range"
done
fi
echo "# A few attempts of pinning to just one random node" >> $outfile
if [ $nr_nodes -gt 1 ]; then
for i in `seq 0 3`; do
node=$(($RANDOM % nr_nodes))
# this assumes that the first $nr_cpus_per_node (from cpu
# 0 to cpu $nr_cpus_per_node-1) are assigned to the first node
# (node 0), the second $nr_cpus_per_node (from $nr_cpus_per_node
# to 2*$nr_cpus_per_node-1) are assigned to the second node (node
# 1), etc. Expect failures if that is not the case.
write "nodes:$node" 0 "cpumap: $((nr_cpus_per_node*node))-$((nr_cpus_per_node*(node+1)-1))"
done
fi
echo "# A few attempts of pinning to all but one random node" >> $outfile
if [ $nr_nodes -gt 1 ]; then
for i in `seq 0 3`; do
node=$(($RANDOM % nr_nodes))
# this assumes that the first $nr_cpus_per_node (from cpu
# 0 to cpu $nr_cpus_per_node-1) are assigned to the first node
# (node 0), the second $nr_cpus_per_node (from $nr_cpus_per_node
# to 2*$nr_cpus_per_node-1) are assigned to the second node (node
# 1), etc. Expect failures if that is not the case.
if [ $node -eq 0 ]; then
expected_range="$nr_cpus_per_node-$((nr_cpus - 1))"
elif [ $node -eq $((nr_nodes - 1)) ]; then
expected_range="0-$((nr_cpus - nr_cpus_per_node - 1))"
else
expected_range="0-$((nr_cpus_per_node*node-1)),$((nr_cpus_per_node*(node+1)))-$nr_cpus"
fi
write "all,^nodes:$node" 0 "cpumap: $expected_range"
done
fi
echo "# A few attempts of pinning to a random range of nodes" >> $outfile
if [ $nr_nodes -gt 1 ]; then
for i in `seq 0 3`; do
nodea=$(($RANDOM % nr_nodes))
range=$((nr_nodes - nodea))
nodeb=$(($RANDOM % range))
nodebb=$((nodea + nodeb))
# this assumes that the first $nr_cpus_per_node (from cpu
# 0 to cpu $nr_cpus_per_node-1) are assigned to the first node
# (node 0), the second $nr_cpus_per_node (from $nr_cpus_per_node
# to 2*$nr_cpus_per_node-1) are assigned to the second node (node
# 1), etc. Expect failures if that is not the case.
if [ $nodea -eq 0 ] && [ $nodebb -eq $((nr_nodes - 1)) ]; then
expected_range="all"
else
expected_range="$((nr_cpus_per_node*nodea))-$((nr_cpus_per_node*(nodebb+1) - 1))"
fi
write "nodes:$nodea-$nodebb" 0 "cpumap: $expected_range"
done
fi
echo "# A few attempts of pinning to a node but excluding one random cpu" >> $outfile
if [ $nr_nodes -gt 1 ]; then
for i in `seq 0 3`; do
node=$(($RANDOM % nr_nodes))
# this assumes that the first $nr_cpus_per_node (from cpu
# 0 to cpu $nr_cpus_per_node-1) are assigned to the first node
# (node 0), the second $nr_cpus_per_node (from $nr_cpus_per_node
# to 2*$nr_cpus_per_node-1) are assigned to the second node (node
# 1), etc. Expect failures if that is not the case.
cpu=$(($RANDOM % nr_cpus_per_node + nr_cpus_per_node*node))
if [ $cpu -eq $((nr_cpus_per_node*node)) ]; then
expected_range="$((nr_cpus_per_node*node + 1))-$((nr_cpus_per_node*(node+1) - 1))"
elif [ $cpu -eq $((nr_cpus_per_node*node + 1)) ]; then
expected_range="$((nr_cpus_per_node*node)),$((nr_cpus_per_node*node + 2))-$((nr_cpus_per_node*(node+1) - 1))"
elif [ $cpu -eq $((nr_cpus_per_node*(node+1) - 2)) ]; then
expected_range="$((nr_cpus_per_node*node))-$((nr_cpus_per_node*(node+1) - 3)),$((nr_cpus_per_node*(node+1) - 1))"
elif [ $cpu -eq $((nr_cpus_per_node*(node+1) - 1)) ]; then
expected_range="$((nr_cpus_per_node*node))-$((nr_cpus_per_node*(node+1) - 2))"
else
expected_range="$((nr_cpus_per_node*node))-$((cpu - 1)),$((cpu + 1))-$((nr_cpus_per_node*(node+1) - 1))"
fi
write "nodes:$node,^$cpu" 0 "cpumap: $expected_range"
done
fi
run $outfile