- APISnoop org-flow: deleteCoreV1CollectionNamespacedPodTest.org
- Test approval issue: kubernetes/kubernetes#90663
- Test pr: kuberenetes/kubernetes#
- Two weeks soak start date: testgrid-link
- Two weeks soak end date:
- Test promotion pr: kubernetes/kubernetes#?
According to this APIsnoop query, there are still an endpoint which is untested.
SELECT
operation_id,
-- k8s_action,
-- path,
description,
kind
FROM untested_stable_core_endpoints
-- FROM untested_stable_endpoints
where path not like '%volume%'
-- and kind like ''
and operation_id ilike 'delete%CollectionNamespacedPod'
ORDER BY kind,operation_id desc
LIMIT 25
;
operation_id | description | kind
-------------------------------------+--------------------------+------
deleteCoreV1CollectionNamespacedPod | delete collection of Pod | Pod
(1 row)
- Kubernetes API Reference Docs
- Kubernetes API: v1.18 /deleteCoreV1CollectionNamespacedPod
- client-go - Pod: DeleteCollection
-
Create a set of 3 Pods with a static label within a Namespace.
-
Confirm that all 3 Pods with the label in the Namespace are created.
-
Delete the set of Namespaced Pods with a label via DeleteCollection.
-
Confirm that all Pods with the label have been deleted.
package main
import (
"context"
"flag"
"fmt"
"time"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
"os"
)
const (
podRetryPeriod = 1 * time.Second
podRetryTimeout = 1 * time.Minute
)
func main() {
// uses the current context in kubeconfig
kubeconfig := flag.String("kubeconfig", fmt.Sprintf("%v/%v/%v", os.Getenv("HOME"), ".kube", "config"), "(optional) absolute path to the kubeconfig file")
flag.Parse()
config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
if err != nil {
fmt.Println(err)
return
}
// make our work easier to find in the audit_event queries
config.UserAgent = "live-test-writing"
// creates the clientset
ClientSet, _ := kubernetes.NewForConfig(config)
// TEST BEGINS HERE
// create a set of pod test names
podTestNames := [3]string{"test-pod-nginx-1", "test-pod-nginx-2", "test-pod-nginx-3"}
// create a set of test pods with a label in the default namespace
for _, podTestName := range podTestNames {
_, err = ClientSet.CoreV1().Pods("default").Create(context.TODO(), &v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: podTestName,
Labels: map[string]string{
"type": "Testing"},
},
Spec: v1.PodSpec{
Containers: []v1.Container{{
Image: "nginx",
Name: "nginx",
}},
RestartPolicy: v1.RestartPolicyNever,
}}, metav1.CreateOptions{})
if err != nil {
fmt.Println("[error]", err)
return
}
fmt.Println("[status] created", podTestName)
}
// wait as required for all 3 pods to be found
fmt.Println("[status] waiting for all 3 pods to be located")
err = wait.PollImmediate(podRetryPeriod, podRetryTimeout, checkPodListQuantity(ClientSet, "type=Testing", 3))
if err != nil {
errMsg := "[error] 3 pods not found" + fmt.Sprintf("%v\n", err)
os.Stderr.WriteString(errMsg)
os.Exit(1)
}
// delete Collection of Pods for the label in the default namespace
_ = ClientSet.CoreV1().Pods("default").DeleteCollection(context.TODO(), metav1.DeleteOptions{}, metav1.ListOptions{
LabelSelector: "type=Testing"})
fmt.Println("[status] DeleteCollection processed")
// wait for all pods to be deleted
fmt.Println("[status] waiting for all pods to be deleted")
err = wait.PollImmediate(podRetryPeriod, podRetryTimeout, checkPodListQuantity(ClientSet, "type=Testing", 0))
if err != nil {
errMsg := "[error] found a pod(s) " + fmt.Sprintf("%v\n", err)
os.Stderr.WriteString(errMsg)
os.Exit(1)
}
// TEST ENDS HERE
fmt.Println("[status] complete")
}
func checkPodListQuantity(ClientSet *kubernetes.Clientset, label string, quantity int) func() (bool, error) {
return func() (bool, error) {
var err error
ns := "default"
fmt.Println("requesting list of pods to confirm quantity")
list, err := ClientSet.CoreV1().Pods(ns).List(context.TODO(), metav1.ListOptions{
LabelSelector: label})
if err != nil {
return false, err
}
if len(list.Items) != quantity {
return false, err
}
return true, nil
}
}
[status] created test-pod-nginx-1
[status] created test-pod-nginx-2
[status] created test-pod-nginx-3
[status] waiting for all 3 pods to be located
requesting list of pods to confirm quantity
[status] DeleteCollection processed
[status] waiting for all pods to be deleted
requesting list of pods to confirm quantity
requesting list of pods to confirm quantity
requesting list of pods to confirm quantity
requesting list of pods to confirm quantity
requesting list of pods to confirm quantity
requesting list of pods to confirm quantity
requesting list of pods to confirm quantity
requesting list of pods to confirm quantity
requesting list of pods to confirm quantity
[status] complete
Discover useragents:
select distinct useragent from audit_event where bucket='apisnoop' and useragent not like 'kube%' and useragent not like 'coredns%' and useragent not like 'kindnetd%' and useragent like 'live%';
useragent
-------------------
live-test-writing
(1 row)
List endpoints hit by the test:
select * from endpoints_hit_by_new_test where useragent like 'live%';
useragent | operation_id | hit_by_ete | hit_by_new_test
-------------------+-------------------------------------+------------+-----------------
live-test-writing | createCoreV1NamespacedPod | t | 3
live-test-writing | deleteCoreV1CollectionNamespacedPod | f | 1
live-test-writing | listCoreV1NamespacedPod | t | 10
(3 rows)
Display endpoint coverage change:
select * from projected_change_in_coverage;
category | total_endpoints | old_coverage | new_coverage | change_in_number
---------------+-----------------+--------------+--------------+------------------
test_coverage | 476 | 224 | 225 | 1
(1 row)
If a test with these calls gets merged, test coverage will go up by 1 points
This test is also created with the goal of conformance promotion.
/sig testing
/sig architecture
/area conformance