mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Forbid syscalls in tests, add 2 new unit tests
This commit is contained in:
parent
df258f5861
commit
bc82940a57
3 changed files with 317 additions and 25 deletions
|
@ -21,7 +21,7 @@ type Driver struct {
|
||||||
home string
|
home string
|
||||||
}
|
}
|
||||||
|
|
||||||
func Init(home string) (graphdriver.Driver, error) {
|
var Init = func(home string) (graphdriver.Driver, error) {
|
||||||
deviceSet, err := NewDeviceSet(home, true)
|
deviceSet, err := NewDeviceSet(home, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -56,7 +56,7 @@ func (d *Driver) Cleanup() error {
|
||||||
return d.DeviceSet.Shutdown()
|
return d.DeviceSet.Shutdown()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Driver) Create(id string, parent string) error {
|
func (d *Driver) Create(id, parent string) error {
|
||||||
if err := d.DeviceSet.AddDevice(id, parent); err != nil {
|
if err := d.DeviceSet.AddDevice(id, parent); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,12 @@ package devmapper
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/dotcloud/docker/graphdriver"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"path"
|
"path"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
"syscall"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -82,6 +84,39 @@ func denyAllDevmapper() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func denyAllSyscall() {
|
||||||
|
sysMount = func(source, target, fstype string, flags uintptr, data string) (err error) {
|
||||||
|
panic("sysMount: this method should not be called here")
|
||||||
|
}
|
||||||
|
sysUnmount = func(target string, flags int) (err error) {
|
||||||
|
panic("sysUnmount: this method should not be called here")
|
||||||
|
}
|
||||||
|
sysCloseOnExec = func(fd int) {
|
||||||
|
panic("sysCloseOnExec: this method should not be called here")
|
||||||
|
}
|
||||||
|
sysSyscall = func(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) {
|
||||||
|
panic("sysSyscall: this method should not be called here")
|
||||||
|
}
|
||||||
|
// Not a syscall, but forbidding it here anyway
|
||||||
|
Mounted = func(mnt string) (bool, error) {
|
||||||
|
panic("devmapper.Mounted: this method should not be called here")
|
||||||
|
}
|
||||||
|
// osOpenFile = os.OpenFile
|
||||||
|
// osNewFile = os.NewFile
|
||||||
|
// osCreate = os.Create
|
||||||
|
// osStat = os.Stat
|
||||||
|
// osIsNotExist = os.IsNotExist
|
||||||
|
// osIsExist = os.IsExist
|
||||||
|
// osMkdirAll = os.MkdirAll
|
||||||
|
// osRemoveAll = os.RemoveAll
|
||||||
|
// osRename = os.Rename
|
||||||
|
// osReadlink = os.Readlink
|
||||||
|
|
||||||
|
// execRun = func(name string, args ...string) error {
|
||||||
|
// return exec.Command(name, args...).Run()
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
func mkTestDirectory(t *testing.T) string {
|
func mkTestDirectory(t *testing.T) string {
|
||||||
dir, err := ioutil.TempDir("", "docker-test-devmapper-")
|
dir, err := ioutil.TempDir("", "docker-test-devmapper-")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -119,12 +154,15 @@ func (r Set) Assert(t *testing.T, names ...string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInit(t *testing.T) {
|
func TestInit(t *testing.T) {
|
||||||
home := mkTestDirectory(t)
|
var (
|
||||||
|
calls = make(Set)
|
||||||
|
devicesAttached = make(Set)
|
||||||
|
taskMessages = make(Set)
|
||||||
|
taskTypes = make(Set)
|
||||||
|
home = mkTestDirectory(t)
|
||||||
|
)
|
||||||
defer osRemoveAll(home)
|
defer osRemoveAll(home)
|
||||||
calls := make(Set)
|
|
||||||
devicesAttached := make(Set)
|
|
||||||
taskMessages := make(Set)
|
|
||||||
taskTypes := make(Set)
|
|
||||||
func() {
|
func() {
|
||||||
denyAllDevmapper()
|
denyAllDevmapper()
|
||||||
DmSetDevDir = func(dir string) int {
|
DmSetDevDir = func(dir string) int {
|
||||||
|
@ -295,8 +333,12 @@ func TestInit(t *testing.T) {
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}()
|
}()
|
||||||
|
// Put all tests in a funciton to make sure the garbage collection will
|
||||||
|
// occur.
|
||||||
|
|
||||||
|
// Call GC to cleanup runtime.Finalizers
|
||||||
runtime.GC()
|
runtime.GC()
|
||||||
|
|
||||||
calls.Assert(t,
|
calls.Assert(t,
|
||||||
"DmSetDevDir",
|
"DmSetDevDir",
|
||||||
"DmLogWithErrnoInit",
|
"DmLogWithErrnoInit",
|
||||||
|
@ -320,38 +362,288 @@ func TestInit(t *testing.T) {
|
||||||
taskMessages.Assert(t, "create_thin 0", "set_transaction_id 0 1")
|
taskMessages.Assert(t, "create_thin 0", "set_transaction_id 0 1")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDriverName(t *testing.T) {
|
func fakeInit() func(home string) (graphdriver.Driver, error) {
|
||||||
t.Skip("FIXME: not a unit test")
|
oldInit := Init
|
||||||
d := newDriver(t)
|
Init = func(home string) (graphdriver.Driver, error) {
|
||||||
defer cleanup(d)
|
return &Driver{
|
||||||
|
home: home,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
return oldInit
|
||||||
|
}
|
||||||
|
|
||||||
|
func restoreInit(init func(home string) (graphdriver.Driver, error)) {
|
||||||
|
Init = init
|
||||||
|
}
|
||||||
|
|
||||||
|
func mockAllDevmapper(calls Set) {
|
||||||
|
DmSetDevDir = func(dir string) int {
|
||||||
|
calls["DmSetDevDir"] = true
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
LogWithErrnoInit = func() {
|
||||||
|
calls["DmLogWithErrnoInit"] = true
|
||||||
|
}
|
||||||
|
DmTaskCreate = func(taskType int) *CDmTask {
|
||||||
|
calls["DmTaskCreate"] = true
|
||||||
|
return &CDmTask{}
|
||||||
|
}
|
||||||
|
DmTaskSetName = func(task *CDmTask, name string) int {
|
||||||
|
calls["DmTaskSetName"] = true
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
DmTaskRun = func(task *CDmTask) int {
|
||||||
|
calls["DmTaskRun"] = true
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
DmTaskGetInfo = func(task *CDmTask, info *Info) int {
|
||||||
|
calls["DmTaskGetInfo"] = true
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
DmTaskSetSector = func(task *CDmTask, sector uint64) int {
|
||||||
|
calls["DmTaskSetSector"] = true
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
DmTaskSetMessage = func(task *CDmTask, message string) int {
|
||||||
|
calls["DmTaskSetMessage"] = true
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
DmAttachLoopDevice = func(filename string, fd *int) string {
|
||||||
|
calls["DmAttachLoopDevice"] = true
|
||||||
|
return "/dev/loop42"
|
||||||
|
}
|
||||||
|
DmTaskDestroy = func(task *CDmTask) {
|
||||||
|
calls["DmTaskDestroy"] = true
|
||||||
|
}
|
||||||
|
DmGetBlockSize = func(fd uintptr) (int64, sysErrno) {
|
||||||
|
calls["DmGetBlockSize"] = true
|
||||||
|
return int64(4242 * 512), 0
|
||||||
|
}
|
||||||
|
DmTaskAddTarget = func(task *CDmTask, start, size uint64, ttype, params string) int {
|
||||||
|
calls["DmTaskSetTarget"] = true
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
DmTaskSetCookie = func(task *CDmTask, cookie *uint, flags uint16) int {
|
||||||
|
calls["DmTaskSetCookie"] = true
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
DmUdevWait = func(cookie uint) int {
|
||||||
|
calls["DmUdevWait"] = true
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
DmTaskSetAddNode = func(task *CDmTask, addNode AddNodeType) int {
|
||||||
|
calls["DmTaskSetAddNode"] = true
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
execRun = func(name string, args ...string) error {
|
||||||
|
calls["execRun"] = true
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDriverName(t *testing.T) {
|
||||||
|
denyAllDevmapper()
|
||||||
|
defer denyAllDevmapper()
|
||||||
|
|
||||||
|
oldInit := fakeInit()
|
||||||
|
defer restoreInit(oldInit)
|
||||||
|
|
||||||
|
d := newDriver(t)
|
||||||
if d.String() != "devicemapper" {
|
if d.String() != "devicemapper" {
|
||||||
t.Fatalf("Expected driver name to be devicemapper got %s", d.String())
|
t.Fatalf("Expected driver name to be devicemapper got %s", d.String())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDriverCreate(t *testing.T) {
|
func TestDriverCreate(t *testing.T) {
|
||||||
t.Skip("FIXME: not a unit test")
|
denyAllDevmapper()
|
||||||
d := newDriver(t)
|
denyAllSyscall()
|
||||||
defer cleanup(d)
|
defer denyAllSyscall()
|
||||||
|
defer denyAllDevmapper()
|
||||||
|
|
||||||
if err := d.Create("1", ""); err != nil {
|
calls := make(Set)
|
||||||
t.Fatal(err)
|
mockAllDevmapper(calls)
|
||||||
|
|
||||||
|
sysMount = func(source, target, fstype string, flags uintptr, data string) (err error) {
|
||||||
|
calls["sysMount"] = true
|
||||||
|
// FIXME: compare the exact source and target strings (inodes + devname)
|
||||||
|
if expectedSource := "/dev/mapper/docker-"; !strings.HasPrefix(source, expectedSource) {
|
||||||
|
t.Fatalf("Wrong syscall call\nExpected: Mount(%v)\nReceived: Mount(%v)\n", expectedSource, source)
|
||||||
|
}
|
||||||
|
if expectedTarget := "/tmp/docker-test-devmapper-"; !strings.HasPrefix(target, expectedTarget) {
|
||||||
|
t.Fatalf("Wrong syscall call\nExpected: Mount(%v)\nReceived: Mount(%v)\n", expectedTarget, target)
|
||||||
|
}
|
||||||
|
if expectedFstype := "ext4"; fstype != expectedFstype {
|
||||||
|
t.Fatalf("Wrong syscall call\nExpected: Mount(%v)\nReceived: Mount(%v)\n", expectedFstype, fstype)
|
||||||
|
}
|
||||||
|
if expectedFlags := uintptr(3236757504); flags != expectedFlags {
|
||||||
|
t.Fatalf("Wrong syscall call\nExpected: Mount(%v)\nReceived: Mount(%v)\n", expectedFlags, flags)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Mounted = func(mnt string) (bool, error) {
|
||||||
|
calls["Mounted"] = true
|
||||||
|
if !strings.HasPrefix(mnt, "/tmp/docker-test-devmapper-") || !strings.HasSuffix(mnt, "/mnt/1") {
|
||||||
|
t.Fatalf("Wrong mounted call\nExpected: Mounted(%v)\nReceived: Mounted(%v)\n", "/tmp/docker-test-devmapper-.../mnt/1", mnt)
|
||||||
|
}
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func() {
|
||||||
|
d := newDriver(t)
|
||||||
|
|
||||||
|
calls.Assert(t,
|
||||||
|
"DmSetDevDir",
|
||||||
|
"DmLogWithErrnoInit",
|
||||||
|
"DmTaskSetName",
|
||||||
|
"DmTaskRun",
|
||||||
|
"DmTaskGetInfo",
|
||||||
|
"DmAttachLoopDevice",
|
||||||
|
"execRun",
|
||||||
|
"DmTaskCreate",
|
||||||
|
"DmGetBlockSize",
|
||||||
|
"DmTaskSetTarget",
|
||||||
|
"DmTaskSetCookie",
|
||||||
|
"DmUdevWait",
|
||||||
|
"DmTaskSetSector",
|
||||||
|
"DmTaskSetMessage",
|
||||||
|
"DmTaskSetAddNode",
|
||||||
|
)
|
||||||
|
|
||||||
|
if err := d.Create("1", ""); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
calls.Assert(t,
|
||||||
|
"DmTaskCreate",
|
||||||
|
"DmTaskGetInfo",
|
||||||
|
"sysMount",
|
||||||
|
"Mounted",
|
||||||
|
"DmTaskRun",
|
||||||
|
"DmTaskSetTarget",
|
||||||
|
"DmTaskSetSector",
|
||||||
|
"DmTaskSetCookie",
|
||||||
|
"DmUdevWait",
|
||||||
|
"DmTaskSetName",
|
||||||
|
"DmTaskSetMessage",
|
||||||
|
"DmTaskSetAddNode",
|
||||||
|
)
|
||||||
|
|
||||||
|
}()
|
||||||
|
|
||||||
|
runtime.GC()
|
||||||
|
|
||||||
|
calls.Assert(t,
|
||||||
|
"DmTaskDestroy",
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDriverRemove(t *testing.T) {
|
func TestDriverRemove(t *testing.T) {
|
||||||
t.Skip("FIXME: not a unit test")
|
denyAllDevmapper()
|
||||||
d := newDriver(t)
|
denyAllSyscall()
|
||||||
defer cleanup(d)
|
defer denyAllSyscall()
|
||||||
|
defer denyAllDevmapper()
|
||||||
|
|
||||||
if err := d.Create("1", ""); err != nil {
|
calls := make(Set)
|
||||||
t.Fatal(err)
|
mockAllDevmapper(calls)
|
||||||
|
|
||||||
|
sysMount = func(source, target, fstype string, flags uintptr, data string) (err error) {
|
||||||
|
calls["sysMount"] = true
|
||||||
|
// FIXME: compare the exact source and target strings (inodes + devname)
|
||||||
|
if expectedSource := "/dev/mapper/docker-"; !strings.HasPrefix(source, expectedSource) {
|
||||||
|
t.Fatalf("Wrong syscall call\nExpected: Mount(%v)\nReceived: Mount(%v)\n", expectedSource, source)
|
||||||
|
}
|
||||||
|
if expectedTarget := "/tmp/docker-test-devmapper-"; !strings.HasPrefix(target, expectedTarget) {
|
||||||
|
t.Fatalf("Wrong syscall call\nExpected: Mount(%v)\nReceived: Mount(%v)\n", expectedTarget, target)
|
||||||
|
}
|
||||||
|
if expectedFstype := "ext4"; fstype != expectedFstype {
|
||||||
|
t.Fatalf("Wrong syscall call\nExpected: Mount(%v)\nReceived: Mount(%v)\n", expectedFstype, fstype)
|
||||||
|
}
|
||||||
|
if expectedFlags := uintptr(3236757504); flags != expectedFlags {
|
||||||
|
t.Fatalf("Wrong syscall call\nExpected: Mount(%v)\nReceived: Mount(%v)\n", expectedFlags, flags)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
sysUnmount = func(target string, flags int) (err error) {
|
||||||
|
calls["sysUnmount"] = true
|
||||||
|
// FIXME: compare the exact source and target strings (inodes + devname)
|
||||||
|
if expectedTarget := "/tmp/docker-test-devmapper-"; !strings.HasPrefix(target, expectedTarget) {
|
||||||
|
t.Fatalf("Wrong syscall call\nExpected: Mount(%v)\nReceived: Mount(%v)\n", expectedTarget, target)
|
||||||
|
}
|
||||||
|
if expectedFlags := 0; flags != expectedFlags {
|
||||||
|
t.Fatalf("Wrong syscall call\nExpected: Mount(%v)\nReceived: Mount(%v)\n", expectedFlags, flags)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
Mounted = func(mnt string) (bool, error) {
|
||||||
|
calls["Mounted"] = true
|
||||||
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := d.Remove("1"); err != nil {
|
func() {
|
||||||
t.Fatal(err)
|
d := newDriver(t)
|
||||||
}
|
|
||||||
|
calls.Assert(t,
|
||||||
|
"DmSetDevDir",
|
||||||
|
"DmLogWithErrnoInit",
|
||||||
|
"DmTaskSetName",
|
||||||
|
"DmTaskRun",
|
||||||
|
"DmTaskGetInfo",
|
||||||
|
"DmAttachLoopDevice",
|
||||||
|
"execRun",
|
||||||
|
"DmTaskCreate",
|
||||||
|
"DmGetBlockSize",
|
||||||
|
"DmTaskSetTarget",
|
||||||
|
"DmTaskSetCookie",
|
||||||
|
"DmUdevWait",
|
||||||
|
"DmTaskSetSector",
|
||||||
|
"DmTaskSetMessage",
|
||||||
|
"DmTaskSetAddNode",
|
||||||
|
)
|
||||||
|
|
||||||
|
if err := d.Create("1", ""); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
calls.Assert(t,
|
||||||
|
"DmTaskCreate",
|
||||||
|
"DmTaskGetInfo",
|
||||||
|
"sysMount",
|
||||||
|
"Mounted",
|
||||||
|
"DmTaskRun",
|
||||||
|
"DmTaskSetTarget",
|
||||||
|
"DmTaskSetSector",
|
||||||
|
"DmTaskSetCookie",
|
||||||
|
"DmUdevWait",
|
||||||
|
"DmTaskSetName",
|
||||||
|
"DmTaskSetMessage",
|
||||||
|
"DmTaskSetAddNode",
|
||||||
|
)
|
||||||
|
|
||||||
|
Mounted = func(mnt string) (bool, error) {
|
||||||
|
calls["Mounted"] = true
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := d.Remove("1"); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
calls.Assert(t,
|
||||||
|
"DmTaskRun",
|
||||||
|
"DmTaskSetSector",
|
||||||
|
"DmTaskSetName",
|
||||||
|
"DmTaskSetMessage",
|
||||||
|
"DmTaskCreate",
|
||||||
|
"DmTaskGetInfo",
|
||||||
|
"Mounted",
|
||||||
|
"sysUnmount",
|
||||||
|
)
|
||||||
|
}()
|
||||||
|
runtime.GC()
|
||||||
|
|
||||||
|
calls.Assert(t,
|
||||||
|
"DmTaskDestroy",
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCleanup(t *testing.T) {
|
func TestCleanup(t *testing.T) {
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
// FIXME: this is copy-pasted from the aufs driver.
|
// FIXME: this is copy-pasted from the aufs driver.
|
||||||
// It should be moved into the core.
|
// It should be moved into the core.
|
||||||
|
|
||||||
func Mounted(mountpoint string) (bool, error) {
|
var Mounted = func(mountpoint string) (bool, error) {
|
||||||
mntpoint, err := osStat(mountpoint)
|
mntpoint, err := osStat(mountpoint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if osIsNotExist(err) {
|
if osIsNotExist(err) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue