From 63ccfa2bebffb5a51a6fa5c7562ea72df0e4b359 Mon Sep 17 00:00:00 2001 From: markturansky Date: Wed, 1 Jul 2015 10:50:39 -0400 Subject: [PATCH] Added unit tests for each PV using IsReadOnly --- pkg/volume/aws_ebs/aws_ebs_test.go | 8 +-- pkg/volume/gce_pd/gce_pd_test.go | 49 +++++++++++++++ pkg/volume/glusterfs/glusterfs_test.go | 62 ++++++++++++++++++- pkg/volume/host_path/host_path.go | 15 +++-- pkg/volume/host_path/host_path_test.go | 49 +++++++++++++++ pkg/volume/iscsi/iscsi_test.go | 56 ++++++++++++++++- pkg/volume/nfs/nfs.go | 7 ++- pkg/volume/nfs/nfs_test.go | 51 ++++++++++++++- .../persistent_claim/persistent_claim.go | 1 - pkg/volume/rbd/rbd_test.go | 55 +++++++++++++++- 10 files changed, 338 insertions(+), 15 deletions(-) diff --git a/pkg/volume/aws_ebs/aws_ebs_test.go b/pkg/volume/aws_ebs/aws_ebs_test.go index 2e7727c6919..97bbc9b6b0b 100644 --- a/pkg/volume/aws_ebs/aws_ebs_test.go +++ b/pkg/volume/aws_ebs/aws_ebs_test.go @@ -196,13 +196,13 @@ func TestPersistentClaimReadOnlyFlag(t *testing.T) { plugMgr := volume.VolumePluginMgr{} plugMgr.InitPlugins(ProbeVolumePlugins(), volume.NewFakeVolumeHost("/tmp/fake", client, nil)) plug, _ := plugMgr.FindPluginByName(awsElasticBlockStorePluginName) - spec := volume.NewSpecFromPersistentVolume(pv, false) + // readOnly bool is supplied by persistent-claim volume source when its builder creates other volumes + spec := volume.NewSpecFromPersistentVolume(pv, true) pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}} builder, _ := plug.NewBuilder(spec, pod, volume.VolumeOptions{}, nil) - if builder.IsReadOnly() { - t.Errorf("Expected false for builder.IsReadOnly") + if !builder.IsReadOnly() { + t.Errorf("Expected true for builder.IsReadOnly") } - } diff --git a/pkg/volume/gce_pd/gce_pd_test.go b/pkg/volume/gce_pd/gce_pd_test.go index cf7c89e5097..c95b841ec77 100644 --- a/pkg/volume/gce_pd/gce_pd_test.go +++ b/pkg/volume/gce_pd/gce_pd_test.go @@ -21,6 +21,8 @@ import ( "testing" "github.com/GoogleCloudPlatform/kubernetes/pkg/api" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest" + "github.com/GoogleCloudPlatform/kubernetes/pkg/client/testclient" "github.com/GoogleCloudPlatform/kubernetes/pkg/types" "github.com/GoogleCloudPlatform/kubernetes/pkg/util/mount" "github.com/GoogleCloudPlatform/kubernetes/pkg/volume" @@ -171,3 +173,50 @@ func TestPlugin(t *testing.T) { t.Errorf("Detach watch not called") } } + +func TestPersistentClaimReadOnlyFlag(t *testing.T) { + pv := &api.PersistentVolume{ + ObjectMeta: api.ObjectMeta{ + Name: "pvA", + }, + Spec: api.PersistentVolumeSpec{ + PersistentVolumeSource: api.PersistentVolumeSource{ + GCEPersistentDisk: &api.GCEPersistentDiskVolumeSource{}, + }, + ClaimRef: &api.ObjectReference{ + Name: "claimA", + }, + }, + } + + claim := &api.PersistentVolumeClaim{ + ObjectMeta: api.ObjectMeta{ + Name: "claimA", + Namespace: "nsA", + }, + Spec: api.PersistentVolumeClaimSpec{ + VolumeName: "pvA", + }, + Status: api.PersistentVolumeClaimStatus{ + Phase: api.ClaimBound, + }, + } + + o := testclient.NewObjects(api.Scheme, api.Scheme) + o.Add(pv) + o.Add(claim) + client := &testclient.Fake{ReactFn: testclient.ObjectReaction(o, latest.RESTMapper)} + + plugMgr := volume.VolumePluginMgr{} + plugMgr.InitPlugins(ProbeVolumePlugins(), volume.NewFakeVolumeHost("/tmp/fake", client, nil)) + plug, _ := plugMgr.FindPluginByName(gcePersistentDiskPluginName) + + // readOnly bool is supplied by persistent-claim volume source when its builder creates other volumes + spec := volume.NewSpecFromPersistentVolume(pv, true) + pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}} + builder, _ := plug.NewBuilder(spec, pod, volume.VolumeOptions{}, nil) + + if !builder.IsReadOnly() { + t.Errorf("Expected true for builder.IsReadOnly") + } +} diff --git a/pkg/volume/glusterfs/glusterfs_test.go b/pkg/volume/glusterfs/glusterfs_test.go index 57baf671894..6961e09ab79 100644 --- a/pkg/volume/glusterfs/glusterfs_test.go +++ b/pkg/volume/glusterfs/glusterfs_test.go @@ -21,6 +21,8 @@ import ( "testing" "github.com/GoogleCloudPlatform/kubernetes/pkg/api" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest" + "github.com/GoogleCloudPlatform/kubernetes/pkg/client/testclient" "github.com/GoogleCloudPlatform/kubernetes/pkg/types" "github.com/GoogleCloudPlatform/kubernetes/pkg/util/exec" "github.com/GoogleCloudPlatform/kubernetes/pkg/util/mount" @@ -153,5 +155,63 @@ func TestPluginPersistentVolume(t *testing.T) { }, } - doTestPlugin(t, volume.NewSpecFromPersistentVolume(vol)) + doTestPlugin(t, volume.NewSpecFromPersistentVolume(vol, false)) +} + +func TestPersistentClaimReadOnlyFlag(t *testing.T) { + pv := &api.PersistentVolume{ + ObjectMeta: api.ObjectMeta{ + Name: "pvA", + }, + Spec: api.PersistentVolumeSpec{ + PersistentVolumeSource: api.PersistentVolumeSource{ + Glusterfs: &api.GlusterfsVolumeSource{"ep", "vol", false}, + }, + ClaimRef: &api.ObjectReference{ + Name: "claimA", + }, + }, + } + + claim := &api.PersistentVolumeClaim{ + ObjectMeta: api.ObjectMeta{ + Name: "claimA", + Namespace: "nsA", + }, + Spec: api.PersistentVolumeClaimSpec{ + VolumeName: "pvA", + }, + Status: api.PersistentVolumeClaimStatus{ + Phase: api.ClaimBound, + }, + } + + ep := &api.Endpoints{ + ObjectMeta: api.ObjectMeta{ + Name: "ep", + }, + Subsets: []api.EndpointSubset{{ + Addresses: []api.EndpointAddress{{IP: "127.0.0.1"}}, + Ports: []api.EndpointPort{{"foo", 80, api.ProtocolTCP}}, + }}, + } + + o := testclient.NewObjects(api.Scheme, api.Scheme) + o.Add(pv) + o.Add(claim) + o.Add(ep) + client := &testclient.Fake{ReactFn: testclient.ObjectReaction(o, latest.RESTMapper)} + + plugMgr := volume.VolumePluginMgr{} + plugMgr.InitPlugins(ProbeVolumePlugins(), volume.NewFakeVolumeHost("/tmp/fake", client, nil)) + plug, _ := plugMgr.FindPluginByName(glusterfsPluginName) + + // readOnly bool is supplied by persistent-claim volume source when its builder creates other volumes + spec := volume.NewSpecFromPersistentVolume(pv, true) + pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}} + builder, _ := plug.NewBuilder(spec, pod, volume.VolumeOptions{}, nil) + + if !builder.IsReadOnly() { + t.Errorf("Expected true for builder.IsReadOnly") + } } diff --git a/pkg/volume/host_path/host_path.go b/pkg/volume/host_path/host_path.go index 3768740509c..2afd40325d8 100644 --- a/pkg/volume/host_path/host_path.go +++ b/pkg/volume/host_path/host_path.go @@ -71,9 +71,15 @@ func (plugin *hostPathPlugin) GetAccessModes() []api.PersistentVolumeAccessMode func (plugin *hostPathPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.VolumeOptions, _ mount.Interface) (volume.Builder, error) { if spec.VolumeSource.HostPath != nil { - return &hostPathBuilder{&hostPath{spec.VolumeSource.HostPath.Path}}, nil + return &hostPathBuilder{ + hostPath: spec.VolumeSource.HostPath, + readOnly: false, + }, nil } else { - return &hostPathBuilder{&hostPath{spec.PersistentVolumeSource.HostPath.Path}}, nil + return &hostPathBuilder{ + hostPath: spec.PersistentVolumeSource.HostPath, + readOnly: spec.ReadOnly, + }, nil } } @@ -96,7 +102,7 @@ func newRecycler(spec *volume.Spec, host volume.VolumeHost) (volume.Recycler, er // HostPath volumes represent a bare host file or directory mount. // The direct at the specified path will be directly exposed to the container. type hostPath struct { - path string + path string } func (hp *hostPath) GetPath() string { @@ -105,6 +111,7 @@ func (hp *hostPath) GetPath() string { type hostPathBuilder struct { *hostPath + readOnly bool } var _ volume.Builder = &hostPathBuilder{} @@ -120,7 +127,7 @@ func (b *hostPathBuilder) SetUpAt(dir string) error { } func (b *hostPathBuilder) IsReadOnly() bool { - return false + return b.readOnly } func (b *hostPathBuilder) GetPath() string { diff --git a/pkg/volume/host_path/host_path_test.go b/pkg/volume/host_path/host_path_test.go index 0dfeeec89c4..0d4ffa217ae 100644 --- a/pkg/volume/host_path/host_path_test.go +++ b/pkg/volume/host_path/host_path_test.go @@ -20,6 +20,8 @@ import ( "testing" "github.com/GoogleCloudPlatform/kubernetes/pkg/api" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest" + "github.com/GoogleCloudPlatform/kubernetes/pkg/client/testclient" "github.com/GoogleCloudPlatform/kubernetes/pkg/types" "github.com/GoogleCloudPlatform/kubernetes/pkg/volume" ) @@ -142,3 +144,50 @@ func TestPlugin(t *testing.T) { t.Errorf("Expected success, got: %v", err) } } + +func TestPersistentClaimReadOnlyFlag(t *testing.T) { + pv := &api.PersistentVolume{ + ObjectMeta: api.ObjectMeta{ + Name: "pvA", + }, + Spec: api.PersistentVolumeSpec{ + PersistentVolumeSource: api.PersistentVolumeSource{ + HostPath: &api.HostPathVolumeSource{"foo"}, + }, + ClaimRef: &api.ObjectReference{ + Name: "claimA", + }, + }, + } + + claim := &api.PersistentVolumeClaim{ + ObjectMeta: api.ObjectMeta{ + Name: "claimA", + Namespace: "nsA", + }, + Spec: api.PersistentVolumeClaimSpec{ + VolumeName: "pvA", + }, + Status: api.PersistentVolumeClaimStatus{ + Phase: api.ClaimBound, + }, + } + + o := testclient.NewObjects(api.Scheme, api.Scheme) + o.Add(pv) + o.Add(claim) + client := &testclient.Fake{ReactFn: testclient.ObjectReaction(o, latest.RESTMapper)} + + plugMgr := volume.VolumePluginMgr{} + plugMgr.InitPlugins(ProbeVolumePlugins(), volume.NewFakeVolumeHost("/tmp/fake", client, nil)) + plug, _ := plugMgr.FindPluginByName(hostPathPluginName) + + // readOnly bool is supplied by persistent-claim volume source when its builder creates other volumes + spec := volume.NewSpecFromPersistentVolume(pv, true) + pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}} + builder, _ := plug.NewBuilder(spec, pod, volume.VolumeOptions{}, nil) + + if !builder.IsReadOnly() { + t.Errorf("Expected true for builder.IsReadOnly") + } +} diff --git a/pkg/volume/iscsi/iscsi_test.go b/pkg/volume/iscsi/iscsi_test.go index 5a66dc265f1..ce8b0f5d6c9 100644 --- a/pkg/volume/iscsi/iscsi_test.go +++ b/pkg/volume/iscsi/iscsi_test.go @@ -21,6 +21,8 @@ import ( "testing" "github.com/GoogleCloudPlatform/kubernetes/pkg/api" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest" + "github.com/GoogleCloudPlatform/kubernetes/pkg/client/testclient" "github.com/GoogleCloudPlatform/kubernetes/pkg/types" "github.com/GoogleCloudPlatform/kubernetes/pkg/util/mount" "github.com/GoogleCloudPlatform/kubernetes/pkg/volume" @@ -193,5 +195,57 @@ func TestPluginPersistentVolume(t *testing.T) { }, }, } - doTestPlugin(t, volume.NewSpecFromPersistentVolume(vol)) + doTestPlugin(t, volume.NewSpecFromPersistentVolume(vol, false)) +} + +func TestPersistentClaimReadOnlyFlag(t *testing.T) { + pv := &api.PersistentVolume{ + ObjectMeta: api.ObjectMeta{ + Name: "pvA", + }, + Spec: api.PersistentVolumeSpec{ + PersistentVolumeSource: api.PersistentVolumeSource{ + ISCSI: &api.ISCSIVolumeSource{ + TargetPortal: "127.0.0.1:3260", + IQN: "iqn.2014-12.server:storage.target01", + FSType: "ext4", + Lun: 0, + }, + }, + ClaimRef: &api.ObjectReference{ + Name: "claimA", + }, + }, + } + + claim := &api.PersistentVolumeClaim{ + ObjectMeta: api.ObjectMeta{ + Name: "claimA", + Namespace: "nsA", + }, + Spec: api.PersistentVolumeClaimSpec{ + VolumeName: "pvA", + }, + Status: api.PersistentVolumeClaimStatus{ + Phase: api.ClaimBound, + }, + } + + o := testclient.NewObjects(api.Scheme, api.Scheme) + o.Add(pv) + o.Add(claim) + client := &testclient.Fake{ReactFn: testclient.ObjectReaction(o, latest.RESTMapper)} + + plugMgr := volume.VolumePluginMgr{} + plugMgr.InitPlugins(ProbeVolumePlugins(), volume.NewFakeVolumeHost("/tmp/fake", client, nil)) + plug, _ := plugMgr.FindPluginByName(iscsiPluginName) + + // readOnly bool is supplied by persistent-claim volume source when its builder creates other volumes + spec := volume.NewSpecFromPersistentVolume(pv, true) + pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}} + builder, _ := plug.NewBuilder(spec, pod, volume.VolumeOptions{}, nil) + + if !builder.IsReadOnly() { + t.Errorf("Expected true for builder.IsReadOnly") + } } diff --git a/pkg/volume/nfs/nfs.go b/pkg/volume/nfs/nfs.go index 54151817dbd..f9544b72962 100644 --- a/pkg/volume/nfs/nfs.go +++ b/pkg/volume/nfs/nfs.go @@ -76,11 +76,13 @@ func (plugin *nfsPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.Vo func (plugin *nfsPlugin) newBuilderInternal(spec *volume.Spec, pod *api.Pod, mounter mount.Interface) (volume.Builder, error) { var source *api.NFSVolumeSource - + var readOnly bool if spec.VolumeSource.NFS != nil { source = spec.VolumeSource.NFS + readOnly = spec.VolumeSource.NFS.ReadOnly } else { source = spec.PersistentVolumeSource.NFS + readOnly = spec.ReadOnly } return &nfsBuilder{ nfs: &nfs{ @@ -91,7 +93,8 @@ func (plugin *nfsPlugin) newBuilderInternal(spec *volume.Spec, pod *api.Pod, mou }, server: source.Server, exportPath: source.Path, - readOnly: source.ReadOnly}, nil + readOnly: readOnly, + }, nil } func (plugin *nfsPlugin) NewCleaner(volName string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) { diff --git a/pkg/volume/nfs/nfs_test.go b/pkg/volume/nfs/nfs_test.go index 837a75660f2..f13575ca9ae 100644 --- a/pkg/volume/nfs/nfs_test.go +++ b/pkg/volume/nfs/nfs_test.go @@ -21,6 +21,8 @@ import ( "testing" "github.com/GoogleCloudPlatform/kubernetes/pkg/api" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest" + "github.com/GoogleCloudPlatform/kubernetes/pkg/client/testclient" "github.com/GoogleCloudPlatform/kubernetes/pkg/types" "github.com/GoogleCloudPlatform/kubernetes/pkg/util/mount" "github.com/GoogleCloudPlatform/kubernetes/pkg/volume" @@ -199,5 +201,52 @@ func TestPluginPersistentVolume(t *testing.T) { }, } - doTestPlugin(t, volume.NewSpecFromPersistentVolume(vol)) + doTestPlugin(t, volume.NewSpecFromPersistentVolume(vol, false)) +} + +func TestPersistentClaimReadOnlyFlag(t *testing.T) { + pv := &api.PersistentVolume{ + ObjectMeta: api.ObjectMeta{ + Name: "pvA", + }, + Spec: api.PersistentVolumeSpec{ + PersistentVolumeSource: api.PersistentVolumeSource{ + NFS: &api.NFSVolumeSource{}, + }, + ClaimRef: &api.ObjectReference{ + Name: "claimA", + }, + }, + } + + claim := &api.PersistentVolumeClaim{ + ObjectMeta: api.ObjectMeta{ + Name: "claimA", + Namespace: "nsA", + }, + Spec: api.PersistentVolumeClaimSpec{ + VolumeName: "pvA", + }, + Status: api.PersistentVolumeClaimStatus{ + Phase: api.ClaimBound, + }, + } + + o := testclient.NewObjects(api.Scheme, api.Scheme) + o.Add(pv) + o.Add(claim) + client := &testclient.Fake{ReactFn: testclient.ObjectReaction(o, latest.RESTMapper)} + + plugMgr := volume.VolumePluginMgr{} + plugMgr.InitPlugins(ProbeVolumePlugins(), volume.NewFakeVolumeHost("/tmp/fake", client, nil)) + plug, _ := plugMgr.FindPluginByName(nfsPluginName) + + // readOnly bool is supplied by persistent-claim volume source when its builder creates other volumes + spec := volume.NewSpecFromPersistentVolume(pv, true) + pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}} + builder, _ := plug.NewBuilder(spec, pod, volume.VolumeOptions{}, nil) + + if !builder.IsReadOnly() { + t.Errorf("Expected true for builder.IsReadOnly") + } } diff --git a/pkg/volume/persistent_claim/persistent_claim.go b/pkg/volume/persistent_claim/persistent_claim.go index 55d48ac4be5..7a69cdc3a3c 100644 --- a/pkg/volume/persistent_claim/persistent_claim.go +++ b/pkg/volume/persistent_claim/persistent_claim.go @@ -53,7 +53,6 @@ func (plugin *persistentClaimPlugin) CanSupport(spec *volume.Spec) bool { } func (plugin *persistentClaimPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) { - plugin.readOnly = spec.ReadOnly claim, err := plugin.host.GetKubeClient().PersistentVolumeClaims(pod.Namespace).Get(spec.VolumeSource.PersistentVolumeClaim.ClaimName) if err != nil { glog.Errorf("Error finding claim: %+v\n", spec.VolumeSource.PersistentVolumeClaim.ClaimName) diff --git a/pkg/volume/rbd/rbd_test.go b/pkg/volume/rbd/rbd_test.go index 94d3aa1c5ec..507972288a7 100644 --- a/pkg/volume/rbd/rbd_test.go +++ b/pkg/volume/rbd/rbd_test.go @@ -21,6 +21,8 @@ import ( "testing" "github.com/GoogleCloudPlatform/kubernetes/pkg/api" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest" + "github.com/GoogleCloudPlatform/kubernetes/pkg/client/testclient" "github.com/GoogleCloudPlatform/kubernetes/pkg/types" "github.com/GoogleCloudPlatform/kubernetes/pkg/util/mount" "github.com/GoogleCloudPlatform/kubernetes/pkg/volume" @@ -151,5 +153,56 @@ func TestPluginPersistentVolume(t *testing.T) { }, } - doTestPlugin(t, volume.NewSpecFromPersistentVolume(vol)) + doTestPlugin(t, volume.NewSpecFromPersistentVolume(vol, false)) +} + +func TestPersistentClaimReadOnlyFlag(t *testing.T) { + pv := &api.PersistentVolume{ + ObjectMeta: api.ObjectMeta{ + Name: "pvA", + }, + Spec: api.PersistentVolumeSpec{ + PersistentVolumeSource: api.PersistentVolumeSource{ + RBD: &api.RBDVolumeSource{ + CephMonitors: []string{"a", "b"}, + RBDImage: "bar", + FSType: "ext4", + }, + }, + ClaimRef: &api.ObjectReference{ + Name: "claimA", + }, + }, + } + + claim := &api.PersistentVolumeClaim{ + ObjectMeta: api.ObjectMeta{ + Name: "claimA", + Namespace: "nsA", + }, + Spec: api.PersistentVolumeClaimSpec{ + VolumeName: "pvA", + }, + Status: api.PersistentVolumeClaimStatus{ + Phase: api.ClaimBound, + }, + } + + o := testclient.NewObjects(api.Scheme, api.Scheme) + o.Add(pv) + o.Add(claim) + client := &testclient.Fake{ReactFn: testclient.ObjectReaction(o, latest.RESTMapper)} + + plugMgr := volume.VolumePluginMgr{} + plugMgr.InitPlugins(ProbeVolumePlugins(), volume.NewFakeVolumeHost("/tmp/fake", client, nil)) + plug, _ := plugMgr.FindPluginByName(rbdPluginName) + + // readOnly bool is supplied by persistent-claim volume source when its builder creates other volumes + spec := volume.NewSpecFromPersistentVolume(pv, true) + pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}} + builder, _ := plug.NewBuilder(spec, pod, volume.VolumeOptions{}, nil) + + if !builder.IsReadOnly() { + t.Errorf("Expected true for builder.IsReadOnly") + } }