jiebi/CodeConvo huggingface dataset:
}, "NodeMonitorGracePeriod": { SchemaProps: spec.SchemaProps{ <del> Description: "nodeMontiorGracePeriod is the amount of time which we allow a running node to be unresponsive before marking it unhealthy. Must be N times more than kubelet's nodeStatusUpdateFrequency, where N means number of retries allowed for kubelet to post node status.", </del> <ins> Description: "nodeMontiorGracePeriod is the amount of time which we allow a running node to be unresponsive before marking it unhealthy. Must be N times more than kubelet's nodeStatusUpdateFrequency, where N means number of retries allowed for kubelet to post node status. This value should also be greater than the sum of HTTP2_PING_TIMEOUT_SECONDS and HTTP2_READ_IDLE_TIMEOUT_SECONDS.", </ins> Ref:         ref("k8s.io/apimachinery/pkg/apis/meta/v1.Duration"), }, },
// nodeMontiorGracePeriod is the amount of time which we allow a running node to be // unresponsive before marking it unhealthy. Must be N times more than kubelet's // nodeStatusUpdateFrequency, where N means number of retries allowed for kubelet <del> // to post node status. </del> <ins> // to post node status. This value should also be greater than the sum of // HTTP2_PING_TIMEOUT_SECONDS and HTTP2_READ_IDLE_TIMEOUT_SECONDS. </ins> NodeMonitorGracePeriod metav1.Duration // podEvictionTimeout is the grace period for deleting pods on failed nodes. PodEvictionTimeout metav1.Duration
Expect(badEvents).NotTo(BeNumerically(">", int(math.Floor(0.01*float64(totalPods))))) }) } <del> type Scalability struct { skip          bool totalPods     int podsPerMinion int rcsPerThread  int } scalabilityTests := []Scalability{ {totalPods: 500, podsPerMinion: 10, rcsPerThread: 5, skip: true}, {totalPods: 500, podsPerMinion: 10, rcsPerThread: 25, skip: true}, } for _, testArg := range scalabilityTests { // # of threads calibrate to totalPods threads := (testArg.totalPods / (testArg.podsPerMinion * testArg.rcsPerThread)) name := fmt.Sprintf( "should be able to launch %v pods, %v per minion, in %v rcs/thread.", testArg.totalPods, testArg.podsPerMinion, testArg.rcsPerThread) if testArg.skip { name = "[Skipped] " + name } itArg := testArg It(name, func() { podsLaunched := 0 var wg sync.WaitGroup wg.Add(threads) // Create queue of pending requests on the api server. for i := 0; i < threads; i++ { go func() { defer wg.Done() for i := 0; i < itArg.rcsPerThread; i++ { name := "my-short-lived-pod" + string(util.NewUUID()) n := itArg.podsPerMinion * minionCount expectNoError(RunRC(c, name, ns, "gcr.io/google_containers/pause:go", n)) podsLaunched += n Logf("Launched %v pods so far...", podsLaunched) err := DeleteRC(c, ns, name) expectNoError(err) } }() } // Wait for all the pods from all the RC's to return. wg.Wait() Logf("%v pods out of %v launched", podsLaunched, itArg.totalPods) }) } </del> })
if err != nil { return nil, "", err } <del> return aggregator.FilterSpecByPathsWithoutSideEffects(result, []string{"/apis/"}), etag, nil </del> <ins> group := specInfo.apiService.Spec.Group version := specInfo.apiService.Spec.Version return aggregator.FilterSpecByPathsWithoutSideEffects(result, []string{"/apis/" + group + "/" + version}), etag, nil </ins> }, cached.Result[*spec.Swagger]{Value: result, Etag: etag, Err: err}) specInfo.spec.Store(filteredResult) return err
} // Ensure that the if the APIService OpenAPI is updated, the // aggregated OpenAPI is also updated. <ins> expectPath(t, swagger, "/apis/apiservicegroup/v1/path2") expectNoPath(t, swagger, "/apis/apiservicegroup/v1/path1") expectPath(t, swagger, "/apis/apiregistration.k8s.io/v1") } // Tests that an APIService that registers OpenAPI will only have the OpenAPI // for its specific group version served registered. // See https://github.com/kubernetes/kubernetes/pull/123570 for full context. func TestAPIServiceOpenAPIServiceMismatch(t *testing.T) { mux := http.NewServeMux() var delegationHandlers []http.Handler delegate1 := &openAPIHandler{openapi: &spec.Swagger{ SwaggerProps: spec.SwaggerProps{ Paths: &spec.Paths{ Paths: map[string]spec.PathItem{ "/apis/foo/v1": {}, }, }, }, }} delegationHandlers = append(delegationHandlers, delegate1) s := buildAndRegisterSpecAggregator(delegationHandlers, mux) apiService := &v1.APIService{ Spec: v1.APIServiceSpec{ Group:   "apiservicegroup", Version: "v1", Service: &v1.ServiceReference{Name: "dummy"}, }, } apiService.Name = "apiservice" apiService2 := &v1.APIService{ Spec: v1.APIServiceSpec{ Group:   "apiservicegroup", Version: "v2", Service: &v1.ServiceReference{Name: "dummy2"}, }, } apiService2.Name = "apiservice2" handler := &openAPIHandler{openapi: &spec.Swagger{ SwaggerProps: spec.SwaggerProps{ Paths: &spec.Paths{ Paths: map[string]spec.PathItem{ "/apis/apiservicegroup/v1": {}, }, }, }, }} handler2 := &openAPIHandler{openapi: &spec.Swagger{ SwaggerProps: spec.SwaggerProps{ Paths: &spec.Paths{ Paths: map[string]spec.PathItem{ "/apis/a":                  {}, "/apis/apiservicegroup/v1": {}, "/apis/apiservicegroup/v2": {}, }, }, }, }} if err := s.AddUpdateAPIService(apiService, handler); err != nil { t.Error(err) } if err := s.UpdateAPIServiceSpec(apiService.Name); err != nil { t.Error(err) } if err := s.AddUpdateAPIService(apiService2, handler2); err != nil { t.Error(err) } if err := s.UpdateAPIServiceSpec(apiService2.Name); err != nil { t.Error(err) } swagger, err := fetchOpenAPI(mux) if err != nil { t.Error(err) } expectPath(t, swagger, "/apis/apiservicegroup/v1") </ins> expectPath(t, swagger, "/apis/apiservicegroup/v2") <ins> expectPath(t, swagger, "/apis/apiregistration.k8s.io/v1") t.Logf("Remove APIService %s", apiService.Name) s.RemoveAPIService(apiService.Name) swagger, err = fetchOpenAPI(mux) if err != nil { t.Error(err) } // Ensure that the if the APIService is added then removed, the OpenAPI disappears from the aggregated OpenAPI as well. </ins> expectNoPath(t, swagger, "/apis/apiservicegroup/v1") expectPath(t, swagger, "/apis/apiregistration.k8s.io/v1") }
<ins> #!/usr/bin/env bash # Copyright 2024 The Kubernetes Authors. # # 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. set -o errexit set -o nounset set -o pipefail KUBE_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. cd "${KUBE_ROOT}" source hack/lib/init.sh # NOTE: Please do NOT add any to this list!! # # We are aiming to consolidate on: registry.k8s.io/e2e-test-images/agnhost # The sources for which are in test/images/agnhost. # If agnhost is missing functionality for your tests, please reach out to SIG Testing. kube::util::read-array PERMITTED_IMAGES < <(sed '/^#/d' ./test/images/.permitted-images) # get current list of images, ignoring tags echo "Getting e2e image list ..." make WHAT=test/e2e/e2e.test e2e_test="$(kube::util::find-binary e2e.test)" kube::util::read-array IMAGES < <("${e2e_test}" --list-images | sed -E 's/^(.+):[^:]+$/1/' | LC_ALL=C sort -u) # diff versus known permitted images ret=0 >&2 echo "Diffing e2e image list ..." diff -Naupr <(printf '%sn' "${IMAGES[@]}") <(printf '%sn' "${PERMITTED_IMAGES[@]}") || ret=$? if [[ $ret -eq 0 ]]; then >&2 echo "PASS: e2e images used are OK." else >&2 echo "FAIL: e2e images do not match the approved list!" >&2 echo "" >&2 echo "Please use registry.k8s.io/e2e-test-images/agnhost wherever possible, we are consolidating test images." >&2 echo "See: test/images/agnhost/README.md" >&2 echo "" >&2 echo "You can reach out to https://git.k8s.io/community/sig-testing for help." exit 1 fi </ins>
<ins> # NOTE: Please do NOT add any to this list!! # # We are aiming to consolidate on: registry.k8s.io/e2e-test-images/agnhost # The sources for which are in test/images/agnhost. # If agnhost is missing functionality for your tests, please reach out to SIG Testing. gcr.io/authenticated-image-pulling/alpine gcr.io/authenticated-image-pulling/windows-nanoserver gcr.io/k8s-authenticated-test/agnhost invalid.registry.k8s.io/invalid/alpine registry.k8s.io/build-image/distroless-iptables registry.k8s.io/cloud-provider-gcp/gcp-compute-persistent-disk-csi-driver registry.k8s.io/e2e-test-images/agnhost registry.k8s.io/e2e-test-images/apparmor-loader registry.k8s.io/e2e-test-images/busybox registry.k8s.io/e2e-test-images/cuda-vector-add registry.k8s.io/e2e-test-images/httpd registry.k8s.io/e2e-test-images/ipc-utils registry.k8s.io/e2e-test-images/jessie-dnsutils registry.k8s.io/e2e-test-images/kitten registry.k8s.io/e2e-test-images/nautilus registry.k8s.io/e2e-test-images/nginx registry.k8s.io/e2e-test-images/node-perf/npb-ep registry.k8s.io/e2e-test-images/node-perf/npb-is registry.k8s.io/e2e-test-images/node-perf/tf-wide-deep registry.k8s.io/e2e-test-images/nonewprivs registry.k8s.io/e2e-test-images/nonroot registry.k8s.io/e2e-test-images/perl registry.k8s.io/e2e-test-images/redis registry.k8s.io/e2e-test-images/regression-issue-74839 registry.k8s.io/e2e-test-images/resource-consumer registry.k8s.io/e2e-test-images/sample-apiserver registry.k8s.io/e2e-test-images/volume/iscsi registry.k8s.io/e2e-test-images/volume/nfs registry.k8s.io/etcd registry.k8s.io/pause registry.k8s.io/prometheus-dummy-exporter registry.k8s.io/prometheus-to-sd registry.k8s.io/sd-dummy-exporter registry.k8s.io/sig-storage/csi-attacher registry.k8s.io/sig-storage/csi-external-health-monitor-controller registry.k8s.io/sig-storage/csi-node-driver-registrar registry.k8s.io/sig-storage/csi-provisioner registry.k8s.io/sig-storage/csi-resizer registry.k8s.io/sig-storage/csi-snapshotter registry.k8s.io/sig-storage/hello-populator registry.k8s.io/sig-storage/hostpathplugin registry.k8s.io/sig-storage/livenessprobe registry.k8s.io/sig-storage/nfs-provisioner registry.k8s.io/sig-storage/volume-data-source-validator </ins>
}, []string{"resource"}, ) <ins> WatchCacheReadWait = compbasemetrics.NewHistogramVec( &compbasemetrics.HistogramOpts{ Namespace:      namespace, Subsystem:      subsystem, Name:           "read_wait_seconds", Help:           "Histogram of time spent waiting for a watch cache to become fresh.", StabilityLevel: compbasemetrics.ALPHA, Buckets:        []float64{0.005, 0.025, 0.05, 0.1, 0.2, 0.4, 0.6, 0.8, 1.0, 1.25, 1.5, 2, 3}, }, []string{"resource"}) </ins> ) var registerMetrics sync.Once
// You HAVE TO explicitly call w.RUnlock() after this function. func (w *watchCache) waitUntilFreshAndBlock(ctx context.Context, resourceVersion uint64) error { startTime := w.clock.Now() <ins> defer func() { if resourceVersion > 0 { metrics.WatchCacheReadWait.WithContext(ctx).WithLabelValues(w.groupResource.String()).Observe(w.clock.Since(startTime).Seconds()) } }() </ins> // In case resourceVersion is 0, we accept arbitrarily stale result. // As a result, the condition in the below for loop will never be
"k8s.io/apimachinery/pkg/watch" "k8s.io/apiserver/pkg/features" "k8s.io/apiserver/pkg/storage" <ins> "k8s.io/apiserver/pkg/storage/cacher/metrics" </ins> utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/client-go/tools/cache" featuregatetesting "k8s.io/component-base/featuregate/testing" <ins> k8smetrics "k8s.io/component-base/metrics" "k8s.io/component-base/metrics/testutil" </ins> "k8s.io/utils/clock" testingclock "k8s.io/utils/clock/testing" )
store.updateCache(add) } } <ins> func TestHistogramCacheReadWait(t *testing.T) { registry := k8smetrics.NewKubeRegistry() if err := registry.Register(metrics.WatchCacheReadWait); err != nil { t.Errorf("unexpected error: %v", err) } ctx := context.Background() testedMetrics := "apiserver_watch_cache_read_wait_seconds" store := newTestWatchCache(2, &cache.Indexers{}) defer store.Stop() // In background, update the store. go func() { if err := store.Add(makeTestPod("foo", 2)); err != nil { t.Errorf("unexpected error: %v", err) } if err := store.Add(makeTestPod("bar", 5)); err != nil { t.Errorf("unexpected error: %v", err) } }() testCases := []struct { desc            string resourceVersion uint64 want            string }{ { desc:            "resourceVersion is non-zero", resourceVersion: 5, want: ` # HELP apiserver_watch_cache_read_wait_seconds [ALPHA] Histogram of time spent waiting for a watch cache to become fresh. # TYPE apiserver_watch_cache_read_wait_seconds histogram apiserver_watch_cache_read_wait_seconds_bucket{resource="pods",le="0.005"} 1 apiserver_watch_cache_read_wait_seconds_bucket{resource="pods",le="0.025"} 1 apiserver_watch_cache_read_wait_seconds_bucket{resource="pods",le="0.05"} 1 apiserver_watch_cache_read_wait_seconds_bucket{resource="pods",le="0.1"} 1 apiserver_watch_cache_read_wait_seconds_bucket{resource="pods",le="0.2"} 1 apiserver_watch_cache_read_wait_seconds_bucket{resource="pods",le="0.4"} 1 apiserver_watch_cache_read_wait_seconds_bucket{resource="pods",le="0.6"} 1 apiserver_watch_cache_read_wait_seconds_bucket{resource="pods",le="0.8"} 1 apiserver_watch_cache_read_wait_seconds_bucket{resource="pods",le="1"} 1 apiserver_watch_cache_read_wait_seconds_bucket{resource="pods",le="1.25"} 1 apiserver_watch_cache_read_wait_seconds_bucket{resource="pods",le="1.5"} 1 apiserver_watch_cache_read_wait_seconds_bucket{resource="pods",le="2"} 1 apiserver_watch_cache_read_wait_seconds_bucket{resource="pods",le="3"} 1 apiserver_watch_cache_read_wait_seconds_bucket{resource="pods",le="+Inf"} 1 apiserver_watch_cache_read_wait_seconds_sum{resource="pods"} 0 apiserver_watch_cache_read_wait_seconds_count{resource="pods"} 1 `, }, { desc:            "resourceVersion is 0", resourceVersion: 0, want:            ``, }, } for _, test := range testCases { t.Run(test.desc, func(t *testing.T) { defer registry.Reset() if _, _, _, err := store.WaitUntilFreshAndGet(ctx, test.resourceVersion, "prefix/ns/bar"); err != nil { t.Errorf("unexpected error: %v", err) } if err := testutil.GatherAndCompare(registry, strings.NewReader(test.want), testedMetrics); err != nil { t.Errorf("unexpected error: %v", err) } }) } } </ins>
MINION_TAG="${INSTANCE_PREFIX}-minion" MINION_NAMES=($(eval echo ${INSTANCE_PREFIX}-minion-{1..${NUM_MINIONS}})) MINION_IP_RANGES=($(eval echo "10.245.{1..${NUM_MINIONS}}.0/24")) <del> MINION_SCOPES="" </del> <ins> MINION_SCOPES="storage-ro,compute-rw" </ins> # Increase the sleep interval value if concerned about API rate limits. 3, in seconds, is the default. POLL_SLEEP_INTERVAL=3 PORTAL_NET="10.0.0.0/16"
<ins> apiVersion: v1beta1 desiredState: manifest: containers: - image: kubernetes/pause name: testpd volumeMounts: - mountPath: "/testpd" name: "testpd" id: testpd version: v1beta1 volumes: - name: testpd source: persistentDisk: # This GCE PD must already exist and be formatted ext4 pdName: "%insert_pd_name_here%" fsType: ext4 id: testpd kind: Pod labels: test: testpd </ins>
<ins> #!/bin/bash # Copyright 2014 Google Inc. 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. # Launches a container and verifies it can be reached. Assumes that # we're being called by hack/e2e-test.sh (we use some env vars it sets up). # TODO: Convert uses of gcutil to gcloud set -o errexit set -o nounset set -o pipefail KUBE_ROOT=$(dirname "${BASH_SOURCE}")/../.. source "${KUBE_ROOT}/cluster/kube-env.sh" source "${KUBE_ROOT}/cluster/$KUBERNETES_PROVIDER/util.sh" if [[ "$KUBERNETES_PROVIDER" != "gce" ]]; then echo "PD test is only run for GCE" return 0 fi disk_name="e2e-$(date +%H-%M-%s)" config="/tmp/${disk_name}.yaml" function teardown() { echo "Cleaning up test artifacts" ${KUBECFG} delete pods/testpd rm -rf ${config} echo "Waiting for disk to become unmounted" sleep 20 gcutil deletedisk -f --zone=${ZONE} ${disk_name} } trap "teardown" EXIT perl -p -e "s/%.*%/${disk_name}/g" ${KUBE_ROOT}/examples/gce-pd/testpd.yaml > ${config} # Create and mount the disk. gcutil adddisk --size_gb=10 --zone=${ZONE} ${disk_name} gcutil attachdisk --disk ${disk_name} ${MASTER_NAME} gcutil ssh ${MASTER_NAME} sudo rm -rf /mnt/tmp gcutil ssh ${MASTER_NAME} sudo mkdir /mnt/tmp gcutil ssh ${MASTER_NAME} sudo /usr/share/google/safe_format_and_mount /dev/disk/by-id/google-${disk_name} /mnt/tmp gcutil ssh ${MASTER_NAME} sudo umount /mnt/tmp gcloud compute instances detach-disk --disk ${disk_name} --zone ${ZONE} ${MASTER_NAME} ${KUBECFG} -c ${config} create pods pod_id_list=$($KUBECFG '-template={{range.items}}{{.id}} {{end}}' -l test=testpd list pods) # Pod turn up on a clean cluster can take a while for the docker image pull. all_running=0 for i in $(seq 1 24); do echo "Waiting for pods to come up." sleep 5 all_running=1 for id in $pod_id_list; do current_status=$($KUBECFG -template '{{.currentState.status}}' get pods/$id) || true if [[ "$current_status" != "Running" ]]; then all_running=0 break fi done if [[ "${all_running}" == 1 ]]; then break fi done if [[ "${all_running}" == 0 ]]; then echo "Pods did not come up in time" exit 1 fi </ins>
// Update uncertain volumes - the new markVolumeOpts may have updated information. // Especially reconstructed volumes (marked as uncertain during reconstruction) need // an update. <del> updateUncertainVolume = utilfeature.DefaultFeatureGate.Enabled(features.SELinuxMountReadWriteOncePod) && podObj.volumeMountStateForPod == operationexecutor.VolumeMountUncertain </del> <ins> updateUncertainVolume = utilfeature.DefaultFeatureGate.Enabled(features.NewVolumeManagerReconstruction) && podObj.volumeMountStateForPod == operationexecutor.VolumeMountUncertain </ins> } if !podExists || updateUncertainVolume { // Add new mountedPod or update existing one.
utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/client-go/kubernetes" "k8s.io/client-go/transport" <ins> "k8s.io/component-base/tracing" </ins> "k8s.io/component-base/version" v1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" v1helper "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1/helper"
openAPIV3Config:            c.GenericConfig.OpenAPIV3Config, proxyCurrentCertKeyContent: func() (bytes []byte, bytes2 []byte) { return nil, nil }, rejectForwardingRedirects:  c.ExtraConfig.RejectForwardingRedirects, <ins> tracerProvider:             c.GenericConfig.TracerProvider, </ins> } // used later  to filter the served resource by those that have expired.
"k8s.io/apiserver/pkg/endpoints/handlers/responsewriters" endpointmetrics "k8s.io/apiserver/pkg/endpoints/metrics" genericapirequest "k8s.io/apiserver/pkg/endpoints/request" <ins> genericfeatures "k8s.io/apiserver/pkg/features" utilfeature "k8s.io/apiserver/pkg/util/feature" </ins> utilflowcontrol "k8s.io/apiserver/pkg/util/flowcontrol" apiserverproxyutil "k8s.io/apiserver/pkg/util/proxy" "k8s.io/apiserver/pkg/util/x509metrics" "k8s.io/client-go/transport" <ins> "k8s.io/component-base/tracing" </ins> "k8s.io/klog/v2" apiregistrationv1api "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" apiregistrationv1apihelper "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1/helper"
proxyRoundTripper = transport.NewAuthProxyRoundTripper(user.GetName(), user.GetGroups(), user.GetExtra(), proxyRoundTripper) <ins> if utilfeature.DefaultFeatureGate.Enabled(genericfeatures.APIServerTracing) && !upgrade { tracingWrapper := tracing.WrapperFor(r.tracerProvider) proxyRoundTripper = tracingWrapper(proxyRoundTripper) } </ins> // If we are upgrading, then the upgrade path tries to use this request with the TLS config we provide, but it does // NOT use the proxyRoundTripper.  It's a direct dial that bypasses the proxyRoundTripper.  This means that we have to // attach the "correct" user headers to the request ahead of time.
"golang.org/x/net/websocket" <ins> "go.opentelemetry.io/otel/propagation" sdktrace "go.opentelemetry.io/otel/sdk/trace" "go.opentelemetry.io/otel/sdk/trace/tracetest" "go.opentelemetry.io/otel/trace" </ins> metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" utilnet "k8s.io/apimachinery/pkg/util/net" "k8s.io/apimachinery/pkg/util/proxy" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apiserver/pkg/authentication/user" <ins> "k8s.io/apiserver/pkg/endpoints/filters" </ins> genericapirequest "k8s.io/apiserver/pkg/endpoints/request" "k8s.io/apiserver/pkg/server/egressselector" utilflowcontrol "k8s.io/apiserver/pkg/util/flowcontrol"
close(stopCh) } <ins> func TestTransformingInformerRace(t *testing.T) { // source simulates an apiserver object endpoint. source := fcache.NewFakeControllerSource() label := "to-be-transformed" makePod := func(name string) *v1.Pod { return &v1.Pod{ ObjectMeta: metav1.ObjectMeta{ Name:      name, Namespace: "namespace", Labels:    map[string]string{label: "true"}, }, Spec: v1.PodSpec{ Hostname: "hostname", }, } } badTransform := atomic.Bool{} podTransformer := func(obj interface{}) (interface{}, error) { pod, ok := obj.(*v1.Pod) if !ok { return nil, fmt.Errorf("unexpected object type: %T", obj) } if pod.ObjectMeta.Labels[label] != "true" { badTransform.Store(true) return nil, fmt.Errorf("object already transformed: %#v", obj) } pod.ObjectMeta.Labels[label] = "false" return pod, nil } numObjs := 5 for i := 0; i < numObjs; i++ { source.Add(makePod(fmt.Sprintf("pod-%d", i))) } type event struct{} events := make(chan event, numObjs) recordEvent := func(eventType watch.EventType, previous, current interface{}) { events <- event{} } checkEvents := func(count int) { for i := 0; i < count; i++ { <-events } } store, controller := NewTransformingInformer( source, &v1.Pod{}, 5*time.Millisecond, ResourceEventHandlerDetailedFuncs{ AddFunc:    func(obj interface{}, isInInitialList bool) { recordEvent(watch.Added, nil, obj) }, UpdateFunc: func(oldObj, newObj interface{}) { recordEvent(watch.Modified, oldObj, newObj) }, DeleteFunc: func(obj interface{}) { recordEvent(watch.Deleted, obj, nil) }, }, podTransformer, ) stopCh := make(chan struct{}) go controller.Run(stopCh) checkEvents(numObjs) // Periodically fetch objects to ensure no access races. wg := sync.WaitGroup{} errors := make(chan error, numObjs) for i := 0; i < numObjs; i++ { wg.Add(1) go func(index int) { defer wg.Done() key := fmt.Sprintf("namespace/pod-%d", index) for { select { case <-stopCh: return default: } obj, ok, err := store.GetByKey(key) if !ok || err != nil { errors <- fmt.Errorf("couldn't get the object for %v", key) return } pod := obj.(*v1.Pod) if pod.ObjectMeta.Labels[label] != "false" { errors <- fmt.Errorf("unexpected object: %#v", pod) return } } }(i) } // Let resyncs to happen for some time. time.Sleep(time.Second) close(stopCh) wg.Wait() close(errors) for err := range errors { t.Error(err) } if badTransform.Load() { t.Errorf("unexpected transformation happened") } } </ins> func TestDeletionHandlingObjectToName(t *testing.T) { cm := &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{