volume/mounts: cleanup tests

- don't use un-keyed structs
- user assert.Check where possible
- use consts for fixed values

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn 2023-07-27 15:00:13 +02:00
parent 10aff57b26
commit d69b1fdb72
No known key found for this signature in database
GPG key ID: 76698F39D527CE8C
7 changed files with 451 additions and 173 deletions

View file

@ -1,12 +1,12 @@
package mounts // import "github.com/docker/docker/volume/mounts"
import (
"fmt"
"strings"
"testing"
"github.com/docker/docker/api/types/mount"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
)
func TestLCOWParseMountRaw(t *testing.T) {
@ -112,18 +112,98 @@ func TestLCOWParseMountRawSplit(t *testing.T) {
expRW bool
fail bool
}{
{`c:\:/foo`, "local", mount.TypeBind, `/foo`, `c:\`, ``, "", true, false},
{`c:\:/foo:ro`, "local", mount.TypeBind, `/foo`, `c:\`, ``, "", false, false},
{`c:\:/foo:rw`, "local", mount.TypeBind, `/foo`, `c:\`, ``, "", true, false},
{`c:\:/foo:foo`, "local", mount.TypeBind, `/foo`, `c:\`, ``, "", false, true},
{`name:/foo:rw`, "local", mount.TypeVolume, `/foo`, ``, `name`, "local", true, false},
{`name:/foo`, "local", mount.TypeVolume, `/foo`, ``, `name`, "local", true, false},
{`name:/foo:ro`, "local", mount.TypeVolume, `/foo`, ``, `name`, "local", false, false},
{`name:/`, "", mount.TypeVolume, ``, ``, ``, "", true, true},
{`driver/name:/`, "", mount.TypeVolume, ``, ``, ``, "", true, true},
{`\\.\pipe\foo:\\.\pipe\bar`, "local", mount.TypeNamedPipe, `\\.\pipe\bar`, `\\.\pipe\foo`, "", "", true, true},
{`\\.\pipe\foo:/data`, "local", mount.TypeNamedPipe, ``, ``, "", "", true, true},
{`c:\foo\bar:\\.\pipe\foo`, "local", mount.TypeNamedPipe, ``, ``, "", "", true, true},
{
bind: `c:\:/foo`,
driver: "local",
expType: mount.TypeBind,
expDest: `/foo`,
expSource: `c:\`,
expRW: true,
},
{
bind: `c:\:/foo:ro`,
driver: "local",
expType: mount.TypeBind,
expDest: `/foo`,
expSource: `c:\`,
},
{
bind: `c:\:/foo:rw`,
driver: "local",
expType: mount.TypeBind,
expDest: `/foo`,
expSource: `c:\`,
expRW: true,
},
{
bind: `c:\:/foo:foo`,
driver: "local",
expType: mount.TypeBind,
expDest: `/foo`,
expSource: `c:\`,
fail: true,
},
{
bind: `name:/foo:rw`,
driver: "local",
expType: mount.TypeVolume,
expDest: `/foo`,
expName: `name`,
expDriver: "local",
expRW: true,
},
{
bind: `name:/foo`,
driver: "local",
expType: mount.TypeVolume,
expDest: `/foo`,
expName: `name`,
expDriver: "local",
expRW: true,
},
{
bind: `name:/foo:ro`,
driver: "local",
expType: mount.TypeVolume,
expDest: `/foo`,
expName: `name`,
expDriver: "local",
},
{
bind: `name:/`,
expType: mount.TypeVolume,
expRW: true,
fail: true,
},
{
bind: `driver/name:/`,
expType: mount.TypeVolume,
expRW: true,
fail: true,
},
{
bind: `\\.\pipe\foo:\\.\pipe\bar`,
driver: "local",
expType: mount.TypeNamedPipe,
expDest: `\\.\pipe\bar`,
expSource: `\\.\pipe\foo`,
expRW: true,
fail: true,
},
{
bind: `\\.\pipe\foo:/data`,
driver: "local",
expType: mount.TypeNamedPipe,
expRW: true,
fail: true,
},
{
bind: `c:\foo\bar:\\.\pipe\foo`,
driver: "local",
expType: mount.TypeNamedPipe,
expRW: true,
fail: true,
},
}
parser := NewLCOWParser()
@ -131,22 +211,22 @@ func TestLCOWParseMountRawSplit(t *testing.T) {
p.fi = mockFiProvider{}
}
for i, c := range cases {
c := c
t.Run(fmt.Sprintf("%d_%s", i, c.bind), func(t *testing.T) {
m, err := parser.ParseMountRaw(c.bind, c.driver)
if c.fail {
assert.ErrorContains(t, err, "", "expected an error")
for _, tc := range cases {
tc := tc
t.Run(tc.bind, func(t *testing.T) {
m, err := parser.ParseMountRaw(tc.bind, tc.driver)
if tc.fail {
assert.Check(t, is.ErrorContains(err, ""), "expected an error")
return
}
assert.NilError(t, err)
assert.Equal(t, m.Destination, c.expDest)
assert.Equal(t, m.Source, c.expSource)
assert.Equal(t, m.Name, c.expName)
assert.Equal(t, m.Driver, c.expDriver)
assert.Equal(t, m.RW, c.expRW)
assert.Equal(t, m.Type, c.expType)
assert.Check(t, err)
assert.Check(t, is.Equal(m.Destination, tc.expDest))
assert.Check(t, is.Equal(m.Source, tc.expSource))
assert.Check(t, is.Equal(m.Name, tc.expName))
assert.Check(t, is.Equal(m.Driver, tc.expDriver))
assert.Check(t, is.Equal(m.RW, tc.expRW))
assert.Check(t, is.Equal(m.Type, tc.expType))
})
}
}

View file

@ -7,6 +7,7 @@ import (
"github.com/docker/docker/api/types/mount"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
)
func TestLinuxParseMountRaw(t *testing.T) {
@ -109,15 +110,68 @@ func TestLinuxParseMountRawSplit(t *testing.T) {
expRW bool
fail bool
}{
{"/tmp:/tmp1", "", mount.TypeBind, "/tmp1", "/tmp", "", "", true, false},
{"/tmp:/tmp2:ro", "", mount.TypeBind, "/tmp2", "/tmp", "", "", false, false},
{"/tmp:/tmp3:rw", "", mount.TypeBind, "/tmp3", "/tmp", "", "", true, false},
{"/tmp:/tmp4:foo", "", mount.TypeBind, "", "", "", "", false, true},
{"name:/named1", "", mount.TypeVolume, "/named1", "", "name", "", true, false},
{"name:/named2", "external", mount.TypeVolume, "/named2", "", "name", "external", true, false},
{"name:/named3:ro", "local", mount.TypeVolume, "/named3", "", "name", "local", false, false},
{"local/name:/tmp:rw", "", mount.TypeVolume, "/tmp", "", "local/name", "", true, false},
{"/tmp:tmp", "", mount.TypeBind, "", "", "", "", true, true},
{
bind: "/tmp:/tmp1",
expType: mount.TypeBind,
expDest: "/tmp1",
expSource: "/tmp",
expRW: true,
},
{
bind: "/tmp:/tmp2:ro",
expType: mount.TypeBind,
expDest: "/tmp2",
expSource: "/tmp",
},
{
bind: "/tmp:/tmp3:rw",
expType: mount.TypeBind,
expDest: "/tmp3",
expSource: "/tmp",
expRW: true,
},
{
bind: "/tmp:/tmp4:foo",
expType: mount.TypeBind,
fail: true,
},
{
bind: "name:/named1",
expType: mount.TypeVolume,
expDest: "/named1",
expName: "name",
expRW: true,
},
{
bind: "name:/named2",
driver: "external",
expType: mount.TypeVolume,
expDest: "/named2",
expName: "name",
expDriver: "external",
expRW: true,
},
{
bind: "name:/named3:ro",
driver: "local",
expType: mount.TypeVolume,
expDest: "/named3",
expName: "name",
expDriver: "local",
},
{
bind: "local/name:/tmp:rw",
expType: mount.TypeVolume,
expDest: "/tmp",
expName: "local/name",
expRW: true,
},
{
bind: "/tmp:tmp",
expType: mount.TypeBind,
expRW: true,
fail: true,
},
}
parser := NewLinuxParser()
@ -125,22 +179,22 @@ func TestLinuxParseMountRawSplit(t *testing.T) {
p.fi = mockFiProvider{}
}
for i, c := range cases {
c := c
t.Run(fmt.Sprintf("%d_%s", i, c.bind), func(t *testing.T) {
m, err := parser.ParseMountRaw(c.bind, c.driver)
if c.fail {
assert.ErrorContains(t, err, "", "expected an error")
for _, tc := range cases {
tc := tc
t.Run(tc.bind, func(t *testing.T) {
m, err := parser.ParseMountRaw(tc.bind, tc.driver)
if tc.fail {
assert.Check(t, is.ErrorContains(err, ""), "expected an error")
return
}
assert.NilError(t, err)
assert.Equal(t, m.Destination, c.expDest)
assert.Equal(t, m.Source, c.expSource)
assert.Equal(t, m.Name, c.expName)
assert.Equal(t, m.Driver, c.expDriver)
assert.Equal(t, m.RW, c.expRW)
assert.Equal(t, m.Type, c.expType)
assert.Check(t, err)
assert.Check(t, is.Equal(m.Destination, tc.expDest))
assert.Check(t, is.Equal(m.Source, tc.expSource))
assert.Check(t, is.Equal(m.Name, tc.expName))
assert.Check(t, is.Equal(m.Driver, tc.expDriver))
assert.Check(t, is.Equal(m.RW, tc.expRW))
assert.Check(t, is.Equal(m.Type, tc.expType))
})
}
}
@ -200,21 +254,21 @@ func TestConvertTmpfsOptions(t *testing.T) {
},
}
p := NewLinuxParser()
for _, c := range cases {
data, err := p.ConvertTmpfsOptions(&c.opt, c.readOnly)
for _, tc := range cases {
data, err := p.ConvertTmpfsOptions(&tc.opt, tc.readOnly)
if err != nil {
t.Fatalf("could not convert %+v (readOnly: %v) to string: %v",
c.opt, c.readOnly, err)
tc.opt, tc.readOnly, err)
}
t.Logf("data=%q", data)
for _, s := range c.expectedSubstrings {
for _, s := range tc.expectedSubstrings {
if !strings.Contains(data, s) {
t.Fatalf("expected substring: %s, got %v (case=%+v)", s, data, c)
t.Fatalf("expected substring: %s, got %v (case=%+v)", s, data, tc)
}
}
for _, s := range c.unexpectedSubstrings {
for _, s := range tc.unexpectedSubstrings {
if strings.Contains(data, s) {
t.Fatalf("unexpected substring: %s, got %v (case=%+v)", s, data, c)
t.Fatalf("unexpected substring: %s, got %v (case=%+v)", s, data, tc)
}
}
}

View file

@ -5,6 +5,8 @@ import (
"testing"
"github.com/docker/docker/api/types/mount"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
)
type mockFiProvider struct{}
@ -50,41 +52,44 @@ func TestParseMountSpec(t *testing.T) {
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()}},
{
input: mount.Mount{Type: mount.TypeBind, Source: testDir, Target: testDestinationPath, ReadOnly: true},
expected: MountPoint{Type: mount.TypeBind, Source: testDir, Destination: testDestinationPath, Propagation: parser.DefaultPropagationMode()},
},
{
input: mount.Mount{Type: mount.TypeBind, Source: testDir, Target: testDestinationPath},
expected: MountPoint{Type: mount.TypeBind, Source: testDir, Destination: testDestinationPath, RW: true, Propagation: parser.DefaultPropagationMode()},
},
{
input: mount.Mount{Type: mount.TypeBind, Source: testDir + string(os.PathSeparator), Target: testDestinationPath, ReadOnly: true},
expected: MountPoint{Type: mount.TypeBind, Source: testDir, Destination: testDestinationPath, Propagation: parser.DefaultPropagationMode()},
},
{
input: mount.Mount{Type: mount.TypeBind, Source: testDir, Target: testDestinationPath + string(os.PathSeparator), ReadOnly: true},
expected: MountPoint{Type: mount.TypeBind, Source: testDir, Destination: testDestinationPath, Propagation: parser.DefaultPropagationMode()},
},
{
input: mount.Mount{Type: mount.TypeVolume, Target: testDestinationPath},
expected: MountPoint{Type: mount.TypeVolume, Destination: testDestinationPath, RW: true, CopyData: parser.DefaultCopyMode()},
},
{
input: mount.Mount{Type: mount.TypeVolume, Target: testDestinationPath + string(os.PathSeparator)},
expected: 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)
}
for _, tc := range cases {
tc := tc
t.Run("", func(t *testing.T) {
mp, err := parser.ParseMountSpec(tc.input)
assert.Check(t, err)
assert.Check(t, is.Equal(mp.Type, tc.expected.Type))
assert.Check(t, is.Equal(mp.Destination, tc.expected.Destination))
assert.Check(t, is.Equal(mp.Source, tc.expected.Source))
assert.Check(t, is.Equal(mp.RW, tc.expected.RW))
assert.Check(t, is.Equal(mp.Propagation, tc.expected.Propagation))
assert.Check(t, is.Equal(mp.Driver, tc.expected.Driver))
assert.Check(t, is.Equal(mp.CopyData, tc.expected.CopyData))
})
}
}

View file

@ -2,71 +2,123 @@ package mounts // import "github.com/docker/docker/volume/mounts"
import (
"errors"
"os"
"runtime"
"strings"
"testing"
"github.com/docker/docker/api/types/mount"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
)
func TestValidateMount(t *testing.T) {
testDir, err := os.MkdirTemp("", "test-validate-mount")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(testDir)
cases := []struct {
input mount.Mount
expected error
}{
{mount.Mount{Type: mount.TypeVolume}, errMissingField("Target")},
{mount.Mount{Type: mount.TypeVolume, Target: testDestinationPath, Source: "hello"}, nil},
{mount.Mount{Type: mount.TypeVolume, Target: testDestinationPath}, nil},
{mount.Mount{Type: mount.TypeBind}, errMissingField("Target")},
{mount.Mount{Type: mount.TypeBind, Target: testDestinationPath}, errMissingField("Source")},
{mount.Mount{Type: mount.TypeBind, Target: testDestinationPath, Source: testSourcePath, VolumeOptions: &mount.VolumeOptions{}}, errExtraField("VolumeOptions")},
{mount.Mount{Type: mount.TypeBind, Source: testDir, Target: testDestinationPath}, nil},
{mount.Mount{Type: "invalid", Target: testDestinationPath}, errors.New("mount type unknown")},
{mount.Mount{Type: mount.TypeBind, Source: testSourcePath, Target: testDestinationPath}, errBindSourceDoesNotExist(testSourcePath)},
}
lcowCases := []struct {
input mount.Mount
expected error
}{
{mount.Mount{Type: mount.TypeVolume}, errMissingField("Target")},
{mount.Mount{Type: mount.TypeVolume, Target: "/foo", Source: "hello"}, nil},
{mount.Mount{Type: mount.TypeVolume, Target: "/foo"}, nil},
{mount.Mount{Type: mount.TypeBind}, errMissingField("Target")},
{mount.Mount{Type: mount.TypeBind, Target: "/foo"}, errMissingField("Source")},
{mount.Mount{Type: mount.TypeBind, Target: "/foo", Source: "c:\\foo", VolumeOptions: &mount.VolumeOptions{}}, errExtraField("VolumeOptions")},
{mount.Mount{Type: mount.TypeBind, Source: "c:\\foo", Target: "/foo"}, errBindSourceDoesNotExist("c:\\foo")},
{mount.Mount{Type: mount.TypeBind, Source: testDir, Target: "/foo"}, nil},
{mount.Mount{Type: "invalid", Target: "/foo"}, errors.New("mount type unknown")},
}
testDir := t.TempDir()
parser := NewParser()
for i, x := range cases {
err := parser.ValidateMountConfig(&x.input)
if err == nil && x.expected == nil {
continue
}
if (err == nil && x.expected != nil) || (x.expected == nil && err != nil) || !strings.Contains(err.Error(), x.expected.Error()) {
t.Errorf("expected %q, got %q, case: %d", x.expected, err, i)
}
tests := []struct {
input mount.Mount
expected error
}{
{
input: mount.Mount{Type: mount.TypeVolume},
expected: errMissingField("Target"),
},
{
input: mount.Mount{Type: mount.TypeVolume, Target: testDestinationPath, Source: "hello"},
},
{
input: mount.Mount{Type: mount.TypeVolume, Target: testDestinationPath},
},
{
input: mount.Mount{Type: mount.TypeBind},
expected: errMissingField("Target"),
},
{
input: mount.Mount{Type: mount.TypeBind, Target: testDestinationPath},
expected: errMissingField("Source"),
},
{
input: mount.Mount{Type: mount.TypeBind, Target: testDestinationPath, Source: testSourcePath, VolumeOptions: &mount.VolumeOptions{}},
expected: errExtraField("VolumeOptions"),
},
{
input: mount.Mount{Type: mount.TypeBind, Source: testDir, Target: testDestinationPath},
},
{
input: mount.Mount{Type: "invalid", Target: testDestinationPath},
expected: errors.New("mount type unknown"),
},
{
input: mount.Mount{Type: mount.TypeBind, Source: testSourcePath, Target: testDestinationPath},
expected: errBindSourceDoesNotExist(testSourcePath),
},
}
if runtime.GOOS == "windows" {
parser = NewLCOWParser()
for i, x := range lcowCases {
err := parser.ValidateMountConfig(&x.input)
if err == nil && x.expected == nil {
continue
for _, tc := range tests {
tc := tc
t.Run("", func(t *testing.T) {
err := parser.ValidateMountConfig(&tc.input)
if tc.expected != nil {
assert.Check(t, is.ErrorContains(err, tc.expected.Error()))
} else {
assert.Check(t, err)
}
if (err == nil && x.expected != nil) || (x.expected == nil && err != nil) || !strings.Contains(err.Error(), x.expected.Error()) {
t.Errorf("expected %q, got %q, case: %d", x.expected, err, i)
}
}
})
}
}
func TestValidateLCOWMount(t *testing.T) {
if runtime.GOOS != "windows" {
t.Skip("only tested on Windows")
}
testDir := t.TempDir()
parser := NewLCOWParser()
tests := []struct {
input mount.Mount
expected error
}{
{
input: mount.Mount{Type: mount.TypeVolume},
expected: errMissingField("Target"),
},
{
input: mount.Mount{Type: mount.TypeVolume, Target: "/foo", Source: "hello"},
},
{
input: mount.Mount{Type: mount.TypeVolume, Target: "/foo"},
},
{
input: mount.Mount{Type: mount.TypeBind},
expected: errMissingField("Target"),
},
{
input: mount.Mount{Type: mount.TypeBind, Target: "/foo"},
expected: errMissingField("Source"),
},
{
input: mount.Mount{Type: mount.TypeBind, Target: "/foo", Source: "c:\\foo", VolumeOptions: &mount.VolumeOptions{}},
expected: errExtraField("VolumeOptions"),
},
{
input: mount.Mount{Type: mount.TypeBind, Source: "c:\\foo", Target: "/foo"},
expected: errBindSourceDoesNotExist("c:\\foo"),
},
{
input: mount.Mount{Type: mount.TypeBind, Source: testDir, Target: "/foo"},
},
{
input: mount.Mount{Type: "invalid", Target: "/foo"},
expected: errors.New("mount type unknown"),
},
}
for _, tc := range tests {
tc := tc
t.Run("", func(t *testing.T) {
err := parser.ValidateMountConfig(&tc.input)
if tc.expected != nil {
assert.Check(t, is.ErrorContains(err, tc.expected.Error()))
} else {
assert.Check(t, err)
}
})
}
}

View file

@ -2,7 +2,7 @@
package mounts // import "github.com/docker/docker/volume/mounts"
var (
const (
testDestinationPath = "/foo"
testSourcePath = "/foo"
)

View file

@ -1,6 +1,6 @@
package mounts // import "github.com/docker/docker/volume/mounts"
var (
const (
testDestinationPath = `c:\foo`
testSourcePath = `c:\foo`
)

View file

@ -7,6 +7,7 @@ import (
"github.com/docker/docker/api/types/mount"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
)
func TestWindowsParseMountRaw(t *testing.T) {
@ -118,19 +119,105 @@ func TestWindowsParseMountRawSplit(t *testing.T) {
expRW bool
fail bool
}{
{`c:\:d:`, "local", mount.TypeBind, `d:`, `c:\`, ``, "", true, false},
{`c:\:d:\`, "local", mount.TypeBind, `d:\`, `c:\`, ``, "", true, false},
{`c:\:d:\:ro`, "local", mount.TypeBind, `d:\`, `c:\`, ``, "", false, false},
{`c:\:d:\:rw`, "local", mount.TypeBind, `d:\`, `c:\`, ``, "", true, false},
{`c:\:d:\:foo`, "local", mount.TypeBind, `d:\`, `c:\`, ``, "", false, true},
{`name:d::rw`, "local", mount.TypeVolume, `d:`, ``, `name`, "local", true, false},
{`name:d:`, "local", mount.TypeVolume, `d:`, ``, `name`, "local", true, false},
{`name:d::ro`, "local", mount.TypeVolume, `d:`, ``, `name`, "local", false, false},
{`name:c:`, "", mount.TypeVolume, ``, ``, ``, "", true, true},
{`driver/name:c:`, "", mount.TypeVolume, ``, ``, ``, "", true, true},
{`\\.\pipe\foo:\\.\pipe\bar`, "local", mount.TypeNamedPipe, `\\.\pipe\bar`, `\\.\pipe\foo`, "", "", true, false},
{`\\.\pipe\foo:c:\foo\bar`, "local", mount.TypeNamedPipe, ``, ``, "", "", true, true},
{`c:\foo\bar:\\.\pipe\foo`, "local", mount.TypeNamedPipe, ``, ``, "", "", true, true},
{
bind: `c:\:d:`,
driver: "local",
expType: mount.TypeBind,
expDest: `d:`,
expSource: `c:\`,
expRW: true,
},
{
bind: `c:\:d:\`,
driver: "local",
expType: mount.TypeBind,
expDest: `d:\`,
expSource: `c:\`,
expRW: true,
},
{
bind: `c:\:d:\:ro`,
driver: "local",
expType: mount.TypeBind,
expDest: `d:\`,
expSource: `c:\`,
},
{
bind: `c:\:d:\:rw`,
driver: "local",
expType: mount.TypeBind,
expDest: `d:\`,
expSource: `c:\`,
expRW: true,
},
{
bind: `c:\:d:\:foo`,
driver: "local",
expType: mount.TypeBind,
expDest: `d:\`,
expSource: `c:\`,
fail: true,
},
{
bind: `name:d::rw`,
driver: "local",
expType: mount.TypeVolume,
expDest: `d:`,
expName: `name`,
expDriver: "local",
expRW: true,
},
{
bind: `name:d:`,
driver: "local",
expType: mount.TypeVolume,
expDest: `d:`,
expName: `name`,
expDriver: "local",
expRW: true,
},
{
bind: `name:d::ro`,
driver: "local",
expType: mount.TypeVolume,
expDest: `d:`,
expName: `name`,
expDriver: "local",
},
{
bind: `name:c:`,
expType: mount.TypeVolume,
expRW: true,
fail: true,
},
{
bind: `driver/name:c:`,
expType: mount.TypeVolume,
expRW: true,
fail: true,
},
{
bind: `\\.\pipe\foo:\\.\pipe\bar`,
driver: "local",
expType: mount.TypeNamedPipe,
expDest: `\\.\pipe\bar`,
expSource: `\\.\pipe\foo`,
expRW: true,
},
{
bind: `\\.\pipe\foo:c:\foo\bar`,
driver: "local",
expType: mount.TypeNamedPipe,
expRW: true,
fail: true,
},
{
bind: `c:\foo\bar:\\.\pipe\foo`,
driver: "local",
expType: mount.TypeNamedPipe,
expRW: true,
fail: true,
},
}
parser := NewWindowsParser()
@ -138,22 +225,22 @@ func TestWindowsParseMountRawSplit(t *testing.T) {
p.fi = mockFiProvider{}
}
for i, c := range cases {
c := c
t.Run(fmt.Sprintf("%d_%s", i, c.bind), func(t *testing.T) {
m, err := parser.ParseMountRaw(c.bind, c.driver)
if c.fail {
assert.ErrorContains(t, err, "", "expected an error")
for _, tc := range cases {
tc := tc
t.Run(tc.bind, func(t *testing.T) {
m, err := parser.ParseMountRaw(tc.bind, tc.driver)
if tc.fail {
assert.Check(t, is.ErrorContains(err, ""), "expected an error")
return
}
assert.NilError(t, err)
assert.Equal(t, m.Destination, c.expDest)
assert.Equal(t, m.Source, c.expSource)
assert.Equal(t, m.Name, c.expName)
assert.Equal(t, m.Driver, c.expDriver)
assert.Equal(t, m.RW, c.expRW)
assert.Equal(t, m.Type, c.expType)
assert.Check(t, err)
assert.Check(t, is.Equal(m.Destination, tc.expDest))
assert.Check(t, is.Equal(m.Source, tc.expSource))
assert.Check(t, is.Equal(m.Name, tc.expName))
assert.Check(t, is.Equal(m.Driver, tc.expDriver))
assert.Check(t, is.Equal(m.RW, tc.expRW))
assert.Check(t, is.Equal(m.Type, tc.expType))
})
}
}