moby/daemon/volumes_unix_test.go
Josh Soref 39bcaee47b
Spelling fixes
* additional
* ambiguous
* anonymous
* anything
* application
* because
* before
* building
* capabilities
* circumstances
* commit
* committer
* compresses
* concatenated
* config
* container
* container's
* current
* definition
* delimiter
* disassociates
* discovery
* distributed
* doesnotexist
* downloads
* duplicates
* either
* enhancing
* enumerate
* escapable
* exactly
* expect
* expectations
* expected
* explicitly
* false
* filesystem
* following
* forbidden
* git with
* healthcheck
* ignore
* independent
* inheritance
* investigating
* irrelevant
* it
* logging
* looking
* membership
* mimic
* minimum
* modify
* mountpoint
* multiline
* notifier
* outputting
* outside
* overridden
* override
* parsable
* plugins
* precedence
* propagation
* provided
* provides
* registries
* repositories
* returning
* settings
* should
* signals
* someone
* something
* specifically
* successfully
* synchronize
* they've
* thinking
* uninitialized
* unintentionally
* unmarshaling
* unnamed
* unreferenced
* verify

Signed-off-by: Josh Soref <jsoref@gmail.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2017-07-03 13:13:09 -07:00

256 lines
7.4 KiB
Go

// +build !windows
package daemon
import (
"encoding/json"
"fmt"
"reflect"
"testing"
containertypes "github.com/docker/docker/api/types/container"
mounttypes "github.com/docker/docker/api/types/mount"
"github.com/docker/docker/container"
"github.com/docker/docker/volume"
)
func TestBackportMountSpec(t *testing.T) {
d := Daemon{containers: container.NewMemoryStore()}
c := &container.Container{
State: &container.State{},
MountPoints: map[string]*volume.MountPoint{
"/apple": {Destination: "/apple", Source: "/var/lib/docker/volumes/12345678", Name: "12345678", RW: true, CopyData: true}, // anonymous volume
"/banana": {Destination: "/banana", Source: "/var/lib/docker/volumes/data", Name: "data", RW: true, CopyData: true}, // named volume
"/cherry": {Destination: "/cherry", Source: "/var/lib/docker/volumes/data", Name: "data", CopyData: true}, // RO named volume
"/dates": {Destination: "/dates", Source: "/var/lib/docker/volumes/data", Name: "data"}, // named volume nocopy
"/elderberry": {Destination: "/elderberry", Source: "/var/lib/docker/volumes/data", Name: "data"}, // masks anon vol
"/fig": {Destination: "/fig", Source: "/data", RW: true}, // RW bind
"/guava": {Destination: "/guava", Source: "/data", RW: false, Propagation: "shared"}, // RO bind + propagation
"/kumquat": {Destination: "/kumquat", Name: "data", RW: false, CopyData: true}, // volumes-from
// partially configured mountpoint due to #32613
// specifically, `mp.Spec.Source` is not set
"/honeydew": {
Type: mounttypes.TypeVolume,
Destination: "/honeydew",
Name: "data",
Source: "/var/lib/docker/volumes/data",
Spec: mounttypes.Mount{Type: mounttypes.TypeVolume, Target: "/honeydew", VolumeOptions: &mounttypes.VolumeOptions{NoCopy: true}},
},
// from hostconfig.Mounts
"/jambolan": {
Type: mounttypes.TypeVolume,
Destination: "/jambolan",
Source: "/var/lib/docker/volumes/data",
RW: true,
Name: "data",
Spec: mounttypes.Mount{Type: mounttypes.TypeVolume, Target: "/jambolan", Source: "data"},
},
},
HostConfig: &containertypes.HostConfig{
Binds: []string{
"data:/banana",
"data:/cherry:ro",
"data:/dates:ro,nocopy",
"data:/elderberry:ro,nocopy",
"/data:/fig",
"/data:/guava:ro,shared",
"data:/honeydew:nocopy",
},
VolumesFrom: []string{"1:ro"},
Mounts: []mounttypes.Mount{
{Type: mounttypes.TypeVolume, Target: "/jambolan"},
},
},
Config: &containertypes.Config{Volumes: map[string]struct{}{
"/apple": {},
"/elderberry": {},
}},
}
d.containers.Add("1", &container.Container{
State: &container.State{},
ID: "1",
MountPoints: map[string]*volume.MountPoint{
"/kumquat": {Destination: "/kumquat", Name: "data", RW: false, CopyData: true},
},
HostConfig: &containertypes.HostConfig{
Binds: []string{
"data:/kumquat:ro",
},
},
})
type expected struct {
mp *volume.MountPoint
comment string
}
pretty := func(mp *volume.MountPoint) string {
b, err := json.MarshalIndent(mp, "\t", " ")
if err != nil {
return fmt.Sprintf("%#v", mp)
}
return string(b)
}
for _, x := range []expected{
{
mp: &volume.MountPoint{
Type: mounttypes.TypeVolume,
Destination: "/apple",
RW: true,
Name: "12345678",
Source: "/var/lib/docker/volumes/12345678",
CopyData: true,
Spec: mounttypes.Mount{
Type: mounttypes.TypeVolume,
Source: "",
Target: "/apple",
},
},
comment: "anonymous volume",
},
{
mp: &volume.MountPoint{
Type: mounttypes.TypeVolume,
Destination: "/banana",
RW: true,
Name: "data",
Source: "/var/lib/docker/volumes/data",
CopyData: true,
Spec: mounttypes.Mount{
Type: mounttypes.TypeVolume,
Source: "data",
Target: "/banana",
},
},
comment: "named volume",
},
{
mp: &volume.MountPoint{
Type: mounttypes.TypeVolume,
Destination: "/cherry",
Name: "data",
Source: "/var/lib/docker/volumes/data",
CopyData: true,
Spec: mounttypes.Mount{
Type: mounttypes.TypeVolume,
Source: "data",
Target: "/cherry",
ReadOnly: true,
},
},
comment: "read-only named volume",
},
{
mp: &volume.MountPoint{
Type: mounttypes.TypeVolume,
Destination: "/dates",
Name: "data",
Source: "/var/lib/docker/volumes/data",
Spec: mounttypes.Mount{
Type: mounttypes.TypeVolume,
Source: "data",
Target: "/dates",
ReadOnly: true,
VolumeOptions: &mounttypes.VolumeOptions{NoCopy: true},
},
},
comment: "named volume with nocopy",
},
{
mp: &volume.MountPoint{
Type: mounttypes.TypeVolume,
Destination: "/elderberry",
Name: "data",
Source: "/var/lib/docker/volumes/data",
Spec: mounttypes.Mount{
Type: mounttypes.TypeVolume,
Source: "data",
Target: "/elderberry",
ReadOnly: true,
VolumeOptions: &mounttypes.VolumeOptions{NoCopy: true},
},
},
comment: "masks an anonymous volume",
},
{
mp: &volume.MountPoint{
Type: mounttypes.TypeBind,
Destination: "/fig",
Source: "/data",
RW: true,
Spec: mounttypes.Mount{
Type: mounttypes.TypeBind,
Source: "/data",
Target: "/fig",
},
},
comment: "bind mount with read/write",
},
{
mp: &volume.MountPoint{
Type: mounttypes.TypeBind,
Destination: "/guava",
Source: "/data",
RW: false,
Propagation: "shared",
Spec: mounttypes.Mount{
Type: mounttypes.TypeBind,
Source: "/data",
Target: "/guava",
ReadOnly: true,
BindOptions: &mounttypes.BindOptions{Propagation: "shared"},
},
},
comment: "bind mount with read/write + shared propagation",
},
{
mp: &volume.MountPoint{
Type: mounttypes.TypeVolume,
Destination: "/honeydew",
Source: "/var/lib/docker/volumes/data",
RW: true,
Propagation: "shared",
Spec: mounttypes.Mount{
Type: mounttypes.TypeVolume,
Source: "data",
Target: "/honeydew",
VolumeOptions: &mounttypes.VolumeOptions{NoCopy: true},
},
},
comment: "partially configured named volume caused by #32613",
},
{
mp: &(*c.MountPoints["/jambolan"]), // copy the mountpoint, expect no changes
comment: "volume defined in mounts API",
},
{
mp: &volume.MountPoint{
Type: mounttypes.TypeVolume,
Destination: "/kumquat",
Source: "/var/lib/docker/volumes/data",
RW: false,
Name: "data",
Spec: mounttypes.Mount{
Type: mounttypes.TypeVolume,
Source: "data",
Target: "/kumquat",
ReadOnly: true,
},
},
comment: "partially configured named volume caused by #32613",
},
} {
mp := c.MountPoints[x.mp.Destination]
d.backportMountSpec(c)
if !reflect.DeepEqual(mp.Spec, x.mp.Spec) {
t.Fatalf("%s\nexpected:\n\t%s\n\ngot:\n\t%s", x.comment, pretty(x.mp), pretty(mp))
}
}
}