Skip to content

Commit 97f9d03

Browse files
committed
Debugging an e2e test with delve
1 parent 08b22fe commit 97f9d03

File tree

1 file changed

+117
-0
lines changed

1 file changed

+117
-0
lines changed

contributors/devel/sig-testing/e2e-tests.md

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
- [Extracting a specific version of Kubernetes](#extracting-a-specific-version-of-kubernetes)
1111
- [Bringing up a cluster for testing](#bringing-up-a-cluster-for-testing)
1212
- [Debugging clusters](#debugging-clusters)
13+
- [Debugging an E2E test with a debugger (delve)](#debugging-an-e2e-test-with-a-debugger-delve)
1314
- [Local clusters](#local-clusters)
1415
- [Testing against local clusters](#testing-against-local-clusters)
1516
- [Version-skewed and upgrade testing](#version-skewed-and-upgrade-testing)
@@ -229,6 +230,7 @@ stale permissions can cause problems.
229230
- `sudo iptables -F`, clear ip tables rules left by the kube-proxy.
230231

231232
### Reproducing failures in flaky tests
233+
232234
You can run a test repeatedly until it fails. This is useful when debugging
233235
flaky tests. In order to do so, you need to set the following environment
234236
variable:
@@ -259,6 +261,121 @@ the provided directory (which should already exist).
259261
The Google-run Jenkins builds automatically collected these logs for every
260262
build, saving them in the `artifacts` directory uploaded to GCS.
261263

264+
### Debugging an E2E test with a debugger (delve)
265+
266+
When debugging E2E tests it's sometimes useful to pause in the middle of an E2E test
267+
to check the value of a variable or to check something in the cluster, instead of adding
268+
`time.Sleep(...)` we can run the E2E test with `delve`
269+
270+
Requirements:
271+
272+
- delve (https://github.com/go-delve/delve/tree/master/Documentation/installation)
273+
274+
For this example we'll debug a [sig-storage test that will provision storage from a snapshot](https://github.com/kubernetes/kubernetes/blob/3ed71cf190a3d6a6dcb965cf73224538059e8e5e/test/e2e/storage/testsuites/provisioning.go#L200-L236)
275+
276+
First, compile the E2E test suite with additional compiler flags
277+
278+
```sh
279+
# -N Disable optimizations.
280+
# -l Disable inlining.
281+
make WHAT=test/e2e/e2e.test GOGCFLAGS="all=-N -l" GOLDFLAGS=""
282+
```
283+
284+
Then set the env var `E2E_TEST_DEBUG_TOOL=delve` and then run the test with `./hack/gingko.sh` instead of `kubetest`, you should see the delve command line prompt
285+
286+
```sh
287+
E2E_TEST_DEBUG_TOOL=delve ./hack/ginkgo-e2e.sh --ginkgo.focus="sig-storage.*csi-hostpath.*Dynamic.PV.*default.fs.*provisioning.should.provision.storage.with.snapshot.data.source" --allowed-not-ready-nodes=10
288+
---
289+
Setting up for KUBERNETES_PROVIDER="gce".
290+
Project: ...
291+
Network Project: ...
292+
Zone: ...
293+
Trying to find master named '...'
294+
Looking for address '...'
295+
Using master: ... (external IP: XX.XXX.XXX.XX; internal IP: (not set))
296+
Type 'help' for list of commands.
297+
(dlv)
298+
```
299+
300+
Use the commands described in the [delve command lists](https://github.com/go-delve/delve/blob/master/Documentation/cli/README.md), for our example we'll set a breakpoint at the start of the method
301+
302+
```sh
303+
(dlv) break test/e2e/storage/testsuites/provisioning.go:201
304+
Breakpoint 1 set at 0x72856f2 for k8s.io/kubernetes/test/e2e/storage/testsuites.(*provisioningTestSuite).DefineTests.func4() _output/local/go/src/k8s.io/kubernetes/test/e2e/storage/testsuites/provisioning.go:201
305+
```
306+
307+
When you're done setting breakpoints execute `continue` to continue the test, once the breakpoint hits you have the chance to explore variables in the test
308+
309+
```sh
310+
(dlv) continue
311+
Apr 16 20:29:18.724: INFO: Fetching cloud provider for "gce"
312+
I0416 20:29:18.725327 3669683 gce.go:909] Using DefaultTokenSource &oauth2.reuseTokenSource{new:(*oauth2.tokenRefresher)(0xc002b65d10), mu:sync.Mutex{state:0, sema:0x0}, t:(*oauth2.Token)(0xc0028e43c0)}
313+
W0416 20:29:18.891866 3669683 gce.go:477] No network name or URL specified.
314+
I0416 20:29:18.892058 3669683 e2e.go:129] Starting e2e run "ae1b58af-9e9e-4745-b1f4-27d763451f8e" on Ginkgo node 1
315+
{"msg":"Test Suite starting","total":1,"completed":0,"skipped":0,"failed":0}
316+
Running Suite: Kubernetes e2e suite
317+
===================================
318+
Random Seed: 1618604956 - Will randomize all specs
319+
Will run 1 of 5745 specs
320+
...
321+
------------------------------
322+
[sig-storage] CSI Volumes [Driver: csi-hostpath] [Testpattern: Dynamic PV (default fs)] provisioning
323+
should provision storage with snapshot data source [Feature:VolumeSnapshotDataSource]
324+
_output/local/go/src/k8s.io/kubernetes/test/e2e/storage/testsuites/provisioning.go:200
325+
[BeforeEach] [Testpattern: Dynamic PV (default fs)] provisioning
326+
_output/local/go/src/k8s.io/kubernetes/test/e2e/storage/framework/testsuite.go:51
327+
[BeforeEach] [Testpattern: Dynamic PV (default fs)] provisioning
328+
_output/local/go/src/k8s.io/kubernetes/test/e2e/framework/framework.go:185
329+
STEP: Creating a kubernetes client
330+
Apr 16 20:29:24.747: INFO: >>> kubeConfig: ...
331+
STEP: Building a namespace api object, basename provisioning
332+
W0416 20:29:24.901750 3669683 warnings.go:70] policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+
333+
Apr 16 20:29:24.901: INFO: No PodSecurityPolicies found; assuming PodSecurityPolicy is disabled.
334+
STEP: Waiting for a default service account to be provisioned in namespace
335+
[It] should provision storage with snapshot data source [Feature:VolumeSnapshotDataSource]
336+
_output/local/go/src/k8s.io/kubernetes/test/e2e/storage/testsuites/provisioning.go:200
337+
> k8s.io/kubernetes/test/e2e/storage/testsuites.(*provisioningTestSuite).DefineTests.func4() _output/local/go/src/k8s.io/kubernetes/test/e2e/storage/testsuites/provisioning.go:201 (hits goroutine(165):1 total:1) (PC: 0x72856f2)
338+
Warning: listing may not match stale executable
339+
196:
340+
197: l.testCase.TestDynamicProvisioning()
341+
198: })
342+
199:
343+
200: ginkgo.It("should provision storage with snapshot data source [Feature:VolumeSnapshotDataSource]", func() {
344+
=> 201: if !dInfo.Capabilities[storageframework.CapSnapshotDataSource] {
345+
202: e2eskipper.Skipf("Driver %q does not support populate data from snapshot - skipping", dInfo.Name)
346+
203: }
347+
204: if !dInfo.SupportedFsType.Has(pattern.FsType) {
348+
205: e2eskipper.Skipf("Driver %q does not support %q fs type - skipping", dInfo.Name, pattern.FsType)
349+
206: }
350+
(dlv) print dInfo
351+
*k8s.io/kubernetes/test/e2e/storage/framework.DriverInfo {
352+
Name: "csi-hostpath",
353+
InTreePluginName: "",
354+
FeatureTag: "",
355+
MaxFileSize: 104857600,
356+
SupportedSizeRange: k8s.io/kubernetes/test/e2e/framework/volume.SizeRange {Max: "", Min: "1Mi"},
357+
SupportedFsType: k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/util/sets.String [
358+
"": {},
359+
],
360+
SupportedMountOption: k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/util/sets.String nil,
361+
RequiredMountOption: k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/util/sets.String nil,
362+
Capabilities: map[k8s.io/kubernetes/test/e2e/storage/framework.Capability]bool [
363+
"persistence": true,
364+
"snapshotDataSource": true,
365+
"multipods": true,
366+
"block": true,
367+
"pvcDataSource": true,
368+
"controllerExpansion": true,
369+
"singleNodeVolume": true,
370+
"volumeLimits": true,
371+
],
372+
RequiredAccessModes: []k8s.io/kubernetes/vendor/k8s.io/api/core/v1.PersistentVolumeAccessMode len: 0, cap: 0, nil,
373+
TopologyKeys: []string len: 0, cap: 0, nil,
374+
NumAllowedTopologies: 0,
375+
StressTestOptions: *k8s.io/kubernetes/test/e2e/storage/framework.StressTestOptions {NumPods: 10, NumRestarts: 10},
376+
VolumeSnapshotStressTestOptions: *k8s.io/kubernetes/test/e2e/storage/framework.VolumeSnapshotStressTestOptions {NumPods: 10, NumSnapshots: 10},}
377+
```
378+
262379
### Local clusters
263380
264381
It can be much faster to iterate on a local cluster instead of a cloud-based

0 commit comments

Comments
 (0)