Browse Source

Adding a test for blkio stats.

Also adds a test utility we can use for other cgroup tests.

Docker-DCO-1.1-Signed-off-by: Victor Marmol <vmarmol@google.com> (github: vmarmol)
Victor Marmol 11 years ago
parent
commit
f4055ee2a4
2 changed files with 244 additions and 0 deletions
  1. 169 0
      pkg/cgroups/fs/blkio_test.go
  2. 75 0
      pkg/cgroups/fs/test_util.go

+ 169 - 0
pkg/cgroups/fs/blkio_test.go

@@ -0,0 +1,169 @@
+package fs
+
+import (
+	"testing"
+)
+
+const (
+	sectorsRecursiveContents      = `8:0 1024`
+	serviceBytesRecursiveContents = `8:0 Read 100
+8:0 Write 400
+8:0 Sync 200
+8:0 Async 300
+8:0 Total 500
+Total 500`
+	servicedRecursiveContents = `8:0 Read 10
+8:0 Write 40
+8:0 Sync 20
+8:0 Async 30
+8:0 Total 50
+Total 50`
+	queuedRecursiveContents = `8:0 Read 1
+8:0 Write 4
+8:0 Sync 2
+8:0 Async 3
+8:0 Total 5
+Total 5`
+)
+
+func TestBlkioStats(t *testing.T) {
+	helper := NewCgroupTestUtil("blkio", t)
+	defer helper.cleanup()
+	helper.writeFileContents(map[string]string{
+		"blkio.io_service_bytes_recursive": serviceBytesRecursiveContents,
+		"blkio.io_serviced_recursive":      servicedRecursiveContents,
+		"blkio.io_queued_recursive":        queuedRecursiveContents,
+		"blkio.sectors_recursive":          sectorsRecursiveContents,
+	})
+
+	blkio := &blkioGroup{}
+	stats, err := blkio.Stats(helper.CgroupData)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// Verify expected stats.
+	expectedStats := map[string]float64{
+		"blkio.sectors_recursive:8:0": 1024.0,
+
+		// Serviced bytes.
+		"io_service_bytes_recursive:8:0:Read":  100.0,
+		"io_service_bytes_recursive:8:0:Write": 400.0,
+		"io_service_bytes_recursive:8:0:Sync":  200.0,
+		"io_service_bytes_recursive:8:0:Async": 300.0,
+		"io_service_bytes_recursive:8:0:Total": 500.0,
+
+		// Serviced requests.
+		"io_serviced_recursive:8:0:Read":  10.0,
+		"io_serviced_recursive:8:0:Write": 40.0,
+		"io_serviced_recursive:8:0:Sync":  20.0,
+		"io_serviced_recursive:8:0:Async": 30.0,
+		"io_serviced_recursive:8:0:Total": 50.0,
+
+		// Queued requests.
+		"io_queued_recursive:8:0:Read":  1.0,
+		"io_queued_recursive:8:0:Write": 4.0,
+		"io_queued_recursive:8:0:Sync":  2.0,
+		"io_queued_recursive:8:0:Async": 3.0,
+		"io_queued_recursive:8:0:Total": 5.0,
+	}
+	expectStats(t, expectedStats, stats)
+}
+
+func TestBlkioStatsNoSectorsFile(t *testing.T) {
+	helper := NewCgroupTestUtil("blkio", t)
+	defer helper.cleanup()
+	helper.writeFileContents(map[string]string{
+		"blkio.io_service_bytes_recursive": serviceBytesRecursiveContents,
+		"blkio.io_serviced_recursive":      servicedRecursiveContents,
+		"blkio.io_queued_recursive":        queuedRecursiveContents,
+	})
+
+	blkio := &blkioGroup{}
+	_, err := blkio.Stats(helper.CgroupData)
+	if err == nil {
+		t.Fatal("Expected to fail, but did not")
+	}
+}
+
+func TestBlkioStatsNoServiceBytesFile(t *testing.T) {
+	helper := NewCgroupTestUtil("blkio", t)
+	defer helper.cleanup()
+	helper.writeFileContents(map[string]string{
+		"blkio.io_serviced_recursive": servicedRecursiveContents,
+		"blkio.io_queued_recursive":   queuedRecursiveContents,
+		"blkio.sectors_recursive":     sectorsRecursiveContents,
+	})
+
+	blkio := &blkioGroup{}
+	_, err := blkio.Stats(helper.CgroupData)
+	if err == nil {
+		t.Fatal("Expected to fail, but did not")
+	}
+}
+
+func TestBlkioStatsNoServicedFile(t *testing.T) {
+	helper := NewCgroupTestUtil("blkio", t)
+	defer helper.cleanup()
+	helper.writeFileContents(map[string]string{
+		"blkio.io_service_bytes_recursive": serviceBytesRecursiveContents,
+		"blkio.io_queued_recursive":        queuedRecursiveContents,
+		"blkio.sectors_recursive":          sectorsRecursiveContents,
+	})
+
+	blkio := &blkioGroup{}
+	_, err := blkio.Stats(helper.CgroupData)
+	if err == nil {
+		t.Fatal("Expected to fail, but did not")
+	}
+}
+
+func TestBlkioStatsNoQueuedFile(t *testing.T) {
+	helper := NewCgroupTestUtil("blkio", t)
+	defer helper.cleanup()
+	helper.writeFileContents(map[string]string{
+		"blkio.io_service_bytes_recursive": serviceBytesRecursiveContents,
+		"blkio.io_serviced_recursive":      servicedRecursiveContents,
+		"blkio.sectors_recursive":          sectorsRecursiveContents,
+	})
+
+	blkio := &blkioGroup{}
+	_, err := blkio.Stats(helper.CgroupData)
+	if err == nil {
+		t.Fatal("Expected to fail, but did not")
+	}
+}
+
+func TestBlkioStatsUnexpectedNumberOfFields(t *testing.T) {
+	helper := NewCgroupTestUtil("blkio", t)
+	defer helper.cleanup()
+	helper.writeFileContents(map[string]string{
+		"blkio.io_service_bytes_recursive": "8:0 Read 100 100",
+		"blkio.io_serviced_recursive":      servicedRecursiveContents,
+		"blkio.io_queued_recursive":        queuedRecursiveContents,
+		"blkio.sectors_recursive":          sectorsRecursiveContents,
+	})
+
+	blkio := &blkioGroup{}
+	_, err := blkio.Stats(helper.CgroupData)
+	if err == nil {
+		t.Fatal("Expected to fail, but did not")
+	}
+}
+
+func TestBlkioStatsUnexpectedFieldType(t *testing.T) {
+	helper := NewCgroupTestUtil("blkio", t)
+	defer helper.cleanup()
+	helper.writeFileContents(map[string]string{
+		"blkio.io_service_bytes_recursive": "8:0 Read Write",
+		"blkio.io_serviced_recursive":      servicedRecursiveContents,
+		"blkio.io_queued_recursive":        queuedRecursiveContents,
+		"blkio.sectors_recursive":          sectorsRecursiveContents,
+	})
+
+	blkio := &blkioGroup{}
+	_, err := blkio.Stats(helper.CgroupData)
+	if err == nil {
+		t.Fatal("Expected to fail, but did not")
+	}
+}

+ 75 - 0
pkg/cgroups/fs/test_util.go

@@ -0,0 +1,75 @@
+/*
+Utility for testing cgroup operations.
+
+Creates a mock of the cgroup filesystem for the duration of the test.
+*/
+package fs
+
+import (
+	"fmt"
+	"io/ioutil"
+	"log"
+	"os"
+	"testing"
+)
+
+type cgroupTestUtil struct {
+	// data to use in tests.
+	CgroupData *data
+
+	// Path to the mock cgroup directory.
+	CgroupPath string
+
+	// Temporary directory to store mock cgroup filesystem.
+	tempDir string
+	t       *testing.T
+}
+
+// Creates a new test util for the specified subsystem
+func NewCgroupTestUtil(subsystem string, t *testing.T) *cgroupTestUtil {
+	d := &data{}
+	tempDir, err := ioutil.TempDir("", fmt.Sprintf("%s_cgroup_test", subsystem))
+	if err != nil {
+		t.Fatal(err)
+	}
+	d.root = tempDir
+	testCgroupPath, err := d.path(subsystem)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// Ensure the full mock cgroup path exists.
+	err = os.MkdirAll(testCgroupPath, 0755)
+	if err != nil {
+		t.Fatal(err)
+	}
+	return &cgroupTestUtil{CgroupData: d, CgroupPath: testCgroupPath, tempDir: tempDir, t: t}
+}
+
+func (c *cgroupTestUtil) cleanup() {
+	os.RemoveAll(c.tempDir)
+}
+
+// Write the specified contents on the mock of the specified cgroup files.
+func (c *cgroupTestUtil) writeFileContents(fileContents map[string]string) {
+	for file, contents := range fileContents {
+		err := writeFile(c.CgroupPath, file, contents)
+		if err != nil {
+			c.t.Fatal(err)
+		}
+	}
+}
+
+// Expect the specified stats.
+func expectStats(t *testing.T, expected, actual map[string]float64) {
+	for stat, expectedValue := range expected {
+		actualValue, ok := actual[stat]
+		if !ok {
+			log.Printf("Expected stat %s to exist: %s", stat, actual)
+			t.Fail()
+		} else if actualValue != expectedValue {
+			log.Printf("Expected stats %s to have value %f but had %f instead", stat, expectedValue, actualValue)
+			t.Fail()
+		}
+	}
+}