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