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

     1  // +build linux
     2  
     3  package fs
     4  
     5  import (
     6  	"strconv"
     7  	"testing"
     8  
     9  	"github.com/opencontainers/runc/libcontainer/cgroups"
    10  )
    11  
    12  const (
    13  	memoryStatContents = `cache 512
    14  rss 1024`
    15  	memoryUsageContents    = "2048\n"
    16  	memoryMaxUsageContents = "4096\n"
    17  	memoryFailcnt          = "100\n"
    18  	memoryLimitContents    = "8192\n"
    19  )
    20  
    21  func TestMemorySetMemory(t *testing.T) {
    22  	helper := NewCgroupTestUtil("memory", t)
    23  	defer helper.cleanup()
    24  
    25  	const (
    26  		memoryBefore      = 314572800 // 300M
    27  		memoryAfter       = 524288000 // 500M
    28  		reservationBefore = 209715200 // 200M
    29  		reservationAfter  = 314572800 // 300M
    30  	)
    31  
    32  	helper.writeFileContents(map[string]string{
    33  		"memory.limit_in_bytes":      strconv.Itoa(memoryBefore),
    34  		"memory.soft_limit_in_bytes": strconv.Itoa(reservationBefore),
    35  	})
    36  
    37  	helper.CgroupData.config.Resources.Memory = memoryAfter
    38  	helper.CgroupData.config.Resources.MemoryReservation = reservationAfter
    39  	memory := &MemoryGroup{}
    40  	if err := memory.Set(helper.CgroupPath, helper.CgroupData.config); err != nil {
    41  		t.Fatal(err)
    42  	}
    43  
    44  	value, err := getCgroupParamUint(helper.CgroupPath, "memory.limit_in_bytes")
    45  	if err != nil {
    46  		t.Fatalf("Failed to parse memory.limit_in_bytes - %s", err)
    47  	}
    48  	if value != memoryAfter {
    49  		t.Fatal("Got the wrong value, set memory.limit_in_bytes failed.")
    50  	}
    51  
    52  	value, err = getCgroupParamUint(helper.CgroupPath, "memory.soft_limit_in_bytes")
    53  	if err != nil {
    54  		t.Fatalf("Failed to parse memory.soft_limit_in_bytes - %s", err)
    55  	}
    56  	if value != reservationAfter {
    57  		t.Fatal("Got the wrong value, set memory.soft_limit_in_bytes failed.")
    58  	}
    59  }
    60  
    61  func TestMemorySetMemoryswap(t *testing.T) {
    62  	helper := NewCgroupTestUtil("memory", t)
    63  	defer helper.cleanup()
    64  
    65  	const (
    66  		memoryswapBefore = 314572800 // 300M
    67  		memoryswapAfter  = 524288000 // 500M
    68  	)
    69  
    70  	helper.writeFileContents(map[string]string{
    71  		"memory.memsw.limit_in_bytes": strconv.Itoa(memoryswapBefore),
    72  	})
    73  
    74  	helper.CgroupData.config.Resources.MemorySwap = memoryswapAfter
    75  	memory := &MemoryGroup{}
    76  	if err := memory.Set(helper.CgroupPath, helper.CgroupData.config); err != nil {
    77  		t.Fatal(err)
    78  	}
    79  
    80  	value, err := getCgroupParamUint(helper.CgroupPath, "memory.memsw.limit_in_bytes")
    81  	if err != nil {
    82  		t.Fatalf("Failed to parse memory.memsw.limit_in_bytes - %s", err)
    83  	}
    84  	if value != memoryswapAfter {
    85  		t.Fatal("Got the wrong value, set memory.memsw.limit_in_bytes failed.")
    86  	}
    87  }
    88  
    89  func TestMemorySetNegativeMemoryswap(t *testing.T) {
    90  	helper := NewCgroupTestUtil("memory", t)
    91  	defer helper.cleanup()
    92  
    93  	const (
    94  		memoryBefore     = 314572800 // 300M
    95  		memoryAfter      = 524288000 // 500M
    96  		memoryswapBefore = 629145600 // 600M
    97  		memoryswapAfter  = 629145600 // 600M
    98  	)
    99  
   100  	helper.writeFileContents(map[string]string{
   101  		"memory.limit_in_bytes":       strconv.Itoa(memoryBefore),
   102  		"memory.memsw.limit_in_bytes": strconv.Itoa(memoryswapBefore),
   103  	})
   104  
   105  	helper.CgroupData.config.Resources.Memory = memoryAfter
   106  	// Negative value means not change
   107  	helper.CgroupData.config.Resources.MemorySwap = -1
   108  	memory := &MemoryGroup{}
   109  	if err := memory.Set(helper.CgroupPath, helper.CgroupData.config); err != nil {
   110  		t.Fatal(err)
   111  	}
   112  
   113  	value, err := getCgroupParamUint(helper.CgroupPath, "memory.limit_in_bytes")
   114  	if err != nil {
   115  		t.Fatalf("Failed to parse memory.limit_in_bytes - %s", err)
   116  	}
   117  	if value != memoryAfter {
   118  		t.Fatal("Got the wrong value, set memory.limit_in_bytes failed.")
   119  	}
   120  
   121  	value, err = getCgroupParamUint(helper.CgroupPath, "memory.memsw.limit_in_bytes")
   122  	if err != nil {
   123  		t.Fatalf("Failed to parse memory.memsw.limit_in_bytes - %s", err)
   124  	}
   125  	if value != memoryswapAfter {
   126  		t.Fatal("Got the wrong value, set memory.memsw.limit_in_bytes failed.")
   127  	}
   128  }
   129  
   130  func TestMemorySetMemoryLargerThanSwap(t *testing.T) {
   131  	helper := NewCgroupTestUtil("memory", t)
   132  	defer helper.cleanup()
   133  
   134  	const (
   135  		memoryBefore     = 314572800 // 300M
   136  		memoryswapBefore = 524288000 // 500M
   137  		memoryAfter      = 629145600 // 600M
   138  		memoryswapAfter  = 838860800 // 800M
   139  	)
   140  
   141  	helper.writeFileContents(map[string]string{
   142  		"memory.limit_in_bytes":       strconv.Itoa(memoryBefore),
   143  		"memory.memsw.limit_in_bytes": strconv.Itoa(memoryswapBefore),
   144  		// Set will call getMemoryData when memory and swap memory are
   145  		// both set, fake these fields so we don't get error.
   146  		"memory.usage_in_bytes":     "0",
   147  		"memory.max_usage_in_bytes": "0",
   148  		"memory.failcnt":            "0",
   149  	})
   150  
   151  	helper.CgroupData.config.Resources.Memory = memoryAfter
   152  	helper.CgroupData.config.Resources.MemorySwap = memoryswapAfter
   153  	memory := &MemoryGroup{}
   154  	if err := memory.Set(helper.CgroupPath, helper.CgroupData.config); err != nil {
   155  		t.Fatal(err)
   156  	}
   157  
   158  	value, err := getCgroupParamUint(helper.CgroupPath, "memory.limit_in_bytes")
   159  	if err != nil {
   160  		t.Fatalf("Failed to parse memory.limit_in_bytes - %s", err)
   161  	}
   162  	if value != memoryAfter {
   163  		t.Fatal("Got the wrong value, set memory.limit_in_bytes failed.")
   164  	}
   165  	value, err = getCgroupParamUint(helper.CgroupPath, "memory.memsw.limit_in_bytes")
   166  	if err != nil {
   167  		t.Fatalf("Failed to parse memory.memsw.limit_in_bytes - %s", err)
   168  	}
   169  	if value != memoryswapAfter {
   170  		t.Fatal("Got the wrong value, set memory.memsw.limit_in_bytes failed.")
   171  	}
   172  }
   173  
   174  func TestMemorySetSwapSmallerThanMemory(t *testing.T) {
   175  	helper := NewCgroupTestUtil("memory", t)
   176  	defer helper.cleanup()
   177  
   178  	const (
   179  		memoryBefore     = 629145600 // 600M
   180  		memoryswapBefore = 838860800 // 800M
   181  		memoryAfter      = 314572800 // 300M
   182  		memoryswapAfter  = 524288000 // 500M
   183  	)
   184  
   185  	helper.writeFileContents(map[string]string{
   186  		"memory.limit_in_bytes":       strconv.Itoa(memoryBefore),
   187  		"memory.memsw.limit_in_bytes": strconv.Itoa(memoryswapBefore),
   188  		// Set will call getMemoryData when memory and swap memory are
   189  		// both set, fake these fields so we don't get error.
   190  		"memory.usage_in_bytes":     "0",
   191  		"memory.max_usage_in_bytes": "0",
   192  		"memory.failcnt":            "0",
   193  	})
   194  
   195  	helper.CgroupData.config.Resources.Memory = memoryAfter
   196  	helper.CgroupData.config.Resources.MemorySwap = memoryswapAfter
   197  	memory := &MemoryGroup{}
   198  	if err := memory.Set(helper.CgroupPath, helper.CgroupData.config); err != nil {
   199  		t.Fatal(err)
   200  	}
   201  
   202  	value, err := getCgroupParamUint(helper.CgroupPath, "memory.limit_in_bytes")
   203  	if err != nil {
   204  		t.Fatalf("Failed to parse memory.limit_in_bytes - %s", err)
   205  	}
   206  	if value != memoryAfter {
   207  		t.Fatal("Got the wrong value, set memory.limit_in_bytes failed.")
   208  	}
   209  	value, err = getCgroupParamUint(helper.CgroupPath, "memory.memsw.limit_in_bytes")
   210  	if err != nil {
   211  		t.Fatalf("Failed to parse memory.memsw.limit_in_bytes - %s", err)
   212  	}
   213  	if value != memoryswapAfter {
   214  		t.Fatal("Got the wrong value, set memory.memsw.limit_in_bytes failed.")
   215  	}
   216  }
   217  
   218  func TestMemorySetKernelMemory(t *testing.T) {
   219  	helper := NewCgroupTestUtil("memory", t)
   220  	defer helper.cleanup()
   221  
   222  	const (
   223  		kernelMemoryBefore = 314572800 // 300M
   224  		kernelMemoryAfter  = 524288000 // 500M
   225  	)
   226  
   227  	helper.writeFileContents(map[string]string{
   228  		"memory.kmem.limit_in_bytes": strconv.Itoa(kernelMemoryBefore),
   229  	})
   230  
   231  	helper.CgroupData.config.Resources.KernelMemory = kernelMemoryAfter
   232  	memory := &MemoryGroup{}
   233  	if err := memory.Set(helper.CgroupPath, helper.CgroupData.config); err != nil {
   234  		t.Fatal(err)
   235  	}
   236  
   237  	value, err := getCgroupParamUint(helper.CgroupPath, "memory.kmem.limit_in_bytes")
   238  	if err != nil {
   239  		t.Fatalf("Failed to parse memory.kmem.limit_in_bytes - %s", err)
   240  	}
   241  	if value != kernelMemoryAfter {
   242  		t.Fatal("Got the wrong value, set memory.kmem.limit_in_bytes failed.")
   243  	}
   244  }
   245  
   246  func TestMemorySetKernelMemoryTCP(t *testing.T) {
   247  	helper := NewCgroupTestUtil("memory", t)
   248  	defer helper.cleanup()
   249  
   250  	const (
   251  		kernelMemoryTCPBefore = 314572800 // 300M
   252  		kernelMemoryTCPAfter  = 524288000 // 500M
   253  	)
   254  
   255  	helper.writeFileContents(map[string]string{
   256  		"memory.kmem.tcp.limit_in_bytes": strconv.Itoa(kernelMemoryTCPBefore),
   257  	})
   258  
   259  	helper.CgroupData.config.Resources.KernelMemoryTCP = kernelMemoryTCPAfter
   260  	memory := &MemoryGroup{}
   261  	if err := memory.Set(helper.CgroupPath, helper.CgroupData.config); err != nil {
   262  		t.Fatal(err)
   263  	}
   264  
   265  	value, err := getCgroupParamUint(helper.CgroupPath, "memory.kmem.tcp.limit_in_bytes")
   266  	if err != nil {
   267  		t.Fatalf("Failed to parse memory.kmem.tcp.limit_in_bytes - %s", err)
   268  	}
   269  	if value != kernelMemoryTCPAfter {
   270  		t.Fatal("Got the wrong value, set memory.kmem.tcp.limit_in_bytes failed.")
   271  	}
   272  }
   273  
   274  func TestMemorySetMemorySwappinessDefault(t *testing.T) {
   275  	helper := NewCgroupTestUtil("memory", t)
   276  	defer helper.cleanup()
   277  
   278  	swappinessBefore := 60 //default is 60
   279  	swappinessAfter := int64(0)
   280  
   281  	helper.writeFileContents(map[string]string{
   282  		"memory.swappiness": strconv.Itoa(swappinessBefore),
   283  	})
   284  
   285  	helper.CgroupData.config.Resources.MemorySwappiness = &swappinessAfter
   286  	memory := &MemoryGroup{}
   287  	if err := memory.Set(helper.CgroupPath, helper.CgroupData.config); err != nil {
   288  		t.Fatal(err)
   289  	}
   290  
   291  	value, err := getCgroupParamUint(helper.CgroupPath, "memory.swappiness")
   292  	if err != nil {
   293  		t.Fatalf("Failed to parse memory.swappiness - %s", err)
   294  	}
   295  	if int64(value) != swappinessAfter {
   296  		t.Fatalf("Got the wrong value (%d), set memory.swappiness = %d failed.", value, swappinessAfter)
   297  	}
   298  }
   299  
   300  func TestMemoryStats(t *testing.T) {
   301  	helper := NewCgroupTestUtil("memory", t)
   302  	defer helper.cleanup()
   303  	helper.writeFileContents(map[string]string{
   304  		"memory.stat":                     memoryStatContents,
   305  		"memory.usage_in_bytes":           memoryUsageContents,
   306  		"memory.limit_in_bytes":           memoryLimitContents,
   307  		"memory.max_usage_in_bytes":       memoryMaxUsageContents,
   308  		"memory.failcnt":                  memoryFailcnt,
   309  		"memory.memsw.usage_in_bytes":     memoryUsageContents,
   310  		"memory.memsw.max_usage_in_bytes": memoryMaxUsageContents,
   311  		"memory.memsw.failcnt":            memoryFailcnt,
   312  		"memory.memsw.limit_in_bytes":     memoryLimitContents,
   313  		"memory.kmem.usage_in_bytes":      memoryUsageContents,
   314  		"memory.kmem.max_usage_in_bytes":  memoryMaxUsageContents,
   315  		"memory.kmem.failcnt":             memoryFailcnt,
   316  		"memory.kmem.limit_in_bytes":      memoryLimitContents,
   317  	})
   318  
   319  	memory := &MemoryGroup{}
   320  	actualStats := *cgroups.NewStats()
   321  	err := memory.GetStats(helper.CgroupPath, &actualStats)
   322  	if err != nil {
   323  		t.Fatal(err)
   324  	}
   325  	expectedStats := cgroups.MemoryStats{Cache: 512, Usage: cgroups.MemoryData{Usage: 2048, MaxUsage: 4096, Failcnt: 100, Limit: 8192}, SwapUsage: cgroups.MemoryData{Usage: 2048, MaxUsage: 4096, Failcnt: 100, Limit: 8192}, KernelUsage: cgroups.MemoryData{Usage: 2048, MaxUsage: 4096, Failcnt: 100, Limit: 8192}, Stats: map[string]uint64{"cache": 512, "rss": 1024}}
   326  	expectMemoryStatEquals(t, expectedStats, actualStats.MemoryStats)
   327  }
   328  
   329  func TestMemoryStatsNoStatFile(t *testing.T) {
   330  	helper := NewCgroupTestUtil("memory", t)
   331  	defer helper.cleanup()
   332  	helper.writeFileContents(map[string]string{
   333  		"memory.usage_in_bytes":     memoryUsageContents,
   334  		"memory.max_usage_in_bytes": memoryMaxUsageContents,
   335  		"memory.limit_in_bytes":     memoryLimitContents,
   336  	})
   337  
   338  	memory := &MemoryGroup{}
   339  	actualStats := *cgroups.NewStats()
   340  	err := memory.GetStats(helper.CgroupPath, &actualStats)
   341  	if err != nil {
   342  		t.Fatal(err)
   343  	}
   344  }
   345  
   346  func TestMemoryStatsNoUsageFile(t *testing.T) {
   347  	helper := NewCgroupTestUtil("memory", t)
   348  	defer helper.cleanup()
   349  	helper.writeFileContents(map[string]string{
   350  		"memory.stat":               memoryStatContents,
   351  		"memory.max_usage_in_bytes": memoryMaxUsageContents,
   352  		"memory.limit_in_bytes":     memoryLimitContents,
   353  	})
   354  
   355  	memory := &MemoryGroup{}
   356  	actualStats := *cgroups.NewStats()
   357  	err := memory.GetStats(helper.CgroupPath, &actualStats)
   358  	if err == nil {
   359  		t.Fatal("Expected failure")
   360  	}
   361  }
   362  
   363  func TestMemoryStatsNoMaxUsageFile(t *testing.T) {
   364  	helper := NewCgroupTestUtil("memory", t)
   365  	defer helper.cleanup()
   366  	helper.writeFileContents(map[string]string{
   367  		"memory.stat":           memoryStatContents,
   368  		"memory.usage_in_bytes": memoryUsageContents,
   369  		"memory.limit_in_bytes": memoryLimitContents,
   370  	})
   371  
   372  	memory := &MemoryGroup{}
   373  	actualStats := *cgroups.NewStats()
   374  	err := memory.GetStats(helper.CgroupPath, &actualStats)
   375  	if err == nil {
   376  		t.Fatal("Expected failure")
   377  	}
   378  }
   379  
   380  func TestMemoryStatsNoLimitInBytesFile(t *testing.T) {
   381  	helper := NewCgroupTestUtil("memory", t)
   382  	defer helper.cleanup()
   383  	helper.writeFileContents(map[string]string{
   384  		"memory.stat":               memoryStatContents,
   385  		"memory.usage_in_bytes":     memoryUsageContents,
   386  		"memory.max_usage_in_bytes": memoryMaxUsageContents,
   387  	})
   388  
   389  	memory := &MemoryGroup{}
   390  	actualStats := *cgroups.NewStats()
   391  	err := memory.GetStats(helper.CgroupPath, &actualStats)
   392  	if err == nil {
   393  		t.Fatal("Expected failure")
   394  	}
   395  }
   396  
   397  func TestMemoryStatsBadStatFile(t *testing.T) {
   398  	helper := NewCgroupTestUtil("memory", t)
   399  	defer helper.cleanup()
   400  	helper.writeFileContents(map[string]string{
   401  		"memory.stat":               "rss rss",
   402  		"memory.usage_in_bytes":     memoryUsageContents,
   403  		"memory.max_usage_in_bytes": memoryMaxUsageContents,
   404  		"memory.limit_in_bytes":     memoryLimitContents,
   405  	})
   406  
   407  	memory := &MemoryGroup{}
   408  	actualStats := *cgroups.NewStats()
   409  	err := memory.GetStats(helper.CgroupPath, &actualStats)
   410  	if err == nil {
   411  		t.Fatal("Expected failure")
   412  	}
   413  }
   414  
   415  func TestMemoryStatsBadUsageFile(t *testing.T) {
   416  	helper := NewCgroupTestUtil("memory", t)
   417  	defer helper.cleanup()
   418  	helper.writeFileContents(map[string]string{
   419  		"memory.stat":               memoryStatContents,
   420  		"memory.usage_in_bytes":     "bad",
   421  		"memory.max_usage_in_bytes": memoryMaxUsageContents,
   422  		"memory.limit_in_bytes":     memoryLimitContents,
   423  	})
   424  
   425  	memory := &MemoryGroup{}
   426  	actualStats := *cgroups.NewStats()
   427  	err := memory.GetStats(helper.CgroupPath, &actualStats)
   428  	if err == nil {
   429  		t.Fatal("Expected failure")
   430  	}
   431  }
   432  
   433  func TestMemoryStatsBadMaxUsageFile(t *testing.T) {
   434  	helper := NewCgroupTestUtil("memory", t)
   435  	defer helper.cleanup()
   436  	helper.writeFileContents(map[string]string{
   437  		"memory.stat":               memoryStatContents,
   438  		"memory.usage_in_bytes":     memoryUsageContents,
   439  		"memory.max_usage_in_bytes": "bad",
   440  		"memory.limit_in_bytes":     memoryLimitContents,
   441  	})
   442  
   443  	memory := &MemoryGroup{}
   444  	actualStats := *cgroups.NewStats()
   445  	err := memory.GetStats(helper.CgroupPath, &actualStats)
   446  	if err == nil {
   447  		t.Fatal("Expected failure")
   448  	}
   449  }
   450  
   451  func TestMemoryStatsBadLimitInBytesFile(t *testing.T) {
   452  	helper := NewCgroupTestUtil("memory", t)
   453  	defer helper.cleanup()
   454  	helper.writeFileContents(map[string]string{
   455  		"memory.stat":               memoryStatContents,
   456  		"memory.usage_in_bytes":     memoryUsageContents,
   457  		"memory.max_usage_in_bytes": memoryMaxUsageContents,
   458  		"memory.limit_in_bytes":     "bad",
   459  	})
   460  
   461  	memory := &MemoryGroup{}
   462  	actualStats := *cgroups.NewStats()
   463  	err := memory.GetStats(helper.CgroupPath, &actualStats)
   464  	if err == nil {
   465  		t.Fatal("Expected failure")
   466  	}
   467  }
   468  
   469  func TestMemorySetOomControl(t *testing.T) {
   470  	helper := NewCgroupTestUtil("memory", t)
   471  	defer helper.cleanup()
   472  
   473  	const (
   474  		oomKillDisable = 1 // disable oom killer, default is 0
   475  	)
   476  
   477  	helper.writeFileContents(map[string]string{
   478  		"memory.oom_control": strconv.Itoa(oomKillDisable),
   479  	})
   480  
   481  	memory := &MemoryGroup{}
   482  	if err := memory.Set(helper.CgroupPath, helper.CgroupData.config); err != nil {
   483  		t.Fatal(err)
   484  	}
   485  
   486  	value, err := getCgroupParamUint(helper.CgroupPath, "memory.oom_control")
   487  	if err != nil {
   488  		t.Fatalf("Failed to parse memory.oom_control - %s", err)
   489  	}
   490  
   491  	if value != oomKillDisable {
   492  		t.Fatalf("Got the wrong value, set memory.oom_control failed.")
   493  	}
   494  }