123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678 |
- package gosigar_test
- import (
- "fmt"
- "io/ioutil"
- "math/rand"
- "os"
- "path/filepath"
- "strconv"
- "testing"
- "time"
- sigar "notabug.org/themusicgod1/gosigar"
- "github.com/stretchr/testify/assert"
- )
- var procd string
- func setUp(t testing.TB) {
- var err error
- procd, err = ioutil.TempDir("", "sigarTests")
- if err != nil {
- t.Fatal(err)
- }
- sigar.Procd = procd
- }
- func tearDown(t testing.TB) {
- sigar.Procd = "/proc"
- err := os.RemoveAll(procd)
- if err != nil {
- t.Fatal(err)
- }
- }
- func TestLinuxProcState(t *testing.T) {
- setUp(t)
- defer tearDown(t)
- var procNames = []string{
- "cron",
- "a very long process name",
- "(sd-pam)",
- "]",
- "(",
- }
- for _, n := range procNames {
- func() {
- pid := rand.Int()
- pidDir := filepath.Join(procd, strconv.Itoa(pid))
- err := os.Mkdir(pidDir, 0755)
- if err != nil {
- t.Fatal(err)
- }
- defer os.RemoveAll(pidDir)
- pidStatFile := filepath.Join(pidDir, "stat")
- writePidStats(pid, n, pidStatFile)
- if err != nil {
- t.Fatal(err)
- }
- pidStatusFile := filepath.Join(pidDir, "status")
- uid := 123456789
- writePidStatus(n, pid, uid, pidStatusFile)
- if err != nil {
- t.Fatal(err)
- }
- state := sigar.ProcState{}
- if assert.NoError(t, state.Get(pid)) {
- expected := sigar.ProcState{
- Name: n,
- Username: strconv.Itoa(uid),
- State: 'S',
- Ppid: 1,
- Pgid: 2,
- Tty: 4,
- Priority: 15,
- Nice: 16,
- Processor: 36,
- }
- assert.Equal(t, expected, state)
- }
- }()
- }
- }
- func TestLinuxCPU(t *testing.T) {
- setUp(t)
- defer tearDown(t)
- tests := []struct {
- stat string
- user uint64
- }{
- {"cpu 25 1 2 3 4 5 6 7", 25},
- // Ignore empty lines
- {"cpu ", 0},
- }
- statFile := procd + "/stat"
- for _, test := range tests {
- func() {
- statContents := []byte(test.stat)
- err := ioutil.WriteFile(statFile, statContents, 0644)
- if err != nil {
- t.Fatal(err)
- }
- defer os.RemoveAll(statFile)
- cpu := sigar.Cpu{}
- if assert.NoError(t, cpu.Get()) {
- assert.Equal(t, uint64(test.user), cpu.User, "cpu.User")
- }
- }()
- }
- }
- func TestLinuxCollectCpuStats(t *testing.T) {
- setUp(t)
- defer tearDown(t)
- statFile := procd + "/stat"
- statContents := []byte("cpu 25 1 2 3 4 5 6 7")
- err := ioutil.WriteFile(statFile, statContents, 0644)
- if err != nil {
- t.Fatal(err)
- }
- concreteSigar := &sigar.ConcreteSigar{}
- cpuUsages, stop := concreteSigar.CollectCpuStats(500 * time.Millisecond)
- assert.Equal(t, sigar.Cpu{
- User: uint64(25),
- Nice: uint64(1),
- Sys: uint64(2),
- Idle: uint64(3),
- Wait: uint64(4),
- Irq: uint64(5),
- SoftIrq: uint64(6),
- Stolen: uint64(7),
- }, <-cpuUsages)
- statContents = []byte("cpu 30 3 7 10 25 55 36 65")
- err = ioutil.WriteFile(statFile, statContents, 0644)
- if err != nil {
- t.Fatal(err)
- }
- assert.Equal(t, sigar.Cpu{
- User: uint64(5),
- Nice: uint64(2),
- Sys: uint64(5),
- Idle: uint64(7),
- Wait: uint64(21),
- Irq: uint64(50),
- SoftIrq: uint64(30),
- Stolen: uint64(58),
- }, <-cpuUsages)
- stop <- struct{}{}
- }
- func TestLinuxMemAndSwap(t *testing.T) {
- setUp(t)
- defer tearDown(t)
- meminfoContents := `
- MemTotal: 374256 kB
- MemFree: 274460 kB
- Buffers: 9764 kB
- Cached: 38648 kB
- SwapCached: 0 kB
- Active: 33772 kB
- Inactive: 31184 kB
- Active(anon): 16572 kB
- Inactive(anon): 552 kB
- Active(file): 17200 kB
- Inactive(file): 30632 kB
- Unevictable: 0 kB
- Mlocked: 0 kB
- SwapTotal: 786428 kB
- SwapFree: 786428 kB
- Dirty: 0 kB
- Writeback: 0 kB
- AnonPages: 16564 kB
- Mapped: 6612 kB
- Shmem: 584 kB
- Slab: 19092 kB
- SReclaimable: 9128 kB
- SUnreclaim: 9964 kB
- KernelStack: 672 kB
- PageTables: 1864 kB
- NFS_Unstable: 0 kB
- Bounce: 0 kB
- WritebackTmp: 0 kB
- CommitLimit: 973556 kB
- Committed_AS: 55880 kB
- VmallocTotal: 34359738367 kB
- VmallocUsed: 21428 kB
- VmallocChunk: 34359713596 kB
- HardwareCorrupted: 0 kB
- AnonHugePages: 0 kB
- HugePages_Total: 0
- HugePages_Free: 0
- HugePages_Rsvd: 0
- HugePages_Surp: 0
- Hugepagesize: 2048 kB
- DirectMap4k: 59328 kB
- DirectMap2M: 333824 kB
- `
- meminfoFile := procd + "/meminfo"
- err := ioutil.WriteFile(meminfoFile, []byte(meminfoContents), 0444)
- if err != nil {
- t.Fatal(err)
- }
- mem := sigar.Mem{}
- if assert.NoError(t, mem.Get()) {
- assert.Equal(t, uint64(374256*1024), mem.Total)
- assert.Equal(t, uint64(274460*1024), mem.Free)
- assert.Equal(t, uint64(mem.Total-mem.Free), mem.Used)
- assert.Equal(t, uint64((274460+9764+38648)*1024), mem.ActualFree)
- assert.Equal(t, uint64(mem.Total-mem.ActualFree), mem.ActualUsed)
- }
- swap := sigar.Swap{}
- if assert.NoError(t, swap.Get()) {
- assert.Equal(t, uint64(786428*1024), swap.Total)
- assert.Equal(t, uint64(786428*1024), swap.Free)
- }
- }
- func TestLinuxMemAndSwapKernel_3_14(t *testing.T) {
- setUp(t)
- defer tearDown(t)
- meminfoContents := `
- MemTotal: 500184 kB
- MemFree: 31360 kB
- MemAvailable: 414168 kB
- Buffers: 28740 kB
- Cached: 325408 kB
- SwapCached: 264 kB
- Active: 195476 kB
- Inactive: 198612 kB
- Active(anon): 14920 kB
- Inactive(anon): 27268 kB
- Active(file): 180556 kB
- Inactive(file): 171344 kB
- Unevictable: 0 kB
- Mlocked: 0 kB
- SwapTotal: 524284 kB
- SwapFree: 520352 kB
- Dirty: 0 kB
- Writeback: 0 kB
- AnonPages: 39772 kB
- Mapped: 24132 kB
- Shmem: 2236 kB
- Slab: 57988 kB
- SReclaimable: 43524 kB
- SUnreclaim: 14464 kB
- KernelStack: 2464 kB
- PageTables: 3096 kB
- NFS_Unstable: 0 kB
- Bounce: 0 kB
- WritebackTmp: 0 kB
- CommitLimit: 774376 kB
- Committed_AS: 490916 kB
- VmallocTotal: 34359738367 kB
- VmallocUsed: 0 kB
- VmallocChunk: 0 kB
- HardwareCorrupted: 0 kB
- AnonHugePages: 0 kB
- CmaTotal: 0 kB
- CmaFree: 0 kB
- HugePages_Total: 0
- HugePages_Free: 0
- HugePages_Rsvd: 0
- HugePages_Surp: 0
- Hugepagesize: 2048 kB
- DirectMap4k: 63424 kB
- DirectMap2M: 460800 kB
- `
- meminfoFile := procd + "/meminfo"
- err := ioutil.WriteFile(meminfoFile, []byte(meminfoContents), 0444)
- if err != nil {
- t.Fatal(err)
- }
- mem := sigar.Mem{}
- if assert.NoError(t, mem.Get()) {
- assert.Equal(t, uint64(500184*1024), mem.Total)
- assert.Equal(t, uint64(31360*1024), mem.Free)
- assert.Equal(t, uint64(414168*1024), mem.ActualFree)
- assert.Equal(t, uint64(mem.Total-mem.Free), mem.Used)
- assert.Equal(t, uint64(mem.Total-mem.ActualFree), mem.ActualUsed)
- }
- swap := sigar.Swap{}
- if assert.NoError(t, swap.Get()) {
- assert.Equal(t, uint64(524284*1024), swap.Total)
- assert.Equal(t, uint64(520352*1024), swap.Free)
- }
- }
- func TestLinuxMemAndSwapMissingMemTotal(t *testing.T) {
- setUp(t)
- defer tearDown(t)
- meminfoContents := `
- MemFree: 31360 kB
- MemAvailable: 414168 kB
- Buffers: 28740 kB
- Cached: 325408 kB
- SwapCached: 264 kB
- Active: 195476 kB
- Inactive: 198612 kB
- Active(anon): 14920 kB
- Inactive(anon): 27268 kB
- Active(file): 180556 kB
- Inactive(file): 171344 kB
- Unevictable: 0 kB
- Mlocked: 0 kB
- SwapTotal: 524284 kB
- SwapFree: 520352 kB
- Dirty: 0 kB
- Writeback: 0 kB
- AnonPages: 39772 kB
- Mapped: 24132 kB
- Shmem: 2236 kB
- Slab: 57988 kB
- SReclaimable: 43524 kB
- SUnreclaim: 14464 kB
- KernelStack: 2464 kB
- PageTables: 3096 kB
- NFS_Unstable: 0 kB
- Bounce: 0 kB
- WritebackTmp: 0 kB
- CommitLimit: 774376 kB
- Committed_AS: 490916 kB
- VmallocTotal: 34359738367 kB
- VmallocUsed: 0 kB
- VmallocChunk: 0 kB
- HardwareCorrupted: 0 kB
- AnonHugePages: 0 kB
- CmaTotal: 0 kB
- CmaFree: 0 kB
- HugePages_Total: 0
- HugePages_Free: 0
- HugePages_Rsvd: 0
- HugePages_Surp: 0
- Hugepagesize: 2048 kB
- DirectMap4k: 63424 kB
- DirectMap2M: 460800 kB
- `
- meminfoFile := procd + "/meminfo"
- err := ioutil.WriteFile(meminfoFile, []byte(meminfoContents), 0444)
- if err != nil {
- t.Fatal(err)
- }
- mem := sigar.Mem{}
- if assert.NoError(t, mem.Get()) {
- assert.Equal(t, uint64(0), mem.Total)
- assert.Equal(t, uint64(31360*1024), mem.Free)
- assert.Equal(t, uint64(414168*1024), mem.ActualFree)
- }
- swap := sigar.Swap{}
- if assert.NoError(t, swap.Get()) {
- assert.Equal(t, uint64(524284*1024), swap.Total)
- assert.Equal(t, uint64(520352*1024), swap.Free)
- }
- }
- func TestLinuxMemAndSwapKernel_3_14_memavailable_zero(t *testing.T) {
- setUp(t)
- defer tearDown(t)
- meminfoContents := `
- MemTotal: 148535680 kB
- MemFree: 417356 kB
- MemAvailable: 0 kB
- Buffers: 1728 kB
- Cached: 129928 kB
- SwapCached: 8208 kB
- Active: 141088676 kB
- Inactive: 5568132 kB
- Active(anon): 141076780 kB
- Inactive(anon): 5556936 kB
- Active(file): 11896 kB
- Inactive(file): 11196 kB
- Unevictable: 3648 kB
- Mlocked: 3648 kB
- SwapTotal: 4882428 kB
- SwapFree: 0 kB
- Dirty: 808 kB
- Writeback: 220 kB
- AnonPages: 146521272 kB
- Mapped: 41384 kB
- Shmem: 105864 kB
- Slab: 522648 kB
- SReclaimable: 233508 kB
- SUnreclaim: 289140 kB
- KernelStack: 85024 kB
- PageTables: 368760 kB
- NFS_Unstable: 0 kB
- Bounce: 0 kB
- WritebackTmp: 0 kB
- CommitLimit: 79150268 kB
- Committed_AS: 272491684 kB
- VmallocTotal: 34359738367 kB
- VmallocUsed: 0 kB
- VmallocChunk: 0 kB
- HardwareCorrupted: 0 kB
- AnonHugePages: 78061568 kB
- ShmemHugePages: 0 kB
- ShmemPmdMapped: 0 kB
- CmaTotal: 0 kB
- CmaFree: 0 kB
- HugePages_Total: 0
- HugePages_Free: 0
- HugePages_Rsvd: 0
- HugePages_Surp: 0
- Hugepagesize: 2048 kB
- DirectMap4k: 124388 kB
- DirectMap2M: 5105664 kB
- DirectMap1G: 147849216 kB
- `
- meminfoFile := procd + "/meminfo"
- err := ioutil.WriteFile(meminfoFile, []byte(meminfoContents), 0444)
- if err != nil {
- t.Fatal(err)
- }
- mem := sigar.Mem{}
- if assert.NoError(t, mem.Get()) {
- assert.Equal(t, uint64(148535680*1024), mem.Total)
- assert.Equal(t, uint64(417356*1024), mem.Free)
- assert.Equal(t, uint64(0), mem.ActualFree)
- }
- swap := sigar.Swap{}
- if assert.NoError(t, swap.Get()) {
- assert.Equal(t, uint64(4882428*1024), swap.Total)
- assert.Equal(t, uint64(0), swap.Free)
- }
- }
- func TestLinuxHugeTLBPages(t *testing.T) {
- setUp(t)
- defer tearDown(t)
- meminfoContents := `
- MemTotal: 374256 kB
- MemFree: 274460 kB
- Buffers: 9764 kB
- Cached: 38648 kB
- SwapCached: 0 kB
- Active: 33772 kB
- Inactive: 31184 kB
- Active(anon): 16572 kB
- Inactive(anon): 552 kB
- Active(file): 17200 kB
- Inactive(file): 30632 kB
- Unevictable: 0 kB
- Mlocked: 0 kB
- SwapTotal: 786428 kB
- SwapFree: 786428 kB
- Dirty: 0 kB
- Writeback: 0 kB
- AnonPages: 16564 kB
- Mapped: 6612 kB
- Shmem: 584 kB
- Slab: 19092 kB
- SReclaimable: 9128 kB
- SUnreclaim: 9964 kB
- KernelStack: 672 kB
- PageTables: 1864 kB
- NFS_Unstable: 0 kB
- Bounce: 0 kB
- WritebackTmp: 0 kB
- CommitLimit: 973556 kB
- Committed_AS: 55880 kB
- VmallocTotal: 34359738367 kB
- VmallocUsed: 21428 kB
- VmallocChunk: 34359713596 kB
- HardwareCorrupted: 0 kB
- AnonHugePages: 0 kB
- HugePages_Total: 16
- HugePages_Free: 14
- HugePages_Rsvd: 2
- HugePages_Surp: 0
- Hugepagesize: 2048 kB
- DirectMap4k: 59328 kB
- DirectMap2M: 333824 kB
- `
- meminfoFile := procd + "/meminfo"
- err := ioutil.WriteFile(meminfoFile, []byte(meminfoContents), 0444)
- if err != nil {
- t.Fatal(err)
- }
- hugePages := sigar.HugeTLBPages{}
- if assert.NoError(t, hugePages.Get()) {
- assert.Equal(t, uint64(16), hugePages.Total)
- assert.Equal(t, uint64(14), hugePages.Free)
- assert.Equal(t, uint64(2), hugePages.Reserved)
- assert.Equal(t, uint64(0), hugePages.Surplus)
- assert.Equal(t, uint64(2048*1024), hugePages.DefaultSize)
- assert.Equal(t, uint64(4*2048*1024), hugePages.TotalAllocatedSize)
- }
- }
- func TestFDUsage(t *testing.T) {
- setUp(t)
- defer tearDown(t)
- // There is no Uint63 until 2.0
- open := uint64(rand.Uint32())
- unused := uint64(rand.Uint32())
- max := uint64(rand.Uint32())
- fileNRContents := fmt.Sprintf("%d %d %d", open, unused, max)
- fileNRPath := procd + "/sys/fs"
- os.MkdirAll(fileNRPath, 0755)
- fileNRFile := fileNRPath + "/file-nr"
- err := ioutil.WriteFile(fileNRFile, []byte(fileNRContents), 0444)
- if err != nil {
- t.Fatal(err)
- }
- fd := sigar.FDUsage{}
- if assert.NoError(t, fd.Get()) {
- assert.Equal(t, open, fd.Open)
- assert.Equal(t, unused, fd.Unused)
- assert.Equal(t, max, fd.Max)
- }
- }
- func TestProcFDUsage(t *testing.T) {
- setUp(t)
- defer tearDown(t)
- pid := rand.Intn(32768)
- pidDir := fmt.Sprintf("%s/%d", procd, pid)
- err := os.Mkdir(pidDir, 0755)
- if err != nil {
- t.Fatal(err)
- }
- soft := uint64(rand.Uint32())
- // subtract to prevent the posibility of overflow
- if soft != 0 {
- soft -= 1
- }
- // max sure hard is always bigger than soft
- hard := soft + uint64(rand.Uint32())
- limitsContents := `Limit Soft Limit Hard Limit Units
- Max cpu time unlimited unlimited seconds
- Max file size unlimited unlimited bytes
- Max data size unlimited unlimited bytes
- Max stack size 8388608 unlimited bytes
- Max core file size 0 unlimited bytes
- Max resident set unlimited unlimited bytes
- Max processes 29875 29875 processes
- Max open files %d %d files
- Max locked memory 65536 65536 bytes
- Max address space unlimited unlimited bytes
- Max file locks unlimited unlimited locks
- Max pending signals 29875 29875 signals
- Max msgqueue size 819200 819200 bytes
- Max nice priority 0 0
- Max realtime priority 0 0
- Max realtime timeout unlimited unlimited us
- `
- limitsContents = fmt.Sprintf(limitsContents, soft, hard)
- limitsFile := pidDir + "/limits"
- err = ioutil.WriteFile(limitsFile, []byte(limitsContents), 0444)
- if err != nil {
- t.Fatal(err)
- }
- open := rand.Intn(32768)
- if err = writeFDs(pid, open); err != nil {
- t.Fatal(err)
- }
- procFD := sigar.ProcFDUsage{}
- if assert.NoError(t, procFD.Get(pid)) {
- assert.Equal(t, uint64(open), procFD.Open)
- assert.Equal(t, soft, procFD.SoftLimit)
- assert.Equal(t, hard, procFD.HardLimit)
- }
- }
- func writeFDs(pid int, count int) error {
- fdDir := fmt.Sprintf("%s/%d/fd", procd, pid)
- err := os.Mkdir(fdDir, 0755)
- if err != nil {
- return err
- }
- for i := 0; i < count; i++ {
- fdPath := fmt.Sprintf("%s/%d", fdDir, i)
- f, err := os.Create(fdPath)
- if err != nil {
- return err
- }
- f.Close()
- }
- return nil
- }
- func writePidStats(pid int, procName string, path string) error {
- stats := "S 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 " +
- "20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 " +
- "35 36 37 38 39"
- statContents := []byte(fmt.Sprintf("%d (%s) %s", pid, procName, stats))
- return ioutil.WriteFile(path, statContents, 0644)
- }
- func writePidStatus(name string, pid int, uid int, pidStatusFile string) error {
- status := `
- Name: %s
- State: R (running)
- Tgid: 5452
- Pid: %d
- PPid: 743
- TracerPid: 0
- Uid: %d %d %d %d
- Gid: 100 100 100 100
- FDSize: 256
- Groups: 100 14 16
- VmPeak: 5004 kB
- VmSize: 5004 kB
- VmLck: 0 kB
- VmHWM: 476 kB
- VmRSS: 476 kB
- RssAnon: 352 kB
- RssFile: 120 kB
- RssShmem: 4 kB
- VmData: 156 kB
- VmStk: 88 kB
- VmExe: 68 kB
- VmLib: 1412 kB
- VmPTE: 20 kb
- VmSwap: 0 kB
- HugetlbPages: 0 kB
- Threads: 1
- SigQ: 0/28578
- SigPnd: 0000000000000000
- ShdPnd: 0000000000000000
- SigBlk: 0000000000000000
- SigIgn: 0000000000000000
- SigCgt: 0000000000000000
- CapInh: 00000000fffffeff
- CapPrm: 0000000000000000
- CapEff: 0000000000000000
- CapBnd: ffffffffffffffff
- Seccomp: 0
- voluntary_ctxt_switches: 0
- nonvoluntary_ctxt_switches: 1`
- statusContents := []byte(fmt.Sprintf(status, name, pid, uid))
- return ioutil.WriteFile(pidStatusFile, statusContents, 0644)
- }
|