19563: Report process size in bytes, not pages.
[arvados.git] / lib / crunchstat / crunchstat_test.go
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 package crunchstat
6
7 import (
8         "bytes"
9         "log"
10         "os"
11         "regexp"
12         "strconv"
13         "testing"
14         "time"
15
16         "github.com/sirupsen/logrus"
17         . "gopkg.in/check.v1"
18 )
19
20 func Test(t *testing.T) {
21         TestingT(t)
22 }
23
24 var _ = Suite(&suite{})
25
26 type suite struct{}
27
28 func (s *suite) TestReadAllOrWarnFail(c *C) {
29         var logger bytes.Buffer
30         rep := Reporter{Logger: log.New(&logger, "", 0)}
31
32         // The special file /proc/self/mem can be opened for
33         // reading, but reading from byte 0 returns an error.
34         f, err := os.Open("/proc/self/mem")
35         c.Assert(err, IsNil)
36         defer f.Close()
37         _, err = rep.readAllOrWarn(f)
38         c.Check(err, NotNil)
39         c.Check(logger.String(), Matches, "^warning: read /proc/self/mem: .*\n")
40 }
41
42 func (s *suite) TestReadAllOrWarnSuccess(c *C) {
43         var logbuf bytes.Buffer
44         rep := Reporter{Logger: log.New(&logbuf, "", 0)}
45
46         f, err := os.Open("./crunchstat_test.go")
47         c.Assert(err, IsNil)
48         defer f.Close()
49         data, err := rep.readAllOrWarn(f)
50         c.Check(err, IsNil)
51         c.Check(string(data), Matches, "(?ms).*\npackage crunchstat\n.*")
52         c.Check(logbuf.String(), Equals, "")
53 }
54
55 func (s *suite) TestReportPIDs(c *C) {
56         var logbuf bytes.Buffer
57         logger := logrus.New()
58         logger.Out = &logbuf
59         r := Reporter{
60                 Logger:     logger,
61                 CgroupRoot: "/sys/fs/cgroup",
62                 PollPeriod: time.Second,
63         }
64         r.Start()
65         r.ReportPID("init", 1)
66         r.ReportPID("test_process", os.Getpid())
67         r.ReportPID("nonexistent", 12345) // should be silently ignored/omitted
68         for deadline := time.Now().Add(10 * time.Second); ; time.Sleep(time.Millisecond) {
69                 if time.Now().After(deadline) {
70                         c.Error("timed out")
71                         break
72                 }
73                 if m := regexp.MustCompile(`(?ms).*procmem \d+ init (\d+) test_process.*`).FindSubmatch(logbuf.Bytes()); len(m) > 0 {
74                         size, err := strconv.ParseInt(string(m[1]), 10, 64)
75                         c.Check(err, IsNil)
76                         // Expect >1 MiB and <100 MiB -- otherwise we
77                         // are probably misinterpreting /proc/N/stat
78                         // or multiplying by the wrong page size.
79                         c.Check(size > 1000000, Equals, true)
80                         c.Check(size < 100000000, Equals, true)
81                         break
82                 }
83         }
84         c.Logf("%s", logbuf.String())
85 }