github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/pkg/test/dockerutil/README.md (about) 1 # dockerutil 2 3 This package is for creating and controlling docker containers for testing 4 runsc, gVisor's docker/kubernetes binary. A simple test may look like: 5 6 ``` 7 func TestSuperCool(t *testing.T) { 8 ctx := context.Background() 9 c := dockerutil.MakeContainer(ctx, t) 10 got, err := c.Run(ctx, dockerutil.RunOpts{ 11 Image: "basic/alpine" 12 }, "echo", "super cool") 13 if err != nil { 14 t.Fatalf("err was not nil: %v", err) 15 } 16 want := "super cool" 17 if !strings.Contains(got, want){ 18 t.Fatalf("want: %s, got: %s", want, got) 19 } 20 } 21 ``` 22 23 For further examples, see many of our end to end tests elsewhere in the repo, 24 such as those in //test/e2e or benchmarks at //test/benchmarks. 25 26 dockerutil uses the "official" docker golang api, which is 27 [very powerful](https://godoc.org/github.com/docker/docker/client). dockerutil 28 is a thin wrapper around this API, allowing desired new use cases to be easily 29 implemented. 30 31 ## Profiling 32 33 dockerutil is capable of generating profiles. Currently, the only option is to 34 use pprof profiles generated by `runsc debug`. The profiler will generate Block, 35 CPU, Heap, Goroutine, and Mutex profiles. To generate profiles: 36 37 * Install runsc with the `--profile` flag: `make configure RUNTIME=myrunsc 38 ARGS="--profile"` Also add other flags with ARGS like `--platform=kvm` or 39 `--vfs2`. 40 * Restart docker: `sudo service docker restart` 41 42 To run and generate CPU profiles run: 43 44 ``` 45 make sudo TARGETS=//path/to:target \ 46 ARGS="--runtime=myrunsc -test.v -test.bench=. --pprof-cpu" OPTIONS="-c opt" 47 ``` 48 49 Profiles would be at: `/tmp/profile/myrunsc/CONTAINERNAME/cpu.pprof` 50 51 Container name in most tests and benchmarks in gVisor is usually the test name 52 and some random characters like so: 53 `BenchmarkABSL-CleanCache-JF2J2ZYF3U7SL47QAA727CSJI3C4ZAW2` 54 55 Profiling requires root as runsc debug inspects running containers in /var/run 56 among other things. 57 58 ### Writing for Profiling 59 60 The below shows an example of using profiles with dockerutil. 61 62 ``` 63 func TestSuperCool(t *testing.T){ 64 ctx := context.Background() 65 // profiled and using runtime from dockerutil.runtime flag 66 profiled := MakeContainer() 67 68 // not profiled and using runtime runc 69 native := MakeNativeContainer() 70 71 err := profiled.Spawn(ctx, RunOpts{ 72 Image: "some/image", 73 }, "sleep", "100000") 74 // profiling has begun here 75 ... 76 expensive setup that I don't want to profile. 77 ... 78 profiled.RestartProfiles() 79 // profiled activity 80 } 81 ``` 82 83 In the above example, `profiled` would be profiled and `native` would not. The 84 call to `RestartProfiles()` restarts the clock on profiling. This is useful if 85 the main activity being tested is done with `docker exec` or `container.Spawn()` 86 followed by one or more `container.Exec()` calls.