2015-05-18 19:41:46 +00:00
|
|
|
/*
|
|
|
|
Copyright 2014 The Kubernetes Authors All rights reserved.
|
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
package e2e
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2015-09-10 15:45:13 +00:00
|
|
|
"strings"
|
|
|
|
"sync"
|
|
|
|
"time"
|
|
|
|
|
2015-12-10 09:39:03 +00:00
|
|
|
"k8s.io/kubernetes/pkg/api"
|
2015-08-13 19:01:50 +00:00
|
|
|
client "k8s.io/kubernetes/pkg/client/unversioned"
|
2015-08-05 22:03:47 +00:00
|
|
|
"k8s.io/kubernetes/pkg/util/wait"
|
2015-05-18 19:41:46 +00:00
|
|
|
|
|
|
|
. "github.com/onsi/ginkgo"
|
|
|
|
. "github.com/onsi/gomega"
|
|
|
|
)
|
|
|
|
|
|
|
|
func extinguish(c *client.Client, totalNS int, maxAllowedAfterDel int, maxSeconds int) {
|
|
|
|
var err error
|
|
|
|
|
2015-07-02 00:38:57 +00:00
|
|
|
By("Creating testing namespaces")
|
|
|
|
wg := &sync.WaitGroup{}
|
2015-05-18 19:41:46 +00:00
|
|
|
for n := 0; n < totalNS; n += 1 {
|
2015-07-02 00:38:57 +00:00
|
|
|
wg.Add(1)
|
|
|
|
go func(n int) {
|
|
|
|
defer wg.Done()
|
|
|
|
defer GinkgoRecover()
|
2015-12-10 22:20:48 +00:00
|
|
|
_, err = createTestingNS(fmt.Sprintf("nslifetest-%v", n), c, nil)
|
2015-07-02 00:38:57 +00:00
|
|
|
Expect(err).NotTo(HaveOccurred())
|
|
|
|
}(n)
|
2015-05-18 19:41:46 +00:00
|
|
|
}
|
2015-07-02 00:38:57 +00:00
|
|
|
wg.Wait()
|
2015-05-18 19:41:46 +00:00
|
|
|
|
|
|
|
//Wait 10 seconds, then SEND delete requests for all the namespaces.
|
2015-11-17 18:44:15 +00:00
|
|
|
By("Waiting 10 seconds")
|
2015-05-18 19:41:46 +00:00
|
|
|
time.Sleep(time.Duration(10 * time.Second))
|
2015-11-17 18:44:15 +00:00
|
|
|
deleted, err := deleteNamespaces(c, []string{"nslifetest"}, nil /* skipFilter */)
|
2015-05-18 19:41:46 +00:00
|
|
|
Expect(err).NotTo(HaveOccurred())
|
2015-11-17 18:44:15 +00:00
|
|
|
Expect(len(deleted)).To(Equal(totalNS))
|
2015-05-18 19:41:46 +00:00
|
|
|
|
2015-07-02 00:38:57 +00:00
|
|
|
By("Waiting for namespaces to vanish")
|
2015-05-18 19:41:46 +00:00
|
|
|
//Now POLL until all namespaces have been eradicated.
|
|
|
|
expectNoError(wait.Poll(2*time.Second, time.Duration(maxSeconds)*time.Second,
|
|
|
|
func() (bool, error) {
|
2015-11-17 18:44:15 +00:00
|
|
|
var cnt = 0
|
2015-12-10 09:39:03 +00:00
|
|
|
nsList, err := c.Namespaces().List(api.ListOptions{})
|
2015-11-17 18:44:15 +00:00
|
|
|
if err != nil {
|
2015-05-18 19:41:46 +00:00
|
|
|
return false, err
|
|
|
|
}
|
2015-11-17 18:44:15 +00:00
|
|
|
for _, item := range nsList.Items {
|
|
|
|
if strings.Contains(item.Name, "nslifetest") {
|
|
|
|
cnt++
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if cnt > maxAllowedAfterDel {
|
|
|
|
Logf("Remaining namespaces : %v", cnt)
|
|
|
|
return false, nil
|
|
|
|
}
|
|
|
|
return true, nil
|
2015-05-18 19:41:46 +00:00
|
|
|
}))
|
|
|
|
}
|
|
|
|
|
2016-01-22 19:26:03 +00:00
|
|
|
// This test must run [Serial] due to the impact of running other parallel
|
|
|
|
// tests can have on its performance. Each test that follows the common
|
|
|
|
// test framework follows this pattern:
|
|
|
|
// 1. Create a Namespace
|
|
|
|
// 2. Do work that generates content in that namespace
|
|
|
|
// 3. Delete a Namespace
|
|
|
|
// Creation of a Namespace is non-trivial since it requires waiting for a
|
|
|
|
// ServiceAccount to be generated.
|
|
|
|
// Deletion of a Namespace is non-trivial and performance intensive since
|
|
|
|
// its an orchestrated process. The controller that handles deletion must
|
|
|
|
// query the namespace for all existing content, and then delete each piece
|
|
|
|
// of content in turn. As the API surface grows to add more KIND objects
|
|
|
|
// that could exist in a Namespace, the number of calls that the namespace
|
|
|
|
// controller must orchestrate grows since it must LIST, DELETE (1x1) each
|
|
|
|
// KIND.
|
|
|
|
// There is work underway to improve this, but it's
|
|
|
|
// most likely not going to get significantly better until etcd v3.
|
|
|
|
// Going back to this test, this test generates 100 Namespace objects, and then
|
|
|
|
// rapidly deletes all of them. This causes the NamespaceController to observe
|
|
|
|
// and attempt to process a large number of deletes concurrently. In effect,
|
|
|
|
// it's like running 100 traditional e2e tests in parallel. If the namespace
|
|
|
|
// controller orchestrating deletes is slowed down deleting another test's
|
|
|
|
// content then this test may fail. Since the goal of this test is to soak
|
|
|
|
// Namespace creation, and soak Namespace deletion, its not appropriate to
|
|
|
|
// further soak the cluster with other parallel Namespace deletion activities
|
|
|
|
// that each have a variable amount of content in the associated Namespace.
|
|
|
|
// When run in [Serial] this test appears to delete Namespace objects at a
|
|
|
|
// rate of approximately 1 per second.
|
|
|
|
var _ = Describe("Namespaces [Serial]", func() {
|
2015-05-18 19:41:46 +00:00
|
|
|
|
|
|
|
//This namespace is modified throughout the course of the test.
|
|
|
|
var c *client.Client
|
|
|
|
var err error = nil
|
|
|
|
BeforeEach(func() {
|
|
|
|
By("Creating a kubernetes client")
|
|
|
|
c, err = loadClient()
|
|
|
|
Expect(err).NotTo(HaveOccurred())
|
|
|
|
})
|
|
|
|
|
|
|
|
AfterEach(func() {
|
|
|
|
})
|
|
|
|
|
2016-01-22 19:26:03 +00:00
|
|
|
It("should delete fast enough (90 percent of 100 namespaces in 150 seconds)",
|
2015-05-18 19:41:46 +00:00
|
|
|
func() { extinguish(c, 100, 10, 150) })
|
|
|
|
|
|
|
|
//comprehensive draining ; uncomment after #7372
|
2015-09-10 15:45:13 +00:00
|
|
|
PIt("should always delete fast (ALL of 100 namespaces in 150 seconds)",
|
2015-05-18 19:41:46 +00:00
|
|
|
func() { extinguish(c, 100, 0, 150) })
|
|
|
|
})
|