github.com/docker/containerd@v0.2.9-0.20170509230648-8ef7df579710/runtime/runtime_test.go (about) 1 package runtime 2 3 import ( 4 "context" 5 "flag" 6 "fmt" 7 "io" 8 "os" 9 "os/exec" 10 "path/filepath" 11 "syscall" 12 "testing" 13 "time" 14 15 utils "github.com/containerd/containerd/testutils" 16 ) 17 18 var ( 19 devNull = "/dev/null" 20 stdin io.WriteCloser 21 runtimeTool = flag.String("runtime", "runc", "Runtime to use for this test") 22 ) 23 24 // Create containerd state and oci bundles directory 25 func setup() error { 26 if err := os.MkdirAll(utils.StateDir, 0755); err != nil { 27 return err 28 } 29 30 if err := os.MkdirAll(utils.BundlesRoot, 0755); err != nil { 31 return err 32 } 33 return nil 34 } 35 36 // Creates the bundleDir with rootfs, io fifo dir and a default spec. 37 // On success, returns the bundlePath 38 func setupBundle(bundleName string) (string, error) { 39 bundlePath := filepath.Join(utils.BundlesRoot, bundleName) 40 if err := os.MkdirAll(bundlePath, 0755); err != nil { 41 fmt.Println("Unable to create bundlePath due to ", err) 42 return "", err 43 } 44 45 io := filepath.Join(bundlePath, "io") 46 if err := os.MkdirAll(io, 0755); err != nil { 47 fmt.Println("Unable to create io dir due to ", err) 48 return "", err 49 } 50 51 if err := utils.GenerateReferenceSpecs(bundlePath); err != nil { 52 fmt.Println("Unable to generate OCI reference spec: ", err) 53 return "", err 54 } 55 56 if err := utils.CreateBusyboxBundle(bundleName); err != nil { 57 fmt.Println("CreateBusyboxBundle error: ", err) 58 return "", err 59 } 60 61 return bundlePath, nil 62 } 63 64 func setupStdio(cwd string, bundlePath string, bundleName string) (Stdio, error) { 65 s := NewStdio(devNull, devNull, devNull) 66 67 pid := "init" 68 for _, pair := range []struct { 69 stdName string 70 stdPath *string 71 }{ 72 {"stdin", &s.Stdin}, 73 {"stdout", &s.Stdout}, 74 {"stderr", &s.Stderr}, 75 } { 76 *pair.stdPath = filepath.Join(cwd, bundlePath, "io", bundleName+"-"+pid+"-"+pair.stdName) 77 if err := syscall.Mkfifo(*pair.stdPath, 0755); err != nil && !os.IsExist(err) { 78 fmt.Println("Mkfifo error: ", err) 79 return s, err 80 } 81 } 82 83 err := attachStdio(s) 84 if err != nil { 85 fmt.Println("attachStdio error: ", err) 86 return s, err 87 } 88 89 return s, nil 90 } 91 92 func attachStdio(s Stdio) error { 93 stdinf, err := os.OpenFile(s.Stdin, syscall.O_RDWR, 0) 94 if err != nil { 95 return err 96 } 97 stdin = stdinf 98 stdoutf, err := os.OpenFile(s.Stdout, syscall.O_RDWR, 0) 99 if err != nil { 100 return err 101 } 102 go io.Copy(os.Stdout, stdoutf) 103 stderrf, err := os.OpenFile(s.Stderr, syscall.O_RDWR, 0) 104 if err != nil { 105 return err 106 } 107 go io.Copy(os.Stderr, stderrf) 108 return nil 109 } 110 111 func teardownBundle(bundleName string) { 112 containerRoot := filepath.Join(utils.StateDir, bundleName) 113 os.RemoveAll(containerRoot) 114 115 bundlePath := filepath.Join(utils.BundlesRoot, bundleName) 116 os.RemoveAll(bundlePath) 117 return 118 } 119 120 // Remove containerd state and oci bundles directory 121 func teardown() { 122 os.RemoveAll(utils.StateDir) 123 os.RemoveAll(utils.BundlesRoot) 124 } 125 126 func BenchmarkBusyboxSh(b *testing.B) { 127 bundleName := "busybox-sh" 128 129 wd := utils.GetTestOutDir() 130 if err := os.Chdir(wd); err != nil { 131 b.Fatalf("Could not change working directory: %v", err) 132 } 133 134 if err := setup(); err != nil { 135 b.Fatalf("Error setting up test: %v", err) 136 } 137 defer teardown() 138 139 for n := 0; n < b.N; n++ { 140 bundlePath, err := setupBundle(bundleName) 141 if err != nil { 142 return 143 } 144 145 s, err := setupStdio(wd, bundlePath, bundleName) 146 if err != nil { 147 return 148 } 149 150 c, err := New(ContainerOpts{ 151 Root: utils.StateDir, 152 ID: bundleName, 153 Bundle: filepath.Join(wd, bundlePath), 154 Runtime: *runtimeTool, 155 Shim: "containerd-shim", 156 Timeout: 15 * time.Second, 157 }) 158 159 if err != nil { 160 b.Fatalf("Error creating a New container: ", err) 161 } 162 163 benchmarkStartContainer(b, c, s, bundleName) 164 165 teardownBundle(bundleName) 166 } 167 } 168 169 func benchmarkStartContainer(b *testing.B, c Container, s Stdio, bundleName string) { 170 p, err := c.Start(context.Background(), "", s) 171 if err != nil { 172 b.Fatalf("Error starting container %v", err) 173 } 174 175 kill := exec.Command(c.Runtime(), "kill", bundleName, "KILL") 176 kill.Run() 177 178 p.Wait() 179 c.Delete() 180 181 // wait for kill to finish. selected wait time is arbitrary 182 time.Sleep(500 * time.Millisecond) 183 184 }