2014-12-30 21:09:05 +08:00
|
|
|
package mem
|
2014-04-18 15:34:47 +08:00
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2017-03-15 21:10:23 +08:00
|
|
|
"runtime"
|
2014-04-18 15:34:47 +08:00
|
|
|
"testing"
|
2016-02-17 14:09:11 +08:00
|
|
|
|
2020-08-30 00:30:36 +08:00
|
|
|
"github.com/shirou/gopsutil/internal/common"
|
2016-02-17 14:09:11 +08:00
|
|
|
"github.com/stretchr/testify/assert"
|
2014-04-18 15:34:47 +08:00
|
|
|
)
|
|
|
|
|
2020-08-30 00:30:36 +08:00
|
|
|
func skipIfNotImplementedErr(t *testing.T, err error) {
|
|
|
|
if err == common.ErrNotImplementedError {
|
|
|
|
t.Skip("not implemented")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-04-18 15:34:47 +08:00
|
|
|
func TestVirtual_memory(t *testing.T) {
|
2017-03-15 21:10:23 +08:00
|
|
|
if runtime.GOOS == "solaris" {
|
|
|
|
t.Skip("Only .Total is supported on Solaris")
|
|
|
|
}
|
|
|
|
|
2014-05-23 09:31:47 +08:00
|
|
|
v, err := VirtualMemory()
|
2020-08-30 00:30:36 +08:00
|
|
|
skipIfNotImplementedErr(t, err)
|
2014-04-18 15:34:47 +08:00
|
|
|
if err != nil {
|
|
|
|
t.Errorf("error %v", err)
|
|
|
|
}
|
2014-05-23 09:31:47 +08:00
|
|
|
empty := &VirtualMemoryStat{}
|
2014-05-12 10:51:08 +08:00
|
|
|
if v == empty {
|
|
|
|
t.Errorf("error %v", v)
|
|
|
|
}
|
2019-03-16 20:43:15 +08:00
|
|
|
t.Log(v)
|
2016-02-17 14:09:11 +08:00
|
|
|
|
|
|
|
assert.True(t, v.Total > 0)
|
|
|
|
assert.True(t, v.Available > 0)
|
|
|
|
assert.True(t, v.Used > 0)
|
|
|
|
|
2018-07-19 06:19:02 +08:00
|
|
|
total := v.Used + v.Free + v.Buffers + v.Cached
|
|
|
|
totalStr := "used + free + buffers + cached"
|
2018-12-26 04:55:58 +08:00
|
|
|
switch runtime.GOOS {
|
|
|
|
case "windows":
|
2018-07-19 06:19:02 +08:00
|
|
|
total = v.Used + v.Available
|
|
|
|
totalStr = "used + available"
|
2020-08-31 18:42:46 +08:00
|
|
|
case "darwin", "openbsd":
|
2018-12-26 04:55:58 +08:00
|
|
|
total = v.Used + v.Free + v.Cached + v.Inactive
|
|
|
|
totalStr = "used + free + cached + inactive"
|
|
|
|
case "freebsd":
|
2018-08-07 19:00:00 +08:00
|
|
|
total = v.Used + v.Free + v.Cached + v.Inactive + v.Laundry
|
|
|
|
totalStr = "used + free + cached + inactive + laundry"
|
2018-08-07 18:30:32 +08:00
|
|
|
}
|
2018-07-19 06:19:02 +08:00
|
|
|
assert.Equal(t, v.Total, total,
|
|
|
|
"Total should be computable (%v): %v", totalStr, v)
|
2016-02-17 14:09:11 +08:00
|
|
|
|
2018-07-19 06:19:02 +08:00
|
|
|
assert.True(t, runtime.GOOS == "windows" || v.Free > 0)
|
2020-08-30 00:30:36 +08:00
|
|
|
assert.True(t, runtime.GOOS == "windows" || v.Available > v.Free,
|
2016-02-17 14:09:11 +08:00
|
|
|
"Free should be a subset of Available: %v", v)
|
|
|
|
|
2018-07-19 06:19:02 +08:00
|
|
|
inDelta := assert.InDelta
|
|
|
|
if runtime.GOOS == "windows" {
|
|
|
|
inDelta = assert.InEpsilon
|
|
|
|
}
|
|
|
|
inDelta(t, v.UsedPercent,
|
2016-02-17 14:09:11 +08:00
|
|
|
100*float64(v.Used)/float64(v.Total), 0.1,
|
|
|
|
"UsedPercent should be how many percent of Total is Used: %v", v)
|
2014-04-18 15:34:47 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestSwap_memory(t *testing.T) {
|
2014-05-23 09:31:47 +08:00
|
|
|
v, err := SwapMemory()
|
2020-08-30 00:30:36 +08:00
|
|
|
skipIfNotImplementedErr(t, err)
|
2014-04-18 15:34:47 +08:00
|
|
|
if err != nil {
|
|
|
|
t.Errorf("error %v", err)
|
|
|
|
}
|
2014-05-23 09:31:47 +08:00
|
|
|
empty := &SwapMemoryStat{}
|
2014-05-12 10:51:08 +08:00
|
|
|
if v == empty {
|
|
|
|
t.Errorf("error %v", v)
|
|
|
|
}
|
2019-03-16 20:43:15 +08:00
|
|
|
|
|
|
|
t.Log(v)
|
2014-05-12 10:51:08 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestVirtualMemoryStat_String(t *testing.T) {
|
2014-05-23 09:31:47 +08:00
|
|
|
v := VirtualMemoryStat{
|
2014-05-12 10:51:08 +08:00
|
|
|
Total: 10,
|
|
|
|
Available: 20,
|
|
|
|
Used: 30,
|
|
|
|
UsedPercent: 30.1,
|
|
|
|
Free: 40,
|
|
|
|
}
|
2019-07-20 22:42:39 +08:00
|
|
|
e := `{"total":10,"available":20,"used":30,"usedPercent":30.1,"free":40,"active":0,"inactive":0,"wired":0,"laundry":0,"buffers":0,"cached":0,"writeback":0,"dirty":0,"writebacktmp":0,"shared":0,"slab":0,"sreclaimable":0,"sunreclaim":0,"pagetables":0,"swapcached":0,"commitlimit":0,"committedas":0,"hightotal":0,"highfree":0,"lowtotal":0,"lowfree":0,"swaptotal":0,"swapfree":0,"mapped":0,"vmalloctotal":0,"vmallocused":0,"vmallocchunk":0,"hugepagestotal":0,"hugepagesfree":0,"hugepagesize":0}`
|
2014-05-12 10:51:08 +08:00
|
|
|
if e != fmt.Sprintf("%v", v) {
|
|
|
|
t.Errorf("VirtualMemoryStat string is invalid: %v", v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestSwapMemoryStat_String(t *testing.T) {
|
2014-05-23 09:31:47 +08:00
|
|
|
v := SwapMemoryStat{
|
2014-05-12 10:51:08 +08:00
|
|
|
Total: 10,
|
|
|
|
Used: 30,
|
|
|
|
Free: 40,
|
|
|
|
UsedPercent: 30.1,
|
2019-04-24 22:11:40 +08:00
|
|
|
Sin: 1,
|
|
|
|
Sout: 2,
|
|
|
|
PgIn: 3,
|
|
|
|
PgOut: 4,
|
|
|
|
PgFault: 5,
|
2020-05-25 15:15:30 +08:00
|
|
|
PgMajFault: 6,
|
2014-05-12 10:51:08 +08:00
|
|
|
}
|
2020-05-25 15:15:30 +08:00
|
|
|
e := `{"total":10,"used":30,"free":40,"usedPercent":30.1,"sin":1,"sout":2,"pgin":3,"pgout":4,"pgfault":5,"pgmajfault":6}`
|
2014-05-12 10:51:08 +08:00
|
|
|
if e != fmt.Sprintf("%v", v) {
|
|
|
|
t.Errorf("SwapMemoryStat string is invalid: %v", v)
|
|
|
|
}
|
2014-04-18 15:34:47 +08:00
|
|
|
}
|
2021-08-18 21:52:13 +08:00
|
|
|
|
|
|
|
func TestSwapDevices(t *testing.T) {
|
|
|
|
v, err := SwapDevices()
|
|
|
|
skipIfNotImplementedErr(t, err)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("error calling SwapDevices: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
t.Logf("SwapDevices() -> %+v", v)
|
|
|
|
|
|
|
|
if len(v) == 0 {
|
|
|
|
t.Fatalf("no swap devices found. [this is expected if the host has swap disabled]")
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, device := range v {
|
|
|
|
if device.Name == "" {
|
|
|
|
t.Fatalf("deviceName not set in %+v", device)
|
|
|
|
}
|
|
|
|
if device.FreeBytes == 0 {
|
|
|
|
t.Logf("[WARNING] free-bytes is zero in %+v. This might be expected", device)
|
|
|
|
}
|
|
|
|
if device.UsedBytes == 0 {
|
|
|
|
t.Logf("[WARNING] used-bytes is zero in %+v. This might be expected", device)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|