func TestPersistentVolumeRecycler(t *testing.T) { _, s := runAMaster(t) defer s.Close() deleteAllEtcdKeys() binderClient := client.NewOrDie(&client.Config{Host: s.URL, Version: testapi.Default.Version()}) recyclerClient := client.NewOrDie(&client.Config{Host: s.URL, Version: testapi.Default.Version()}) testClient := client.NewOrDie(&client.Config{Host: s.URL, Version: testapi.Default.Version()}) binder := volumeclaimbinder.NewPersistentVolumeClaimBinder(binderClient, 1*time.Second) binder.Run() defer binder.Stop() recycler, _ := volumeclaimbinder.NewPersistentVolumeRecycler(recyclerClient, 1*time.Second, []volume.VolumePlugin{&volume.FakeVolumePlugin{"plugin-name", volume.NewFakeVolumeHost("/tmp/fake", nil, nil)}}) recycler.Run() defer recycler.Stop() // This PV will be claimed, released, and recycled. pv := &api.PersistentVolume{ ObjectMeta: api.ObjectMeta{Name: "fake-pv"}, Spec: api.PersistentVolumeSpec{ PersistentVolumeSource: api.PersistentVolumeSource{HostPath: &api.HostPathVolumeSource{Path: "foo"}}, Capacity: api.ResourceList{api.ResourceName(api.ResourceStorage): resource.MustParse("10G")}, AccessModes: []api.PersistentVolumeAccessMode{api.ReadWriteOnce}, PersistentVolumeReclaimPolicy: api.PersistentVolumeReclaimRecycle, }, } pvc := &api.PersistentVolumeClaim{ ObjectMeta: api.ObjectMeta{Name: "fake-pvc"}, Spec: api.PersistentVolumeClaimSpec{ Resources: api.ResourceRequirements{Requests: api.ResourceList{api.ResourceName(api.ResourceStorage): resource.MustParse("5G")}}, AccessModes: []api.PersistentVolumeAccessMode{api.ReadWriteOnce}, }, } watch, _ := testClient.PersistentVolumes().Watch(labels.Everything(), fields.Everything(), "0") defer watch.Stop() _, _ = testClient.PersistentVolumes().Create(pv) _, _ = testClient.PersistentVolumeClaims(api.NamespaceDefault).Create(pvc) // wait until the binder pairs the volume and claim waitForPersistentVolumePhase(watch, api.VolumeBound) // deleting a claim releases the volume, after which it can be recycled if err := testClient.PersistentVolumeClaims(api.NamespaceDefault).Delete(pvc.Name); err != nil { t.Errorf("error deleting claim %s", pvc.Name) } waitForPersistentVolumePhase(watch, api.VolumeReleased) waitForPersistentVolumePhase(watch, api.VolumeAvailable) }
func TestPersistentVolumeClaimBinder(t *testing.T) { _, s := runAMaster(t) defer s.Close() deleteAllEtcdKeys() binderClient := client.NewOrDie(&client.Config{Host: s.URL, Version: testapi.Default.Version()}) testClient := client.NewOrDie(&client.Config{Host: s.URL, Version: testapi.Default.Version()}) binder := volumeclaimbinder.NewPersistentVolumeClaimBinder(binderClient, 1*time.Second) binder.Run() defer binder.Stop() for _, volume := range createTestVolumes() { _, err := testClient.PersistentVolumes().Create(volume) if err != nil { t.Fatalf("Unexpected error: %v", err) } } volumes, err := testClient.PersistentVolumes().List(labels.Everything(), fields.Everything()) if err != nil { t.Fatalf("unexpected error: %v", err) } if len(volumes.Items) != 2 { t.Errorf("expected 2 PVs, got %#v", len(volumes.Items)) } for _, claim := range createTestClaims() { _, err := testClient.PersistentVolumeClaims(api.NamespaceDefault).Create(claim) if err != nil { t.Fatalf("Unexpected error: %v", err) } } claims, err := testClient.PersistentVolumeClaims(api.NamespaceDefault).List(labels.Everything(), fields.Everything()) if err != nil { t.Fatalf("unexpected error: %v", err) } if len(claims.Items) != 3 { t.Errorf("expected 3 PVCs, got %#v", len(claims.Items)) } // the binder will eventually catch up and set status on Claims watch, err := testClient.PersistentVolumeClaims(api.NamespaceDefault).Watch(labels.Everything(), fields.Everything(), "0") if err != nil { t.Fatalf("Couldn't subscribe to PersistentVolumeClaims: %v", err) } defer watch.Stop() // Wait for claim01 and claim02 to become bound claim01Pending := true claim02Pending := true for claim01Pending || claim02Pending { event := <-watch.ResultChan() claim := event.Object.(*api.PersistentVolumeClaim) if claim.Spec.VolumeName != "" && claim.Status.Phase != "Bound" { if claim.Name == "claim01" { claim01Pending = false } else if claim.Name == "claim02" { claim02Pending = false } } } for _, claim := range createTestClaims() { claim, err := testClient.PersistentVolumeClaims(api.NamespaceDefault).Get(claim.Name) if err != nil { t.Fatalf("Unexpected error: %v", err) } if (claim.Name == "claim01" || claim.Name == "claim02") && claim.Spec.VolumeName == "" { t.Errorf("Expected claim to be bound: %+v", claim) } if claim.Name == "claim03" && claim.Spec.VolumeName != "" { t.Errorf("Expected claim03 to be unbound: %v", claim) } } }