github.com/zhuohuang-hust/src-cbuild@v0.0.0-20230105071821-c7aab3e7c840/mergeCode/runc/libcontainer/integration/utils_test.go (about) 1 package integration 2 3 import ( 4 "bytes" 5 "crypto/md5" 6 "encoding/hex" 7 "fmt" 8 "io/ioutil" 9 "os" 10 "os/exec" 11 "path/filepath" 12 "runtime" 13 "strings" 14 "syscall" 15 "testing" 16 "time" 17 18 "github.com/opencontainers/runc/libcontainer" 19 "github.com/opencontainers/runc/libcontainer/configs" 20 ) 21 22 func newStdBuffers() *stdBuffers { 23 return &stdBuffers{ 24 Stdin: bytes.NewBuffer(nil), 25 Stdout: bytes.NewBuffer(nil), 26 Stderr: bytes.NewBuffer(nil), 27 } 28 } 29 30 type stdBuffers struct { 31 Stdin *bytes.Buffer 32 Stdout *bytes.Buffer 33 Stderr *bytes.Buffer 34 } 35 36 func (b *stdBuffers) String() string { 37 s := []string{} 38 if b.Stderr != nil { 39 s = append(s, b.Stderr.String()) 40 } 41 if b.Stdout != nil { 42 s = append(s, b.Stdout.String()) 43 } 44 return strings.Join(s, "|") 45 } 46 47 // ok fails the test if an err is not nil. 48 func ok(t testing.TB, err error) { 49 if err != nil { 50 _, file, line, _ := runtime.Caller(1) 51 t.Fatalf("%s:%d: unexpected error: %s\n\n", filepath.Base(file), line, err.Error()) 52 } 53 } 54 55 func waitProcess(p *libcontainer.Process, t *testing.T) { 56 _, file, line, _ := runtime.Caller(1) 57 status, err := p.Wait() 58 59 if err != nil { 60 t.Fatalf("%s:%d: unexpected error: %s\n\n", filepath.Base(file), line, err.Error()) 61 } 62 63 if !status.Success() { 64 t.Fatalf("%s:%d: unexpected status: %s\n\n", filepath.Base(file), line, status.String()) 65 } 66 } 67 68 func newTestRoot() (string, error) { 69 dir, err := ioutil.TempDir("", "libcontainer") 70 if err != nil { 71 return "", err 72 } 73 if err := os.MkdirAll(dir, 0700); err != nil { 74 return "", err 75 } 76 return dir, nil 77 } 78 79 // newRootfs creates a new tmp directory and copies the busybox root filesystem 80 func newRootfs() (string, error) { 81 dir, err := ioutil.TempDir("", "") 82 if err != nil { 83 return "", err 84 } 85 if err := os.MkdirAll(dir, 0700); err != nil { 86 return "", err 87 } 88 if err := copyBusybox(dir); err != nil { 89 return "", err 90 } 91 return dir, nil 92 } 93 94 func remove(dir string) { 95 os.RemoveAll(dir) 96 } 97 98 // copyBusybox copies the rootfs for a busybox container created for the test image 99 // into the new directory for the specific test 100 func copyBusybox(dest string) error { 101 out, err := exec.Command("sh", "-c", fmt.Sprintf("cp -R /busybox/* %s/", dest)).CombinedOutput() 102 if err != nil { 103 return fmt.Errorf("copy error %q: %q", err, out) 104 } 105 return nil 106 } 107 108 func newContainer(config *configs.Config) (libcontainer.Container, error) { 109 h := md5.New() 110 h.Write([]byte(time.Now().String())) 111 return newContainerWithName(hex.EncodeToString(h.Sum(nil)), config) 112 } 113 114 func newContainerWithName(name string, config *configs.Config) (libcontainer.Container, error) { 115 f := factory 116 if config.Cgroups != nil && config.Cgroups.Parent == "system.slice" { 117 f = systemdFactory 118 } 119 return f.Create(name, config) 120 } 121 122 // runContainer runs the container with the specific config and arguments 123 // 124 // buffers are returned containing the STDOUT and STDERR output for the run 125 // along with the exit code and any go error 126 func runContainer(config *configs.Config, console string, args ...string) (buffers *stdBuffers, exitCode int, err error) { 127 container, err := newContainer(config) 128 if err != nil { 129 return nil, -1, err 130 } 131 defer container.Destroy() 132 buffers = newStdBuffers() 133 process := &libcontainer.Process{ 134 Cwd: "/", 135 Args: args, 136 Env: standardEnvironment, 137 Stdin: buffers.Stdin, 138 Stdout: buffers.Stdout, 139 Stderr: buffers.Stderr, 140 } 141 142 err = container.Run(process) 143 if err != nil { 144 return buffers, -1, err 145 } 146 ps, err := process.Wait() 147 if err != nil { 148 return buffers, -1, err 149 } 150 status := ps.Sys().(syscall.WaitStatus) 151 if status.Exited() { 152 exitCode = status.ExitStatus() 153 } else if status.Signaled() { 154 exitCode = -int(status.Signal()) 155 } else { 156 return buffers, -1, err 157 } 158 return 159 }