Merge pull request #2590 from Poor12/add-ut-for-lifted

[UT]Add ut for lifted codes
This commit is contained in:
karmada-bot 2022-09-29 12:05:57 +08:00 committed by GitHub
commit c817ace443
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 1187 additions and 65 deletions

View File

@ -4,69 +4,81 @@
package lifted package lifted
/* /*
| lifted file | source file | const/var/type/func | changed | | lifted file | source file | const/var/type/func | changed |
|--------------------------|-------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------|---------| |--------------------------|------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------|---------|
| corehelpers.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/apis/core/helper/helpers.go#L57-L61 | func IsQuotaHugePageResourceName | N | | corehelpers.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/apis/core/helper/helpers.go#L57-L61 | func IsQuotaHugePageResourceName | N |
| corehelpers.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/apis/core/helper/helpers.go#L212-L232 | var standardQuotaResources | N | | corehelpers.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/apis/core/helper/helpers.go#L212-L232 | var standardQuotaResources | N |
| corehelpers.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/apis/core/helper/helpers.go#L234-L238 | func IsStandardQuotaResourceName | N | | corehelpers.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/apis/core/helper/helpers.go#L234-L238 | func IsStandardQuotaResourceName | N |
| corehelpers.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/apis/core/helper/helpers.go#L240-L261 | var standardResources | N | | corehelpers.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/apis/core/helper/helpers.go#L240-L261 | var standardResources | N |
| corehelpers.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/apis/core/helper/helpers.go#L263-L266 | func IsStandardResourceName | N | | corehelpers.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/apis/core/helper/helpers.go#L263-L266 | func IsStandardResourceName | N |
| corehelpers.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/apis/core/helper/helpers.go#L268-L278 | var integerResources | N | | corehelpers.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/apis/core/helper/helpers.go#L268-L278 | var integerResources | N |
| corehelpers.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/apis/core/helper/helpers.go#L280-L283 | func IsIntegerResourceName | N | | corehelpers.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/apis/core/helper/helpers.go#L280-L283 | func IsIntegerResourceName | N |
| corev1helpers.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/apis/core/v1/helper/helpers.go#L31-L46 | func IsExtendedResourceName | Y | | corev1helpers.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/apis/core/v1/helper/helpers.go#L31-L46 | func IsExtendedResourceName | Y |
| corev1helpers.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/apis/core/v1/helper/helpers.go#L48-L51 | func IsPrefixedNativeResource | N | | corev1helpers.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/apis/core/v1/helper/helpers.go#L48-L51 | func IsPrefixedNativeResource | N |
| corev1helpers.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/apis/core/v1/helper/helpers.go#L54-L60 | func IsNativeResource | N | | corev1helpers.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/apis/core/v1/helper/helpers.go#L54-L60 | func IsNativeResource | N |
| corev1helpers.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/apis/core/v1/helper/helpers.go#L62-L66 | func IsHugePageResourceName | N | | corev1helpers.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/apis/core/v1/helper/helpers.go#L62-L66 | func IsHugePageResourceName | N |
| corev1helpers.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/apis/core/v1/helper/helpers.go#L132-L135 | func IsAttachableVolumeResourceName | N | | corev1helpers.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/apis/core/v1/helper/helpers.go#L132-L135 | func IsAttachableVolumeResourceName | N |
| corevalidation.go | https://github.com/kubernetes/kubernetes/blob/release-1.22/pkg/apis/core/validation/validation.go#L59 | const isNegativeErrorMsg | N | | corevalidation.go | https://github.com/kubernetes/kubernetes/blob/release-1.22/pkg/apis/core/validation/validation.go#L59 | const isNegativeErrorMsg | N |
| corevalidation.go | https://github.com/kubernetes/kubernetes/blob/release-1.22/pkg/apis/core/validation/validation.go#L60 | const isInvalidQuotaResource | N | | corevalidation.go | https://github.com/kubernetes/kubernetes/blob/release-1.22/pkg/apis/core/validation/validation.go#L60 | const isInvalidQuotaResource | N |
| corevalidation.go | https://github.com/kubernetes/kubernetes/blob/release-1.22/pkg/apis/core/validation/validation.go#L62 | const isNotIntegerErrorMsg | N | | corevalidation.go | https://github.com/kubernetes/kubernetes/blob/release-1.22/pkg/apis/core/validation/validation.go#L62 | const isNotIntegerErrorMsg | N |
| corevalidation.go | https://github.com/kubernetes/kubernetes/blob/release-1.22/pkg/apis/core/validation/validation.go#L225-L228 | var ValidatePodName | N | | corevalidation.go | https://github.com/kubernetes/kubernetes/blob/release-1.22/pkg/apis/core/validation/validation.go#L225-L228 | var ValidatePodName | N |
| corevalidation.go | https://github.com/kubernetes/kubernetes/blob/release-1.22/pkg/apis/core/validation/validation.go#L311-L318 | func ValidateNonnegativeQuantity | N | | corevalidation.go | https://github.com/kubernetes/kubernetes/blob/release-1.22/pkg/apis/core/validation/validation.go#L311-L318 | func ValidateNonnegativeQuantity | N |
| corevalidation.go | https://github.com/kubernetes/kubernetes/blob/release-1.22/pkg/apis/core/validation/validation.go#L5036-L5054 | func validateResourceName | Y | | corevalidation.go | https://github.com/kubernetes/kubernetes/blob/release-1.22/pkg/apis/core/validation/validation.go#L5036-L5054 | func validateResourceName | Y |
| corevalidation.go | https://github.com/kubernetes/kubernetes/blob/release-1.22/pkg/apis/core/validation/validation.go#L5073-L5084 | func ValidateResourceQuotaResourceName | Y | | corevalidation.go | https://github.com/kubernetes/kubernetes/blob/release-1.22/pkg/apis/core/validation/validation.go#L5073-L5084 | func ValidateResourceQuotaResourceName | Y |
| corevalidation.go | https://github.com/kubernetes/kubernetes/blob/release-1.22/pkg/apis/core/validation/validation.go#L5651-L5661 | func ValidateResourceQuantityValue | Y | | corevalidation.go | https://github.com/kubernetes/kubernetes/blob/release-1.22/pkg/apis/core/validation/validation.go#L5651-L5661 | func ValidateResourceQuantityValue | Y |
| deployment.go | https://github.com/kubernetes/kubernetes/blob/release-1.22/pkg/controller/controller_utils.go#L1003-L1012 | type ReplicaSetsByCreationTimestamp | N | | deployment.go | https://github.com/kubernetes/kubernetes/blob/release-1.22/pkg/controller/controller_utils.go#L1003-L1012 | type ReplicaSetsByCreationTimestamp | N |
| deployment.go | https://github.com/kubernetes/kubernetes/blob/release-1.22/pkg/controller/deployment/util/deployment_util.go#L569-L594 | func ListReplicaSetsByDeployment | Y | | deployment.go | https://github.com/kubernetes/kubernetes/blob/release-1.22/pkg/controller/deployment/util/deployment_util.go#L569-L594 | func ListReplicaSetsByDeployment | Y |
| deployment.go | https://github.com/kubernetes/kubernetes/blob/release-1.22/pkg/controller/deployment/util/deployment_util.go#L596-L628 | func ListPodsByRS | Y | | deployment.go | https://github.com/kubernetes/kubernetes/blob/release-1.22/pkg/controller/deployment/util/deployment_util.go#L596-L628 | func ListPodsByRS | Y |
| deployment.go | https://github.com/kubernetes/kubernetes/blob/release-1.22/pkg/controller/deployment/util/deployment_util.go#L630-L642 | func EqualIgnoreHash | N | | deployment.go | https://github.com/kubernetes/kubernetes/blob/release-1.22/pkg/controller/deployment/util/deployment_util.go#L630-L642 | func EqualIgnoreHash | N |
| deployment.go | https://github.com/kubernetes/kubernetes/blob/release-1.22/pkg/controller/deployment/util/deployment_util.go#L536-L544 | func GetNewReplicaSet | Y | | deployment.go | https://github.com/kubernetes/kubernetes/blob/release-1.22/pkg/controller/deployment/util/deployment_util.go#L536-L544 | func GetNewReplicaSet | Y |
| deployment.go | https://github.com/kubernetes/kubernetes/blob/release-1.22/pkg/controller/deployment/util/deployment_util.go#L644-L658 | func FindNewReplicaSet | N | | deployment.go | https://github.com/kubernetes/kubernetes/blob/release-1.22/pkg/controller/deployment/util/deployment_util.go#L644-L658 | func FindNewReplicaSet | N |
| discovery.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/controller/garbagecollector/garbagecollector.go#L696-L732 | func GetDeletableResources | N | | discovery.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/controller/garbagecollector/garbagecollector.go#L696-L732 | func GetDeletableResources | N |
| discovery_test.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/controller/garbagecollector/garbagecollector_test.go#L943-L990 | type fakeServerResources | N | | discovery_test.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/controller/garbagecollector/garbagecollector_test.go#L943-L990 | type fakeServerResources | N |
| discovery_test.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/controller/garbagecollector/garbagecollector_test.go#L707-L797 | func TestGetDeletableResources | N | | discovery_test.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/controller/garbagecollector/garbagecollector_test.go#L707-L797 | func TestGetDeletableResources | N |
| nodeselector.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/apis/core/helper/helpers.go#L365-L397 | func NodeSelectorRequirementsAsSelector | N | | nodeselector.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/apis/core/helper/helpers.go#L365-L397 | func NodeSelectorRequirementsAsSelector | N |
| objectwatcher.go | https://github.com/kubernetes-sigs/kubefed/blob/master/pkg/controller/util/propagatedversion.go#L35-L43 | func ObjectVersion | N | | nodeselector_test.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/apis/core/helper/helpers_test.go#L138-L200 | func TestNodeSelectorRequirementsAsSelector | N |
| objectwatcher.go | https://github.com/kubernetes-sigs/kubefed/blob/master/pkg/controller/util/propagatedversion.go#L45-L59 | func ObjectNeedsUpdate | N | | objectwatcher.go | https://github.com/kubernetes-sigs/kubefed/blob/master/pkg/controller/util/propagatedversion.go#L35-L43 | func ObjectVersion | N |
| objectwatcher.go | https://github.com/kubernetes-sigs/kubefed/blob/master/pkg/controller/util/meta.go#L63-L80 | func objectMetaObjEquivalent | Y | | objectwatcher.go | https://github.com/kubernetes-sigs/kubefed/blob/master/pkg/controller/util/propagatedversion.go#L45-L59 | func ObjectNeedsUpdate | N |
| podtemplate.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/controller/controller_utils.go#L466-L472 | func getPodsLabelSet | N | | objectwatcher.go | https://github.com/kubernetes-sigs/kubefed/blob/master/pkg/controller/util/meta.go#L63-L80 | func objectMetaObjEquivalent | Y |
| podtemplate.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/controller/controller_utils.go#L474-L478 | func getPodsFinalizers | N | | parallelism_test.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/scheduler/framework/parallelize/parallelism_test.go | func TestChunkSize | N |
| podtemplate.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/controller/controller_utils.go#L480-L486 | func getPodsAnnotationSet | N | | podtemplate.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/controller/controller_utils.go#L466-L472 | func getPodsLabelSet | N |
| podtemplate.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/controller/controller_utils.go#L488-L495 | func getPodsPrefix | N | | podtemplate.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/controller/controller_utils.go#L474-L478 | func getPodsFinalizers | N |
| podtemplate.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/controller/controller_utils.go#L539-L562 | func GetPodFromTemplate | Y | | podtemplate.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/controller/controller_utils.go#L480-L486 | func getPodsAnnotationSet | N |
| requestinfo.go | https://github.com/kubernetes/apiserver/blob/release-1.23/pkg/endpoints/request/requestinfo.go#L88-L247 | func NewRequestInfo | Y | | podtemplate.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/controller/controller_utils.go#L488-L495 | func getPodsPrefix | N |
| requestinfo.go | https://github.com/kubernetes/apiserver/blob/release-1.23/pkg/endpoints/request/requestinfo.go#L267-L274 | func SplitPath | Y | | podtemplate.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/controller/controller_utils.go#L539-L562 | func GetPodFromTemplate | Y |
| requestinfo.go | https://github.com/kubernetes/apiserver/blob/release-1.23/pkg/endpoints/request/requestinfo.go#L73-L74 | var specialVerbsNoSubresources | N | | requestinfo.go | https://github.com/kubernetes/apiserver/blob/release-1.23/pkg/endpoints/request/requestinfo.go#L88-L247 | func NewRequestInfo | Y |
| requestinfo.go | https://github.com/kubernetes/apiserver/blob/release-1.23/pkg/endpoints/request/requestinfo.go#L76-L78 | var namespaceSubresources | N | | requestinfo.go | https://github.com/kubernetes/apiserver/blob/release-1.23/pkg/endpoints/request/requestinfo.go#L267-L274 | func SplitPath | Y |
| requestinfo.go | https://github.com/kubernetes/apiserver/blob/release-1.23/pkg/endpoints/request/requestinfo.go#L67-L71 | var specialVerbs | N | | requestinfo.go | https://github.com/kubernetes/apiserver/blob/release-1.23/pkg/endpoints/request/requestinfo.go#L73-L74 | var specialVerbsNoSubresources | N |
| resourcename.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/scheduler/util/utils.go#L144-L148 | func IsScalarResourceName | Y | | requestinfo.go | https://github.com/kubernetes/apiserver/blob/release-1.23/pkg/endpoints/request/requestinfo.go#L76-L78 | var namespaceSubresources | N |
| retain.go | https://github.com/kubernetes-sigs/kubefed/blob/master/pkg/controller/sync/dispatch/retain.go | func RetainServiceFields | Y | | requestinfo.go | https://github.com/kubernetes/apiserver/blob/release-1.23/pkg/endpoints/request/requestinfo.go#L67-L71 | var specialVerbs | N |
| retain.go | https://github.com/kubernetes-sigs/kubefed/blob/master/pkg/controller/sync/dispatch/retain.go | func retainServiceHealthCheckNodePort | Y | | requestinfo_test.go | https://github.com/kubernetes/apiserver/blob/release-1.23/pkg/endpoints/request/requestinfo_test.go#L30-L148 | func TestGetAPIRequestInfo | Y |
| retain.go | https://github.com/kubernetes-sigs/kubefed/blob/master/pkg/controller/sync/dispatch/retain.go | func retainServiceClusterIP | Y | | requestinfo_test.go | https://github.com/kubernetes/apiserver/blob/release-1.23/pkg/endpoints/request/requestinfo_test.go#L150-L184 | func TestGetNonAPIRequestInfo | Y |
| retain.go | https://github.com/kubernetes-sigs/kubefed/blob/master/pkg/controller/sync/dispatch/retain.go | func RetainServiceAccountFields | Y | | resourcename.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/scheduler/util/utils.go#L144-L148 | func IsScalarResourceName | Y |
| taint.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/staging/src/k8s.io/kubectl/pkg/cmd/taint/utils.go#L37-L73 | func ParseTaints | N | | retain.go | https://github.com/kubernetes-sigs/kubefed/blob/master/pkg/controller/sync/dispatch/retain.go | func RetainServiceFields | Y |
| taint.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/staging/src/k8s.io/kubectl/pkg/cmd/taint/utils.go#L75-L118 | func parseTaint | N | | retain.go | https://github.com/kubernetes-sigs/kubefed/blob/master/pkg/controller/sync/dispatch/retain.go | func retainServiceHealthCheckNodePort | Y |
| taint.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/staging/src/k8s.io/kubectl/pkg/cmd/taint/utils.go#L120-L126 | func validateTaintEffect | N | | retain.go | https://github.com/kubernetes-sigs/kubefed/blob/master/pkg/controller/sync/dispatch/retain.go | func retainServiceClusterIP | Y |
| validateclustertaints.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/apis/core/validation/validation.go#L5001-L5033 | func ValidateClusterTaints | Y | | retain.go | https://github.com/kubernetes-sigs/kubefed/blob/master/pkg/controller/sync/dispatch/retain.go | func RetainServiceAccountFields | Y |
| validateclustertaints.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/apis/core/validation/validation.go#L3305-L3326 | func validateClusterTaintEffect | Y | | retain_test.go | https://github.com/kubernetes-sigs/kubefed/blob/master/pkg/controller/sync/dispatch/retain_test.go#L91-L174 | func TestRetainHealthCheckNodePortInServiceFields | Y |
| visitpod.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/api/v1/pod/util.go#L53-L63 | type ContainerType | N | | retain_test.go | https://github.com/kubernetes-sigs/kubefed/blob/master/pkg/controller/sync/dispatch/retain_test.go#L176-L292 | func TestRetainClusterIPInServiceFields | Y |
| visitpod.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/api/v1/pod/util.go#L65-L66 | const AllContainers | N | | taint.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/staging/src/k8s.io/kubectl/pkg/cmd/taint/utils.go#L37-L73 | func ParseTaints | N |
| visitpod.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/api/v1/pod/util.go#L78-L80 | type ContainerVisitor | N | | taint.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/staging/src/k8s.io/kubectl/pkg/cmd/taint/utils.go#L75-L118 | func parseTaint | N |
| visitpod.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/api/v1/pod/util.go#L82-L83 | type Visitor | N | | taint.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/staging/src/k8s.io/kubectl/pkg/cmd/taint/utils.go#L120-L126 | func validateTaintEffect | N |
| visitpod.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/api/v1/pod/util.go#L85-L94 | func skipEmptyNames | N | | validateclustertaints.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/apis/core/validation/validation.go#L5001-L5033 | func ValidateClusterTaints | Y |
| visitpod.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/api/v1/pod/util.go#L96-L123 | func VisitContainers | N | | validateclustertaints.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/apis/core/validation/validation.go#L3305-L3326 | func validateClusterTaintEffect | Y |
| visitpod.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/api/v1/pod/util.go#L125-L195 | func VisitPodSecretNames | N | | visitpod.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/api/v1/pod/util.go#L53-L63 | type ContainerType | N |
| visitpod.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/api/v1/pod/util.go#L197-L213 | func visitContainerSecretNames | N | | visitpod.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/api/v1/pod/util.go#L65-L66 | const AllContainers | N |
| visitpod.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/api/v1/pod/util.go#L215-L243 | func VisitPodConfigmapNames | N | | visitpod.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/api/v1/pod/util.go#L78-L80 | type ContainerVisitor | N |
| visitpod.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/api/v1/pod/util.go#L245-L261 | func visitContainerConfigmapNames | N | | visitpod.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/api/v1/pod/util.go#L82-L83 | type Visitor | N |
| visitpod.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/api/v1/pod/util.go#L85-L94 | func skipEmptyNames | N |
| visitpod.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/api/v1/pod/util.go#L96-L123 | func VisitContainers | N |
| visitpod.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/api/v1/pod/util.go#L125-L195 | func VisitPodSecretNames | N |
| visitpod.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/api/v1/pod/util.go#L197-L213 | func visitContainerSecretNames | N |
| visitpod.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/api/v1/pod/util.go#L215-L243 | func VisitPodConfigmapNames | N |
| visitpod.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/api/v1/pod/util.go#L245-L261 | func visitContainerConfigmapNames | N |
| visitpod_test.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/api/v1/pod/util.go#L68-L76 | func AllFeatureEnabledContainers | N |
| visitpod_test.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/staging/src/k8s.io/component-base/featuregate/testing/feature_gate.go#L26-L44 | func SetFeatureGateDuringTest | N |
| visitpod_test.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/api/v1/pod/util_test.go#L205-L392 | func TestVisitContainers | Y |
| visitpod_test.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/api/v1/pod/util_test.go#L394-L551 | func TestPodSecrets | Y |
| visitpod_test.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/api/v1/pod/util_test.go#L553-L591 | func collectResourcePaths | N |
| visitpod_test.go | https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/api/v1/pod/util_test.go#L593-L695 | func TestPodConfigmaps | Y |
*/ */

View File

@ -0,0 +1,95 @@
/*
Copyright 2020 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.
*/
// This code is directly lifted from the Kubernetes codebase in order to avoid relying on the k8s.io/kubernetes package.
// For reference:
// https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/apis/core/helper/helpers_test.go#L138-L200
package lifted
import (
"reflect"
"testing"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/labels"
)
// +lifted:source=https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/apis/core/helper/helpers_test.go#L138-L200
func TestNodeSelectorRequirementsAsSelector(t *testing.T) {
matchExpressions := []corev1.NodeSelectorRequirement{{
Key: "foo",
Operator: corev1.NodeSelectorOpIn,
Values: []string{"bar", "baz"},
}}
mustParse := func(s string) labels.Selector {
out, e := labels.Parse(s)
if e != nil {
panic(e)
}
return out
}
tc := []struct {
in []corev1.NodeSelectorRequirement
out labels.Selector
expectErr bool
}{
{in: nil, out: labels.Nothing()},
{in: []corev1.NodeSelectorRequirement{}, out: labels.Nothing()},
{
in: matchExpressions,
out: mustParse("foo in (baz,bar)"),
},
{
in: []corev1.NodeSelectorRequirement{{
Key: "foo",
Operator: corev1.NodeSelectorOpExists,
Values: []string{"bar", "baz"},
}},
expectErr: true,
},
{
in: []corev1.NodeSelectorRequirement{{
Key: "foo",
Operator: corev1.NodeSelectorOpGt,
Values: []string{"1"},
}},
out: mustParse("foo>1"),
},
{
in: []corev1.NodeSelectorRequirement{{
Key: "bar",
Operator: corev1.NodeSelectorOpLt,
Values: []string{"7"},
}},
out: mustParse("bar<7"),
},
}
for i, tc := range tc {
out, err := NodeSelectorRequirementsAsSelector(tc.in)
if err == nil && tc.expectErr {
t.Errorf("[%v]expected error but got none.", i)
}
if err != nil && !tc.expectErr {
t.Errorf("[%v]did not expect error but got: %v", i, err)
}
if !reflect.DeepEqual(out, tc.out) {
t.Errorf("[%v]expected:\n\t%+v\nbut got:\n\t%+v", i, tc.out, out)
}
}
}

View File

@ -0,0 +1,60 @@
/*
Copyright 2020 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.
*/
// This code is directly lifted from the Kubernetes codebase.
// For reference:
// https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/scheduler/framework/parallelize/parallelism_test.go
package lifted
import (
"fmt"
"testing"
)
// +lifted:source=https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/scheduler/framework/parallelize/parallelism_test.go
func TestChunkSize(t *testing.T) {
tests := []struct {
input int
wantOutput int
}{
{
input: 32,
wantOutput: 3,
},
{
input: 16,
wantOutput: 2,
},
{
input: 1,
wantOutput: 1,
},
{
input: 0,
wantOutput: 1,
},
}
for _, test := range tests {
t.Run(fmt.Sprintf("%d", test.input), func(t *testing.T) {
if chunkSizeFor(test.input, DefaultParallelism) != test.wantOutput {
t.Errorf("Expected: %d, got: %d", test.wantOutput, chunkSizeFor(test.input, DefaultParallelism))
}
})
}
}

View File

@ -1,9 +1,12 @@
/* /*
Copyright 2016 The Kubernetes Authors. Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

View File

@ -0,0 +1,178 @@
/*
Copyright 2016 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.
*/
// This code is directly lifted from the Kubernetes codebase.
// For reference:
// https://github.com/kubernetes/apiserver/blob/release-1.23/pkg/endpoints/request/requestinfo_test.go#L30-L184
package lifted
import (
"net/http"
"reflect"
"testing"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// +lifted:source=https://github.com/kubernetes/apiserver/blob/release-1.23/pkg/endpoints/request/requestinfo_test.go#L30-L148
// +lifted:changed
func TestGetAPIRequestInfo(t *testing.T) {
namespaceAll := metav1.NamespaceAll
successCases := []struct {
method string
url string
expectedVerb string
expectedAPIPrefix string
expectedAPIGroup string
expectedAPIVersion string
expectedNamespace string
expectedResource string
expectedSubresource string
expectedName string
expectedParts []string
}{
// resource paths
{"GET", "/api/v1/namespaces", "list", "api", "", "v1", "", "namespaces", "", "", []string{"namespaces"}},
{"GET", "/api/v1/namespaces/other", "get", "api", "", "v1", "other", "namespaces", "", "other", []string{"namespaces", "other"}},
{"GET", "/api/v1/namespaces/other/pods", "list", "api", "", "v1", "other", "pods", "", "", []string{"pods"}},
{"GET", "/api/v1/namespaces/other/pods/foo", "get", "api", "", "v1", "other", "pods", "", "foo", []string{"pods", "foo"}},
{"HEAD", "/api/v1/namespaces/other/pods/foo", "get", "api", "", "v1", "other", "pods", "", "foo", []string{"pods", "foo"}},
{"GET", "/api/v1/pods", "list", "api", "", "v1", namespaceAll, "pods", "", "", []string{"pods"}},
{"HEAD", "/api/v1/pods", "list", "api", "", "v1", namespaceAll, "pods", "", "", []string{"pods"}},
{"GET", "/api/v1/namespaces/other/pods/foo", "get", "api", "", "v1", "other", "pods", "", "foo", []string{"pods", "foo"}},
{"GET", "/api/v1/namespaces/other/pods", "list", "api", "", "v1", "other", "pods", "", "", []string{"pods"}},
// special verbs
{"GET", "/api/v1/proxy/namespaces/other/pods/foo", "proxy", "api", "", "v1", "other", "pods", "", "foo", []string{"pods", "foo"}},
{"GET", "/api/v1/proxy/namespaces/other/pods/foo/subpath/not/a/subresource", "proxy", "api", "", "v1", "other", "pods", "", "foo", []string{"pods", "foo", "subpath", "not", "a", "subresource"}},
{"GET", "/api/v1/watch/pods", "watch", "api", "", "v1", namespaceAll, "pods", "", "", []string{"pods"}},
{"GET", "/api/v1/pods?watch=true", "watch", "api", "", "v1", namespaceAll, "pods", "", "", []string{"pods"}},
{"GET", "/api/v1/pods?watch=false", "list", "api", "", "v1", namespaceAll, "pods", "", "", []string{"pods"}},
{"GET", "/api/v1/watch/namespaces/other/pods", "watch", "api", "", "v1", "other", "pods", "", "", []string{"pods"}},
{"GET", "/api/v1/namespaces/other/pods?watch=1", "watch", "api", "", "v1", "other", "pods", "", "", []string{"pods"}},
{"GET", "/api/v1/namespaces/other/pods?watch=0", "list", "api", "", "v1", "other", "pods", "", "", []string{"pods"}},
// subresource identification
{"GET", "/api/v1/namespaces/other/pods/foo/status", "get", "api", "", "v1", "other", "pods", "status", "foo", []string{"pods", "foo", "status"}},
{"GET", "/api/v1/namespaces/other/pods/foo/proxy/subpath", "get", "api", "", "v1", "other", "pods", "proxy", "foo", []string{"pods", "foo", "proxy", "subpath"}},
{"PUT", "/api/v1/namespaces/other/finalize", "update", "api", "", "v1", "other", "namespaces", "finalize", "other", []string{"namespaces", "other", "finalize"}},
{"PUT", "/api/v1/namespaces/other/status", "update", "api", "", "v1", "other", "namespaces", "status", "other", []string{"namespaces", "other", "status"}},
// verb identification
{"PATCH", "/api/v1/namespaces/other/pods/foo", "patch", "api", "", "v1", "other", "pods", "", "foo", []string{"pods", "foo"}},
{"DELETE", "/api/v1/namespaces/other/pods/foo", "delete", "api", "", "v1", "other", "pods", "", "foo", []string{"pods", "foo"}},
{"POST", "/api/v1/namespaces/other/pods", "create", "api", "", "v1", "other", "pods", "", "", []string{"pods"}},
// deletecollection verb identification
{"DELETE", "/api/v1/nodes", "deletecollection", "api", "", "v1", "", "nodes", "", "", []string{"nodes"}},
{"DELETE", "/api/v1/namespaces", "deletecollection", "api", "", "v1", "", "namespaces", "", "", []string{"namespaces"}},
{"DELETE", "/api/v1/namespaces/other/pods", "deletecollection", "api", "", "v1", "other", "pods", "", "", []string{"pods"}},
{"DELETE", "/apis/extensions/v1/namespaces/other/pods", "deletecollection", "api", "extensions", "v1", "other", "pods", "", "", []string{"pods"}},
// api group identification
{"POST", "/apis/extensions/v1/namespaces/other/pods", "create", "api", "extensions", "v1", "other", "pods", "", "", []string{"pods"}},
// api version identification
{"POST", "/apis/extensions/v1beta3/namespaces/other/pods", "create", "api", "extensions", "v1beta3", "other", "pods", "", "", []string{"pods"}},
}
for _, successCase := range successCases {
req, _ := http.NewRequest(successCase.method, successCase.url, nil)
apiRequestInfo := NewRequestInfo(req)
if !apiRequestInfo.IsResourceRequest {
t.Errorf("Expected resource request")
}
if successCase.expectedVerb != apiRequestInfo.Verb {
t.Errorf("Unexpected verb for url: %s, expected: %s, actual: %s", successCase.url, successCase.expectedVerb, apiRequestInfo.Verb)
}
if successCase.expectedAPIVersion != apiRequestInfo.APIVersion {
t.Errorf("Unexpected apiVersion for url: %s, expected: %s, actual: %s", successCase.url, successCase.expectedAPIVersion, apiRequestInfo.APIVersion)
}
if successCase.expectedNamespace != apiRequestInfo.Namespace {
t.Errorf("Unexpected namespace for url: %s, expected: %s, actual: %s", successCase.url, successCase.expectedNamespace, apiRequestInfo.Namespace)
}
if successCase.expectedResource != apiRequestInfo.Resource {
t.Errorf("Unexpected resource for url: %s, expected: %s, actual: %s", successCase.url, successCase.expectedResource, apiRequestInfo.Resource)
}
if successCase.expectedSubresource != apiRequestInfo.Subresource {
t.Errorf("Unexpected resource for url: %s, expected: %s, actual: %s", successCase.url, successCase.expectedSubresource, apiRequestInfo.Subresource)
}
if successCase.expectedName != apiRequestInfo.Name {
t.Errorf("Unexpected name for url: %s, expected: %s, actual: %s", successCase.url, successCase.expectedName, apiRequestInfo.Name)
}
if !reflect.DeepEqual(successCase.expectedParts, apiRequestInfo.Parts) {
t.Errorf("Unexpected parts for url: %s, expected: %v, actual: %v", successCase.url, successCase.expectedParts, apiRequestInfo.Parts)
}
}
errorCases := map[string]string{
"no resource path": "/",
"just apiversion": "/api/version/",
"just prefix, group, version": "/apis/group/version/",
"apiversion with no resource": "/api/version/",
"bad prefix": "/badprefix/version/resource",
"missing api group": "/apis/version/resource",
}
for k, v := range errorCases {
req, err := http.NewRequest("GET", v, nil)
if err != nil {
t.Errorf("Unexpected error %v", err)
}
apiRequestInfo := NewRequestInfo(req)
if apiRequestInfo.IsResourceRequest {
t.Errorf("%s: expected non-resource request", k)
}
}
}
// +lifted:source=https://github.com/kubernetes/apiserver/blob/release-1.23/pkg/endpoints/request/requestinfo_test.go#L150-L184
// +lifted:changed
func TestGetNonAPIRequestInfo(t *testing.T) {
tests := map[string]struct {
url string
expected bool
}{
"simple groupless": {"/api/version/resource", true},
"simple group": {"/apis/group/version/resource/name/subresource", true},
"more steps": {"/api/version/resource/name/subresource", true},
"group list": {"/apis/batch/v1/job", true},
"group get": {"/apis/batch/v1/job/foo", true},
"group subresource": {"/apis/batch/v1/job/foo/scale", true},
"bad root": {"/not-api/version/resource", false},
"group without enough steps": {"/apis/extensions/v1beta1", false},
"group without enough steps 2": {"/apis/extensions/v1beta1/", false},
"not enough steps": {"/api/version", false},
"one step": {"/api", false},
"zero step": {"/", false},
"empty": {"", false},
}
for testName, tc := range tests {
req, _ := http.NewRequest("GET", tc.url, nil)
apiRequestInfo := NewRequestInfo(req)
if e, a := tc.expected, apiRequestInfo.IsResourceRequest; e != a {
t.Errorf("%s: expected %v, actual %v", testName, e, a)
}
}
}

View File

@ -0,0 +1,189 @@
/*
Copyright 2020 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.
*/
// This code is directly lifted from the kubefed codebase.
// For reference:
// https://github.com/kubernetes-sigs/kubefed/blob/master/pkg/controller/sync/dispatch/retain_test.go#L91-L292
package lifted
import (
"testing"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/utils/pointer"
)
// +lifted:source=https://github.com/kubernetes-sigs/kubefed/blob/master/pkg/controller/sync/dispatch/retain_test.go#L91-L174
// +lifted:changed
func TestRetainHealthCheckNodePortInServiceFields(t *testing.T) {
tests := []struct {
name string
desiredObj *unstructured.Unstructured
clusterObj *unstructured.Unstructured
retainSucceed bool
expectedValue *int64
}{
{
"cluster object has no healthCheckNodePort",
&unstructured.Unstructured{
Object: map[string]interface{}{},
},
&unstructured.Unstructured{
Object: map[string]interface{}{},
},
true,
nil,
},
{
"cluster object has invalid healthCheckNodePort",
&unstructured.Unstructured{
Object: map[string]interface{}{},
},
&unstructured.Unstructured{
Object: map[string]interface{}{
"spec": map[string]interface{}{
"healthCheckNodePort": "invalid string",
},
},
},
false,
nil,
},
{
"cluster object has healthCheckNodePort 0",
&unstructured.Unstructured{
Object: map[string]interface{}{},
},
&unstructured.Unstructured{
Object: map[string]interface{}{
"spec": map[string]interface{}{
"healthCheckNodePort": int64(0),
},
},
},
true,
nil,
},
{
"cluster object has healthCheckNodePort 1000",
&unstructured.Unstructured{
Object: map[string]interface{}{},
},
&unstructured.Unstructured{
Object: map[string]interface{}{
"spec": map[string]interface{}{
"healthCheckNodePort": int64(1000),
},
},
},
true,
pointer.Int64Ptr(1000),
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
if _, err := RetainServiceFields(test.desiredObj, test.clusterObj); (err == nil) != test.retainSucceed {
t.Fatalf("test %s fails: unexpected returned error %v", test.name, err)
}
currentValue, ok, err := unstructured.NestedInt64(test.desiredObj.Object, "spec", "healthCheckNodePort")
if err != nil {
t.Fatalf("test %s fails: %v", test.name, err)
}
if !ok && test.expectedValue != nil {
t.Fatalf("test %s fails: expect specified healthCheckNodePort but not found", test.name)
}
if ok && (test.expectedValue == nil || *test.expectedValue != currentValue) {
t.Fatalf("test %s fails: unexpected current healthCheckNodePort %d", test.name, currentValue)
}
})
}
}
// +lifted:source=https://github.com/kubernetes-sigs/kubefed/blob/master/pkg/controller/sync/dispatch/retain_test.go#L176-L292
// +lifted:changed
func TestRetainClusterIPInServiceFields(t *testing.T) {
tests := []struct {
name string
desiredObj *unstructured.Unstructured
clusterObj *unstructured.Unstructured
retainSucceed bool
expectedClusterIPValue *string
}{
{
"cluster object has no clusterIP",
&unstructured.Unstructured{
Object: map[string]interface{}{},
},
&unstructured.Unstructured{
Object: map[string]interface{}{},
},
true,
nil,
},
{
"cluster object has invalid clusterIP",
&unstructured.Unstructured{
Object: map[string]interface{}{},
},
&unstructured.Unstructured{
Object: map[string]interface{}{
"spec": map[string]interface{}{
"clusterIP": -1000,
},
},
},
false,
nil,
},
{
"cluster object has valid clusterIP",
&unstructured.Unstructured{
Object: map[string]interface{}{},
},
&unstructured.Unstructured{
Object: map[string]interface{}{
"spec": map[string]interface{}{
"clusterIP": "1.2.3.4",
},
},
},
true,
pointer.String("1.2.3.4"),
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
if _, err := RetainServiceFields(test.desiredObj, test.clusterObj); (err == nil) != test.retainSucceed {
t.Fatalf("test %s fails: unexpected returned error %v", test.name, err)
}
currentClusterIPValue, ok, err := unstructured.NestedString(test.desiredObj.Object, "spec", "clusterIP")
if err != nil {
t.Fatalf("test %s fails: %v", test.name, err)
}
if !ok && test.expectedClusterIPValue != nil {
t.Fatalf("test %s fails: expect specified clusterIP but not found", test.name)
}
if ok && (test.expectedClusterIPValue == nil || *test.expectedClusterIPValue != currentClusterIPValue) {
t.Fatalf("test %s fails: unexpected current clusterIP %s", test.name, currentClusterIPValue)
}
})
}
}

View File

@ -0,0 +1,585 @@
/*
Copyright 2015 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.
*/
// This code is directly lifted from the Kubernetes codebase in order to avoid relying on the k8s.io/kubernetes package.
// For reference:
// https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/api/v1/pod/util_test.go#L205-L695
package lifted
import (
"fmt"
"reflect"
"strings"
"testing"
"github.com/google/go-cmp/cmp"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/validation/field"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/component-base/featuregate"
)
const (
// Allows running an ephemeral container in pod namespaces to troubleshoot a running pod.
EphemeralContainersFeature featuregate.Feature = "EphemeralContainers"
)
func init() {
testKubernetesFeatureGates := map[featuregate.Feature]featuregate.FeatureSpec{
EphemeralContainersFeature: {Default: true, PreRelease: featuregate.Beta},
}
runtime.Must(utilfeature.DefaultMutableFeatureGate.Add(testKubernetesFeatureGates))
}
// +lifted:source=https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/api/v1/pod/util.go#L68-L76
// AllFeatureEnabledContainers returns a ContainerType mask which includes all container
// types except for the ones guarded by feature gate.
func AllFeatureEnabledContainers() ContainerType {
containerType := AllContainers
if !utilfeature.DefaultFeatureGate.Enabled(EphemeralContainersFeature) {
containerType &= ^EphemeralContainers
}
return containerType
}
// +lifted:source=https://github.com/kubernetes/kubernetes/blob/release-1.23/staging/src/k8s.io/component-base/featuregate/testing/feature_gate.go#L26-L44
// SetFeatureGateDuringTest sets the specified gate to the specified value, and returns a function that restores the original value.
// Failures to set or restore cause the test to fail.
//
// Example use:
//
// defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.<FeatureName>, true)()
func SetFeatureGateDuringTest(tb testing.TB, gate featuregate.FeatureGate, f featuregate.Feature, value bool) func() {
originalValue := gate.Enabled(f)
if err := gate.(featuregate.MutableFeatureGate).Set(fmt.Sprintf("%s=%v", f, value)); err != nil {
tb.Errorf("error setting %s=%v: %v", f, value, err)
}
return func() {
if err := gate.(featuregate.MutableFeatureGate).Set(fmt.Sprintf("%s=%v", f, originalValue)); err != nil {
tb.Errorf("error restoring %s=%v: %v", f, originalValue, err)
}
}
}
// +lifted:source=https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/api/v1/pod/util_test.go#L205-L392
// +lifted:changed
func TestVisitContainers(t *testing.T) {
setAllFeatureEnabledContainersDuringTest := ContainerType(0)
testCases := []struct {
desc string
spec *corev1.PodSpec
wantContainers []string
mask ContainerType
ephemeralContainersEnabled bool
}{
{
desc: "empty podspec",
spec: &corev1.PodSpec{},
wantContainers: []string{},
mask: AllContainers,
},
{
desc: "regular containers",
spec: &corev1.PodSpec{
Containers: []corev1.Container{
{Name: "c1"},
{Name: "c2"},
},
InitContainers: []corev1.Container{
{Name: "i1"},
{Name: "i2"},
},
EphemeralContainers: []corev1.EphemeralContainer{
{EphemeralContainerCommon: corev1.EphemeralContainerCommon{Name: "e1"}},
{EphemeralContainerCommon: corev1.EphemeralContainerCommon{Name: "e2"}},
},
},
wantContainers: []string{"c1", "c2"},
mask: Containers,
},
{
desc: "init containers",
spec: &corev1.PodSpec{
Containers: []corev1.Container{
{Name: "c1"},
{Name: "c2"},
},
InitContainers: []corev1.Container{
{Name: "i1"},
{Name: "i2"},
},
EphemeralContainers: []corev1.EphemeralContainer{
{EphemeralContainerCommon: corev1.EphemeralContainerCommon{Name: "e1"}},
{EphemeralContainerCommon: corev1.EphemeralContainerCommon{Name: "e2"}},
},
},
wantContainers: []string{"i1", "i2"},
mask: InitContainers,
},
{
desc: "ephemeral containers",
spec: &corev1.PodSpec{
Containers: []corev1.Container{
{Name: "c1"},
{Name: "c2"},
},
InitContainers: []corev1.Container{
{Name: "i1"},
{Name: "i2"},
},
EphemeralContainers: []corev1.EphemeralContainer{
{EphemeralContainerCommon: corev1.EphemeralContainerCommon{Name: "e1"}},
{EphemeralContainerCommon: corev1.EphemeralContainerCommon{Name: "e2"}},
},
},
wantContainers: []string{"e1", "e2"},
mask: EphemeralContainers,
},
{
desc: "all container types",
spec: &corev1.PodSpec{
Containers: []corev1.Container{
{Name: "c1"},
{Name: "c2"},
},
InitContainers: []corev1.Container{
{Name: "i1"},
{Name: "i2"},
},
EphemeralContainers: []corev1.EphemeralContainer{
{EphemeralContainerCommon: corev1.EphemeralContainerCommon{Name: "e1"}},
{EphemeralContainerCommon: corev1.EphemeralContainerCommon{Name: "e2"}},
},
},
wantContainers: []string{"i1", "i2", "c1", "c2", "e1", "e2"},
mask: AllContainers,
},
{
desc: "all feature enabled container types with ephemeral containers disabled",
spec: &corev1.PodSpec{
Containers: []corev1.Container{
{Name: "c1"},
{Name: "c2"},
},
InitContainers: []corev1.Container{
{Name: "i1"},
{Name: "i2"},
},
EphemeralContainers: []corev1.EphemeralContainer{
{EphemeralContainerCommon: corev1.EphemeralContainerCommon{Name: "e1"}},
{EphemeralContainerCommon: corev1.EphemeralContainerCommon{Name: "e2"}},
},
},
wantContainers: []string{"i1", "i2", "c1", "c2"},
mask: setAllFeatureEnabledContainersDuringTest,
},
{
desc: "all feature enabled container types with ephemeral containers enabled",
spec: &corev1.PodSpec{
Containers: []corev1.Container{
{Name: "c1"},
{Name: "c2", SecurityContext: &corev1.SecurityContext{}},
},
InitContainers: []corev1.Container{
{Name: "i1"},
{Name: "i2", SecurityContext: &corev1.SecurityContext{}},
},
EphemeralContainers: []corev1.EphemeralContainer{
{EphemeralContainerCommon: corev1.EphemeralContainerCommon{Name: "e1"}},
{EphemeralContainerCommon: corev1.EphemeralContainerCommon{Name: "e2"}},
},
},
wantContainers: []string{"i1", "i2", "c1", "c2", "e1", "e2"},
mask: setAllFeatureEnabledContainersDuringTest,
ephemeralContainersEnabled: true,
},
{
desc: "dropping fields",
spec: &corev1.PodSpec{
Containers: []corev1.Container{
{Name: "c1"},
{Name: "c2", SecurityContext: &corev1.SecurityContext{}},
},
InitContainers: []corev1.Container{
{Name: "i1"},
{Name: "i2", SecurityContext: &corev1.SecurityContext{}},
},
EphemeralContainers: []corev1.EphemeralContainer{
{EphemeralContainerCommon: corev1.EphemeralContainerCommon{Name: "e1"}},
{EphemeralContainerCommon: corev1.EphemeralContainerCommon{Name: "e2", SecurityContext: &corev1.SecurityContext{}}},
},
},
wantContainers: []string{"i1", "i2", "c1", "c2", "e1", "e2"},
mask: AllContainers,
},
}
for _, tc := range testCases {
t.Run(tc.desc, func(t *testing.T) {
defer SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, EphemeralContainersFeature, tc.ephemeralContainersEnabled)()
if tc.mask == setAllFeatureEnabledContainersDuringTest {
tc.mask = AllFeatureEnabledContainers()
}
gotContainers := []string{}
VisitContainers(tc.spec, tc.mask, func(c *corev1.Container, containerType ContainerType) bool {
gotContainers = append(gotContainers, c.Name)
if c.SecurityContext != nil {
c.SecurityContext = nil
}
return true
})
if !cmp.Equal(gotContainers, tc.wantContainers) {
t.Errorf("VisitContainers() = %+v, want %+v", gotContainers, tc.wantContainers)
}
for _, c := range tc.spec.Containers {
if c.SecurityContext != nil {
t.Errorf("VisitContainers() did not drop SecurityContext for container %q", c.Name)
}
}
for _, c := range tc.spec.InitContainers {
if c.SecurityContext != nil {
t.Errorf("VisitContainers() did not drop SecurityContext for init container %q", c.Name)
}
}
for _, c := range tc.spec.EphemeralContainers {
if c.SecurityContext != nil {
t.Errorf("VisitContainers() did not drop SecurityContext for ephemeral container %q", c.Name)
}
}
})
}
}
// +lifted:source=https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/api/v1/pod/util_test.go#L394-L551
// +lifted:changed
func TestPodSecrets(t *testing.T) {
defer SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, EphemeralContainersFeature, true)()
// Stub containing all possible secret references in a pod.
// The names of the referenced secrets match struct paths detected by reflection.
pod := &corev1.Pod{
Spec: corev1.PodSpec{
Containers: []corev1.Container{{
EnvFrom: []corev1.EnvFromSource{{
SecretRef: &corev1.SecretEnvSource{
LocalObjectReference: corev1.LocalObjectReference{
Name: "Spec.Containers[*].EnvFrom[*].SecretRef"}}}},
Env: []corev1.EnvVar{{
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
LocalObjectReference: corev1.LocalObjectReference{
Name: "Spec.Containers[*].Env[*].ValueFrom.SecretKeyRef"}}}}}}},
ImagePullSecrets: []corev1.LocalObjectReference{{
Name: "Spec.ImagePullSecrets"}},
InitContainers: []corev1.Container{{
EnvFrom: []corev1.EnvFromSource{{
SecretRef: &corev1.SecretEnvSource{
LocalObjectReference: corev1.LocalObjectReference{
Name: "Spec.InitContainers[*].EnvFrom[*].SecretRef"}}}},
Env: []corev1.EnvVar{{
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
LocalObjectReference: corev1.LocalObjectReference{
Name: "Spec.InitContainers[*].Env[*].ValueFrom.SecretKeyRef"}}}}}}},
Volumes: []corev1.Volume{{
VolumeSource: corev1.VolumeSource{
AzureFile: &corev1.AzureFileVolumeSource{
SecretName: "Spec.Volumes[*].VolumeSource.AzureFile.SecretName"}}}, {
VolumeSource: corev1.VolumeSource{
CephFS: &corev1.CephFSVolumeSource{
SecretRef: &corev1.LocalObjectReference{
Name: "Spec.Volumes[*].VolumeSource.CephFS.SecretRef"}}}}, {
VolumeSource: corev1.VolumeSource{
Cinder: &corev1.CinderVolumeSource{
SecretRef: &corev1.LocalObjectReference{
Name: "Spec.Volumes[*].VolumeSource.Cinder.SecretRef"}}}}, {
VolumeSource: corev1.VolumeSource{
FlexVolume: &corev1.FlexVolumeSource{
SecretRef: &corev1.LocalObjectReference{
Name: "Spec.Volumes[*].VolumeSource.FlexVolume.SecretRef"}}}}, {
VolumeSource: corev1.VolumeSource{
Projected: &corev1.ProjectedVolumeSource{
Sources: []corev1.VolumeProjection{{
Secret: &corev1.SecretProjection{
LocalObjectReference: corev1.LocalObjectReference{
Name: "Spec.Volumes[*].VolumeSource.Projected.Sources[*].Secret"}}}}}}}, {
VolumeSource: corev1.VolumeSource{
RBD: &corev1.RBDVolumeSource{
SecretRef: &corev1.LocalObjectReference{
Name: "Spec.Volumes[*].VolumeSource.RBD.SecretRef"}}}}, {
VolumeSource: corev1.VolumeSource{
Secret: &corev1.SecretVolumeSource{
SecretName: "Spec.Volumes[*].VolumeSource.Secret.SecretName"}}}, {
VolumeSource: corev1.VolumeSource{
Secret: &corev1.SecretVolumeSource{
SecretName: "Spec.Volumes[*].VolumeSource.Secret"}}}, {
VolumeSource: corev1.VolumeSource{
ScaleIO: &corev1.ScaleIOVolumeSource{
SecretRef: &corev1.LocalObjectReference{
Name: "Spec.Volumes[*].VolumeSource.ScaleIO.SecretRef"}}}}, {
VolumeSource: corev1.VolumeSource{
ISCSI: &corev1.ISCSIVolumeSource{
SecretRef: &corev1.LocalObjectReference{
Name: "Spec.Volumes[*].VolumeSource.ISCSI.SecretRef"}}}}, {
VolumeSource: corev1.VolumeSource{
StorageOS: &corev1.StorageOSVolumeSource{
SecretRef: &corev1.LocalObjectReference{
Name: "Spec.Volumes[*].VolumeSource.StorageOS.SecretRef"}}}}, {
VolumeSource: corev1.VolumeSource{
CSI: &corev1.CSIVolumeSource{
NodePublishSecretRef: &corev1.LocalObjectReference{
Name: "Spec.Volumes[*].VolumeSource.CSI.NodePublishSecretRef"}}}}},
EphemeralContainers: []corev1.EphemeralContainer{{
EphemeralContainerCommon: corev1.EphemeralContainerCommon{
EnvFrom: []corev1.EnvFromSource{{
SecretRef: &corev1.SecretEnvSource{
LocalObjectReference: corev1.LocalObjectReference{
Name: "Spec.EphemeralContainers[*].EphemeralContainerCommon.EnvFrom[*].SecretRef"}}}},
Env: []corev1.EnvVar{{
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
LocalObjectReference: corev1.LocalObjectReference{
Name: "Spec.EphemeralContainers[*].EphemeralContainerCommon.Env[*].ValueFrom.SecretKeyRef"}}}}}}}},
},
}
extractedNames := sets.NewString()
VisitPodSecretNames(pod, func(name string) bool {
extractedNames.Insert(name)
return true
})
// excludedSecretPaths holds struct paths to fields with "secret" in the name that are not actually references to secret API objects
excludedSecretPaths := sets.NewString(
"Spec.Volumes[*].VolumeSource.CephFS.SecretFile",
)
// expectedSecretPaths holds struct paths to fields with "secret" in the name that are references to secret API objects.
// every path here should be represented as an example in the Pod stub above, with the secret name set to the path.
expectedSecretPaths := sets.NewString(
"Spec.Containers[*].EnvFrom[*].SecretRef",
"Spec.Containers[*].Env[*].ValueFrom.SecretKeyRef",
"Spec.EphemeralContainers[*].EphemeralContainerCommon.EnvFrom[*].SecretRef",
"Spec.EphemeralContainers[*].EphemeralContainerCommon.Env[*].ValueFrom.SecretKeyRef",
"Spec.ImagePullSecrets",
"Spec.InitContainers[*].EnvFrom[*].SecretRef",
"Spec.InitContainers[*].Env[*].ValueFrom.SecretKeyRef",
"Spec.Volumes[*].VolumeSource.AzureFile.SecretName",
"Spec.Volumes[*].VolumeSource.CephFS.SecretRef",
"Spec.Volumes[*].VolumeSource.Cinder.SecretRef",
"Spec.Volumes[*].VolumeSource.FlexVolume.SecretRef",
"Spec.Volumes[*].VolumeSource.Projected.Sources[*].Secret",
"Spec.Volumes[*].VolumeSource.RBD.SecretRef",
"Spec.Volumes[*].VolumeSource.Secret",
"Spec.Volumes[*].VolumeSource.Secret.SecretName",
"Spec.Volumes[*].VolumeSource.ScaleIO.SecretRef",
"Spec.Volumes[*].VolumeSource.ISCSI.SecretRef",
"Spec.Volumes[*].VolumeSource.StorageOS.SecretRef",
"Spec.Volumes[*].VolumeSource.CSI.NodePublishSecretRef",
)
secretPaths := collectResourcePaths(t, "secret", nil, "", reflect.TypeOf(&corev1.Pod{}))
secretPaths = secretPaths.Difference(excludedSecretPaths)
if missingPaths := expectedSecretPaths.Difference(secretPaths); len(missingPaths) > 0 {
t.Logf("Missing expected secret paths:\n%s", strings.Join(missingPaths.List(), "\n"))
t.Error("Missing expected secret paths. Verify VisitPodSecretNames() is correctly finding the missing paths, then correct expectedSecretPaths")
}
if extraPaths := secretPaths.Difference(expectedSecretPaths); len(extraPaths) > 0 {
t.Logf("Extra secret paths:\n%s", strings.Join(extraPaths.List(), "\n"))
t.Error("Extra fields with 'secret' in the name found. Verify VisitPodSecretNames() is including these fields if appropriate, then correct expectedSecretPaths")
}
if missingNames := expectedSecretPaths.Difference(extractedNames); len(missingNames) > 0 {
t.Logf("Missing expected secret names:\n%s", strings.Join(missingNames.List(), "\n"))
t.Error("Missing expected secret names. Verify the pod stub above includes these references, then verify VisitPodSecretNames() is correctly finding the missing names")
}
if extraNames := extractedNames.Difference(expectedSecretPaths); len(extraNames) > 0 {
t.Logf("Extra secret names:\n%s", strings.Join(extraNames.List(), "\n"))
t.Error("Extra secret names extracted. Verify VisitPodSecretNames() is correctly extracting secret names")
}
// emptyPod is a stub containing empty object names
emptyPod := &corev1.Pod{
Spec: corev1.PodSpec{
Containers: []corev1.Container{{
EnvFrom: []corev1.EnvFromSource{{
SecretRef: &corev1.SecretEnvSource{
LocalObjectReference: corev1.LocalObjectReference{
Name: ""}}}}}},
},
}
VisitPodSecretNames(emptyPod, func(name string) bool {
t.Fatalf("expected no empty names collected, got %q", name)
return false
})
}
// +lifted:source=https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/api/v1/pod/util_test.go#L553-L591
// collectResourcePaths traverses the object, computing all the struct paths that lead to fields with resourcename in the name.
func collectResourcePaths(t *testing.T, resourcename string, path *field.Path, name string, tp reflect.Type) sets.String {
resourcename = strings.ToLower(resourcename)
resourcePaths := sets.NewString()
if tp.Kind() == reflect.Pointer {
resourcePaths.Insert(collectResourcePaths(t, resourcename, path, name, tp.Elem()).List()...)
return resourcePaths
}
if strings.Contains(strings.ToLower(name), resourcename) {
resourcePaths.Insert(path.String())
}
switch tp.Kind() {
case reflect.Pointer:
resourcePaths.Insert(collectResourcePaths(t, resourcename, path, name, tp.Elem()).List()...)
case reflect.Struct:
// ObjectMeta is generic and therefore should never have a field with a specific resource's name;
// it contains cycles so it's easiest to just skip it.
if name == "ObjectMeta" {
break
}
for i := 0; i < tp.NumField(); i++ {
field := tp.Field(i)
resourcePaths.Insert(collectResourcePaths(t, resourcename, path.Child(field.Name), field.Name, field.Type).List()...)
}
case reflect.Interface:
t.Errorf("cannot find %s fields in interface{} field %s", resourcename, path.String())
case reflect.Map:
resourcePaths.Insert(collectResourcePaths(t, resourcename, path.Key("*"), "", tp.Elem()).List()...)
case reflect.Slice:
resourcePaths.Insert(collectResourcePaths(t, resourcename, path.Key("*"), "", tp.Elem()).List()...)
default:
// all primitive types
}
return resourcePaths
}
// +lifted:source=https://github.com/kubernetes/kubernetes/blob/release-1.23/pkg/api/v1/pod/util_test.go#L593-L695
// +lifted:changed
func TestPodConfigmaps(t *testing.T) {
defer SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, EphemeralContainersFeature, true)()
// Stub containing all possible ConfigMap references in a pod.
// The names of the referenced ConfigMaps match struct paths detected by reflection.
pod := &corev1.Pod{
Spec: corev1.PodSpec{
Containers: []corev1.Container{{
EnvFrom: []corev1.EnvFromSource{{
ConfigMapRef: &corev1.ConfigMapEnvSource{
LocalObjectReference: corev1.LocalObjectReference{
Name: "Spec.Containers[*].EnvFrom[*].ConfigMapRef"}}}},
Env: []corev1.EnvVar{{
ValueFrom: &corev1.EnvVarSource{
ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
LocalObjectReference: corev1.LocalObjectReference{
Name: "Spec.Containers[*].Env[*].ValueFrom.ConfigMapKeyRef"}}}}}}},
EphemeralContainers: []corev1.EphemeralContainer{{
EphemeralContainerCommon: corev1.EphemeralContainerCommon{
EnvFrom: []corev1.EnvFromSource{{
ConfigMapRef: &corev1.ConfigMapEnvSource{
LocalObjectReference: corev1.LocalObjectReference{
Name: "Spec.EphemeralContainers[*].EphemeralContainerCommon.EnvFrom[*].ConfigMapRef"}}}},
Env: []corev1.EnvVar{{
ValueFrom: &corev1.EnvVarSource{
ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
LocalObjectReference: corev1.LocalObjectReference{
Name: "Spec.EphemeralContainers[*].EphemeralContainerCommon.Env[*].ValueFrom.ConfigMapKeyRef"}}}}}}}},
InitContainers: []corev1.Container{{
EnvFrom: []corev1.EnvFromSource{{
ConfigMapRef: &corev1.ConfigMapEnvSource{
LocalObjectReference: corev1.LocalObjectReference{
Name: "Spec.InitContainers[*].EnvFrom[*].ConfigMapRef"}}}},
Env: []corev1.EnvVar{{
ValueFrom: &corev1.EnvVarSource{
ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
LocalObjectReference: corev1.LocalObjectReference{
Name: "Spec.InitContainers[*].Env[*].ValueFrom.ConfigMapKeyRef"}}}}}}},
Volumes: []corev1.Volume{{
VolumeSource: corev1.VolumeSource{
Projected: &corev1.ProjectedVolumeSource{
Sources: []corev1.VolumeProjection{{
ConfigMap: &corev1.ConfigMapProjection{
LocalObjectReference: corev1.LocalObjectReference{
Name: "Spec.Volumes[*].VolumeSource.Projected.Sources[*].ConfigMap"}}}}}}}, {
VolumeSource: corev1.VolumeSource{
ConfigMap: &corev1.ConfigMapVolumeSource{
LocalObjectReference: corev1.LocalObjectReference{
Name: "Spec.Volumes[*].VolumeSource.ConfigMap"}}}}},
},
}
extractedNames := sets.NewString()
VisitPodConfigmapNames(pod, func(name string) bool {
extractedNames.Insert(name)
return true
})
// expectedPaths holds struct paths to fields with "ConfigMap" in the name that are references to ConfigMap API objects.
// every path here should be represented as an example in the Pod stub above, with the ConfigMap name set to the path.
expectedPaths := sets.NewString(
"Spec.Containers[*].EnvFrom[*].ConfigMapRef",
"Spec.Containers[*].Env[*].ValueFrom.ConfigMapKeyRef",
"Spec.EphemeralContainers[*].EphemeralContainerCommon.EnvFrom[*].ConfigMapRef",
"Spec.EphemeralContainers[*].EphemeralContainerCommon.Env[*].ValueFrom.ConfigMapKeyRef",
"Spec.InitContainers[*].EnvFrom[*].ConfigMapRef",
"Spec.InitContainers[*].Env[*].ValueFrom.ConfigMapKeyRef",
"Spec.Volumes[*].VolumeSource.Projected.Sources[*].ConfigMap",
"Spec.Volumes[*].VolumeSource.ConfigMap",
)
collectPaths := collectResourcePaths(t, "ConfigMap", nil, "", reflect.TypeOf(&corev1.Pod{}))
if missingPaths := expectedPaths.Difference(collectPaths); len(missingPaths) > 0 {
t.Logf("Missing expected paths:\n%s", strings.Join(missingPaths.List(), "\n"))
t.Error("Missing expected paths. Verify VisitPodConfigmapNames() is correctly finding the missing paths, then correct expectedPaths")
}
if extraPaths := collectPaths.Difference(expectedPaths); len(extraPaths) > 0 {
t.Logf("Extra paths:\n%s", strings.Join(extraPaths.List(), "\n"))
t.Error("Extra fields with resource in the name found. Verify VisitPodConfigmapNames() is including these fields if appropriate, then correct expectedPaths")
}
if missingNames := expectedPaths.Difference(extractedNames); len(missingNames) > 0 {
t.Logf("Missing expected names:\n%s", strings.Join(missingNames.List(), "\n"))
t.Error("Missing expected names. Verify the pod stub above includes these references, then verify VisitPodConfigmapNames() is correctly finding the missing names")
}
if extraNames := extractedNames.Difference(expectedPaths); len(extraNames) > 0 {
t.Logf("Extra names:\n%s", strings.Join(extraNames.List(), "\n"))
t.Error("Extra names extracted. Verify VisitPodConfigmapNames() is correctly extracting resource names")
}
// emptyPod is a stub containing empty object names
emptyPod := &corev1.Pod{
Spec: corev1.PodSpec{
Containers: []corev1.Container{{
EnvFrom: []corev1.EnvFromSource{{
ConfigMapRef: &corev1.ConfigMapEnvSource{
LocalObjectReference: corev1.LocalObjectReference{
Name: ""}}}}}},
},
}
VisitPodConfigmapNames(emptyPod, func(name string) bool {
t.Fatalf("expected no empty names collected, got %q", name)
return false
})
}