github.com/zhuohuang-hust/src-cbuild@v0.0.0-20230105071821-c7aab3e7c840/mergeCode/runc/libcontainer/container_linux_test.go (about)

     1  // +build linux
     2  
     3  package libcontainer
     4  
     5  import (
     6  	"fmt"
     7  	"os"
     8  	"testing"
     9  
    10  	"github.com/opencontainers/runc/libcontainer/cgroups"
    11  	"github.com/opencontainers/runc/libcontainer/configs"
    12  )
    13  
    14  type mockCgroupManager struct {
    15  	pids    []int
    16  	allPids []int
    17  	stats   *cgroups.Stats
    18  	paths   map[string]string
    19  }
    20  
    21  func (m *mockCgroupManager) GetPids() ([]int, error) {
    22  	return m.pids, nil
    23  }
    24  
    25  func (m *mockCgroupManager) GetAllPids() ([]int, error) {
    26  	return m.allPids, nil
    27  }
    28  
    29  func (m *mockCgroupManager) GetStats() (*cgroups.Stats, error) {
    30  	return m.stats, nil
    31  }
    32  
    33  func (m *mockCgroupManager) Apply(pid int) error {
    34  	return nil
    35  }
    36  
    37  func (m *mockCgroupManager) Set(container *configs.Config) error {
    38  	return nil
    39  }
    40  
    41  func (m *mockCgroupManager) Destroy() error {
    42  	return nil
    43  }
    44  
    45  func (m *mockCgroupManager) GetPaths() map[string]string {
    46  	return m.paths
    47  }
    48  
    49  func (m *mockCgroupManager) Freeze(state configs.FreezerState) error {
    50  	return nil
    51  }
    52  
    53  type mockProcess struct {
    54  	_pid    int
    55  	started string
    56  }
    57  
    58  func (m *mockProcess) terminate() error {
    59  	return nil
    60  }
    61  
    62  func (m *mockProcess) pid() int {
    63  	return m._pid
    64  }
    65  
    66  func (m *mockProcess) startTime() (string, error) {
    67  	return m.started, nil
    68  }
    69  
    70  func (m *mockProcess) start() error {
    71  	return nil
    72  }
    73  
    74  func (m *mockProcess) wait() (*os.ProcessState, error) {
    75  	return nil, nil
    76  }
    77  
    78  func (m *mockProcess) signal(_ os.Signal) error {
    79  	return nil
    80  }
    81  
    82  func (m *mockProcess) externalDescriptors() []string {
    83  	return []string{}
    84  }
    85  
    86  func (m *mockProcess) setExternalDescriptors(newFds []string) {
    87  }
    88  
    89  func TestGetContainerPids(t *testing.T) {
    90  	container := &linuxContainer{
    91  		id:            "myid",
    92  		config:        &configs.Config{},
    93  		cgroupManager: &mockCgroupManager{allPids: []int{1, 2, 3}},
    94  	}
    95  	pids, err := container.Processes()
    96  	if err != nil {
    97  		t.Fatal(err)
    98  	}
    99  	for i, expected := range []int{1, 2, 3} {
   100  		if pids[i] != expected {
   101  			t.Fatalf("expected pid %d but received %d", expected, pids[i])
   102  		}
   103  	}
   104  }
   105  
   106  func TestGetContainerStats(t *testing.T) {
   107  	container := &linuxContainer{
   108  		id:     "myid",
   109  		config: &configs.Config{},
   110  		cgroupManager: &mockCgroupManager{
   111  			pids: []int{1, 2, 3},
   112  			stats: &cgroups.Stats{
   113  				MemoryStats: cgroups.MemoryStats{
   114  					Usage: cgroups.MemoryData{
   115  						Usage: 1024,
   116  					},
   117  				},
   118  			},
   119  		},
   120  	}
   121  	stats, err := container.Stats()
   122  	if err != nil {
   123  		t.Fatal(err)
   124  	}
   125  	if stats.CgroupStats == nil {
   126  		t.Fatal("cgroup stats are nil")
   127  	}
   128  	if stats.CgroupStats.MemoryStats.Usage.Usage != 1024 {
   129  		t.Fatalf("expected memory usage 1024 but recevied %d", stats.CgroupStats.MemoryStats.Usage.Usage)
   130  	}
   131  }
   132  
   133  func TestGetContainerState(t *testing.T) {
   134  	var (
   135  		pid                 = os.Getpid()
   136  		expectedMemoryPath  = "/sys/fs/cgroup/memory/myid"
   137  		expectedNetworkPath = "/networks/fd"
   138  	)
   139  	container := &linuxContainer{
   140  		id: "myid",
   141  		config: &configs.Config{
   142  			Namespaces: []configs.Namespace{
   143  				{Type: configs.NEWPID},
   144  				{Type: configs.NEWNS},
   145  				{Type: configs.NEWNET, Path: expectedNetworkPath},
   146  				{Type: configs.NEWUTS},
   147  				// emulate host for IPC
   148  				//{Type: configs.NEWIPC},
   149  			},
   150  		},
   151  		initProcess: &mockProcess{
   152  			_pid:    pid,
   153  			started: "010",
   154  		},
   155  		cgroupManager: &mockCgroupManager{
   156  			pids: []int{1, 2, 3},
   157  			stats: &cgroups.Stats{
   158  				MemoryStats: cgroups.MemoryStats{
   159  					Usage: cgroups.MemoryData{
   160  						Usage: 1024,
   161  					},
   162  				},
   163  			},
   164  			paths: map[string]string{
   165  				"memory": expectedMemoryPath,
   166  			},
   167  		},
   168  	}
   169  	container.state = &createdState{c: container}
   170  	state, err := container.State()
   171  	if err != nil {
   172  		t.Fatal(err)
   173  	}
   174  	if state.InitProcessPid != pid {
   175  		t.Fatalf("expected pid %d but received %d", pid, state.InitProcessPid)
   176  	}
   177  	if state.InitProcessStartTime != "010" {
   178  		t.Fatalf("expected process start time 010 but received %s", state.InitProcessStartTime)
   179  	}
   180  	paths := state.CgroupPaths
   181  	if paths == nil {
   182  		t.Fatal("cgroup paths should not be nil")
   183  	}
   184  	if memPath := paths["memory"]; memPath != expectedMemoryPath {
   185  		t.Fatalf("expected memory path %q but received %q", expectedMemoryPath, memPath)
   186  	}
   187  	for _, ns := range container.config.Namespaces {
   188  		path := state.NamespacePaths[ns.Type]
   189  		if path == "" {
   190  			t.Fatalf("expected non nil namespace path for %s", ns.Type)
   191  		}
   192  		if ns.Type == configs.NEWNET {
   193  			if path != expectedNetworkPath {
   194  				t.Fatalf("expected path %q but received %q", expectedNetworkPath, path)
   195  			}
   196  		} else {
   197  			file := ""
   198  			switch ns.Type {
   199  			case configs.NEWNET:
   200  				file = "net"
   201  			case configs.NEWNS:
   202  				file = "mnt"
   203  			case configs.NEWPID:
   204  				file = "pid"
   205  			case configs.NEWIPC:
   206  				file = "ipc"
   207  			case configs.NEWUSER:
   208  				file = "user"
   209  			case configs.NEWUTS:
   210  				file = "uts"
   211  			}
   212  			expected := fmt.Sprintf("/proc/%d/ns/%s", pid, file)
   213  			if expected != path {
   214  				t.Fatalf("expected path %q but received %q", expected, path)
   215  			}
   216  		}
   217  	}
   218  }