From 13b2387c0c19af995d08eb678aa1b522f9397674 Mon Sep 17 00:00:00 2001 From: Wojciech Tyczynski Date: Tue, 5 Jul 2016 09:58:22 +0200 Subject: [PATCH 1/4] Migrate PersistentVolume integration tests --- test/integration/persistent_volumes_test.go | 197 ++++++++++++-------- 1 file changed, 121 insertions(+), 76 deletions(-) diff --git a/test/integration/persistent_volumes_test.go b/test/integration/persistent_volumes_test.go index 43edc3be36f..1def6df2771 100644 --- a/test/integration/persistent_volumes_test.go +++ b/test/integration/persistent_volumes_test.go @@ -104,23 +104,27 @@ func testSleep() { } func TestPersistentVolumeRecycler(t *testing.T) { - // TODO: Limit the test to a single non-default namespace and clean this up at the end. - framework.DeleteAllEtcdKeys() - glog.V(2).Infof("TestPersistentVolumeRecycler started") _, s := framework.RunAMaster(nil) defer s.Close() - testClient, ctrl, watchPV, watchPVC := createClients(t, s) + ns := framework.CreateTestingNamespace("pv-recycler", s, t) + defer framework.DeleteTestingNamespace(ns, s, t) + + testClient, ctrl, watchPV, watchPVC := createClients(ns, t, s) defer watchPV.Stop() defer watchPVC.Stop() + // NOTE: This test cannot run in parallel, because it is creating and deleting + // non-namespaced objects (PersistenceVolumes). + defer testClient.Core().PersistentVolumes().DeleteCollection(nil, api.ListOptions{}) + ctrl.Run() defer ctrl.Stop() // This PV will be claimed, released, and recycled. 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-recycler", ns.Name, "5G", []api.PersistentVolumeAccessMode{api.ReadWriteOnce}) _, err := testClient.PersistentVolumes().Create(pv) if err != nil { @@ -128,7 +132,7 @@ func TestPersistentVolumeRecycler(t *testing.T) { } glog.V(2).Infof("TestPersistentVolumeRecycler pvc created") - _, err = testClient.PersistentVolumeClaims(api.NamespaceDefault).Create(pvc) + _, err = testClient.PersistentVolumeClaims(ns.Name).Create(pvc) if err != nil { t.Errorf("Failed to create PersistentVolumeClaim: %v", err) } @@ -137,11 +141,11 @@ func TestPersistentVolumeRecycler(t *testing.T) { // wait until the controller pairs the volume and claim 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, ns.Name, watchPVC, api.ClaimBound) glog.V(2).Infof("TestPersistentVolumeRecycler pvc bound") // 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(ns.Name).Delete(pvc.Name, nil); err != nil { t.Errorf("error deleting claim %s", pvc.Name) } glog.V(2).Infof("TestPersistentVolumeRecycler pvc deleted") @@ -150,45 +154,48 @@ func TestPersistentVolumeRecycler(t *testing.T) { glog.V(2).Infof("TestPersistentVolumeRecycler pv released") waitForPersistentVolumePhase(testClient, pv.Name, watchPV, api.VolumeAvailable) glog.V(2).Infof("TestPersistentVolumeRecycler pv available") - } func TestPersistentVolumeDeleter(t *testing.T) { - // TODO: Limit the test to a single non-default namespace and clean this up at the end. - framework.DeleteAllEtcdKeys() - glog.V(2).Infof("TestPersistentVolumeDeleter started") _, s := framework.RunAMaster(nil) defer s.Close() - testClient, ctrl, watchPV, watchPVC := createClients(t, s) + ns := framework.CreateTestingNamespace("pv-deleter", s, t) + defer framework.DeleteTestingNamespace(ns, s, t) + + testClient, ctrl, watchPV, watchPVC := createClients(ns, t, s) defer watchPV.Stop() defer watchPVC.Stop() + // NOTE: This test cannot run in parallel, because it is creating and deleting + // non-namespaced objects (PersistenceVolumes). + defer testClient.Core().PersistentVolumes().DeleteCollection(nil, api.ListOptions{}) + ctrl.Run() defer ctrl.Stop() // 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}) + pvc := createPVC("fake-pvc-deleter", ns.Name, "5G", []api.PersistentVolumeAccessMode{api.ReadWriteOnce}) _, err := testClient.PersistentVolumes().Create(pv) if err != nil { 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(ns.Name).Create(pvc) if err != nil { t.Errorf("Failed to create PersistentVolumeClaim: %v", err) } glog.V(2).Infof("TestPersistentVolumeDeleter pvc created") 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, ns.Name, watchPVC, api.ClaimBound) glog.V(2).Infof("TestPersistentVolumeDeleter pvc bound") // 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(ns.Name).Delete(pvc.Name, nil); err != nil { t.Errorf("error deleting claim %s", pvc.Name) } glog.V(2).Infof("TestPersistentVolumeDeleter pvc deleted") @@ -206,25 +213,28 @@ func TestPersistentVolumeDeleter(t *testing.T) { } func TestPersistentVolumeBindRace(t *testing.T) { - // TODO: Limit the test to a single non-default namespace and clean this up at the end. - framework.DeleteAllEtcdKeys() - // 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(nil) defer s.Close() - testClient, ctrl, watchPV, watchPVC := createClients(t, s) + ns := framework.CreateTestingNamespace("pv-bind-race", s, t) + defer framework.DeleteTestingNamespace(ns, s, t) + + testClient, ctrl, watchPV, watchPVC := createClients(ns, t, s) defer watchPV.Stop() defer watchPVC.Stop() + // NOTE: This test cannot run in parallel, because it is creating and deleting + // non-namespaced objects (PersistenceVolumes). + defer testClient.Core().PersistentVolumes().DeleteCollection(nil, api.ListOptions{}) + 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}) + pvc := createPVC("fake-pvc-race", ns.Name, "5G", []api.PersistentVolumeAccessMode{api.ReadWriteOnce}) counter := 0 maxClaims := 100 claims := []*api.PersistentVolumeClaim{} @@ -233,7 +243,7 @@ func TestPersistentVolumeBindRace(t *testing.T) { clone, _ := conversion.NewCloner().DeepCopy(pvc) newPvc, _ := clone.(*api.PersistentVolumeClaim) newPvc.ObjectMeta = api.ObjectMeta{Name: fmt.Sprintf("fake-pvc-race-%d", counter)} - claim, err := testClient.PersistentVolumeClaims(api.NamespaceDefault).Create(newPvc) + claim, err := testClient.PersistentVolumeClaims(ns.Name).Create(newPvc) if err != nil { t.Fatal("Error creating newPvc: %v", err) } @@ -276,16 +286,20 @@ func TestPersistentVolumeBindRace(t *testing.T) { // TestPersistentVolumeClaimLabelSelector test binding using label selectors func TestPersistentVolumeClaimLabelSelector(t *testing.T) { - // TODO: Limit the test to a single non-default namespace and clean this up at the end. - framework.DeleteAllEtcdKeys() - _, s := framework.RunAMaster(nil) defer s.Close() - testClient, controller, watchPV, watchPVC := createClients(t, s) + ns := framework.CreateTestingNamespace("pvc-label-selector", s, t) + defer framework.DeleteTestingNamespace(ns, s, t) + + testClient, controller, watchPV, watchPVC := createClients(ns, t, s) defer watchPV.Stop() defer watchPVC.Stop() + // NOTE: This test cannot run in parallel, because it is creating and deleting + // non-namespaced objects (PersistenceVolumes). + defer testClient.Core().PersistentVolumes().DeleteCollection(nil, api.ListOptions{}) + controller.Run() defer controller.Stop() @@ -296,7 +310,7 @@ func TestPersistentVolumeClaimLabelSelector(t *testing.T) { pv_true = createPV("pv-true", "/tmp/foo-label", "1G", modes, reclaim) pv_false = createPV("pv-false", "/tmp/foo-label", "1G", modes, reclaim) - pvc = createPVC("pvc-ls-1", "1G", modes) + pvc = createPVC("pvc-ls-1", ns.Name, "1G", modes) ) pv_true.ObjectMeta.SetLabels(map[string]string{"foo": "true"}) @@ -318,7 +332,7 @@ func TestPersistentVolumeClaimLabelSelector(t *testing.T) { }, } - _, err = testClient.PersistentVolumeClaims(api.NamespaceDefault).Create(pvc) + _, err = testClient.PersistentVolumeClaims(ns.Name).Create(pvc) if err != nil { t.Fatalf("Failed to create PersistentVolumeClaim: %v", err) } @@ -326,7 +340,7 @@ func TestPersistentVolumeClaimLabelSelector(t *testing.T) { waitForAnyPersistentVolumePhase(watchPV, api.VolumeBound) t.Log("volume bound") - waitForPersistentVolumeClaimPhase(testClient, pvc.Name, watchPVC, api.ClaimBound) + waitForPersistentVolumeClaimPhase(testClient, pvc.Name, ns.Name, watchPVC, api.ClaimBound) t.Log("claim bound") pv, err := testClient.PersistentVolumes().Get("pv-false") @@ -351,16 +365,20 @@ func TestPersistentVolumeClaimLabelSelector(t *testing.T) { // TestPersistentVolumeClaimLabelSelectorMatchExpressions test binding using // MatchExpressions label selectors func TestPersistentVolumeClaimLabelSelectorMatchExpressions(t *testing.T) { - // TODO: Limit the test to a single non-default namespace and clean this up at the end. - framework.DeleteAllEtcdKeys() - _, s := framework.RunAMaster(nil) defer s.Close() - testClient, controller, watchPV, watchPVC := createClients(t, s) + ns := framework.CreateTestingNamespace("pvc-match-expresssions", s, t) + defer framework.DeleteTestingNamespace(ns, s, t) + + testClient, controller, watchPV, watchPVC := createClients(ns, t, s) defer watchPV.Stop() defer watchPVC.Stop() + // NOTE: This test cannot run in parallel, because it is creating and deleting + // non-namespaced objects (PersistenceVolumes). + defer testClient.Core().PersistentVolumes().DeleteCollection(nil, api.ListOptions{}) + controller.Run() defer controller.Stop() @@ -371,7 +389,7 @@ func TestPersistentVolumeClaimLabelSelectorMatchExpressions(t *testing.T) { pv_true = createPV("pv-true", "/tmp/foo-label", "1G", modes, reclaim) pv_false = createPV("pv-false", "/tmp/foo-label", "1G", modes, reclaim) - pvc = createPVC("pvc-ls-1", "1G", modes) + pvc = createPVC("pvc-ls-1", ns.Name, "1G", modes) ) pv_true.ObjectMeta.SetLabels(map[string]string{"foo": "valA", "bar": ""}) @@ -412,7 +430,7 @@ func TestPersistentVolumeClaimLabelSelectorMatchExpressions(t *testing.T) { }, } - _, err = testClient.PersistentVolumeClaims(api.NamespaceDefault).Create(pvc) + _, err = testClient.PersistentVolumeClaims(ns.Name).Create(pvc) if err != nil { t.Fatalf("Failed to create PersistentVolumeClaim: %v", err) } @@ -420,7 +438,7 @@ func TestPersistentVolumeClaimLabelSelectorMatchExpressions(t *testing.T) { waitForAnyPersistentVolumePhase(watchPV, api.VolumeBound) t.Log("volume bound") - waitForPersistentVolumeClaimPhase(testClient, pvc.Name, watchPVC, api.ClaimBound) + waitForPersistentVolumeClaimPhase(testClient, pvc.Name, ns.Name, watchPVC, api.ClaimBound) t.Log("claim bound") pv, err := testClient.PersistentVolumes().Get("pv-false") @@ -445,16 +463,20 @@ func TestPersistentVolumeClaimLabelSelectorMatchExpressions(t *testing.T) { // TestPersistentVolumeMultiPVs tests binding of one PVC to 100 PVs with // different size. func TestPersistentVolumeMultiPVs(t *testing.T) { - // TODO: Limit the test to a single non-default namespace and clean this up at the end. - framework.DeleteAllEtcdKeys() - _, s := framework.RunAMaster(nil) defer s.Close() - testClient, controller, watchPV, watchPVC := createClients(t, s) + ns := framework.CreateTestingNamespace("multi-pvs", s, t) + defer framework.DeleteTestingNamespace(ns, s, t) + + testClient, controller, watchPV, watchPVC := createClients(ns, t, s) defer watchPV.Stop() defer watchPVC.Stop() + // NOTE: This test cannot run in parallel, because it is creating and deleting + // non-namespaced objects (PersistenceVolumes). + defer testClient.Core().PersistentVolumes().DeleteCollection(nil, api.ListOptions{}) + controller.Run() defer controller.Stop() @@ -466,7 +488,7 @@ func TestPersistentVolumeMultiPVs(t *testing.T) { []api.PersistentVolumeAccessMode{api.ReadWriteOnce}, api.PersistentVolumeReclaimRetain) } - pvc := createPVC("pvc-2", strconv.Itoa(maxPVs/2)+"G", []api.PersistentVolumeAccessMode{api.ReadWriteOnce}) + pvc := createPVC("pvc-2", ns.Name, strconv.Itoa(maxPVs/2)+"G", []api.PersistentVolumeAccessMode{api.ReadWriteOnce}) for i := 0; i < maxPVs; i++ { _, err := testClient.PersistentVolumes().Create(pvs[i]) @@ -477,7 +499,7 @@ func TestPersistentVolumeMultiPVs(t *testing.T) { } t.Log("volumes created") - _, err := testClient.PersistentVolumeClaims(api.NamespaceDefault).Create(pvc) + _, err := testClient.PersistentVolumeClaims(ns.Name).Create(pvc) if err != nil { t.Errorf("Failed to create PersistentVolumeClaim: %v", err) } @@ -486,7 +508,7 @@ func TestPersistentVolumeMultiPVs(t *testing.T) { // wait until the binder pairs the claim with a volume waitForAnyPersistentVolumePhase(watchPV, api.VolumeBound) t.Log("volume bound") - waitForPersistentVolumeClaimPhase(testClient, pvc.Name, watchPVC, api.ClaimBound) + waitForPersistentVolumeClaimPhase(testClient, pvc.Name, ns.Name, watchPVC, api.ClaimBound) t.Log("claim bound") // only one PV is bound @@ -517,7 +539,7 @@ func TestPersistentVolumeMultiPVs(t *testing.T) { } // deleting a claim releases the volume - if err := testClient.PersistentVolumeClaims(api.NamespaceDefault).Delete(pvc.Name, nil); err != nil { + if err := testClient.PersistentVolumeClaims(ns.Name).Delete(pvc.Name, nil); err != nil { t.Errorf("error deleting claim %s", pvc.Name) } t.Log("claim deleted") @@ -529,16 +551,20 @@ func TestPersistentVolumeMultiPVs(t *testing.T) { // TestPersistentVolumeMultiPVsPVCs tests binding of 100 PVC to 100 PVs. // This test is configurable by KUBE_INTEGRATION_PV_* variables. func TestPersistentVolumeMultiPVsPVCs(t *testing.T) { - // TODO: Limit the test to a single non-default namespace and clean this up at the end. - framework.DeleteAllEtcdKeys() - _, s := framework.RunAMaster(nil) defer s.Close() - testClient, binder, watchPV, watchPVC := createClients(t, s) + ns := framework.CreateTestingNamespace("multi-pvs-pvcs", s, t) + defer framework.DeleteTestingNamespace(ns, s, t) + + testClient, binder, watchPV, watchPVC := createClients(ns, t, s) defer watchPV.Stop() defer watchPVC.Stop() + // NOTE: This test cannot run in parallel, because it is creating and deleting + // non-namespaced objects (PersistenceVolumes). + defer testClient.Core().PersistentVolumes().DeleteCollection(nil, api.ListOptions{}) + binder.Run() defer binder.Stop() @@ -549,7 +575,7 @@ func TestPersistentVolumeMultiPVsPVCs(t *testing.T) { // This PV will be claimed, released, and deleted pvs[i] = createPV("pv-"+strconv.Itoa(i), "/tmp/foo"+strconv.Itoa(i), "1G", []api.PersistentVolumeAccessMode{api.ReadWriteOnce}, api.PersistentVolumeReclaimRetain) - pvcs[i] = createPVC("pvc-"+strconv.Itoa(i), "1G", []api.PersistentVolumeAccessMode{api.ReadWriteOnce}) + pvcs[i] = createPVC("pvc-"+strconv.Itoa(i), ns.Name, "1G", []api.PersistentVolumeAccessMode{api.ReadWriteOnce}) } // Create PVs first @@ -573,7 +599,7 @@ func TestPersistentVolumeMultiPVsPVCs(t *testing.T) { // Create the claims, again in a separate goroutine. go func() { for i := 0; i < objCount; i++ { - _, _ = testClient.PersistentVolumeClaims(api.NamespaceDefault).Create(pvcs[i]) + _, _ = testClient.PersistentVolumeClaims(ns.Name).Create(pvcs[i]) } }() @@ -595,7 +621,7 @@ func TestPersistentVolumeMultiPVsPVCs(t *testing.T) { } glog.V(2).Infof("PV %q is bound to PVC %q", pv.Name, pv.Spec.ClaimRef.Name) - pvc, err := testClient.PersistentVolumeClaims(api.NamespaceDefault).Get(pvcs[i].Name) + pvc, err := testClient.PersistentVolumeClaims(ns.Name).Get(pvcs[i].Name) if err != nil { t.Fatalf("Unexpected error getting pvc: %v", err) } @@ -610,22 +636,27 @@ func TestPersistentVolumeMultiPVsPVCs(t *testing.T) { // TestPersistentVolumeProvisionMultiPVCs tests provisioning of many PVCs. // This test is configurable by KUBE_INTEGRATION_PV_* variables. func TestPersistentVolumeProvisionMultiPVCs(t *testing.T) { - // TODO: Limit the test to a single non-default namespace and clean this up at the end. - framework.DeleteAllEtcdKeys() - _, s := framework.RunAMaster(nil) defer s.Close() - testClient, binder, watchPV, watchPVC := createClients(t, s) + ns := framework.CreateTestingNamespace("provision-multi-pvs", s, t) + defer framework.DeleteTestingNamespace(ns, s, t) + + testClient, binder, watchPV, watchPVC := createClients(ns, t, s) defer watchPV.Stop() defer watchPVC.Stop() + + // NOTE: This test cannot run in parallel, because it is creating and deleting + // non-namespaced objects (PersistenceVolumes). + defer testClient.Core().PersistentVolumes().DeleteCollection(nil, api.ListOptions{}) + binder.Run() defer binder.Stop() objCount := getObjectCount() pvcs := make([]*api.PersistentVolumeClaim, objCount) for i := 0; i < objCount; i++ { - pvc := createPVC("pvc-provision-"+strconv.Itoa(i), "1G", []api.PersistentVolumeAccessMode{api.ReadWriteOnce}) + pvc := createPVC("pvc-provision-"+strconv.Itoa(i), ns.Name, "1G", []api.PersistentVolumeAccessMode{api.ReadWriteOnce}) pvc.Annotations = map[string]string{ "volume.alpha.kubernetes.io/storage-class": "", } @@ -637,7 +668,7 @@ func TestPersistentVolumeProvisionMultiPVCs(t *testing.T) { // early. It gets stuck with >3000 claims. go func() { for i := 0; i < objCount; i++ { - _, _ = testClient.PersistentVolumeClaims(api.NamespaceDefault).Create(pvcs[i]) + _, _ = testClient.PersistentVolumeClaims(ns.Name).Create(pvcs[i]) } }() @@ -666,7 +697,7 @@ func TestPersistentVolumeProvisionMultiPVCs(t *testing.T) { // Delete the claims for i := 0; i < objCount; i++ { - _ = testClient.PersistentVolumeClaims(api.NamespaceDefault).Delete(pvcs[i].Name, nil) + _ = testClient.PersistentVolumeClaims(ns.Name).Delete(pvcs[i].Name, nil) } // Wait for the PVs to get deleted by listing remaining volumes @@ -689,16 +720,20 @@ func TestPersistentVolumeProvisionMultiPVCs(t *testing.T) { // TestPersistentVolumeMultiPVsDiffAccessModes tests binding of one PVC to two // PVs with different access modes. func TestPersistentVolumeMultiPVsDiffAccessModes(t *testing.T) { - // TODO: Limit the test to a single non-default namespace and clean this up at the end. - framework.DeleteAllEtcdKeys() - _, s := framework.RunAMaster(nil) defer s.Close() - testClient, controller, watchPV, watchPVC := createClients(t, s) + ns := framework.CreateTestingNamespace("multi-pvs-diff-access", s, t) + defer framework.DeleteTestingNamespace(ns, s, t) + + testClient, controller, watchPV, watchPVC := createClients(ns, t, s) defer watchPV.Stop() defer watchPVC.Stop() + // NOTE: This test cannot run in parallel, because it is creating and deleting + // non-namespaced objects (PersistenceVolumes). + defer testClient.Core().PersistentVolumes().DeleteCollection(nil, api.ListOptions{}) + controller.Run() defer controller.Stop() @@ -708,7 +743,7 @@ func TestPersistentVolumeMultiPVsDiffAccessModes(t *testing.T) { pv_rwm := createPV("pv-rwm", "/tmp/bar", "10G", []api.PersistentVolumeAccessMode{api.ReadWriteMany}, api.PersistentVolumeReclaimRetain) - pvc := createPVC("pvc-rwm", "5G", []api.PersistentVolumeAccessMode{api.ReadWriteMany}) + pvc := createPVC("pvc-rwm", ns.Name, "5G", []api.PersistentVolumeAccessMode{api.ReadWriteMany}) _, err := testClient.PersistentVolumes().Create(pv_rwm) if err != nil { @@ -720,7 +755,7 @@ func TestPersistentVolumeMultiPVsDiffAccessModes(t *testing.T) { } t.Log("volumes created") - _, err = testClient.PersistentVolumeClaims(api.NamespaceDefault).Create(pvc) + _, err = testClient.PersistentVolumeClaims(ns.Name).Create(pvc) if err != nil { t.Errorf("Failed to create PersistentVolumeClaim: %v", err) } @@ -729,7 +764,7 @@ func TestPersistentVolumeMultiPVsDiffAccessModes(t *testing.T) { // wait until the controller pairs the volume and claim waitForAnyPersistentVolumePhase(watchPV, api.VolumeBound) t.Log("volume bound") - waitForPersistentVolumeClaimPhase(testClient, pvc.Name, watchPVC, api.ClaimBound) + waitForPersistentVolumeClaimPhase(testClient, pvc.Name, ns.Name, watchPVC, api.ClaimBound) t.Log("claim bound") // only RWM PV is bound @@ -752,7 +787,7 @@ func TestPersistentVolumeMultiPVsDiffAccessModes(t *testing.T) { } // deleting a claim releases the volume - if err := testClient.PersistentVolumeClaims(api.NamespaceDefault).Delete(pvc.Name, nil); err != nil { + if err := testClient.PersistentVolumeClaims(ns.Name).Delete(pvc.Name, nil); err != nil { t.Errorf("error deleting claim %s", pvc.Name) } t.Log("claim deleted") @@ -782,9 +817,9 @@ func waitForPersistentVolumePhase(client *clientset.Clientset, pvName string, w } } -func waitForPersistentVolumeClaimPhase(client *clientset.Clientset, claimName string, w watch.Interface, phase api.PersistentVolumeClaimPhase) { +func waitForPersistentVolumeClaimPhase(client *clientset.Clientset, claimName, namespace string, w watch.Interface, phase api.PersistentVolumeClaimPhase) { // Check if the claim is already in requested phase - claim, err := client.Core().PersistentVolumeClaims(api.NamespaceDefault).Get(claimName) + claim, err := client.Core().PersistentVolumeClaims(namespace).Get(claimName) if err == nil && claim.Status.Phase == phase { return } @@ -831,11 +866,21 @@ func waitForAnyPersistentVolumeClaimPhase(w watch.Interface, phase api.Persisten } } -func createClients(t *testing.T, s *httptest.Server) (*clientset.Clientset, *persistentvolumecontroller.PersistentVolumeController, watch.Interface, watch.Interface) { +func createClients(ns *api.Namespace, t *testing.T, s *httptest.Server) (*clientset.Clientset, *persistentvolumecontroller.PersistentVolumeController, watch.Interface, watch.Interface) { // Use higher QPS and Burst, there is a test for race conditions which // creates many objects and default values were too low. - binderClient := clientset.NewForConfigOrDie(&restclient.Config{Host: s.URL, ContentConfig: restclient.ContentConfig{GroupVersion: testapi.Default.GroupVersion()}, QPS: 1000000, Burst: 1000000}) - testClient := clientset.NewForConfigOrDie(&restclient.Config{Host: s.URL, ContentConfig: restclient.ContentConfig{GroupVersion: testapi.Default.GroupVersion()}, QPS: 1000000, Burst: 1000000}) + binderClient := clientset.NewForConfigOrDie(&restclient.Config{ + Host: s.URL, + ContentConfig: restclient.ContentConfig{GroupVersion: testapi.Default.GroupVersion()}, + QPS: 1000000, + Burst: 1000000, + }) + testClient := clientset.NewForConfigOrDie(&restclient.Config{ + Host: s.URL, + ContentConfig: restclient.ContentConfig{GroupVersion: testapi.Default.GroupVersion()}, + QPS: 1000000, + Burst: 1000000, + }) host := volumetest.NewFakeVolumeHost("/tmp/fake", nil, nil, "" /* rootContext */) plugin := &volumetest.FakeVolumePlugin{ @@ -860,7 +905,7 @@ func createClients(t *testing.T, s *httptest.Server) (*clientset.Clientset, *per if err != nil { t.Fatalf("Failed to watch PersistentVolumes: %v", err) } - watchPVC, err := testClient.PersistentVolumeClaims(api.NamespaceDefault).Watch(api.ListOptions{}) + watchPVC, err := testClient.PersistentVolumeClaims(ns.Name).Watch(api.ListOptions{}) if err != nil { t.Fatalf("Failed to watch PersistentVolumeClaimss: %v", err) } @@ -880,11 +925,11 @@ func createPV(name, path, cap string, mode []api.PersistentVolumeAccessMode, rec } } -func createPVC(name, cap string, mode []api.PersistentVolumeAccessMode) *api.PersistentVolumeClaim { +func createPVC(name, namespace, cap string, mode []api.PersistentVolumeAccessMode) *api.PersistentVolumeClaim { return &api.PersistentVolumeClaim{ ObjectMeta: api.ObjectMeta{ Name: name, - Namespace: api.NamespaceDefault, + Namespace: namespace, }, Spec: api.PersistentVolumeClaimSpec{ Resources: api.ResourceRequirements{Requests: api.ResourceList{api.ResourceName(api.ResourceStorage): resource.MustParse(cap)}}, From 3c9b68698ded2d766612fad60b647df3ae4375f1 Mon Sep 17 00:00:00 2001 From: Wojciech Tyczynski Date: Tue, 5 Jul 2016 10:22:13 +0200 Subject: [PATCH 2/4] Migrate scheduler integration tests --- pkg/client/unversioned/nodes.go | 11 ++++ .../unversioned/testclient/fake_nodes.go | 5 ++ test/integration/extender_test.go | 20 +++--- test/integration/scheduler_test.go | 65 +++++++++++-------- 4 files changed, 67 insertions(+), 34 deletions(-) diff --git a/pkg/client/unversioned/nodes.go b/pkg/client/unversioned/nodes.go index 6a05a2a2167..15a7db2ad18 100644 --- a/pkg/client/unversioned/nodes.go +++ b/pkg/client/unversioned/nodes.go @@ -30,6 +30,7 @@ type NodeInterface interface { Create(node *api.Node) (*api.Node, error) List(opts api.ListOptions) (*api.NodeList, error) Delete(name string) error + DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error Update(*api.Node) (*api.Node, error) UpdateStatus(*api.Node) (*api.Node, error) Watch(opts api.ListOptions) (watch.Interface, error) @@ -76,6 +77,16 @@ func (c *nodes) Delete(name string) error { return c.r.Delete().Resource(c.resourceName()).Name(name).Do().Error() } +// DeleteCollection deletes a collection of nodes. +func (c *nodes) DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error { + return c.r.Delete(). + Resource(c.resourceName()). + VersionedParams(&listOptions, api.ParameterCodec). + Body(options). + Do(). + Error() +} + // Update updates an existing node. func (c *nodes) Update(node *api.Node) (*api.Node, error) { result := &api.Node{} diff --git a/pkg/client/unversioned/testclient/fake_nodes.go b/pkg/client/unversioned/testclient/fake_nodes.go index 859a1c64732..d03882fb979 100644 --- a/pkg/client/unversioned/testclient/fake_nodes.go +++ b/pkg/client/unversioned/testclient/fake_nodes.go @@ -68,6 +68,11 @@ func (c *FakeNodes) Delete(name string) error { return err } +func (c *FakeNodes) DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error { + _, err := c.Fake.Invokes(NewRootDeleteCollectionAction("nodes", listOptions), &api.NodeList{}) + return err +} + func (c *FakeNodes) Watch(opts api.ListOptions) (watch.Interface, error) { return c.Fake.InvokesWatch(NewRootWatchAction("nodes", opts)) } diff --git a/test/integration/extender_test.go b/test/integration/extender_test.go index b2acaeb30b4..07e4745fac9 100644 --- a/test/integration/extender_test.go +++ b/test/integration/extender_test.go @@ -185,12 +185,12 @@ func machine_3_Prioritizer(pod *api.Pod, nodes *api.NodeList) (*schedulerapi.Hos } func TestSchedulerExtender(t *testing.T) { - // TODO: Limit the test to a single non-default namespace and clean this up at the end. - framework.DeleteAllEtcdKeys() - _, s := framework.RunAMaster(nil) defer s.Close() + ns := framework.CreateTestingNamespace("scheduler-extender", s, t) + defer framework.DeleteTestingNamespace(ns, s, t) + restClient := client.NewOrDie(&restclient.Config{Host: s.URL, ContentConfig: restclient.ContentConfig{GroupVersion: testapi.Default.GroupVersion()}}) extender1 := &Extender{ @@ -240,15 +240,19 @@ func TestSchedulerExtender(t *testing.T) { } eventBroadcaster := record.NewBroadcaster() schedulerConfig.Recorder = eventBroadcaster.NewRecorder(api.EventSource{Component: api.DefaultSchedulerName}) - eventBroadcaster.StartRecordingToSink(restClient.Events("")) + eventBroadcaster.StartRecordingToSink(restClient.Events(ns.Name)) scheduler.New(schedulerConfig).Run() defer close(schedulerConfig.StopEverything) - DoTestPodScheduling(t, restClient) + DoTestPodScheduling(ns, t, restClient) } -func DoTestPodScheduling(t *testing.T, restClient *client.Client) { +func DoTestPodScheduling(ns *api.Namespace, t *testing.T, restClient *client.Client) { + // NOTE: This test cannot run in parallel, because it is creating and deleting + // non-namespaced objects (Nodes). + defer restClient.Nodes().DeleteCollection(nil, api.ListOptions{}) + goodCondition := api.NodeCondition{ Type: api.NodeReady, Status: api.ConditionTrue, @@ -279,7 +283,7 @@ func DoTestPodScheduling(t *testing.T, restClient *client.Client) { }, } - myPod, err := restClient.Pods(api.NamespaceDefault).Create(pod) + myPod, err := restClient.Pods(ns.Name).Create(pod) if err != nil { t.Fatalf("Failed to create pod: %v", err) } @@ -289,7 +293,7 @@ func DoTestPodScheduling(t *testing.T, restClient *client.Client) { t.Fatalf("Failed to schedule pod: %v", err) } - if myPod, err := restClient.Pods(api.NamespaceDefault).Get(myPod.Name); err != nil { + if myPod, err := restClient.Pods(ns.Name).Get(myPod.Name); err != nil { t.Fatalf("Failed to get pod: %v", err) } else if myPod.Spec.NodeName != "machine3" { t.Fatalf("Failed to schedule using extender, expected machine3, got %v", myPod.Spec.NodeName) diff --git a/test/integration/scheduler_test.go b/test/integration/scheduler_test.go index 08239e82c4e..e81ae03d8cb 100644 --- a/test/integration/scheduler_test.go +++ b/test/integration/scheduler_test.go @@ -50,12 +50,12 @@ type nodeStateManager struct { } func TestUnschedulableNodes(t *testing.T) { - // TODO: Limit the test to a single non-default namespace and clean this up at the end. - framework.DeleteAllEtcdKeys() - _, s := framework.RunAMaster(nil) defer s.Close() + ns := framework.CreateTestingNamespace("unschedulable-nodes", s, t) + defer framework.DeleteTestingNamespace(ns, s, t) + restClient := client.NewOrDie(&restclient.Config{Host: s.URL, ContentConfig: restclient.ContentConfig{GroupVersion: testapi.Default.GroupVersion()}}) schedulerConfigFactory := factory.NewConfigFactory(restClient, api.DefaultSchedulerName, api.DefaultHardPodAffinitySymmetricWeight, api.DefaultFailureDomains) @@ -65,12 +65,12 @@ func TestUnschedulableNodes(t *testing.T) { } eventBroadcaster := record.NewBroadcaster() schedulerConfig.Recorder = eventBroadcaster.NewRecorder(api.EventSource{Component: api.DefaultSchedulerName}) - eventBroadcaster.StartRecordingToSink(restClient.Events("")) + eventBroadcaster.StartRecordingToSink(restClient.Events(ns.Name)) scheduler.New(schedulerConfig).Run() defer close(schedulerConfig.StopEverything) - DoTestUnschedulableNodes(t, restClient, schedulerConfigFactory.NodeLister.Store) + DoTestUnschedulableNodes(t, restClient, ns, schedulerConfigFactory.NodeLister.Store) } func podScheduled(c *client.Client, podNamespace, podName string) wait.ConditionFunc { @@ -119,7 +119,11 @@ func waitForReflection(t *testing.T, s cache.Store, key string, passFunc func(n return err } -func DoTestUnschedulableNodes(t *testing.T, restClient *client.Client, nodeStore cache.Store) { +func DoTestUnschedulableNodes(t *testing.T, restClient *client.Client, ns *api.Namespace, nodeStore cache.Store) { + // NOTE: This test cannot run in parallel, because it is creating and deleting + // non-namespaced objects (Nodes). + defer restClient.Nodes().DeleteCollection(nil, api.ListOptions{}) + goodCondition := api.NodeCondition{ Type: api.NodeReady, Status: api.ConditionTrue, @@ -246,7 +250,7 @@ func DoTestUnschedulableNodes(t *testing.T, restClient *client.Client, nodeStore Containers: []api.Container{{Name: "container", Image: e2e.GetPauseImageName(restClient)}}, }, } - myPod, err := restClient.Pods(api.NamespaceDefault).Create(pod) + myPod, err := restClient.Pods(ns.Name).Create(pod) if err != nil { t.Fatalf("Failed to create pod: %v", err) } @@ -277,7 +281,7 @@ func DoTestUnschedulableNodes(t *testing.T, restClient *client.Client, nodeStore t.Logf("Test %d: Pod got scheduled on a schedulable node", i) } - err = restClient.Pods(api.NamespaceDefault).Delete(myPod.Name, api.NewDeleteOptions(0)) + err = restClient.Pods(ns.Name).Delete(myPod.Name, api.NewDeleteOptions(0)) if err != nil { t.Errorf("Failed to delete pod: %v", err) } @@ -289,14 +293,14 @@ func DoTestUnschedulableNodes(t *testing.T, restClient *client.Client, nodeStore } func TestMultiScheduler(t *testing.T) { - // TODO: Limit the test to a single non-default namespace and clean this up at the end. - framework.DeleteAllEtcdKeys() - _, s := framework.RunAMaster(nil) // TODO: Uncomment when fix #19254 // This seems to be a different issue - it still doesn't work. // defer s.Close() + ns := framework.CreateTestingNamespace("multi-scheduler", s, t) + defer framework.DeleteTestingNamespace(ns, s, t) + /* This integration tests the multi-scheduler feature in the following way: 1. create a default scheduler @@ -319,6 +323,10 @@ func TestMultiScheduler(t *testing.T) { // 1. create and start default-scheduler restClient := client.NewOrDie(&restclient.Config{Host: s.URL, ContentConfig: restclient.ContentConfig{GroupVersion: testapi.Default.GroupVersion()}}) + // NOTE: This test cannot run in parallel, because it is creating and deleting + // non-namespaced objects (Nodes). + defer restClient.Nodes().DeleteCollection(nil, api.ListOptions{}) + schedulerConfigFactory := factory.NewConfigFactory(restClient, api.DefaultSchedulerName, api.DefaultHardPodAffinitySymmetricWeight, api.DefaultFailureDomains) schedulerConfig, err := schedulerConfigFactory.Create() if err != nil { @@ -326,7 +334,7 @@ func TestMultiScheduler(t *testing.T) { } eventBroadcaster := record.NewBroadcaster() schedulerConfig.Recorder = eventBroadcaster.NewRecorder(api.EventSource{Component: api.DefaultSchedulerName}) - eventBroadcaster.StartRecordingToSink(restClient.Events("")) + eventBroadcaster.StartRecordingToSink(restClient.Events(ns.Name)) scheduler.New(schedulerConfig).Run() // default-scheduler will be stopped later @@ -344,21 +352,21 @@ func TestMultiScheduler(t *testing.T) { // 3. create 3 pods for testing podWithNoAnnotation := createPod(restClient, "pod-with-no-annotation", nil) - testPodNoAnnotation, err := restClient.Pods(api.NamespaceDefault).Create(podWithNoAnnotation) + testPodNoAnnotation, err := restClient.Pods(ns.Name).Create(podWithNoAnnotation) if err != nil { t.Fatalf("Failed to create pod: %v", err) } schedulerAnnotationFitsDefault := map[string]string{"scheduler.alpha.kubernetes.io/name": "default-scheduler"} podWithAnnotationFitsDefault := createPod(restClient, "pod-with-annotation-fits-default", schedulerAnnotationFitsDefault) - testPodWithAnnotationFitsDefault, err := restClient.Pods(api.NamespaceDefault).Create(podWithAnnotationFitsDefault) + testPodWithAnnotationFitsDefault, err := restClient.Pods(ns.Name).Create(podWithAnnotationFitsDefault) if err != nil { t.Fatalf("Failed to create pod: %v", err) } schedulerAnnotationFitsFoo := map[string]string{"scheduler.alpha.kubernetes.io/name": "foo-scheduler"} podWithAnnotationFitsFoo := createPod(restClient, "pod-with-annotation-fits-foo", schedulerAnnotationFitsFoo) - testPodWithAnnotationFitsFoo, err := restClient.Pods(api.NamespaceDefault).Create(podWithAnnotationFitsFoo) + testPodWithAnnotationFitsFoo, err := restClient.Pods(ns.Name).Create(podWithAnnotationFitsFoo) if err != nil { t.Fatalf("Failed to create pod: %v", err) } @@ -397,7 +405,7 @@ func TestMultiScheduler(t *testing.T) { } eventBroadcaster2 := record.NewBroadcaster() schedulerConfig2.Recorder = eventBroadcaster2.NewRecorder(api.EventSource{Component: "foo-scheduler"}) - eventBroadcaster2.StartRecordingToSink(restClient2.Events("")) + eventBroadcaster2.StartRecordingToSink(restClient2.Events(ns.Name)) scheduler.New(schedulerConfig2).Run() defer close(schedulerConfig2.StopEverything) @@ -412,11 +420,11 @@ func TestMultiScheduler(t *testing.T) { } // 7. delete the pods that were scheduled by the default scheduler, and stop the default scheduler - err = restClient.Pods(api.NamespaceDefault).Delete(testPodNoAnnotation.Name, api.NewDeleteOptions(0)) + err = restClient.Pods(ns.Name).Delete(testPodNoAnnotation.Name, api.NewDeleteOptions(0)) if err != nil { t.Errorf("Failed to delete pod: %v", err) } - err = restClient.Pods(api.NamespaceDefault).Delete(testPodWithAnnotationFitsDefault.Name, api.NewDeleteOptions(0)) + err = restClient.Pods(ns.Name).Delete(testPodWithAnnotationFitsDefault.Name, api.NewDeleteOptions(0)) if err != nil { t.Errorf("Failed to delete pod: %v", err) } @@ -434,11 +442,11 @@ func TestMultiScheduler(t *testing.T) { // - note: these two pods belong to default scheduler which no longer exists podWithNoAnnotation2 := createPod("pod-with-no-annotation2", nil) podWithAnnotationFitsDefault2 := createPod("pod-with-annotation-fits-default2", schedulerAnnotationFitsDefault) - testPodNoAnnotation2, err := restClient.Pods(api.NamespaceDefault).Create(podWithNoAnnotation2) + testPodNoAnnotation2, err := restClient.Pods(ns.Name).Create(podWithNoAnnotation2) if err != nil { t.Fatalf("Failed to create pod: %v", err) } - testPodWithAnnotationFitsDefault2, err := restClient.Pods(api.NamespaceDefault).Create(podWithAnnotationFitsDefault2) + testPodWithAnnotationFitsDefault2, err := restClient.Pods(ns.Name).Create(podWithAnnotationFitsDefault2) if err != nil { t.Fatalf("Failed to create pod: %v", err) } @@ -471,14 +479,19 @@ func createPod(client *client.Client, name string, annotation map[string]string) // This test will verify scheduler can work well regardless of whether kubelet is allocatable aware or not. func TestAllocatable(t *testing.T) { - framework.DeleteAllEtcdKeys() - _, s := framework.RunAMaster(nil) defer s.Close() + ns := framework.CreateTestingNamespace("allocatable", s, t) + defer framework.DeleteTestingNamespace(ns, s, t) + // 1. create and start default-scheduler restClient := client.NewOrDie(&restclient.Config{Host: s.URL, ContentConfig: restclient.ContentConfig{GroupVersion: testapi.Default.GroupVersion()}}) + // NOTE: This test cannot run in parallel, because it is creating and deleting + // non-namespaced objects (Nodes). + defer restClient.Nodes().DeleteCollection(nil, api.ListOptions{}) + schedulerConfigFactory := factory.NewConfigFactory(restClient, api.DefaultSchedulerName, api.DefaultHardPodAffinitySymmetricWeight, api.DefaultFailureDomains) schedulerConfig, err := schedulerConfigFactory.Create() if err != nil { @@ -486,7 +499,7 @@ func TestAllocatable(t *testing.T) { } eventBroadcaster := record.NewBroadcaster() schedulerConfig.Recorder = eventBroadcaster.NewRecorder(api.EventSource{Component: api.DefaultSchedulerName}) - eventBroadcaster.StartRecordingToSink(restClient.Events("")) + eventBroadcaster.StartRecordingToSink(restClient.Events(ns.Name)) scheduler.New(schedulerConfig).Run() // default-scheduler will be stopped later defer close(schedulerConfig.StopEverything) @@ -528,7 +541,7 @@ func TestAllocatable(t *testing.T) { }, } - testAllocPod, err := restClient.Pods(api.NamespaceDefault).Create(podResource) + testAllocPod, err := restClient.Pods(ns.Name).Create(podResource) if err != nil { t.Fatalf("Test allocatable unawareness failed to create pod: %v", err) } @@ -559,13 +572,13 @@ func TestAllocatable(t *testing.T) { t.Fatalf("Failed to update node with Status.Allocatable: %v", err) } - if err := restClient.Pods(api.NamespaceDefault).Delete(podResource.Name, &api.DeleteOptions{}); err != nil { + if err := restClient.Pods(ns.Name).Delete(podResource.Name, &api.DeleteOptions{}); err != nil { t.Fatalf("Failed to remove first resource pod: %v", err) } // 6. Make another pod with different name, same resource request podResource.ObjectMeta.Name = "pod-test-allocatable2" - testAllocPod2, err := restClient.Pods(api.NamespaceDefault).Create(podResource) + testAllocPod2, err := restClient.Pods(ns.Name).Create(podResource) if err != nil { t.Fatalf("Test allocatable awareness failed to create pod: %v", err) } From c2126f6820fb498ead863c3f44a678feb485c8b3 Mon Sep 17 00:00:00 2001 From: Wojciech Tyczynski Date: Tue, 5 Jul 2016 10:58:22 +0200 Subject: [PATCH 3/4] Migrate garbage collection integration tests --- test/integration/garbage_collector_test.go | 110 +++++++++++---------- 1 file changed, 58 insertions(+), 52 deletions(-) diff --git a/test/integration/garbage_collector_test.go b/test/integration/garbage_collector_test.go index 5f6a090a59b..49b0acd87bf 100644 --- a/test/integration/garbage_collector_test.go +++ b/test/integration/garbage_collector_test.go @@ -20,7 +20,6 @@ package integration import ( "fmt" - "net/http" "net/http/httptest" "strconv" "strings" @@ -36,7 +35,6 @@ import ( "k8s.io/kubernetes/pkg/client/restclient" "k8s.io/kubernetes/pkg/client/typed/dynamic" "k8s.io/kubernetes/pkg/controller/garbagecollector" - "k8s.io/kubernetes/pkg/master" "k8s.io/kubernetes/pkg/registry/generic/registry" "k8s.io/kubernetes/pkg/types" "k8s.io/kubernetes/pkg/util/wait" @@ -59,7 +57,7 @@ const oneValidOwnerPodName = "test.pod.3" const toBeDeletedRCName = "test.rc.1" const remainingRCName = "test.rc.2" -func newPod(podName string, ownerReferences []v1.OwnerReference) *v1.Pod { +func newPod(podName, podNamespace string, ownerReferences []v1.OwnerReference) *v1.Pod { for i := 0; i < len(ownerReferences); i++ { if len(ownerReferences[i].Kind) == 0 { ownerReferences[i].Kind = "ReplicationController" @@ -73,7 +71,7 @@ func newPod(podName string, ownerReferences []v1.OwnerReference) *v1.Pod { }, ObjectMeta: v1.ObjectMeta{ Name: podName, - Namespace: framework.TestNS, + Namespace: podNamespace, OwnerReferences: ownerReferences, }, Spec: v1.PodSpec{ @@ -87,14 +85,14 @@ func newPod(podName string, ownerReferences []v1.OwnerReference) *v1.Pod { } } -func newOwnerRC(name string) *v1.ReplicationController { +func newOwnerRC(name, namespace string) *v1.ReplicationController { return &v1.ReplicationController{ TypeMeta: unversioned.TypeMeta{ Kind: "ReplicationController", APIVersion: "v1", }, ObjectMeta: v1.ObjectMeta{ - Namespace: framework.TestNS, + Namespace: namespace, Name: name, }, Spec: v1.ReplicationControllerSpec{ @@ -116,22 +114,10 @@ func newOwnerRC(name string) *v1.ReplicationController { } } -func setup(t *testing.T) (*garbagecollector.GarbageCollector, clientset.Interface) { - // TODO: Limit the test to a single non-default namespace and clean this up at the end. - framework.DeleteAllEtcdKeys() - - var m *master.Master - s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { - m.Handler.ServeHTTP(w, req) - })) - // TODO: close the http server - +func setup(t *testing.T) (*httptest.Server, *garbagecollector.GarbageCollector, clientset.Interface) { masterConfig := framework.NewIntegrationTestMasterConfig() masterConfig.EnableCoreControllers = false - m, err := master.New(masterConfig) - if err != nil { - t.Fatalf("Error in bringing up the master: %v", err) - } + _, s := framework.RunAMaster(masterConfig) clientSet, err := clientset.NewForConfig(&restclient.Config{Host: s.URL}) if err != nil { @@ -146,23 +132,28 @@ func setup(t *testing.T) (*garbagecollector.GarbageCollector, clientset.Interfac if err != nil { t.Fatalf("Failed to create garbage collector") } - return gc, clientSet + return s, gc, clientSet } // This test simulates the cascading deletion. func TestCascadingDeletion(t *testing.T) { - gc, clientSet := setup(t) + s, gc, clientSet := setup(t) + defer s.Close() + + ns := framework.CreateTestingNamespace("gc-cascading-deletion", s, t) + defer framework.DeleteTestingNamespace(ns, s, t) + oldEnableGarbageCollector := registry.EnableGarbageCollector registry.EnableGarbageCollector = true defer func() { registry.EnableGarbageCollector = oldEnableGarbageCollector }() - rcClient := clientSet.Core().ReplicationControllers(framework.TestNS) - podClient := clientSet.Core().Pods(framework.TestNS) + rcClient := clientSet.Core().ReplicationControllers(ns.Name) + podClient := clientSet.Core().Pods(ns.Name) - toBeDeletedRC, err := rcClient.Create(newOwnerRC(toBeDeletedRCName)) + toBeDeletedRC, err := rcClient.Create(newOwnerRC(toBeDeletedRCName, ns.Name)) if err != nil { t.Fatalf("Failed to create replication controller: %v", err) } - remainingRC, err := rcClient.Create(newOwnerRC(remainingRCName)) + remainingRC, err := rcClient.Create(newOwnerRC(remainingRCName, ns.Name)) if err != nil { t.Fatalf("Failed to create replication controller: %v", err) } @@ -176,14 +167,14 @@ func TestCascadingDeletion(t *testing.T) { } // this pod should be cascadingly deleted. - pod := newPod(garbageCollectedPodName, []v1.OwnerReference{{UID: toBeDeletedRC.ObjectMeta.UID, Name: toBeDeletedRCName}}) + pod := newPod(garbageCollectedPodName, ns.Name, []v1.OwnerReference{{UID: toBeDeletedRC.ObjectMeta.UID, Name: toBeDeletedRCName}}) _, err = podClient.Create(pod) if err != nil { t.Fatalf("Failed to create Pod: %v", err) } // this pod shouldn't be cascadingly deleted, because it has a valid reference. - pod = newPod(oneValidOwnerPodName, []v1.OwnerReference{ + pod = newPod(oneValidOwnerPodName, ns.Name, []v1.OwnerReference{ {UID: toBeDeletedRC.ObjectMeta.UID, Name: toBeDeletedRCName}, {UID: remainingRC.ObjectMeta.UID, Name: remainingRCName}, }) @@ -193,7 +184,7 @@ func TestCascadingDeletion(t *testing.T) { } // this pod shouldn't be cascadingly deleted, because it doesn't have an owner. - pod = newPod(independentPodName, []v1.OwnerReference{}) + pod = newPod(independentPodName, ns.Name, []v1.OwnerReference{}) _, err = podClient.Create(pod) if err != nil { t.Fatalf("Failed to create Pod: %v", err) @@ -253,13 +244,18 @@ func TestCascadingDeletion(t *testing.T) { // This test simulates the case where an object is created with an owner that // doesn't exist. It verifies the GC will delete such an object. func TestCreateWithNonExistentOwner(t *testing.T) { - gc, clientSet := setup(t) + s, gc, clientSet := setup(t) + defer s.Close() + + ns := framework.CreateTestingNamespace("gc-non-existing-owner", s, t) + defer framework.DeleteTestingNamespace(ns, s, t) + oldEnableGarbageCollector := registry.EnableGarbageCollector registry.EnableGarbageCollector = true defer func() { registry.EnableGarbageCollector = oldEnableGarbageCollector }() - podClient := clientSet.Core().Pods(framework.TestNS) + podClient := clientSet.Core().Pods(ns.Name) - pod := newPod(garbageCollectedPodName, []v1.OwnerReference{{UID: "doesn't matter", Name: toBeDeletedRCName}}) + pod := newPod(garbageCollectedPodName, ns.Name, []v1.OwnerReference{{UID: "doesn't matter", Name: toBeDeletedRCName}}) _, err := podClient.Create(pod) if err != nil { t.Fatalf("Failed to create Pod: %v", err) @@ -288,13 +284,13 @@ func TestCreateWithNonExistentOwner(t *testing.T) { } } -func setupRCsPods(t *testing.T, gc *garbagecollector.GarbageCollector, clientSet clientset.Interface, nameSuffix string, initialFinalizers []string, options *api.DeleteOptions, wg *sync.WaitGroup, rcUIDs chan types.UID) { +func setupRCsPods(t *testing.T, gc *garbagecollector.GarbageCollector, clientSet clientset.Interface, nameSuffix, namespace string, initialFinalizers []string, options *api.DeleteOptions, wg *sync.WaitGroup, rcUIDs chan types.UID) { defer wg.Done() - rcClient := clientSet.Core().ReplicationControllers(framework.TestNS) - podClient := clientSet.Core().Pods(framework.TestNS) + rcClient := clientSet.Core().ReplicationControllers(namespace) + podClient := clientSet.Core().Pods(namespace) // create rc. rcName := "test.rc." + nameSuffix - rc := newOwnerRC(rcName) + rc := newOwnerRC(rcName, namespace) rc.ObjectMeta.Finalizers = initialFinalizers rc, err := rcClient.Create(rc) if err != nil { @@ -305,7 +301,7 @@ func setupRCsPods(t *testing.T, gc *garbagecollector.GarbageCollector, clientSet var podUIDs []types.UID for j := 0; j < 3; j++ { podName := "test.pod." + nameSuffix + "-" + strconv.Itoa(j) - pod := newPod(podName, []v1.OwnerReference{{UID: rc.ObjectMeta.UID, Name: rc.ObjectMeta.Name}}) + pod := newPod(podName, namespace, []v1.OwnerReference{{UID: rc.ObjectMeta.UID, Name: rc.ObjectMeta.Name}}) _, err = podClient.Create(pod) if err != nil { t.Fatalf("Failed to create Pod: %v", err) @@ -325,9 +321,9 @@ func setupRCsPods(t *testing.T, gc *garbagecollector.GarbageCollector, clientSet } } -func verifyRemainingObjects(t *testing.T, clientSet clientset.Interface, rcNum, podNum int) (bool, error) { - rcClient := clientSet.Core().ReplicationControllers(framework.TestNS) - podClient := clientSet.Core().Pods(framework.TestNS) +func verifyRemainingObjects(t *testing.T, clientSet clientset.Interface, namespace string, rcNum, podNum int) (bool, error) { + rcClient := clientSet.Core().ReplicationControllers(namespace) + podClient := clientSet.Core().Pods(namespace) pods, err := podClient.List(api.ListOptions{}) if err != nil { return false, fmt.Errorf("Failed to list pods: %v", err) @@ -353,7 +349,12 @@ func verifyRemainingObjects(t *testing.T, clientSet clientset.Interface, rcNum, // e2e tests that put more stress. func TestStressingCascadingDeletion(t *testing.T) { t.Logf("starts garbage collector stress test") - gc, clientSet := setup(t) + s, gc, clientSet := setup(t) + defer s.Close() + + ns := framework.CreateTestingNamespace("gc-stressing-cascading-deletion", s, t) + defer framework.DeleteTestingNamespace(ns, s, t) + oldEnableGarbageCollector := registry.EnableGarbageCollector registry.EnableGarbageCollector = true defer func() { registry.EnableGarbageCollector = oldEnableGarbageCollector }() @@ -367,13 +368,13 @@ func TestStressingCascadingDeletion(t *testing.T) { rcUIDs := make(chan types.UID, collections*4) for i := 0; i < collections; i++ { // rc is created with empty finalizers, deleted with nil delete options, pods will be deleted - go setupRCsPods(t, gc, clientSet, "collection1-"+strconv.Itoa(i), []string{}, nil, &wg, rcUIDs) + go setupRCsPods(t, gc, clientSet, "collection1-"+strconv.Itoa(i), ns.Name, []string{}, nil, &wg, rcUIDs) // rc is created with the orphan finalizer, deleted with nil options, pods will remain. - go setupRCsPods(t, gc, clientSet, "collection2-"+strconv.Itoa(i), []string{api.FinalizerOrphan}, nil, &wg, rcUIDs) + go setupRCsPods(t, gc, clientSet, "collection2-"+strconv.Itoa(i), ns.Name, []string{api.FinalizerOrphan}, nil, &wg, rcUIDs) // rc is created with the orphan finalizer, deleted with DeleteOptions.OrphanDependents=false, pods will be deleted. - go setupRCsPods(t, gc, clientSet, "collection3-"+strconv.Itoa(i), []string{api.FinalizerOrphan}, getNonOrphanOptions(), &wg, rcUIDs) + go setupRCsPods(t, gc, clientSet, "collection3-"+strconv.Itoa(i), ns.Name, []string{api.FinalizerOrphan}, getNonOrphanOptions(), &wg, rcUIDs) // rc is created with empty finalizers, deleted with DeleteOptions.OrphanDependents=true, pods will remain. - go setupRCsPods(t, gc, clientSet, "collection4-"+strconv.Itoa(i), []string{}, getOrphanOptions(), &wg, rcUIDs) + go setupRCsPods(t, gc, clientSet, "collection4-"+strconv.Itoa(i), ns.Name, []string{}, getOrphanOptions(), &wg, rcUIDs) } wg.Wait() t.Logf("all pods are created, all replications controllers are created then deleted") @@ -390,14 +391,14 @@ func TestStressingCascadingDeletion(t *testing.T) { podsInEachCollection := 3 // see the comments on the calls to setupRCsPods for details remainingGroups := 2 - return verifyRemainingObjects(t, clientSet, 0, collections*podsInEachCollection*remainingGroups) + return verifyRemainingObjects(t, clientSet, ns.Name, 0, collections*podsInEachCollection*remainingGroups) }); err != nil { t.Fatal(err) } t.Logf("number of remaining replication controllers and pods are as expected") // verify the remaining pods all have "orphan" in their names. - podClient := clientSet.Core().Pods(framework.TestNS) + podClient := clientSet.Core().Pods(ns.Name) pods, err := podClient.List(api.ListOptions{}) if err != nil { t.Fatal(err) @@ -420,14 +421,19 @@ func TestStressingCascadingDeletion(t *testing.T) { } func TestOrphaning(t *testing.T) { - gc, clientSet := setup(t) + s, gc, clientSet := setup(t) + defer s.Close() + + ns := framework.CreateTestingNamespace("gc-orphaning", s, t) + defer framework.DeleteTestingNamespace(ns, s, t) + oldEnableGarbageCollector := registry.EnableGarbageCollector registry.EnableGarbageCollector = true defer func() { registry.EnableGarbageCollector = oldEnableGarbageCollector }() - podClient := clientSet.Core().Pods(framework.TestNS) - rcClient := clientSet.Core().ReplicationControllers(framework.TestNS) + podClient := clientSet.Core().Pods(ns.Name) + rcClient := clientSet.Core().ReplicationControllers(ns.Name) // create the RC with the orphan finalizer set - toBeDeletedRC := newOwnerRC(toBeDeletedRCName) + toBeDeletedRC := newOwnerRC(toBeDeletedRCName, ns.Name) toBeDeletedRC, err := rcClient.Create(toBeDeletedRC) if err != nil { t.Fatalf("Failed to create replication controller: %v", err) @@ -438,7 +444,7 @@ func TestOrphaning(t *testing.T) { podsNum := 3 for i := 0; i < podsNum; i++ { podName := garbageCollectedPodName + strconv.Itoa(i) - pod := newPod(podName, []v1.OwnerReference{{UID: toBeDeletedRC.ObjectMeta.UID, Name: toBeDeletedRCName}}) + pod := newPod(podName, ns.Name, []v1.OwnerReference{{UID: toBeDeletedRC.ObjectMeta.UID, Name: toBeDeletedRCName}}) _, err = podClient.Create(pod) if err != nil { t.Fatalf("Failed to create Pod: %v", err) From 122f97d29b2dba58e3495ea797b9c9fe8c7e4321 Mon Sep 17 00:00:00 2001 From: Wojciech Tyczynski Date: Tue, 5 Jul 2016 11:26:12 +0200 Subject: [PATCH 4/4] Migrate remaining integration tests --- test/integration/framework/master_utils.go | 17 +++--- test/integration/master_benchmark_test.go | 17 ++++-- test/integration/quota_test.go | 17 ++++-- test/integration/rbac_test.go | 67 ++++++++++++---------- test/integration/service_account_test.go | 2 - 5 files changed, 69 insertions(+), 51 deletions(-) diff --git a/test/integration/framework/master_utils.go b/test/integration/framework/master_utils.go index bac6f01f39f..cdcd6aea8d7 100644 --- a/test/integration/framework/master_utils.go +++ b/test/integration/framework/master_utils.go @@ -64,9 +64,6 @@ const ( // Rc manifest used to create pods for benchmarks. // TODO: Convert this to a full path? TestRCManifest = "benchmark-controller.json" - - // Test Namspace, for pods and rcs. - TestNS = "test" ) // MasterComponents is a control struct for all master components started via NewMasterComponents. @@ -326,23 +323,27 @@ func StartRC(controller *api.ReplicationController, restClient *client.Client) ( return ScaleRC(created.Name, created.Namespace, controller.Spec.Replicas, restClient) } -// StartPods check for numPods in TestNS. If they exist, it no-ops, otherwise it starts up +// StartPods check for numPods in namespace. If they exist, it no-ops, otherwise it starts up // a temp rc, scales it to match numPods, then deletes the rc leaving behind the pods. -func StartPods(numPods int, host string, restClient *client.Client) error { +func StartPods(namespace string, numPods int, host string, restClient *client.Client) error { start := time.Now() defer func() { glog.Infof("StartPods took %v with numPods %d", time.Since(start), numPods) }() hostField := fields.OneTermEqualSelector(api.PodHostField, host) options := api.ListOptions{FieldSelector: hostField} - pods, err := restClient.Pods(TestNS).List(options) + pods, err := restClient.Pods(namespace).List(options) if err != nil || len(pods.Items) == numPods { return err } glog.Infof("Found %d pods that match host %v, require %d", len(pods.Items), hostField, numPods) - // For the sake of simplicity, assume all pods in TestNS have selectors matching TestRCManifest. + // For the sake of simplicity, assume all pods in namespace have selectors matching TestRCManifest. controller := RCFromManifest(TestRCManifest) + // Overwrite namespace + controller.ObjectMeta.Namespace = namespace + controller.Spec.Template.ObjectMeta.Namespace = namespace + // Make the rc unique to the given host. controller.Spec.Replicas = int32(numPods) controller.Spec.Template.Spec.NodeName = host @@ -355,7 +356,7 @@ func StartPods(numPods int, host string, restClient *client.Client) error { } else { // Delete the rc, otherwise when we restart master components for the next benchmark // the rc controller will race with the pods controller in the rc manager. - return restClient.ReplicationControllers(TestNS).Delete(rc.Name) + return restClient.ReplicationControllers(namespace).Delete(rc.Name) } } diff --git a/test/integration/master_benchmark_test.go b/test/integration/master_benchmark_test.go index 53099252662..75627dc15ff 100644 --- a/test/integration/master_benchmark_test.go +++ b/test/integration/master_benchmark_test.go @@ -64,7 +64,6 @@ func init() { Pods = *pods Workers = *workers Tasks = *tasks - framework.DeleteAllEtcdKeys() } // getPods returns the cmd line -pods or b.N if -pods wasn't specified. @@ -98,7 +97,7 @@ func getIterations(bN int) int { } // startPodsOnNodes creates numPods sharded across numNodes -func startPodsOnNodes(numPods, numNodes int, restClient *client.Client) { +func startPodsOnNodes(ns string, numPods, numNodes int, restClient *client.Client) { podsPerNode := numPods / numNodes if podsPerNode < 1 { podsPerNode = 1 @@ -114,6 +113,9 @@ func BenchmarkPodList(b *testing.B) { m := framework.NewMasterComponents(&framework.Config{nil, true, false, 250.0, 500}) defer m.Stop(true, true) + ns := framework.CreateTestingNamespace("benchmark-pod-list", s, t) + defer framework.DeleteTestingNamespace(ns, s, t) + numPods, numTasks, iter := getPods(b.N), getTasks(b.N), getIterations(b.N) podsPerNode := numPods / numTasks if podsPerNode < 1 { @@ -122,7 +124,7 @@ func BenchmarkPodList(b *testing.B) { glog.Infof("Starting benchmark: b.N %d, pods %d, workers %d, podsPerNode %d", b.N, numPods, numTasks, podsPerNode) - startPodsOnNodes(numPods, numTasks, m.RestClient) + startPodsOnNodes(ns.Name, numPods, numTasks, m.RestClient) // Stop the rc manager so it doesn't steal resources m.Stop(false, true) @@ -134,7 +136,7 @@ func BenchmarkPodList(b *testing.B) { defer func() { glog.V(3).Infof("Worker %d: Node %v listing pods took %v", id, host, time.Since(now)) }() - if pods, err := m.RestClient.Pods(framework.TestNS).List( + if pods, err := m.RestClient.Pods(ns.Name).List( labels.Everything(), fields.OneTermEqualSelector(client.PodHost, host)); err != nil { return err @@ -153,13 +155,16 @@ func BenchmarkPodListEtcd(b *testing.B) { m := framework.NewMasterComponents(&framework.Config{nil, true, false, 250.0, 500}) defer m.Stop(true, true) + ns := framework.CreateTestingNamespace("benchmark-pod-list-etcd", s, t) + defer framework.DeleteTestingNamespace(ns, s, t) + numPods, numTasks, iter := getPods(b.N), getTasks(b.N), getIterations(b.N) podsPerNode := numPods / numTasks if podsPerNode < 1 { podsPerNode = 1 } - startPodsOnNodes(numPods, numTasks, m.RestClient) + startPodsOnNodes(ns.Name, numPods, numTasks, m.RestClient) // Stop the rc manager so it doesn't steal resources m.Stop(false, true) @@ -173,7 +178,7 @@ func BenchmarkPodListEtcd(b *testing.B) { defer func() { glog.V(3).Infof("Worker %d: listing pods took %v", id, time.Since(now)) }() - pods, err := m.RestClient.Pods(framework.TestNS).List(labels.Everything(), fields.Everything()) + pods, err := m.RestClient.Pods(ns.Name).List(labels.Everything(), fields.Everything()) if err != nil { return err } diff --git a/test/integration/quota_test.go b/test/integration/quota_test.go index 3bcf133de44..8fd9a547e4b 100644 --- a/test/integration/quota_test.go +++ b/test/integration/quota_test.go @@ -54,9 +54,6 @@ func init() { // quota_test.go:100: Took 4.196205966s to scale up without quota // quota_test.go:115: Took 12.021640372s to scale up with quota func TestQuota(t *testing.T) { - // TODO: Limit the test to a single non-default namespace and clean this up at the end. - framework.DeleteAllEtcdKeys() - initializationCh := make(chan struct{}) // Set up a master var m *master.Master @@ -81,6 +78,11 @@ func TestQuota(t *testing.T) { } close(initializationCh) + ns := framework.CreateTestingNamespace("quotaed", s, t) + defer framework.DeleteTestingNamespace(ns, s, t) + ns2 := framework.CreateTestingNamespace("non-quotaed", s, t) + defer framework.DeleteTestingNamespace(ns2, s, t) + controllerCh := make(chan struct{}) defer close(controllerCh) @@ -102,12 +104,15 @@ func TestQuota(t *testing.T) { go resourcequotacontroller.NewResourceQuotaController(resourceQuotaControllerOptions).Run(2, controllerCh) startTime := time.Now() - scale(t, api.NamespaceDefault, clientset) + scale(t, ns2.Name, clientset) endTime := time.Now() t.Logf("Took %v to scale up without quota", endTime.Sub(startTime)) quota := &api.ResourceQuota{ - ObjectMeta: api.ObjectMeta{Name: "quota"}, + ObjectMeta: api.ObjectMeta{ + Name: "quota", + Namespace: ns.Name, + }, Spec: api.ResourceQuotaSpec{ Hard: api.ResourceList{ api.ResourcePods: resource.MustParse("1000"), @@ -128,7 +133,7 @@ func waitForQuota(t *testing.T, quota *api.ResourceQuota, clientset *clientset.C t.Fatalf("unexpected error: %v", err) } - if _, err := clientset.Core().ResourceQuotas("quotaed").Create(quota); err != nil { + if _, err := clientset.Core().ResourceQuotas(quota.Namespace).Create(quota); err != nil { t.Fatalf("unexpected error: %v", err) } diff --git a/test/integration/rbac_test.go b/test/integration/rbac_test.go index 7e14c0aeb09..0f52cd0cffa 100644 --- a/test/integration/rbac_test.go +++ b/test/integration/rbac_test.go @@ -26,14 +26,12 @@ import ( "io" "io/ioutil" "net/http" - "net/http/httptest" "net/http/httputil" "strings" "testing" "github.com/golang/glog" - "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/testapi" "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/v1" @@ -228,6 +226,15 @@ var ( } } } +` + podNamespace = ` +{ + "apiVersion": "` + testapi.Default.GroupVersion().String() + `", + "kind": "Namespace", + "metadata": { + "name": "pod-namespace"%s + } +} ` jobNamespace = ` { @@ -237,6 +244,15 @@ var ( "name": "job-namespace"%s } } +` + forbiddenNamespace = ` +{ + "apiVersion": "` + testapi.Default.GroupVersion().String() + `", + "kind": "Namespace", + "metadata": { + "name": "forbidden-namespace"%s + } +} ` ) @@ -292,16 +308,19 @@ func TestRBAC(t *testing.T) { }, }, requests: []request{ + // Create the namespace used later in the test + {superUser, "POST", "", "namespaces", "", "", podNamespace, http.StatusCreated}, + {superUser, "GET", "", "pods", "", "", "", http.StatusOK}, - {superUser, "GET", "", "pods", api.NamespaceDefault, "a", "", http.StatusNotFound}, - {superUser, "POST", "", "pods", api.NamespaceDefault, "", aPod, http.StatusCreated}, - {superUser, "GET", "", "pods", api.NamespaceDefault, "a", "", http.StatusOK}, + {superUser, "GET", "", "pods", "pod-namespace", "a", "", http.StatusNotFound}, + {superUser, "POST", "", "pods", "pod-namespace", "", aPod, http.StatusCreated}, + {superUser, "GET", "", "pods", "pod-namespace", "a", "", http.StatusOK}, {"bob", "GET", "", "pods", "", "", "", http.StatusForbidden}, - {"bob", "GET", "", "pods", api.NamespaceDefault, "a", "", http.StatusForbidden}, + {"bob", "GET", "", "pods", "pod-namespace", "a", "", http.StatusForbidden}, {"pod-reader", "GET", "", "pods", "", "", "", http.StatusOK}, - {"pod-reader", "POST", "", "pods", api.NamespaceDefault, "", aPod, http.StatusForbidden}, + {"pod-reader", "POST", "", "pods", "pod-namespace", "", aPod, http.StatusForbidden}, }, }, { @@ -330,21 +349,22 @@ func TestRBAC(t *testing.T) { requests: []request{ // Create the namespace used later in the test {superUser, "POST", "", "namespaces", "", "", jobNamespace, http.StatusCreated}, + {superUser, "POST", "", "namespaces", "", "", forbiddenNamespace, http.StatusCreated}, {"user-with-no-permissions", "POST", "batch", "jobs", "job-namespace", "", aJob, http.StatusForbidden}, {"user-with-no-permissions", "GET", "batch", "jobs", "job-namespace", "pi", "", http.StatusForbidden}, - // job-writer-namespace cannot write to the "default" namespace - {"job-writer-namespace", "GET", "batch", "jobs", "default", "", "", http.StatusForbidden}, - {"job-writer-namespace", "GET", "batch", "jobs", "default", "pi", "", http.StatusForbidden}, - {"job-writer-namespace", "POST", "batch", "jobs", "default", "", aJob, http.StatusForbidden}, - {"job-writer-namespace", "GET", "batch", "jobs", "default", "pi", "", http.StatusForbidden}, + // job-writer-namespace cannot write to the "forbidden-namespace" + {"job-writer-namespace", "GET", "batch", "jobs", "forbidden-namespace", "", "", http.StatusForbidden}, + {"job-writer-namespace", "GET", "batch", "jobs", "forbidden-namespace", "pi", "", http.StatusForbidden}, + {"job-writer-namespace", "POST", "batch", "jobs", "forbidden-namespace", "", aJob, http.StatusForbidden}, + {"job-writer-namespace", "GET", "batch", "jobs", "forbidden-namespace", "pi", "", http.StatusForbidden}, // job-writer can write to any namespace - {"job-writer", "GET", "batch", "jobs", "default", "", "", http.StatusOK}, - {"job-writer", "GET", "batch", "jobs", "default", "pi", "", http.StatusNotFound}, - {"job-writer", "POST", "batch", "jobs", "default", "", aJob, http.StatusCreated}, - {"job-writer", "GET", "batch", "jobs", "default", "pi", "", http.StatusOK}, + {"job-writer", "GET", "batch", "jobs", "forbidden-namespace", "", "", http.StatusOK}, + {"job-writer", "GET", "batch", "jobs", "forbidden-namespace", "pi", "", http.StatusNotFound}, + {"job-writer", "POST", "batch", "jobs", "forbidden-namespace", "", aJob, http.StatusCreated}, + {"job-writer", "GET", "batch", "jobs", "forbidden-namespace", "pi", "", http.StatusOK}, {"job-writer-namespace", "GET", "batch", "jobs", "job-namespace", "", "", http.StatusOK}, {"job-writer-namespace", "GET", "batch", "jobs", "job-namespace", "pi", "", http.StatusNotFound}, @@ -355,24 +375,13 @@ func TestRBAC(t *testing.T) { } for i, tc := range tests { - // TODO: Limit the test to a single non-default namespace and clean this up at the end. - framework.DeleteAllEtcdKeys() - - var m *master.Master - s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - m.Handler.ServeHTTP(w, r) - })) - defer s.Close() - // Create an API Server. masterConfig := framework.NewIntegrationTestMasterConfig() masterConfig.Authorizer = newRBACAuthorizer(t, superUser, masterConfig) masterConfig.Authenticator = newFakeAuthenticator() masterConfig.AuthorizerRBACSuperUser = superUser - m, err := master.New(masterConfig) - if err != nil { - t.Fatalf("case %d: error bringing up master: %v", i, err) - } + _, s := framework.RunAMaster(masterConfig) + defer s.Close() // Bootstrap the API Server with the test case's initial roles. if err := tc.bootstrapRoles.bootstrap(clientForUser(superUser), s.URL); err != nil { diff --git a/test/integration/service_account_test.go b/test/integration/service_account_test.go index d4569d6a843..9df0b0744ce 100644 --- a/test/integration/service_account_test.go +++ b/test/integration/service_account_test.go @@ -336,8 +336,6 @@ func TestServiceAccountTokenAuthentication(t *testing.T) { // startServiceAccountTestServer returns a started server // It is the responsibility of the caller to ensure the returned stopFunc is called func startServiceAccountTestServer(t *testing.T) (*clientset.Clientset, restclient.Config, func()) { - framework.DeleteAllEtcdKeys() - // Listener var m *master.Master apiServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {