gitee.com/leisunstar/runtime@v0.0.0-20200521203717-5cef3e7b53f9/virtcontainers/cgroups_test.go (about)

     1  // Copyright (c) 2018 Huawei Corporation
     2  //
     3  // SPDX-License-Identifier: Apache-2.0
     4  //
     5  
     6  package virtcontainers
     7  
     8  import (
     9  	"fmt"
    10  	"os"
    11  	"os/exec"
    12  	"path/filepath"
    13  	"testing"
    14  
    15  	"github.com/containerd/cgroups"
    16  	"github.com/kata-containers/runtime/virtcontainers/types"
    17  	specs "github.com/opencontainers/runtime-spec/specs-go"
    18  	"github.com/stretchr/testify/assert"
    19  )
    20  
    21  type mockCgroup struct {
    22  }
    23  
    24  func (m *mockCgroup) New(string, *specs.LinuxResources) (cgroups.Cgroup, error) {
    25  	return &mockCgroup{}, nil
    26  }
    27  func (m *mockCgroup) Add(cgroups.Process) error {
    28  	return nil
    29  }
    30  
    31  func (m *mockCgroup) AddTask(cgroups.Process) error {
    32  	return nil
    33  }
    34  
    35  func (m *mockCgroup) Delete() error {
    36  	return nil
    37  }
    38  
    39  func (m *mockCgroup) MoveTo(cgroups.Cgroup) error {
    40  	return nil
    41  }
    42  
    43  func (m *mockCgroup) Stat(...cgroups.ErrorHandler) (*cgroups.Metrics, error) {
    44  	return &cgroups.Metrics{}, nil
    45  }
    46  
    47  func (m *mockCgroup) Update(resources *specs.LinuxResources) error {
    48  	return nil
    49  }
    50  
    51  func (m *mockCgroup) Processes(cgroups.Name, bool) ([]cgroups.Process, error) {
    52  	return nil, nil
    53  }
    54  
    55  func (m *mockCgroup) Freeze() error {
    56  	return nil
    57  }
    58  
    59  func (m *mockCgroup) Thaw() error {
    60  	return nil
    61  }
    62  
    63  func (m *mockCgroup) OOMEventFD() (uintptr, error) {
    64  	return 0, nil
    65  }
    66  
    67  func (m *mockCgroup) State() cgroups.State {
    68  	return ""
    69  }
    70  
    71  func (m *mockCgroup) Subsystems() []cgroups.Subsystem {
    72  	return nil
    73  }
    74  
    75  func (m *mockCgroup) Tasks(cgroups.Name, bool) ([]cgroups.Task, error) {
    76  	return nil, nil
    77  }
    78  
    79  func mockCgroupNew(hierarchy cgroups.Hierarchy, path cgroups.Path, resources *specs.LinuxResources, opts ...cgroups.InitOpts) (cgroups.Cgroup, error) {
    80  	return &mockCgroup{}, nil
    81  }
    82  
    83  func mockCgroupLoad(hierarchy cgroups.Hierarchy, path cgroups.Path, opts ...cgroups.InitOpts) (cgroups.Cgroup, error) {
    84  	return &mockCgroup{}, nil
    85  }
    86  
    87  func init() {
    88  	cgroupsNewFunc = mockCgroupNew
    89  	cgroupsLoadFunc = mockCgroupLoad
    90  }
    91  
    92  func TestV1Constraints(t *testing.T) {
    93  	assert := assert.New(t)
    94  
    95  	systems, err := V1Constraints()
    96  	assert.NoError(err)
    97  	assert.NotEmpty(systems)
    98  }
    99  
   100  func TestV1NoConstraints(t *testing.T) {
   101  	assert := assert.New(t)
   102  
   103  	systems, err := V1NoConstraints()
   104  	assert.NoError(err)
   105  	assert.NotEmpty(systems)
   106  }
   107  
   108  func TestCgroupNoConstraintsPath(t *testing.T) {
   109  	assert := assert.New(t)
   110  
   111  	cgrouPath := "abc"
   112  	expectedPath := filepath.Join(cgroupKataPath, cgrouPath)
   113  	path := cgroupNoConstraintsPath(cgrouPath)
   114  	assert.Equal(expectedPath, path)
   115  }
   116  
   117  func TestUpdateCgroups(t *testing.T) {
   118  	assert := assert.New(t)
   119  
   120  	oldCgroupsNew := cgroupsNewFunc
   121  	oldCgroupsLoad := cgroupsLoadFunc
   122  	cgroupsNewFunc = cgroups.New
   123  	cgroupsLoadFunc = cgroups.Load
   124  	defer func() {
   125  		cgroupsNewFunc = oldCgroupsNew
   126  		cgroupsLoadFunc = oldCgroupsLoad
   127  	}()
   128  
   129  	s := &Sandbox{
   130  		state: types.SandboxState{
   131  			CgroupPath: "",
   132  		},
   133  		config: &SandboxConfig{SandboxCgroupOnly: false},
   134  	}
   135  
   136  	// empty path
   137  	err := s.cgroupsUpdate()
   138  	assert.NoError(err)
   139  
   140  	// path doesn't exist
   141  	s.state.CgroupPath = "/abc/123/rgb"
   142  	err = s.cgroupsUpdate()
   143  	assert.Error(err)
   144  
   145  	if os.Getuid() != 0 {
   146  		return
   147  	}
   148  
   149  	s.state.CgroupPath = fmt.Sprintf("/kata-tests-%d", os.Getpid())
   150  	testCgroup, err := cgroups.New(cgroups.V1, cgroups.StaticPath(s.state.CgroupPath), &specs.LinuxResources{})
   151  	assert.NoError(err)
   152  	defer testCgroup.Delete()
   153  	s.hypervisor = &mockHypervisor{mockPid: 0}
   154  
   155  	// bad pid
   156  	err = s.cgroupsUpdate()
   157  	assert.Error(err)
   158  
   159  	// fake workload
   160  	cmd := exec.Command("tail", "-f", "/dev/null")
   161  	assert.NoError(cmd.Start())
   162  	s.hypervisor = &mockHypervisor{mockPid: cmd.Process.Pid}
   163  
   164  	// no containers
   165  	err = s.cgroupsUpdate()
   166  	assert.NoError(err)
   167  
   168  	s.config = &SandboxConfig{}
   169  	s.config.HypervisorConfig.NumVCPUs = 1
   170  
   171  	s.containers = map[string]*Container{
   172  		"abc": {
   173  			process: Process{
   174  				Pid: cmd.Process.Pid,
   175  			},
   176  			config: &ContainerConfig{
   177  				Annotations: containerAnnotations,
   178  				CustomSpec:  newEmptySpec(),
   179  			},
   180  		},
   181  		"xyz": {
   182  			process: Process{
   183  				Pid: cmd.Process.Pid,
   184  			},
   185  			config: &ContainerConfig{
   186  				Annotations: containerAnnotations,
   187  				CustomSpec:  newEmptySpec(),
   188  			},
   189  		},
   190  	}
   191  
   192  	err = s.cgroupsUpdate()
   193  	assert.NoError(err)
   194  
   195  	// cleanup
   196  	assert.NoError(cmd.Process.Kill())
   197  	err = s.cgroupsDelete()
   198  	assert.NoError(err)
   199  }