Add cgroup manage for mocking of package resources

Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
Michael Crosby
2014-10-22 23:53:28 +00:00
committed by Victor Marmol
parent 926ab56ea8
commit ccb83a1e83
6 changed files with 125 additions and 33 deletions

41
cgroups.go Normal file
View File

@@ -0,0 +1,41 @@
package libcontainer
import (
"github.com/docker/libcontainer/cgroups"
"github.com/docker/libcontainer/cgroups/fs"
"github.com/docker/libcontainer/cgroups/systemd"
)
type CgroupManager interface {
GetPids(*cgroups.Cgroup) ([]int, error)
GetStats(*cgroups.Cgroup) (*cgroups.Stats, error)
}
func newCgroupsManager() CgroupManager {
if systemd.UseSystemd() {
return &systemdCgroupManager{}
}
return &fsCgroupsManager{}
}
type systemdCgroupManager struct {
}
func (m *systemdCgroupManager) GetPids(config *cgroups.Cgroup) ([]int, error) {
return systemd.GetPids(config)
}
func (m *systemdCgroupManager) GetStats(config *cgroups.Cgroup) (*cgroups.Stats, error) {
return systemd.GetStats(config)
}
type fsCgroupsManager struct {
}
func (m *fsCgroupsManager) GetPids(config *cgroups.Cgroup) ([]int, error) {
return fs.GetPids(config)
}
func (m *fsCgroupsManager) GetStats(config *cgroups.Cgroup) (*cgroups.Stats, error) {
return fs.GetStats(config)
}

View File

@@ -12,7 +12,7 @@ type ContainerInfo interface {
// errors: // errors:
// ContainerDestroyed - Container no longer exists, // ContainerDestroyed - Container no longer exists,
// Systemerror - System error. // Systemerror - System error.
RunState() (*RunState, error) RunState() (RunState, error)
// Returns the current config of the container. // Returns the current config of the container.
Config() *Config Config() *Config

View File

@@ -2,17 +2,14 @@
package libcontainer package libcontainer
import ( import "github.com/docker/libcontainer/network"
"github.com/docker/libcontainer/cgroups/fs"
"github.com/docker/libcontainer/cgroups/systemd"
"github.com/docker/libcontainer/network"
)
type linuxContainer struct { type linuxContainer struct {
id string id string
root string root string
config *Config config *Config
state *State state *State
cgroupManager CgroupManager
} }
func (c *linuxContainer) ID() string { func (c *linuxContainer) ID() string {
@@ -23,21 +20,12 @@ func (c *linuxContainer) Config() *Config {
return c.config return c.config
} }
func (c *linuxContainer) RunState() (*RunState, error) { func (c *linuxContainer) RunState() (RunState, error) {
panic("not implemented") panic("not implemented")
} }
func (c *linuxContainer) Processes() ([]int, error) { func (c *linuxContainer) Processes() ([]int, error) {
var ( pids, err := c.cgroupManager.GetPids(c.config.Cgroups)
err error
pids []int
)
if systemd.UseSystemd() {
pids, err = systemd.GetPids(c.config.Cgroups)
} else {
pids, err = fs.GetPids(c.config.Cgroups)
}
if err != nil { if err != nil {
return nil, newGenericError(err, SystemError) return nil, newGenericError(err, SystemError)
} }
@@ -50,15 +38,9 @@ func (c *linuxContainer) Stats() (*ContainerStats, error) {
stats = &ContainerStats{} stats = &ContainerStats{}
) )
if systemd.UseSystemd() { if stats.CgroupStats, err = c.cgroupManager.GetStats(c.config.Cgroups); err != nil {
stats.CgroupStats, err = systemd.GetStats(c.config.Cgroups)
} else {
stats.CgroupStats, err = fs.GetStats(c.config.Cgroups)
}
if err != nil {
return stats, newGenericError(err, SystemError) return stats, newGenericError(err, SystemError)
} }
if stats.NetworkStats, err = network.GetStats(&c.state.NetworkState); err != nil { if stats.NetworkStats, err = network.GetStats(&c.state.NetworkState); err != nil {
return stats, newGenericError(err, SystemError) return stats, newGenericError(err, SystemError)
} }

68
linux_container_test.go Normal file
View File

@@ -0,0 +1,68 @@
// +build linux
package libcontainer
import (
"testing"
"github.com/docker/libcontainer/cgroups"
)
type mockCgroupManager struct {
pids []int
stats *cgroups.Stats
}
func (m *mockCgroupManager) GetPids(config *cgroups.Cgroup) ([]int, error) {
return m.pids, nil
}
func (m *mockCgroupManager) GetStats(config *cgroups.Cgroup) (*cgroups.Stats, error) {
return m.stats, nil
}
func TestGetContainerPids(t *testing.T) {
container := &linuxContainer{
id: "myid",
config: &Config{},
cgroupManager: &mockCgroupManager{pids: []int{1, 2, 3}},
}
pids, err := container.Processes()
if err != nil {
t.Fatal(err)
}
for i, expected := range []int{1, 2, 3} {
if pids[i] != expected {
t.Fatalf("expected pid %d but received %d", expected, pids[i])
}
}
}
func TestGetContainerStats(t *testing.T) {
container := &linuxContainer{
id: "myid",
config: &Config{},
cgroupManager: &mockCgroupManager{
pids: []int{1, 2, 3},
stats: &cgroups.Stats{
MemoryStats: cgroups.MemoryStats{
Usage: 1024,
},
},
},
state: &State{},
}
stats, err := container.Stats()
if err != nil {
t.Fatal(err)
}
if stats.CgroupStats == nil {
t.Fatal("cgroup stats are nil")
}
if stats.CgroupStats.MemoryStats.Usage != 1024 {
t.Fatalf("expected memory usage 1024 but recevied %d", stats.CgroupStats.MemoryStats.Usage)
}
}

View File

@@ -51,6 +51,7 @@ func (l *linuxFactory) Load(id string) (ContainerInfo, error) {
root: containerRoot, root: containerRoot,
config: config, config: config,
state: state, state: state,
cgroupManager: newCgroupsManager(),
}, nil }, nil
} }

View File

@@ -31,7 +31,7 @@ const (
stateFile = "state.json" stateFile = "state.json"
// The container exists and is running. // The container exists and is running.
Running RunState = iota Running RunState = iota + 1
// The container exists, it is in the process of being paused. // The container exists, it is in the process of being paused.
Pausing Pausing