Fix panic in expand controller when checking PVs

Unbound PVs have their Spec.ClaimRef = nil, so we should not dereference it blindly.

In addition, increase AddPVCUpdate test coverage to 100%
This commit is contained in:
Jan Safranek 2017-09-06 13:27:10 +02:00
parent 0076f02df0
commit e054dd297a
2 changed files with 79 additions and 20 deletions

View File

@ -89,8 +89,8 @@ func NewVolumeResizeMap(kubeClient clientset.Interface) VolumeResizeMap {
// AddPVCUpdate adds pvc for resizing
func (resizeMap *volumeResizeMap) AddPVCUpdate(pvc *v1.PersistentVolumeClaim, pv *v1.PersistentVolume) {
if pvc.Namespace != pv.Spec.ClaimRef.Namespace || pvc.Name != pv.Spec.ClaimRef.Name {
glog.V(4).Infof("Persistent Volume is not mapped to PVC being updated : %s", util.ClaimToClaimKey(pvc))
if pv.Spec.ClaimRef == nil || pvc.Namespace != pv.Spec.ClaimRef.Namespace || pvc.Name != pv.Spec.ClaimRef.Name {
glog.V(4).Infof("Persistent Volume is not bound to PVC being updated : %s", util.ClaimToClaimKey(pvc))
return
}

View File

@ -27,31 +27,87 @@ import (
"k8s.io/kubernetes/pkg/volume/util/types"
)
func Test_AddValidPvcUpdate(t *testing.T) {
resizeMap := createTestVolumeResizeMap()
claim1 := testVolumeClaim("foo", "ns", v1.PersistentVolumeClaimSpec{
func Test_AddValidPVCUpdate(t *testing.T) {
claim := testVolumeClaim("foo", "ns", v1.PersistentVolumeClaimSpec{
AccessModes: []v1.PersistentVolumeAccessMode{
v1.ReadWriteOnce,
v1.ReadOnlyMany,
},
Resources: v1.ResourceRequirements{
Requests: v1.ResourceList{
v1.ResourceName(v1.ResourceStorage): resource.MustParse("10G"),
v1.ResourceName(v1.ResourceStorage): resource.MustParse("12G"),
},
},
VolumeName: "foo",
})
claimClone := claim1.DeepCopy()
claimClone.Spec.Resources.Requests[v1.ResourceStorage] = resource.MustParse("12G")
pv := getPersistentVolume("foo", resource.MustParse("10G"), claim1)
resizeMap.AddPVCUpdate(claimClone, pv)
pvcr := resizeMap.GetPVCsWithResizeRequest()
if len(pvcr) != 1 {
t.Fatalf("Expected 1 pvc resize request got 0")
unboundClaim := claim.DeepCopy()
unboundClaim.Status.Phase = v1.ClaimPending
noResizeClaim := claim.DeepCopy()
noResizeClaim.Status.Capacity = v1.ResourceList{
v1.ResourceName(v1.ResourceStorage): resource.MustParse("12G"),
}
boundPV := getPersistentVolume("foo", resource.MustParse("10G"), claim)
unboundPV := getPersistentVolume("foo", resource.MustParse("10G"), nil)
misboundPV := getPersistentVolume("foo", resource.MustParse("10G"), nil)
misboundPV.Spec.ClaimRef = &v1.ObjectReference{
Namespace: "someOtherNamespace",
Name: "someOtherName",
}
tests := []struct {
name string
pvc *v1.PersistentVolumeClaim
pv *v1.PersistentVolume
expectedPVCs int
}{
{
"validPVCUpdate",
claim,
boundPV,
1,
},
{
"noResizeRequired",
noResizeClaim,
boundPV,
0,
},
{
"unboundPVC",
unboundClaim,
boundPV,
0,
},
{
"unboundPV",
claim,
unboundPV,
0,
},
{
"misboundPV",
claim,
misboundPV,
0,
},
}
for _, test := range tests {
resizeMap := createTestVolumeResizeMap()
pvc := test.pvc.DeepCopy()
pv := test.pv.DeepCopy()
resizeMap.AddPVCUpdate(pvc, pv)
pvcr := resizeMap.GetPVCsWithResizeRequest()
if len(pvcr) != test.expectedPVCs {
t.Errorf("Test %q expected %d pvc resize request got %d", test.name, test.expectedPVCs, len(pvcr))
}
if test.expectedPVCs > 0 {
assert.Equal(t, resource.MustParse("12G"), pvcr[0].ExpectedSize, test.name)
}
assert.Equal(t, 0, len(resizeMap.pvcrs), test.name)
}
assert.Equal(t, resource.MustParse("12G"), pvcr[0].ExpectedSize)
assert.Equal(t, 0, len(resizeMap.pvcrs))
}
func createTestVolumeResizeMap() *volumeResizeMap {
@ -73,16 +129,19 @@ func testVolumeClaim(name string, namespace string, spec v1.PersistentVolumeClai
}
func getPersistentVolume(volumeName string, capacity resource.Quantity, pvc *v1.PersistentVolumeClaim) *v1.PersistentVolume {
return &v1.PersistentVolume{
volume := &v1.PersistentVolume{
ObjectMeta: metav1.ObjectMeta{Name: volumeName},
Spec: v1.PersistentVolumeSpec{
Capacity: v1.ResourceList{
v1.ResourceName(v1.ResourceStorage): capacity,
},
ClaimRef: &v1.ObjectReference{
Namespace: pvc.Namespace,
Name: pvc.Name,
},
},
}
if pvc != nil {
volume.Spec.ClaimRef = &v1.ObjectReference{
Namespace: pvc.Namespace,
Name: pvc.Name,
}
}
return volume
}