github.com/zhuohuang-hust/src-cbuild@v0.0.0-20230105071821-c7aab3e7c840/mergeCode/containerd/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/docker/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 stdName, stdPath := range map[string]*string{
    69  		"stdin":  &s.Stdin,
    70  		"stdout": &s.Stdout,
    71  		"stderr": &s.Stderr,
    72  	} {
    73  		*stdPath = filepath.Join(cwd, bundlePath, "io", bundleName+"-"+pid+"-"+stdName)
    74  		if err := syscall.Mkfifo(*stdPath, 0755); err != nil && !os.IsExist(err) {
    75  			fmt.Println("Mkfifo error: ", err)
    76  			return s, err
    77  		}
    78  	}
    79  
    80  	err := attachStdio(s)
    81  	if err != nil {
    82  		fmt.Println("attachStdio error: ", err)
    83  		return s, err
    84  	}
    85  
    86  	return s, nil
    87  }
    88  
    89  func attachStdio(s Stdio) error {
    90  	stdinf, err := os.OpenFile(s.Stdin, syscall.O_RDWR, 0)
    91  	if err != nil {
    92  		return err
    93  	}
    94  	stdin = stdinf
    95  	stdoutf, err := os.OpenFile(s.Stdout, syscall.O_RDWR, 0)
    96  	if err != nil {
    97  		return err
    98  	}
    99  	go io.Copy(os.Stdout, stdoutf)
   100  	stderrf, err := os.OpenFile(s.Stderr, syscall.O_RDWR, 0)
   101  	if err != nil {
   102  		return err
   103  	}
   104  	go io.Copy(os.Stderr, stderrf)
   105  	return nil
   106  }
   107  
   108  func teardownBundle(bundleName string) {
   109  	containerRoot := filepath.Join(utils.StateDir, bundleName)
   110  	os.RemoveAll(containerRoot)
   111  
   112  	bundlePath := filepath.Join(utils.BundlesRoot, bundleName)
   113  	os.RemoveAll(bundlePath)
   114  	return
   115  }
   116  
   117  // Remove containerd state and oci bundles directory
   118  func teardown() {
   119  	os.RemoveAll(utils.StateDir)
   120  	os.RemoveAll(utils.BundlesRoot)
   121  }
   122  
   123  func BenchmarkBusyboxSh(b *testing.B) {
   124  	bundleName := "busybox-sh"
   125  
   126  	wd := utils.GetTestOutDir()
   127  	if err := os.Chdir(wd); err != nil {
   128  		b.Fatalf("Could not change working directory: %v", err)
   129  	}
   130  
   131  	if err := setup(); err != nil {
   132  		b.Fatalf("Error setting up test: %v", err)
   133  	}
   134  	defer teardown()
   135  
   136  	for n := 0; n < b.N; n++ {
   137  		bundlePath, err := setupBundle(bundleName)
   138  		if err != nil {
   139  			return
   140  		}
   141  
   142  		s, err := setupStdio(wd, bundlePath, bundleName)
   143  		if err != nil {
   144  			return
   145  		}
   146  
   147  		c, err := New(ContainerOpts{
   148  			Root:    utils.StateDir,
   149  			ID:      bundleName,
   150  			Bundle:  filepath.Join(wd, bundlePath),
   151  			Runtime: *runtimeTool,
   152  			Shim:    "containerd-shim",
   153  			Timeout: 15 * time.Second,
   154  		})
   155  
   156  		if err != nil {
   157  			b.Fatalf("Error creating a New container: ", err)
   158  		}
   159  
   160  		benchmarkStartContainer(b, c, s, bundleName)
   161  
   162  		teardownBundle(bundleName)
   163  	}
   164  }
   165  
   166  func benchmarkStartContainer(b *testing.B, c Container, s Stdio, bundleName string) {
   167  	p, err := c.Start(context.Background(), "", s)
   168  	if err != nil {
   169  		b.Fatalf("Error starting container %v", err)
   170  	}
   171  
   172  	kill := exec.Command(c.Runtime(), "kill", bundleName, "KILL")
   173  	kill.Run()
   174  
   175  	p.Wait()
   176  	c.Delete()
   177  
   178  	// wait for kill to finish. selected wait time is arbitrary
   179  	time.Sleep(500 * time.Millisecond)
   180  
   181  }