summaryrefslogtreecommitdiffhomepage
path: root/test/benchmarks/tools
diff options
context:
space:
mode:
Diffstat (limited to 'test/benchmarks/tools')
-rw-r--r--test/benchmarks/tools/BUILD2
-rw-r--r--test/benchmarks/tools/meminfo.go60
-rw-r--r--test/benchmarks/tools/meminfo_test.go84
3 files changed, 146 insertions, 0 deletions
diff --git a/test/benchmarks/tools/BUILD b/test/benchmarks/tools/BUILD
index a6bd949e6..e5734d85c 100644
--- a/test/benchmarks/tools/BUILD
+++ b/test/benchmarks/tools/BUILD
@@ -9,6 +9,7 @@ go_library(
"fio.go",
"hey.go",
"iperf.go",
+ "meminfo.go",
"redis.go",
"sysbench.go",
"tools.go",
@@ -24,6 +25,7 @@ go_test(
"fio_test.go",
"hey_test.go",
"iperf_test.go",
+ "meminfo_test.go",
"redis_test.go",
"sysbench_test.go",
],
diff --git a/test/benchmarks/tools/meminfo.go b/test/benchmarks/tools/meminfo.go
new file mode 100644
index 000000000..2414a96a7
--- /dev/null
+++ b/test/benchmarks/tools/meminfo.go
@@ -0,0 +1,60 @@
+// Copyright 2020 The gVisor Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package tools
+
+import (
+ "fmt"
+ "regexp"
+ "strconv"
+ "testing"
+)
+
+// Meminfo wraps measurements of MemAvailable using /proc/meminfo.
+type Meminfo struct {
+}
+
+// MakeCmd returns a command for checking meminfo.
+func (*Meminfo) MakeCmd() (string, []string) {
+ return "cat", []string{"/proc/meminfo"}
+}
+
+// Report takes two reads of meminfo, parses them, and reports the difference
+// divided by b.N.
+func (*Meminfo) Report(b *testing.B, before, after string) {
+ b.Helper()
+
+ beforeVal, err := parseMemAvailable(before)
+ if err != nil {
+ b.Fatalf("could not parse before value %s: %v", before, err)
+ }
+
+ afterVal, err := parseMemAvailable(after)
+ if err != nil {
+ b.Fatalf("could not parse before value %s: %v", before, err)
+ }
+ val := 1024 * ((beforeVal - afterVal) / float64(b.N))
+ b.ReportMetric(val, "average_container_size_bytes")
+}
+
+var memInfoRE = regexp.MustCompile(`MemAvailable:\s*(\d+)\skB\n`)
+
+// parseMemAvailable grabs the MemAvailable number from /proc/meminfo.
+func parseMemAvailable(data string) (float64, error) {
+ match := memInfoRE.FindStringSubmatch(data)
+ if len(match) < 2 {
+ return 0, fmt.Errorf("couldn't find MemAvailable in %s", data)
+ }
+ return strconv.ParseFloat(match[1], 64)
+}
diff --git a/test/benchmarks/tools/meminfo_test.go b/test/benchmarks/tools/meminfo_test.go
new file mode 100644
index 000000000..ba803540f
--- /dev/null
+++ b/test/benchmarks/tools/meminfo_test.go
@@ -0,0 +1,84 @@
+// Copyright 2020 The gVisor Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package tools
+
+import (
+ "testing"
+)
+
+// TestMeminfo checks the Meminfo parser on sample output.
+func TestMeminfo(t *testing.T) {
+ sampleData := `
+MemTotal: 16337408 kB
+MemFree: 3742696 kB
+MemAvailable: 9319948 kB
+Buffers: 1433884 kB
+Cached: 4607036 kB
+SwapCached: 45284 kB
+Active: 8288376 kB
+Inactive: 2685928 kB
+Active(anon): 4724912 kB
+Inactive(anon): 1047940 kB
+Active(file): 3563464 kB
+Inactive(file): 1637988 kB
+Unevictable: 326940 kB
+Mlocked: 48 kB
+SwapTotal: 33292284 kB
+SwapFree: 32865736 kB
+Dirty: 708 kB
+Writeback: 0 kB
+AnonPages: 4304204 kB
+Mapped: 975424 kB
+Shmem: 910292 kB
+KReclaimable: 744532 kB
+Slab: 1058448 kB
+SReclaimable: 744532 kB
+SUnreclaim: 313916 kB
+KernelStack: 25188 kB
+PageTables: 65300 kB
+NFS_Unstable: 0 kB
+Bounce: 0 kB
+WritebackTmp: 0 kB
+CommitLimit: 41460988 kB
+Committed_AS: 22859492 kB
+VmallocTotal: 34359738367 kB
+VmallocUsed: 63088 kB
+VmallocChunk: 0 kB
+Percpu: 9248 kB
+HardwareCorrupted: 0 kB
+AnonHugePages: 786432 kB
+ShmemHugePages: 0 kB
+ShmemPmdMapped: 0 kB
+FileHugePages: 0 kB
+FilePmdMapped: 0 kB
+HugePages_Total: 0
+HugePages_Free: 0
+HugePages_Rsvd: 0
+HugePages_Surp: 0
+Hugepagesize: 2048 kB
+Hugetlb: 0 kB
+DirectMap4k: 5408532 kB
+DirectMap2M: 11241472 kB
+DirectMap1G: 1048576 kB
+`
+ want := 9319948.0
+ got, err := parseMemAvailable(sampleData)
+ if err != nil {
+ t.Fatalf("parseMemAvailable failed: %v", err)
+ }
+ if got != want {
+ t.Fatalf("parseMemAvailable got %f, want %f", got, want)
+ }
+}