forked from kubernetes-sigs/dra-driver-nvidia-gpu
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_gpu_updowngrade.bats
More file actions
234 lines (196 loc) · 9.51 KB
/
Copy pathtest_gpu_updowngrade.bats
File metadata and controls
234 lines (196 loc) · 9.51 KB
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
# shellcheck disable=SC2148
# shellcheck disable=SC2329
setup_file() {
load 'helpers.sh'
local _iargs=("--set" "logVerbosity=6")
iupgrade_wait "${TEST_CHART_REPO}" "${TEST_CHART_VERSION}" _iargs
}
# Executed before entering each test in this file.
setup() {
load 'helpers.sh'
_common_setup
log_objects
}
bats::on_failure() {
echo -e "\n\nFAILURE HOOK START"
log_objects
show_kubelet_plugin_error_logs
show_gpu_plugin_log_tails
echo -e "FAILURE HOOK END\n\n"
}
# bats test_tags=fastfeedback
@test "GPUs: upgrade: wipe-state, install-last-stable, upgrade-to-current-dev (simple GPU)" {
if [ "${MOCK_NVML:-}" = "true" ]; then skip "MOCK_NVML is set"; fi
# Stage 1: clean slate
helm uninstall "${TEST_HELM_RELEASE_NAME}" -n dra-driver-nvidia-gpu --wait --timeout=30s
kubectl wait --for=delete pods -A -l app.kubernetes.io/name=dra-driver-nvidia-gpu --timeout=10s
bash tests/bats/clean-state-dirs-all-nodes.sh
kubectl get crd computedomains.resource.nvidia.com
timeout -v 10 kubectl delete crd computedomains.resource.nvidia.com
# Stage 2: install last-stable (this guarantees to install the "old" CRD)
iupgrade_wait "${TEST_CHART_LASTSTABLE_REPO}" "${TEST_CHART_LASTSTABLE_VERSION}" NOARGS
# Stage 3: apply workload, do not delete (users care about old workloads to
# ideally still run, but at the very least be deletable after upgrade).
local _specpath="tests/bats/specs/gpu-simple-full.yaml"
local _podname="pod-full-gpu"
kubectl apply -f "${_specpath}"
kubectl wait --for=condition=READY pods "${_podname}" --timeout=8s
run kubectl logs "${_podname}"
assert_output --partial "UUID: GPU-"
echo "${output}" | wc -l | grep 1
# Capture the checkpoint content written by last-stable (valuable debug input
# if the checkpoint upgrade breaks).
local _node _kpod
_node=$(kubectl get pod "${_podname}" -o jsonpath='{.spec.nodeName}')
log "workload runs on node: ${_node}"
_kpod=$(kubectl get pods -n dra-driver-nvidia-gpu \
-l dra-driver-nvidia-gpu-component=kubelet-plugin \
--field-selector spec.nodeName="${_node}" \
-o jsonpath='{.items[0].metadata.name}')
log "kubelet-plugin pod on that node: ${_kpod}"
log "checkpoint.json written by last-stable:"
kubectl exec -n dra-driver-nvidia-gpu "${_kpod}" -c gpus -- \
cat /var/lib/kubelet/plugins/gpu.nvidia.com/checkpoint.json
echo
# Stage 4: update CRD, as a user would do.
kubectl apply -f "${CRD_UPGRADE_URL}"
# Stage 5: install target version (as users would do).
iupgrade_wait "${TEST_CHART_REPO}" "${TEST_CHART_VERSION}" NOARGS
# Stage 6: confirm deleting old workload works (critical, see above).
kubectl delete -f "${_specpath}"
kubectl wait --for=delete pods "${_podname}" --timeout=15s
# Stage 7: fresh create-confirm-delete workload cycle.
kubectl apply -f "${_specpath}"
kubectl wait --for=condition=READY pods "${_podname}" --timeout=8s
run kubectl logs "${_podname}"
assert_output --partial "UUID: GPU-"
kubectl delete -f "${_specpath}"
kubectl wait --for=delete pods "${_podname}" --timeout=15s
}
# bats test_tags=fastfeedback
@test "GPUs: upgrade: wipe-state, install-last-stable, upgrade-to-current-dev (DynMIG)" {
if [ "${MOCK_NVML:-}" = "true" ]; then skip "MOCK_NVML is set"; fi
# DynamicMIG must be enabled in both last-stable and current dev installs.
local _iargs=("--set" "featureGates.DynamicMIG=true")
mig_confirm_disabled_on_all_nodes
# Stage 1: clean slate
helm uninstall "${TEST_HELM_RELEASE_NAME}" -n dra-driver-nvidia-gpu --wait --timeout=30s
kubectl wait --for=delete pods -A -l app.kubernetes.io/name=dra-driver-nvidia-gpu --timeout=10s
bash tests/bats/clean-state-dirs-all-nodes.sh
kubectl get crd computedomains.resource.nvidia.com
timeout -v 10 kubectl delete crd computedomains.resource.nvidia.com
# Stage 2: install last-stable (this guarantees to install the "old" CRD)
iupgrade_wait "${TEST_CHART_LASTSTABLE_REPO}" "${TEST_CHART_LASTSTABLE_VERSION}" _iargs
# Stage 3: apply workload, do not delete (users care about old workloads to
# ideally still run, but at the very least be deletable after upgrade).
local _specpath="tests/bats/specs/gpu-simple-mig.yaml"
local _podname="pod-mig1g"
kubectl apply -f "${_specpath}"
kubectl wait --for=condition=READY pods "${_podname}" --timeout=15s
run kubectl logs "${_podname}"
assert_output --partial "UUID: MIG-"
assert_output --partial "UUID: GPU-"
echo "${output}" | wc -l | grep 2
# Capture the checkpoint content written by last-stable (valuable debug input
# if the checkpoint upgrade breaks).
local _node _kpod
_node=$(kubectl get pod "${_podname}" -o jsonpath='{.spec.nodeName}')
log "workload runs on node: ${_node}"
_kpod=$(kubectl get pods -n dra-driver-nvidia-gpu \
-l dra-driver-nvidia-gpu-component=kubelet-plugin \
--field-selector spec.nodeName="${_node}" \
-o jsonpath='{.items[0].metadata.name}')
log "kubelet-plugin pod on that node: ${_kpod}"
log "checkpoint.json written by last-stable:"
kubectl exec -n dra-driver-nvidia-gpu "${_kpod}" -c gpus -- \
cat /var/lib/kubelet/plugins/gpu.nvidia.com/checkpoint.json
echo
# Stage 4: update CRD, as a user would do.
kubectl apply -f "${CRD_UPGRADE_URL}"
# Stage 5: install target version (as users would do).
iupgrade_wait "${TEST_CHART_REPO}" "${TEST_CHART_VERSION}" _iargs
# Stage 6: confirm deleting old workload works (critical, see above).
kubectl delete -f "${_specpath}"
kubectl wait --for=delete pods "${_podname}" --timeout=15s
# After unprepare by the new binary: the GI/CI created by last-stable must be
# destroyed and MIG mode disabled.
mig_confirm_disabled_on_all_nodes
# Stage 7: fresh create-confirm-delete workload cycle.
kubectl apply -f "${_specpath}"
kubectl wait --for=condition=READY pods "${_podname}" --timeout=15s
run kubectl logs "${_podname}"
assert_output --partial "UUID: MIG-"
assert_output --partial "UUID: GPU-"
kubectl delete -f "${_specpath}"
kubectl wait --for=delete pods "${_podname}" --timeout=15s
# Confirm cleanup.
mig_confirm_disabled_on_all_nodes
}
# bats test_tags=fastfeedback
@test "GPUs: corrupted checkpoint leads to diff being logged" {
if [ "${MOCK_NVML:-}" = "true" ]; then skip "MOCK_NVML is set"; fi
# Stage 1: clean slate, install current dev. The plugin creates an empty
# checkpoint at first startup.
helm uninstall "${TEST_HELM_RELEASE_NAME}" -n dra-driver-nvidia-gpu --wait --timeout=30s
kubectl wait --for=delete pods -A -l app.kubernetes.io/name=dra-driver-nvidia-gpu --timeout=10s
bash tests/bats/clean-state-dirs-all-nodes.sh
kubectl get crd computedomains.resource.nvidia.com
timeout -v 10 kubectl delete crd computedomains.resource.nvidia.com
iupgrade_wait "${TEST_CHART_REPO}" "${TEST_CHART_VERSION}" NOARGS
# Stage 2: pick any kubelet plugin pod.
local _kpod _node
_kpod=$(kubectl get pods -n dra-driver-nvidia-gpu \
-l dra-driver-nvidia-gpu-component=kubelet-plugin \
-o jsonpath='{.items[0].metadata.name}')
_node=$(kubectl get pod -n dra-driver-nvidia-gpu "${_kpod}" -o jsonpath='{.spec.nodeName}')
log "targeting plugin pod ${_kpod} on node ${_node}"
# Stage 3: two independent mutations to v2, both in one sed:
# 1) Zero v2's checksum -- this trips the error.
# 2) Insert a dummy unknown field -- this shows up in the diff. We
# want to confirm that the diff shows a field that is not
# contained in both JSON documents.
# Inserting only an unknown field passes verification (the deserializer
# drops it, so the recomputed checksum still matches), so the checksum
# mutation is also required to exercise the diagnostic path.
kubectl exec -n dra-driver-nvidia-gpu "${_kpod}" -c gpus -- sh -c '
set -ex
CP=/var/lib/kubelet/plugins/gpu.nvidia.com/checkpoint.json
echo "BEFORE:" && cat "$CP" && echo
sed -i "s/\"v2\":{\"checksum\":[0-9]*/\"v2\":{\"checksum\":0,\"dummy\":\"this-should-show-in-diff\"/" "$CP"
echo "AFTER:" && cat "$CP" && echo
'
# Stage 4: bounce the plugin pod so it re-reads the corrupted file at
# startup. The daemonset creates a replacement with a new name.
kubectl delete pod -n dra-driver-nvidia-gpu "${_kpod}"
local _newkpod="" _deadline=$((SECONDS + 60))
while true; do
_newkpod=$(kubectl get pods -n dra-driver-nvidia-gpu \
-l dra-driver-nvidia-gpu-component=kubelet-plugin \
--field-selector spec.nodeName="${_node}" \
-o jsonpath='{.items[0].metadata.name}' 2>/dev/null) || true
if [ -n "${_newkpod}" ] && [ "${_newkpod}" != "${_kpod}" ]; then
break
fi
(( SECONDS > _deadline )) && { echo "timeout waiting for replacement pod"; return 1; }
sleep 1
done
log "replacement kubelet-plugin pod: ${_newkpod}"
# Stage 5: poll for the diagnostic log line in the new pod's logs.
_deadline=$((SECONDS + 60))
while ! kubectl logs -n dra-driver-nvidia-gpu "${_newkpod}" -c gpus 2>/dev/null \
| grep -q "checkpoint failed checksum verification; unified diff"; do
if (( SECONDS > _deadline )); then
echo "timeout waiting for unified diff log line"
kubectl logs -n dra-driver-nvidia-gpu "${_newkpod}" -c gpus | tail -100 || true
return 1
fi
sleep 2
done
run kubectl logs -n dra-driver-nvidia-gpu "${_newkpod}" -c gpus
assert_output --partial "checkpoint failed checksum verification; unified diff"
assert_output --partial "dummy"
# Stage 6: cleanup. Wipe kubelet plugin state dirs to delete the corrupted
# checkpoint, then helm uninstall.
bash tests/bats/clean-state-dirs-all-nodes.sh
helm uninstall "${TEST_HELM_RELEASE_NAME}" -n dra-driver-nvidia-gpu --wait --timeout=30s || true
}