github.com/gravitational/moby@v1.13.1/opts/mount_test.go (about)

     1  package opts
     2  
     3  import (
     4  	"os"
     5  	"testing"
     6  
     7  	mounttypes "github.com/docker/docker/api/types/mount"
     8  	"github.com/docker/docker/pkg/testutil/assert"
     9  )
    10  
    11  func TestMountOptString(t *testing.T) {
    12  	mount := MountOpt{
    13  		values: []mounttypes.Mount{
    14  			{
    15  				Type:   mounttypes.TypeBind,
    16  				Source: "/home/path",
    17  				Target: "/target",
    18  			},
    19  			{
    20  				Type:   mounttypes.TypeVolume,
    21  				Source: "foo",
    22  				Target: "/target/foo",
    23  			},
    24  		},
    25  	}
    26  	expected := "bind /home/path /target, volume foo /target/foo"
    27  	assert.Equal(t, mount.String(), expected)
    28  }
    29  
    30  func TestMountOptSetBindNoErrorBind(t *testing.T) {
    31  	for _, testcase := range []string{
    32  		// tests several aliases that should have same result.
    33  		"type=bind,target=/target,source=/source",
    34  		"type=bind,src=/source,dst=/target",
    35  		"type=bind,source=/source,dst=/target",
    36  		"type=bind,src=/source,target=/target",
    37  	} {
    38  		var mount MountOpt
    39  
    40  		assert.NilError(t, mount.Set(testcase))
    41  
    42  		mounts := mount.Value()
    43  		assert.Equal(t, len(mounts), 1)
    44  		assert.Equal(t, mounts[0], mounttypes.Mount{
    45  			Type:   mounttypes.TypeBind,
    46  			Source: "/source",
    47  			Target: "/target",
    48  		})
    49  	}
    50  }
    51  
    52  func TestMountOptSetVolumeNoError(t *testing.T) {
    53  	for _, testcase := range []string{
    54  		// tests several aliases that should have same result.
    55  		"type=volume,target=/target,source=/source",
    56  		"type=volume,src=/source,dst=/target",
    57  		"type=volume,source=/source,dst=/target",
    58  		"type=volume,src=/source,target=/target",
    59  	} {
    60  		var mount MountOpt
    61  
    62  		assert.NilError(t, mount.Set(testcase))
    63  
    64  		mounts := mount.Value()
    65  		assert.Equal(t, len(mounts), 1)
    66  		assert.Equal(t, mounts[0], mounttypes.Mount{
    67  			Type:   mounttypes.TypeVolume,
    68  			Source: "/source",
    69  			Target: "/target",
    70  		})
    71  	}
    72  }
    73  
    74  // TestMountOptDefaultType ensures that a mount without the type defaults to a
    75  // volume mount.
    76  func TestMountOptDefaultType(t *testing.T) {
    77  	var mount MountOpt
    78  	assert.NilError(t, mount.Set("target=/target,source=/foo"))
    79  	assert.Equal(t, mount.values[0].Type, mounttypes.TypeVolume)
    80  }
    81  
    82  func TestMountOptSetErrorNoTarget(t *testing.T) {
    83  	var mount MountOpt
    84  	assert.Error(t, mount.Set("type=volume,source=/foo"), "target is required")
    85  }
    86  
    87  func TestMountOptSetErrorInvalidKey(t *testing.T) {
    88  	var mount MountOpt
    89  	assert.Error(t, mount.Set("type=volume,bogus=foo"), "unexpected key 'bogus'")
    90  }
    91  
    92  func TestMountOptSetErrorInvalidField(t *testing.T) {
    93  	var mount MountOpt
    94  	assert.Error(t, mount.Set("type=volume,bogus"), "invalid field 'bogus'")
    95  }
    96  
    97  func TestMountOptSetErrorInvalidReadOnly(t *testing.T) {
    98  	var mount MountOpt
    99  	assert.Error(t, mount.Set("type=volume,readonly=no"), "invalid value for readonly: no")
   100  	assert.Error(t, mount.Set("type=volume,readonly=invalid"), "invalid value for readonly: invalid")
   101  }
   102  
   103  func TestMountOptDefaultEnableReadOnly(t *testing.T) {
   104  	var m MountOpt
   105  	assert.NilError(t, m.Set("type=bind,target=/foo,source=/foo"))
   106  	assert.Equal(t, m.values[0].ReadOnly, false)
   107  
   108  	m = MountOpt{}
   109  	assert.NilError(t, m.Set("type=bind,target=/foo,source=/foo,readonly"))
   110  	assert.Equal(t, m.values[0].ReadOnly, true)
   111  
   112  	m = MountOpt{}
   113  	assert.NilError(t, m.Set("type=bind,target=/foo,source=/foo,readonly=1"))
   114  	assert.Equal(t, m.values[0].ReadOnly, true)
   115  
   116  	m = MountOpt{}
   117  	assert.NilError(t, m.Set("type=bind,target=/foo,source=/foo,readonly=true"))
   118  	assert.Equal(t, m.values[0].ReadOnly, true)
   119  
   120  	m = MountOpt{}
   121  	assert.NilError(t, m.Set("type=bind,target=/foo,source=/foo,readonly=0"))
   122  	assert.Equal(t, m.values[0].ReadOnly, false)
   123  }
   124  
   125  func TestMountOptVolumeNoCopy(t *testing.T) {
   126  	var m MountOpt
   127  	assert.NilError(t, m.Set("type=volume,target=/foo,volume-nocopy"))
   128  	assert.Equal(t, m.values[0].Source, "")
   129  
   130  	m = MountOpt{}
   131  	assert.NilError(t, m.Set("type=volume,target=/foo,source=foo"))
   132  	assert.Equal(t, m.values[0].VolumeOptions == nil, true)
   133  
   134  	m = MountOpt{}
   135  	assert.NilError(t, m.Set("type=volume,target=/foo,source=foo,volume-nocopy=true"))
   136  	assert.Equal(t, m.values[0].VolumeOptions != nil, true)
   137  	assert.Equal(t, m.values[0].VolumeOptions.NoCopy, true)
   138  
   139  	m = MountOpt{}
   140  	assert.NilError(t, m.Set("type=volume,target=/foo,source=foo,volume-nocopy"))
   141  	assert.Equal(t, m.values[0].VolumeOptions != nil, true)
   142  	assert.Equal(t, m.values[0].VolumeOptions.NoCopy, true)
   143  
   144  	m = MountOpt{}
   145  	assert.NilError(t, m.Set("type=volume,target=/foo,source=foo,volume-nocopy=1"))
   146  	assert.Equal(t, m.values[0].VolumeOptions != nil, true)
   147  	assert.Equal(t, m.values[0].VolumeOptions.NoCopy, true)
   148  }
   149  
   150  func TestMountOptTypeConflict(t *testing.T) {
   151  	var m MountOpt
   152  	assert.Error(t, m.Set("type=bind,target=/foo,source=/foo,volume-nocopy=true"), "cannot mix")
   153  	assert.Error(t, m.Set("type=volume,target=/foo,source=/foo,bind-propagation=rprivate"), "cannot mix")
   154  }
   155  
   156  func TestMountOptSetTmpfsNoError(t *testing.T) {
   157  	for _, testcase := range []string{
   158  		// tests several aliases that should have same result.
   159  		"type=tmpfs,target=/target,tmpfs-size=1m,tmpfs-mode=0700",
   160  		"type=tmpfs,target=/target,tmpfs-size=1MB,tmpfs-mode=700",
   161  	} {
   162  		var mount MountOpt
   163  
   164  		assert.NilError(t, mount.Set(testcase))
   165  
   166  		mounts := mount.Value()
   167  		assert.Equal(t, len(mounts), 1)
   168  		assert.DeepEqual(t, mounts[0], mounttypes.Mount{
   169  			Type:   mounttypes.TypeTmpfs,
   170  			Target: "/target",
   171  			TmpfsOptions: &mounttypes.TmpfsOptions{
   172  				SizeBytes: 1024 * 1024, // not 1000 * 1000
   173  				Mode:      os.FileMode(0700),
   174  			},
   175  		})
   176  	}
   177  }
   178  
   179  func TestMountOptSetTmpfsError(t *testing.T) {
   180  	var m MountOpt
   181  	assert.Error(t, m.Set("type=tmpfs,target=/foo,tmpfs-size=foo"), "invalid value for tmpfs-size")
   182  	assert.Error(t, m.Set("type=tmpfs,target=/foo,tmpfs-mode=foo"), "invalid value for tmpfs-mode")
   183  	assert.Error(t, m.Set("type=tmpfs"), "target is required")
   184  }