mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-26 21:17:23 +00:00
Merge pull request #26894 from jsafrane/fix-integration-pv-flake
Automatic merge from submit-queue Fix integration pv flakes There are two fixes in this PR: - run tests in separarate functions and use objects with different names, otherwise events from the beginning of the function are caught later when we watch for events of a different PV/PVC - don't set PV.Spec.ClaimRef.UID of pre-bound PVs. PVs with UID set are considered as bound and they are deleted/recycled when appropriate PVC does not exists yet. Fixes #26730 and probably also ~~#26894~~ #26256
This commit is contained in:
commit
1ed5342b35
@ -103,6 +103,7 @@ func testSleep() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestPersistentVolumeRecycler(t *testing.T) {
|
func TestPersistentVolumeRecycler(t *testing.T) {
|
||||||
|
glog.V(2).Infof("TestPersistentVolumeRecycler started")
|
||||||
_, s := framework.RunAMaster(t)
|
_, s := framework.RunAMaster(t)
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
|
|
||||||
@ -115,58 +116,80 @@ func TestPersistentVolumeRecycler(t *testing.T) {
|
|||||||
defer ctrl.Stop()
|
defer ctrl.Stop()
|
||||||
|
|
||||||
// This PV will be claimed, released, and recycled.
|
// This PV will be claimed, released, and recycled.
|
||||||
pv := createPV("fake-pv", "/tmp/foo", "10G", []api.PersistentVolumeAccessMode{api.ReadWriteOnce}, api.PersistentVolumeReclaimRecycle)
|
pv := createPV("fake-pv-recycler", "/tmp/foo", "10G", []api.PersistentVolumeAccessMode{api.ReadWriteOnce}, api.PersistentVolumeReclaimRecycle)
|
||||||
|
pvc := createPVC("fake-pvc-recycler", "5G", []api.PersistentVolumeAccessMode{api.ReadWriteOnce})
|
||||||
pvc := createPVC("fake-pvc", "5G", []api.PersistentVolumeAccessMode{api.ReadWriteOnce})
|
|
||||||
|
|
||||||
_, err := testClient.PersistentVolumes().Create(pv)
|
_, err := testClient.PersistentVolumes().Create(pv)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Failed to create PersistentVolume: %v", err)
|
t.Errorf("Failed to create PersistentVolume: %v", err)
|
||||||
}
|
}
|
||||||
|
glog.V(2).Infof("TestPersistentVolumeRecycler pvc created")
|
||||||
|
|
||||||
_, err = testClient.PersistentVolumeClaims(api.NamespaceDefault).Create(pvc)
|
_, err = testClient.PersistentVolumeClaims(api.NamespaceDefault).Create(pvc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Failed to create PersistentVolumeClaim: %v", err)
|
t.Errorf("Failed to create PersistentVolumeClaim: %v", err)
|
||||||
}
|
}
|
||||||
|
glog.V(2).Infof("TestPersistentVolumeRecycler pvc created")
|
||||||
|
|
||||||
// wait until the controller pairs the volume and claim
|
// wait until the controller pairs the volume and claim
|
||||||
waitForPersistentVolumePhase(testClient, pv.Name, watchPV, api.VolumeBound)
|
waitForPersistentVolumePhase(testClient, pv.Name, watchPV, api.VolumeBound)
|
||||||
|
glog.V(2).Infof("TestPersistentVolumeRecycler pv bound")
|
||||||
waitForPersistentVolumeClaimPhase(testClient, pvc.Name, watchPVC, api.ClaimBound)
|
waitForPersistentVolumeClaimPhase(testClient, pvc.Name, watchPVC, api.ClaimBound)
|
||||||
|
glog.V(2).Infof("TestPersistentVolumeRecycler pvc bound")
|
||||||
|
|
||||||
// deleting a claim releases the volume, after which it can be recycled
|
// deleting a claim releases the volume, after which it can be recycled
|
||||||
if err := testClient.PersistentVolumeClaims(api.NamespaceDefault).Delete(pvc.Name, nil); err != nil {
|
if err := testClient.PersistentVolumeClaims(api.NamespaceDefault).Delete(pvc.Name, nil); err != nil {
|
||||||
t.Errorf("error deleting claim %s", pvc.Name)
|
t.Errorf("error deleting claim %s", pvc.Name)
|
||||||
}
|
}
|
||||||
|
glog.V(2).Infof("TestPersistentVolumeRecycler pvc deleted")
|
||||||
|
|
||||||
waitForPersistentVolumePhase(testClient, pv.Name, watchPV, api.VolumeReleased)
|
waitForPersistentVolumePhase(testClient, pv.Name, watchPV, api.VolumeReleased)
|
||||||
|
glog.V(2).Infof("TestPersistentVolumeRecycler pv released")
|
||||||
waitForPersistentVolumePhase(testClient, pv.Name, watchPV, api.VolumeAvailable)
|
waitForPersistentVolumePhase(testClient, pv.Name, watchPV, api.VolumeAvailable)
|
||||||
|
glog.V(2).Infof("TestPersistentVolumeRecycler pv available")
|
||||||
|
|
||||||
// end of Recycler test.
|
}
|
||||||
// Deleter test begins now.
|
|
||||||
// tests are serial because running masters concurrently that delete keys may cause similar tests to time out
|
func TestPersistentVolumeDeleter(t *testing.T) {
|
||||||
|
glog.V(2).Infof("TestPersistentVolumeDeleter started")
|
||||||
|
_, s := framework.RunAMaster(t)
|
||||||
|
defer s.Close()
|
||||||
|
|
||||||
deleteAllEtcdKeys()
|
deleteAllEtcdKeys()
|
||||||
|
testClient, ctrl, watchPV, watchPVC := createClients(t, s)
|
||||||
|
defer watchPV.Stop()
|
||||||
|
defer watchPVC.Stop()
|
||||||
|
|
||||||
// change the reclamation policy of the PV for the next test
|
ctrl.Run()
|
||||||
pv.Spec.PersistentVolumeReclaimPolicy = api.PersistentVolumeReclaimDelete
|
defer ctrl.Stop()
|
||||||
|
|
||||||
_, err = testClient.PersistentVolumes().Create(pv)
|
// This PV will be claimed, released, and deleted.
|
||||||
|
pv := createPV("fake-pv-deleter", "/tmp/foo", "10G", []api.PersistentVolumeAccessMode{api.ReadWriteOnce}, api.PersistentVolumeReclaimDelete)
|
||||||
|
pvc := createPVC("fake-pvc-deleter", "5G", []api.PersistentVolumeAccessMode{api.ReadWriteOnce})
|
||||||
|
|
||||||
|
_, err := testClient.PersistentVolumes().Create(pv)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Failed to create PersistentVolume: %v", err)
|
t.Errorf("Failed to create PersistentVolume: %v", err)
|
||||||
}
|
}
|
||||||
|
glog.V(2).Infof("TestPersistentVolumeDeleter pv created")
|
||||||
_, err = testClient.PersistentVolumeClaims(api.NamespaceDefault).Create(pvc)
|
_, err = testClient.PersistentVolumeClaims(api.NamespaceDefault).Create(pvc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Failed to create PersistentVolumeClaim: %v", err)
|
t.Errorf("Failed to create PersistentVolumeClaim: %v", err)
|
||||||
}
|
}
|
||||||
|
glog.V(2).Infof("TestPersistentVolumeDeleter pvc created")
|
||||||
waitForPersistentVolumePhase(testClient, pv.Name, watchPV, api.VolumeBound)
|
waitForPersistentVolumePhase(testClient, pv.Name, watchPV, api.VolumeBound)
|
||||||
|
glog.V(2).Infof("TestPersistentVolumeDeleter pv bound")
|
||||||
waitForPersistentVolumeClaimPhase(testClient, pvc.Name, watchPVC, api.ClaimBound)
|
waitForPersistentVolumeClaimPhase(testClient, pvc.Name, watchPVC, api.ClaimBound)
|
||||||
|
glog.V(2).Infof("TestPersistentVolumeDeleter pvc bound")
|
||||||
|
|
||||||
// deleting a claim releases the volume, after which it can be recycled
|
// deleting a claim releases the volume, after which it can be recycled
|
||||||
if err := testClient.PersistentVolumeClaims(api.NamespaceDefault).Delete(pvc.Name, nil); err != nil {
|
if err := testClient.PersistentVolumeClaims(api.NamespaceDefault).Delete(pvc.Name, nil); err != nil {
|
||||||
t.Errorf("error deleting claim %s", pvc.Name)
|
t.Errorf("error deleting claim %s", pvc.Name)
|
||||||
}
|
}
|
||||||
|
glog.V(2).Infof("TestPersistentVolumeDeleter pvc deleted")
|
||||||
|
|
||||||
waitForPersistentVolumePhase(testClient, pv.Name, watchPV, api.VolumeReleased)
|
waitForPersistentVolumePhase(testClient, pv.Name, watchPV, api.VolumeReleased)
|
||||||
|
glog.V(2).Infof("TestPersistentVolumeDeleter pv released")
|
||||||
|
|
||||||
for {
|
for {
|
||||||
event := <-watchPV.ResultChan()
|
event := <-watchPV.ResultChan()
|
||||||
@ -174,9 +197,27 @@ func TestPersistentVolumeRecycler(t *testing.T) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
glog.V(2).Infof("TestPersistentVolumeDeleter pv deleted")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPersistentVolumeBindRace(t *testing.T) {
|
||||||
|
// Test a race binding many claims to a PV that is pre-bound to a specific
|
||||||
|
// PVC. Only this specific PVC should get bound.
|
||||||
|
glog.V(2).Infof("TestPersistentVolumeBindRace started")
|
||||||
|
_, s := framework.RunAMaster(t)
|
||||||
|
defer s.Close()
|
||||||
|
|
||||||
// test the race between claims and volumes. ensure only a volume only binds to a single claim.
|
|
||||||
deleteAllEtcdKeys()
|
deleteAllEtcdKeys()
|
||||||
|
testClient, ctrl, watchPV, watchPVC := createClients(t, s)
|
||||||
|
defer watchPV.Stop()
|
||||||
|
defer watchPVC.Stop()
|
||||||
|
|
||||||
|
ctrl.Run()
|
||||||
|
defer ctrl.Stop()
|
||||||
|
|
||||||
|
pv := createPV("fake-pv-race", "/tmp/foo", "10G", []api.PersistentVolumeAccessMode{api.ReadWriteOnce}, api.PersistentVolumeReclaimRetain)
|
||||||
|
|
||||||
|
pvc := createPVC("fake-pvc-race", "5G", []api.PersistentVolumeAccessMode{api.ReadWriteOnce})
|
||||||
counter := 0
|
counter := 0
|
||||||
maxClaims := 100
|
maxClaims := 100
|
||||||
claims := []*api.PersistentVolumeClaim{}
|
claims := []*api.PersistentVolumeClaim{}
|
||||||
@ -184,13 +225,14 @@ func TestPersistentVolumeRecycler(t *testing.T) {
|
|||||||
counter += 1
|
counter += 1
|
||||||
clone, _ := conversion.NewCloner().DeepCopy(pvc)
|
clone, _ := conversion.NewCloner().DeepCopy(pvc)
|
||||||
newPvc, _ := clone.(*api.PersistentVolumeClaim)
|
newPvc, _ := clone.(*api.PersistentVolumeClaim)
|
||||||
newPvc.ObjectMeta = api.ObjectMeta{Name: fmt.Sprintf("fake-pvc-%d", counter)}
|
newPvc.ObjectMeta = api.ObjectMeta{Name: fmt.Sprintf("fake-pvc-race-%d", counter)}
|
||||||
claim, err := testClient.PersistentVolumeClaims(api.NamespaceDefault).Create(newPvc)
|
claim, err := testClient.PersistentVolumeClaims(api.NamespaceDefault).Create(newPvc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("Error creating newPvc: %v", err)
|
t.Fatal("Error creating newPvc: %v", err)
|
||||||
}
|
}
|
||||||
claims = append(claims, claim)
|
claims = append(claims, claim)
|
||||||
}
|
}
|
||||||
|
glog.V(2).Infof("TestPersistentVolumeBindRace claims created")
|
||||||
|
|
||||||
// putting a bind manually on a pv should only match the claim it is bound to
|
// putting a bind manually on a pv should only match the claim it is bound to
|
||||||
rand.Seed(time.Now().Unix())
|
rand.Seed(time.Now().Unix())
|
||||||
@ -200,14 +242,18 @@ func TestPersistentVolumeRecycler(t *testing.T) {
|
|||||||
t.Fatalf("Unexpected error getting claimRef: %v", err)
|
t.Fatalf("Unexpected error getting claimRef: %v", err)
|
||||||
}
|
}
|
||||||
pv.Spec.ClaimRef = claimRef
|
pv.Spec.ClaimRef = claimRef
|
||||||
|
pv.Spec.ClaimRef.UID = ""
|
||||||
|
|
||||||
pv, err = testClient.PersistentVolumes().Create(pv)
|
pv, err = testClient.PersistentVolumes().Create(pv)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unexpected error creating pv: %v", err)
|
t.Fatalf("Unexpected error creating pv: %v", err)
|
||||||
}
|
}
|
||||||
|
glog.V(2).Infof("TestPersistentVolumeBindRace pv created, pre-bound to %s", claim.Name)
|
||||||
|
|
||||||
waitForPersistentVolumePhase(testClient, pv.Name, watchPV, api.VolumeBound)
|
waitForPersistentVolumePhase(testClient, pv.Name, watchPV, api.VolumeBound)
|
||||||
|
glog.V(2).Infof("TestPersistentVolumeBindRace pv bound")
|
||||||
waitForAnyPersistentVolumeClaimPhase(watchPVC, api.ClaimBound)
|
waitForAnyPersistentVolumeClaimPhase(watchPVC, api.ClaimBound)
|
||||||
|
glog.V(2).Infof("TestPersistentVolumeBindRace pvc bound")
|
||||||
|
|
||||||
pv, err = testClient.PersistentVolumes().Get(pv.Name)
|
pv, err = testClient.PersistentVolumes().Get(pv.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user