package mounts // import "github.com/docker/docker/volume/mounts" import ( "os" "testing" "github.com/docker/docker/api/types/mount" ) type mockFiProvider struct{} func (mockFiProvider) fileInfo(path string) (exists, isDir bool, err error) { dirs := map[string]struct{}{ `c:\`: {}, `c:\windows\`: {}, `c:\windows`: {}, `c:\program files`: {}, `c:\Windows`: {}, `c:\Program Files (x86)`: {}, `\\?\c:\windows\`: {}, } files := map[string]struct{}{ `c:\windows\system32\ntdll.dll`: {}, } if _, ok := dirs[path]; ok { return true, true, nil } if _, ok := files[path]; ok { return true, false, nil } return false, false, nil } // always returns the configured error // this is used to test error handling type mockFiProviderWithError struct{ err error } func (m mockFiProviderWithError) fileInfo(path string) (bool, bool, error) { return false, false, m.err } func TestParseMountSpec(t *testing.T) { testDir, err := os.MkdirTemp("", "test-mount-config") if err != nil { t.Fatal(err) } defer os.RemoveAll(testDir) parser := NewParser() cases := []struct { input mount.Mount expected MountPoint }{ {mount.Mount{Type: mount.TypeBind, Source: testDir, Target: testDestinationPath, ReadOnly: true}, MountPoint{Type: mount.TypeBind, Source: testDir, Destination: testDestinationPath, Propagation: parser.DefaultPropagationMode()}}, {mount.Mount{Type: mount.TypeBind, Source: testDir, Target: testDestinationPath}, MountPoint{Type: mount.TypeBind, Source: testDir, Destination: testDestinationPath, RW: true, Propagation: parser.DefaultPropagationMode()}}, {mount.Mount{Type: mount.TypeBind, Source: testDir + string(os.PathSeparator), Target: testDestinationPath, ReadOnly: true}, MountPoint{Type: mount.TypeBind, Source: testDir, Destination: testDestinationPath, Propagation: parser.DefaultPropagationMode()}}, {mount.Mount{Type: mount.TypeBind, Source: testDir, Target: testDestinationPath + string(os.PathSeparator), ReadOnly: true}, MountPoint{Type: mount.TypeBind, Source: testDir, Destination: testDestinationPath, Propagation: parser.DefaultPropagationMode()}}, {mount.Mount{Type: mount.TypeVolume, Target: testDestinationPath}, MountPoint{Type: mount.TypeVolume, Destination: testDestinationPath, RW: true, CopyData: parser.DefaultCopyMode()}}, {mount.Mount{Type: mount.TypeVolume, Target: testDestinationPath + string(os.PathSeparator)}, MountPoint{Type: mount.TypeVolume, Destination: testDestinationPath, RW: true, CopyData: parser.DefaultCopyMode()}}, } for i, c := range cases { t.Logf("case %d", i) mp, err := parser.ParseMountSpec(c.input) if err != nil { t.Error(err) } if c.expected.Type != mp.Type { t.Errorf("Expected mount types to match. Expected: '%s', Actual: '%s'", c.expected.Type, mp.Type) } if c.expected.Destination != mp.Destination { t.Errorf("Expected mount destination to match. Expected: '%s', Actual: '%s'", c.expected.Destination, mp.Destination) } if c.expected.Source != mp.Source { t.Errorf("Expected mount source to match. Expected: '%s', Actual: '%s'", c.expected.Source, mp.Source) } if c.expected.RW != mp.RW { t.Errorf("Expected mount writable to match. Expected: '%v', Actual: '%v'", c.expected.RW, mp.RW) } if c.expected.Propagation != mp.Propagation { t.Errorf("Expected mount propagation to match. Expected: '%v', Actual: '%s'", c.expected.Propagation, mp.Propagation) } if c.expected.Driver != mp.Driver { t.Errorf("Expected mount driver to match. Expected: '%v', Actual: '%s'", c.expected.Driver, mp.Driver) } if c.expected.CopyData != mp.CopyData { t.Errorf("Expected mount copy data to match. Expected: '%v', Actual: '%v'", c.expected.CopyData, mp.CopyData) } } }