|
@@ -2,71 +2,123 @@ package mounts // import "github.com/docker/docker/volume/mounts"
|
|
|
|
|
|
import (
|
|
import (
|
|
"errors"
|
|
"errors"
|
|
- "os"
|
|
|
|
"runtime"
|
|
"runtime"
|
|
- "strings"
|
|
|
|
"testing"
|
|
"testing"
|
|
|
|
|
|
"github.com/docker/docker/api/types/mount"
|
|
"github.com/docker/docker/api/types/mount"
|
|
|
|
+ "gotest.tools/v3/assert"
|
|
|
|
+ is "gotest.tools/v3/assert/cmp"
|
|
)
|
|
)
|
|
|
|
|
|
func TestValidateMount(t *testing.T) {
|
|
func TestValidateMount(t *testing.T) {
|
|
- testDir, err := os.MkdirTemp("", "test-validate-mount")
|
|
|
|
- if err != nil {
|
|
|
|
- t.Fatal(err)
|
|
|
|
- }
|
|
|
|
- defer os.RemoveAll(testDir)
|
|
|
|
|
|
+ testDir := t.TempDir()
|
|
|
|
+ parser := NewParser()
|
|
|
|
|
|
- cases := []struct {
|
|
|
|
|
|
+ tests := []struct {
|
|
input mount.Mount
|
|
input mount.Mount
|
|
expected error
|
|
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")},
|
|
|
|
|
|
+ {
|
|
|
|
+ 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),
|
|
|
|
+ },
|
|
|
|
+ }
|
|
|
|
+ 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)
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
|
|
- {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)},
|
|
|
|
|
|
+func TestValidateLCOWMount(t *testing.T) {
|
|
|
|
+ if runtime.GOOS != "windows" {
|
|
|
|
+ t.Skip("only tested on Windows")
|
|
}
|
|
}
|
|
|
|
+ testDir := t.TempDir()
|
|
|
|
+ parser := NewLCOWParser()
|
|
|
|
|
|
- lcowCases := []struct {
|
|
|
|
|
|
+ tests := []struct {
|
|
input mount.Mount
|
|
input mount.Mount
|
|
expected error
|
|
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")},
|
|
|
|
- }
|
|
|
|
- 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)
|
|
|
|
- }
|
|
|
|
|
|
+ {
|
|
|
|
+ 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"),
|
|
|
|
+ },
|
|
}
|
|
}
|
|
- if runtime.GOOS == "windows" {
|
|
|
|
- parser = NewLCOWParser()
|
|
|
|
- for i, x := range lcowCases {
|
|
|
|
- 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)
|
|
|
|
|
|
+ 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)
|
|
}
|
|
}
|
|
- }
|
|
|
|
|
|
+ })
|
|
}
|
|
}
|
|
}
|
|
}
|