Merge pull request #5898 from anujagrawal699/addedTests-pkg/estimator/server/replica/replica.go
Added unit tests for the replica package in the estimator server
This commit is contained in:
commit
f72a312d14
|
@ -0,0 +1,580 @@
|
||||||
|
/*
|
||||||
|
Copyright 2024 The Karmada 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package replica
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
appsv1 "k8s.io/api/apps/v1"
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
|
"k8s.io/apimachinery/pkg/labels"
|
||||||
|
listappsv1 "k8s.io/client-go/listers/apps/v1"
|
||||||
|
listcorev1 "k8s.io/client-go/listers/core/v1"
|
||||||
|
"k8s.io/utils/ptr"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGetUnschedulablePodsOfWorkload(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
workload *unstructured.Unstructured
|
||||||
|
threshold time.Duration
|
||||||
|
pods []*corev1.Pod
|
||||||
|
replicaSets []*appsv1.ReplicaSet
|
||||||
|
expected int32
|
||||||
|
expectError bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "deployment with no unschedulable pods",
|
||||||
|
// Create a deployment with a single pod that is properly scheduled
|
||||||
|
workload: &unstructured.Unstructured{
|
||||||
|
Object: map[string]interface{}{
|
||||||
|
"apiVersion": "apps/v1",
|
||||||
|
"kind": "Deployment",
|
||||||
|
"metadata": map[string]interface{}{
|
||||||
|
"name": "test-deployment",
|
||||||
|
"namespace": "default",
|
||||||
|
"uid": "test-deployment-uid",
|
||||||
|
},
|
||||||
|
"spec": map[string]interface{}{
|
||||||
|
"selector": map[string]interface{}{
|
||||||
|
"matchLabels": map[string]interface{}{
|
||||||
|
"app": "test",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"template": map[string]interface{}{
|
||||||
|
"metadata": map[string]interface{}{
|
||||||
|
"labels": map[string]interface{}{
|
||||||
|
"app": "test",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
threshold: 5 * time.Minute,
|
||||||
|
// Pod is running and scheduled
|
||||||
|
pods: []*corev1.Pod{
|
||||||
|
{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "test-pod-1",
|
||||||
|
Namespace: "default",
|
||||||
|
Labels: map[string]string{
|
||||||
|
"app": "test",
|
||||||
|
"pod-template-hash": "xyz123",
|
||||||
|
},
|
||||||
|
OwnerReferences: []metav1.OwnerReference{
|
||||||
|
{
|
||||||
|
APIVersion: "apps/v1",
|
||||||
|
Kind: "ReplicaSet",
|
||||||
|
Name: "test-rs",
|
||||||
|
UID: "test-rs-uid",
|
||||||
|
Controller: ptr.To[bool](true),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Status: corev1.PodStatus{
|
||||||
|
Phase: corev1.PodRunning,
|
||||||
|
Conditions: []corev1.PodCondition{
|
||||||
|
{
|
||||||
|
Type: corev1.PodScheduled,
|
||||||
|
Status: corev1.ConditionTrue,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// ReplicaSet that owns the pod and is owned by deployment
|
||||||
|
replicaSets: []*appsv1.ReplicaSet{
|
||||||
|
{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "test-rs",
|
||||||
|
Namespace: "default",
|
||||||
|
UID: "test-rs-uid",
|
||||||
|
Labels: map[string]string{
|
||||||
|
"app": "test",
|
||||||
|
"pod-template-hash": "xyz123",
|
||||||
|
},
|
||||||
|
OwnerReferences: []metav1.OwnerReference{
|
||||||
|
{
|
||||||
|
APIVersion: "apps/v1",
|
||||||
|
Kind: "Deployment",
|
||||||
|
Name: "test-deployment",
|
||||||
|
UID: "test-deployment-uid",
|
||||||
|
Controller: ptr.To[bool](true),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Spec: appsv1.ReplicaSetSpec{
|
||||||
|
Selector: &metav1.LabelSelector{
|
||||||
|
MatchLabels: map[string]string{
|
||||||
|
"app": "test",
|
||||||
|
"pod-template-hash": "xyz123",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Template: corev1.PodTemplateSpec{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Labels: map[string]string{
|
||||||
|
"app": "test",
|
||||||
|
"pod-template-hash": "xyz123",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: 0,
|
||||||
|
expectError: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "deployment with unschedulable pods beyond threshold",
|
||||||
|
// Create a deployment with a single unschedulable pod
|
||||||
|
workload: &unstructured.Unstructured{
|
||||||
|
Object: map[string]interface{}{
|
||||||
|
"apiVersion": "apps/v1",
|
||||||
|
"kind": "Deployment",
|
||||||
|
"metadata": map[string]interface{}{
|
||||||
|
"name": "test-deployment",
|
||||||
|
"namespace": "default",
|
||||||
|
"uid": "test-deployment-uid",
|
||||||
|
},
|
||||||
|
"spec": map[string]interface{}{
|
||||||
|
"selector": map[string]interface{}{
|
||||||
|
"matchLabels": map[string]interface{}{
|
||||||
|
"app": "test",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"template": map[string]interface{}{
|
||||||
|
"metadata": map[string]interface{}{
|
||||||
|
"labels": map[string]interface{}{
|
||||||
|
"app": "test",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
threshold: 5 * time.Minute,
|
||||||
|
// Pod is pending and unschedulable for longer than threshold
|
||||||
|
pods: []*corev1.Pod{
|
||||||
|
{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "test-pod-1",
|
||||||
|
Namespace: "default",
|
||||||
|
Labels: map[string]string{
|
||||||
|
"app": "test",
|
||||||
|
"pod-template-hash": "xyz123",
|
||||||
|
},
|
||||||
|
OwnerReferences: []metav1.OwnerReference{
|
||||||
|
{
|
||||||
|
APIVersion: "apps/v1",
|
||||||
|
Kind: "ReplicaSet",
|
||||||
|
Name: "test-rs",
|
||||||
|
UID: "test-rs-uid",
|
||||||
|
Controller: ptr.To[bool](true),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Status: corev1.PodStatus{
|
||||||
|
Phase: corev1.PodPending,
|
||||||
|
Conditions: []corev1.PodCondition{
|
||||||
|
{
|
||||||
|
Type: corev1.PodScheduled,
|
||||||
|
Status: corev1.ConditionFalse,
|
||||||
|
Reason: corev1.PodReasonUnschedulable,
|
||||||
|
LastTransitionTime: metav1.Time{Time: time.Now().Add(-10 * time.Minute)},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
replicaSets: []*appsv1.ReplicaSet{
|
||||||
|
{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "test-rs",
|
||||||
|
Namespace: "default",
|
||||||
|
UID: "test-rs-uid",
|
||||||
|
Labels: map[string]string{
|
||||||
|
"app": "test",
|
||||||
|
"pod-template-hash": "xyz123",
|
||||||
|
},
|
||||||
|
OwnerReferences: []metav1.OwnerReference{
|
||||||
|
{
|
||||||
|
APIVersion: "apps/v1",
|
||||||
|
Kind: "Deployment",
|
||||||
|
Name: "test-deployment",
|
||||||
|
UID: "test-deployment-uid",
|
||||||
|
Controller: ptr.To[bool](true),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Spec: appsv1.ReplicaSetSpec{
|
||||||
|
Selector: &metav1.LabelSelector{
|
||||||
|
MatchLabels: map[string]string{
|
||||||
|
"app": "test",
|
||||||
|
"pod-template-hash": "xyz123",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Template: corev1.PodTemplateSpec{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Labels: map[string]string{
|
||||||
|
"app": "test",
|
||||||
|
"pod-template-hash": "xyz123",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: 1,
|
||||||
|
expectError: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "unsupported workload kind",
|
||||||
|
// Create a StatefulSet workload which is not supported
|
||||||
|
workload: &unstructured.Unstructured{
|
||||||
|
Object: map[string]interface{}{
|
||||||
|
"apiVersion": "apps/v1",
|
||||||
|
"kind": "StatefulSet",
|
||||||
|
"metadata": map[string]interface{}{
|
||||||
|
"name": "test-statefulset",
|
||||||
|
"namespace": "default",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
threshold: 5 * time.Minute,
|
||||||
|
expected: 0,
|
||||||
|
expectError: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "deployment with negative threshold",
|
||||||
|
// Testing that negative threshold is handled correctly (should be set to 0)
|
||||||
|
workload: &unstructured.Unstructured{
|
||||||
|
Object: map[string]interface{}{
|
||||||
|
"apiVersion": "apps/v1",
|
||||||
|
"kind": "Deployment",
|
||||||
|
"metadata": map[string]interface{}{
|
||||||
|
"name": "test-deployment",
|
||||||
|
"namespace": "default",
|
||||||
|
"uid": "test-deployment-uid",
|
||||||
|
},
|
||||||
|
"spec": map[string]interface{}{
|
||||||
|
"selector": map[string]interface{}{
|
||||||
|
"matchLabels": map[string]interface{}{
|
||||||
|
"app": "test",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"template": map[string]interface{}{
|
||||||
|
"metadata": map[string]interface{}{
|
||||||
|
"labels": map[string]interface{}{
|
||||||
|
"app": "test",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
threshold: -5 * time.Minute,
|
||||||
|
// Add pods that are unschedulable for different durations
|
||||||
|
pods: []*corev1.Pod{
|
||||||
|
{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "test-pod-1",
|
||||||
|
Namespace: "default",
|
||||||
|
Labels: map[string]string{
|
||||||
|
"app": "test",
|
||||||
|
"pod-template-hash": "xyz123",
|
||||||
|
},
|
||||||
|
OwnerReferences: []metav1.OwnerReference{
|
||||||
|
{
|
||||||
|
APIVersion: "apps/v1",
|
||||||
|
Kind: "ReplicaSet",
|
||||||
|
Name: "test-rs",
|
||||||
|
UID: "test-rs-uid",
|
||||||
|
Controller: ptr.To[bool](true),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Status: corev1.PodStatus{
|
||||||
|
Phase: corev1.PodPending,
|
||||||
|
Conditions: []corev1.PodCondition{
|
||||||
|
{
|
||||||
|
Type: corev1.PodScheduled,
|
||||||
|
Status: corev1.ConditionFalse,
|
||||||
|
Reason: corev1.PodReasonUnschedulable,
|
||||||
|
LastTransitionTime: metav1.Time{Time: time.Now().Add(-1 * time.Second)},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
replicaSets: []*appsv1.ReplicaSet{
|
||||||
|
// Include matching ReplicaSet configuration
|
||||||
|
{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "test-rs",
|
||||||
|
Namespace: "default",
|
||||||
|
UID: "test-rs-uid",
|
||||||
|
Labels: map[string]string{
|
||||||
|
"app": "test",
|
||||||
|
"pod-template-hash": "xyz123",
|
||||||
|
},
|
||||||
|
OwnerReferences: []metav1.OwnerReference{
|
||||||
|
{
|
||||||
|
APIVersion: "apps/v1",
|
||||||
|
Kind: "Deployment",
|
||||||
|
Name: "test-deployment",
|
||||||
|
UID: "test-deployment-uid",
|
||||||
|
Controller: ptr.To[bool](true),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Spec: appsv1.ReplicaSetSpec{
|
||||||
|
Selector: &metav1.LabelSelector{
|
||||||
|
MatchLabels: map[string]string{
|
||||||
|
"app": "test",
|
||||||
|
"pod-template-hash": "xyz123",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Template: corev1.PodTemplateSpec{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Labels: map[string]string{
|
||||||
|
"app": "test",
|
||||||
|
"pod-template-hash": "xyz123",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: 1, // Count as unschedulable since negative threshold becomes 0
|
||||||
|
expectError: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
// Create mock listers with test data
|
||||||
|
podLister := &mockPodLister{
|
||||||
|
pods: map[string][]*corev1.Pod{
|
||||||
|
"default": tt.pods,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
rsLister := &mockReplicaSetLister{
|
||||||
|
replicaSets: map[string][]*appsv1.ReplicaSet{
|
||||||
|
"default": tt.replicaSets,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
listers := &ListerWrapper{
|
||||||
|
PodLister: podLister,
|
||||||
|
ReplicaSetLister: rsLister,
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := GetUnschedulablePodsOfWorkload(tt.workload, tt.threshold, listers)
|
||||||
|
|
||||||
|
if tt.expectError {
|
||||||
|
assert.Error(t, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, tt.expected, result)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPodUnschedulable(t *testing.T) {
|
||||||
|
now := time.Now()
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
pod *corev1.Pod
|
||||||
|
threshold time.Duration
|
||||||
|
expected bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "pod is schedulable",
|
||||||
|
// Test case for a normally scheduled pod
|
||||||
|
pod: &corev1.Pod{
|
||||||
|
Status: corev1.PodStatus{
|
||||||
|
Conditions: []corev1.PodCondition{
|
||||||
|
{
|
||||||
|
Type: corev1.PodScheduled,
|
||||||
|
Status: corev1.ConditionTrue,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
threshold: 5 * time.Minute,
|
||||||
|
expected: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "pod is unschedulable beyond threshold",
|
||||||
|
// Test case for pod that has been unschedulable longer than threshold
|
||||||
|
pod: &corev1.Pod{
|
||||||
|
Status: corev1.PodStatus{
|
||||||
|
Conditions: []corev1.PodCondition{
|
||||||
|
{
|
||||||
|
Type: corev1.PodScheduled,
|
||||||
|
Status: corev1.ConditionFalse,
|
||||||
|
Reason: corev1.PodReasonUnschedulable,
|
||||||
|
LastTransitionTime: metav1.Time{Time: now.Add(-10 * time.Minute)},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
threshold: 5 * time.Minute,
|
||||||
|
expected: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "pod is unschedulable within threshold",
|
||||||
|
// Test case for pod that has been unschedulable less than threshold
|
||||||
|
pod: &corev1.Pod{
|
||||||
|
Status: corev1.PodStatus{
|
||||||
|
Conditions: []corev1.PodCondition{
|
||||||
|
{
|
||||||
|
Type: corev1.PodScheduled,
|
||||||
|
Status: corev1.ConditionFalse,
|
||||||
|
Reason: corev1.PodReasonUnschedulable,
|
||||||
|
LastTransitionTime: metav1.Time{Time: now.Add(-2 * time.Minute)},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
threshold: 5 * time.Minute,
|
||||||
|
expected: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
result := podUnschedulable(tt.pod, tt.threshold)
|
||||||
|
assert.Equal(t, tt.expected, result)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mock implementations of the Kubernetes listers
|
||||||
|
type mockPodLister struct {
|
||||||
|
pods map[string][]*corev1.Pod // namespace -> pods mapping
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockPodLister) List(selector labels.Selector) (ret []*corev1.Pod, err error) {
|
||||||
|
var pods []*corev1.Pod
|
||||||
|
for _, nsPods := range m.pods {
|
||||||
|
for _, pod := range nsPods {
|
||||||
|
if selector == nil || selector.Matches(labels.Set(pod.Labels)) {
|
||||||
|
pods = append(pods, pod)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pods, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockPodLister) Pods(namespace string) listcorev1.PodNamespaceLister {
|
||||||
|
return &mockPodNamespaceLister{
|
||||||
|
pods: m.pods[namespace],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type mockPodNamespaceLister struct {
|
||||||
|
pods []*corev1.Pod
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockPodNamespaceLister) List(selector labels.Selector) (ret []*corev1.Pod, err error) {
|
||||||
|
var result []*corev1.Pod
|
||||||
|
for _, pod := range m.pods {
|
||||||
|
if selector == nil || selector.Matches(labels.Set(pod.Labels)) {
|
||||||
|
result = append(result, pod)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockPodNamespaceLister) Get(name string) (*corev1.Pod, error) {
|
||||||
|
for _, pod := range m.pods {
|
||||||
|
if pod.Name == name {
|
||||||
|
return pod, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type mockReplicaSetLister struct {
|
||||||
|
replicaSets map[string][]*appsv1.ReplicaSet // namespace -> replicasets mapping
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockReplicaSetLister) List(selector labels.Selector) (ret []*appsv1.ReplicaSet, err error) {
|
||||||
|
var replicaSets []*appsv1.ReplicaSet
|
||||||
|
for _, nsRS := range m.replicaSets {
|
||||||
|
for _, rs := range nsRS {
|
||||||
|
if selector == nil || selector.Matches(labels.Set(rs.Labels)) {
|
||||||
|
replicaSets = append(replicaSets, rs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return replicaSets, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockReplicaSetLister) GetPodReplicaSets(pod *corev1.Pod) ([]*appsv1.ReplicaSet, error) {
|
||||||
|
var matchingRS []*appsv1.ReplicaSet
|
||||||
|
for _, rsList := range m.replicaSets {
|
||||||
|
for _, rs := range rsList {
|
||||||
|
if rs.Namespace == pod.Namespace {
|
||||||
|
selector, err := metav1.LabelSelectorAsSelector(rs.Spec.Selector)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if selector.Matches(labels.Set(pod.Labels)) {
|
||||||
|
matchingRS = append(matchingRS, rs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return matchingRS, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockReplicaSetLister) ReplicaSets(namespace string) listappsv1.ReplicaSetNamespaceLister {
|
||||||
|
return &mockReplicaSetNamespaceLister{
|
||||||
|
replicaSets: m.replicaSets[namespace],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type mockReplicaSetNamespaceLister struct {
|
||||||
|
replicaSets []*appsv1.ReplicaSet
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockReplicaSetNamespaceLister) List(selector labels.Selector) (ret []*appsv1.ReplicaSet, err error) {
|
||||||
|
var result []*appsv1.ReplicaSet
|
||||||
|
for _, rs := range m.replicaSets {
|
||||||
|
if selector == nil || selector.Matches(labels.Set(rs.Labels)) {
|
||||||
|
result = append(result, rs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockReplicaSetNamespaceLister) Get(name string) (*appsv1.ReplicaSet, error) {
|
||||||
|
for _, rs := range m.replicaSets {
|
||||||
|
if rs.Name == name {
|
||||||
|
return rs, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, nil
|
||||||
|
}
|
Loading…
Reference in New Issue