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  }