moby/volume/validate_test.go
Brian Goff fc7b904dce Add new HostConfig field, Mounts.
`Mounts` allows users to specify in a much safer way the volumes they
want to use in the container.
This replaces `Binds` and `Volumes`, which both still exist, but
`Mounts` and `Binds`/`Volumes` are exclussive.
The CLI will continue to use `Binds` and `Volumes` due to concerns with
parsing the volume specs on the client side and cross-platform support
(for now).

The new API follows exactly the services mount API.

Example usage of `Mounts`:

```
$ curl -XPOST localhost:2375/containers/create -d '{
  "Image": "alpine:latest",
  "HostConfig": {
    "Mounts": [{
      "Type": "Volume",
      "Target": "/foo"
      },{
      "Type": "bind",
      "Source": "/var/run/docker.sock",
      "Target": "/var/run/docker.sock",
      },{
      "Type": "volume",
      "Name": "important_data",
      "Target": "/var/data",
      "ReadOnly": true,
      "VolumeOptions": {
	"DriverConfig": {
	  Name: "awesomeStorage",
	  Options: {"size": "10m"},
	  Labels: {"some":"label"}
	}
      }]
    }
}'
```

There are currently 2 types of mounts:

  - **bind**: Paths on the host that get mounted into the
    container. Paths must exist prior to creating the container.
  - **volume**: Volumes that persist after the
    container is removed.

Not all fields are available in each type, and validation is done to
ensure these fields aren't mixed up between types.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
2016-09-13 09:55:35 -04:00

43 lines
1.5 KiB
Go

package volume
import (
"errors"
"io/ioutil"
"os"
"strings"
"testing"
"github.com/docker/docker/api/types/mount"
)
func TestValidateMount(t *testing.T) {
testDir, err := ioutil.TempDir("", "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: testSourcePath, Target: testDestinationPath}, errBindNotExist},
{mount.Mount{Type: mount.TypeBind, Source: testDir, Target: testDestinationPath}, nil},
{mount.Mount{Type: "invalid", Target: testDestinationPath}, errors.New("mount type unknown")},
}
for i, x := range cases {
err := 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.Fatalf("expected %q, got %q, case: %d", x.expected, err, i)
}
}
}