1 package memory
2
3 import (
4 "context"
5 "testing"
6 "time"
7
8 "github.com/stretchr/testify/assert"
9
10 "github.com/datawire/dlib/dlog"
11 )
12
13
14
15 func TestMemoryUsage(t *testing.T) {
16 start := time.Now()
17 usage := &MemoryUsage{}
18
19
20 usage.maybeDo(start, func() {
21 assert.Fail(t, "no action")
22 })
23
24
25 usage.usage = 1024 * 1024
26 usage.maybeDo(start, func() {
27 assert.Fail(t, "no action")
28 })
29
30
31 usage.usage = 1024 * 1024 * 1024
32 did := false
33 usage.maybeDo(start, func() {
34 did = true
35 })
36 assert.True(t, did)
37
38
39 usage.maybeDo(start, func() {
40 assert.Fail(t, "no action")
41 })
42
43
44 usage.maybeDo(start.Add(60*time.Second), func() {
45 assert.Fail(t, "no action")
46 })
47
48
49 usage.limit = usage.usage + 1
50 did = false
51 usage.maybeDo(start.Add(60*time.Second), func() {
52 did = true
53 })
54 assert.True(t, did)
55
56
57 usage.maybeDo(start.Add(61*time.Second), func() {
58 assert.Fail(t, "no action")
59 })
60
61
62 did = false
63 usage.maybeDo(start.Add(120*time.Second), func() {
64 did = true
65 })
66 assert.True(t, did)
67 }
68
69
70 func TestMemoryUsageGCExited(t *testing.T) {
71 ctx := dlog.NewTestContext(t, false)
72 count := 0
73 m := &MemoryUsage{
74 limit: unlimited,
75 perProcess: map[int]*ProcessUsage{},
76 readUsage: func(_ context.Context) (memory, memory) {
77 return 0, unlimited
78 },
79 readPerProcess: func(_ context.Context) map[int]*ProcessUsage {
80 defer func() {
81 count = count + 1
82 }()
83 switch count {
84 case 0:
85 return map[int]*ProcessUsage{
86 1: {1, []string{"one"}, 1024, 0},
87 2: {2, []string{"two"}, 1024, 0},
88 3: {3, []string{"three"}, 1024, 0},
89 4: {4, []string{"four"}, 1024, 0},
90 5: {5, []string{"five"}, 1024, 0},
91 }
92 case 1:
93 return map[int]*ProcessUsage{
94 1: {1, []string{"one"}, 1024, 0},
95 2: {2, []string{"two"}, 1024, 0},
96 4: {4, []string{"four"}, 1024, 0},
97 5: {5, []string{"five"}, 1024, 0},
98 }
99 case 2:
100 return map[int]*ProcessUsage{
101 1: {1, []string{"one"}, 1024, 0},
102 2: {2, []string{"two"}, 1024, 0},
103 5: {5, []string{"five"}, 1024, 0},
104 }
105 case 3:
106 return map[int]*ProcessUsage{
107 1: {1, []string{"one"}, 1024, 0},
108 5: {5, []string{"five"}, 1024, 0},
109 }
110 default:
111 return map[int]*ProcessUsage{
112 1: {1, []string{"one"}, 1024, 0},
113 5: {5, []string{"five"}, 1024, 0},
114 }
115 }
116 },
117 }
118
119 t.Log(m.String())
120
121 assert.Equal(t, 0, len(m.perProcess))
122 m.Refresh(ctx)
123 t.Log(m.String())
124 assert.Equal(t, 5, len(m.perProcess))
125 m.Refresh(ctx)
126 t.Log(m.String())
127 for i := 0; i < 10; i++ {
128 assert.Equal(t, 5, len(m.perProcess))
129 m.Refresh(ctx)
130 t.Log(m.String())
131 }
132
133 m.Refresh(ctx)
134 assert.Equal(t, 4, len(m.perProcess))
135 t.Log(m.String())
136 assert.NotContains(t, m.perProcess, 3)
137
138 m.Refresh(ctx)
139 assert.Equal(t, 3, len(m.perProcess))
140 t.Log(m.String())
141 assert.NotContains(t, m.perProcess, 4)
142
143 m.Refresh(ctx)
144 assert.Equal(t, 2, len(m.perProcess))
145 t.Log(m.String())
146 assert.NotContains(t, m.perProcess, 2)
147
148 m.Refresh(ctx)
149 assert.Equal(t, 2, len(m.perProcess))
150 t.Log(m.String())
151 assert.Contains(t, m.perProcess, 1)
152 assert.Contains(t, m.perProcess, 5)
153
154 }
155
156 func TestParseMemoryStat(t *testing.T) {
157 assert := assert.New(t)
158 contents := `
159 cache 175247360
160 rss 403296256
161 rss_huge 65011712
162 shmem 0
163 mapped_file 93401088
164 dirty 0
165 writeback 0
166 swap 1
167 pgpgin 5829351
168 pgpgout 5726886
169 pgfault 5848359
170 pgmajfault 792
171 inactive_anon 0
172 active_anon 309968896
173 inactive_file 222568448
174 active_file 46092288
175 unevictable 0
176 hierarchical_memory_limit 2097152000
177 hierarchical_memsw_limit 9223372036854771712
178 total_cache 175247360
179 total_rss 403296256
180 total_rss_huge 65011712
181 total_shmem 0
182 total_mapped_file 93401088
183 total_dirty 0
184 total_writeback 0
185 total_swap 0
186 total_pgpgin 5829351
187 total_pgpgout 5726886
188 total_pgfault 5848359
189 total_pgmajfault 792
190 total_inactive_anon 0
191 total_active_anon 309968896
192 total_inactive_file 222568448
193 total_active_file 46092288
194 total_unevictable 0
195 `
196 result, err := parseMemoryStat(contents)
197 assert.NoError(err)
198 assert.Equal(uint64(403296256), result.Rss)
199 assert.Equal(uint64(175247360), result.Cache)
200 assert.Equal(uint64(1), result.Swap)
201 assert.Equal(uint64(222568448), result.InactiveFile)
202 }
203
View as plain text