|
1 | 1 | package managed |
2 | 2 |
|
3 | 3 | import ( |
| 4 | + "context" |
4 | 5 | "fmt" |
5 | 6 | "testing" |
6 | 7 |
|
7 | 8 | v1 "k8s.io/api/core/v1" |
8 | 9 | "k8s.io/apimachinery/pkg/api/resource" |
9 | 10 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" |
| 11 | + runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1" |
10 | 12 | ) |
11 | 13 |
|
12 | 14 | func TestModifyStaticPodForPinnedManagementErrorStates(t *testing.T) { |
@@ -1007,3 +1009,173 @@ func createPod(annotations map[string]string, initContainer, container *v1.Conta |
1007 | 1009 |
|
1008 | 1010 | return pod |
1009 | 1011 | } |
| 1012 | + |
| 1013 | +func TestIsPodSandboxManagedPod(t *testing.T) { |
| 1014 | + testCases := []struct { |
| 1015 | + name string |
| 1016 | + annotations map[string]string |
| 1017 | + expected bool |
| 1018 | + }{ |
| 1019 | + { |
| 1020 | + name: "nil annotations", |
| 1021 | + annotations: nil, |
| 1022 | + expected: false, |
| 1023 | + }, |
| 1024 | + { |
| 1025 | + name: "empty annotations", |
| 1026 | + annotations: map[string]string{}, |
| 1027 | + expected: false, |
| 1028 | + }, |
| 1029 | + { |
| 1030 | + name: "regular pod annotations without workload annotations", |
| 1031 | + annotations: map[string]string{ |
| 1032 | + "some.annotation": "value", |
| 1033 | + "another.annotation": "value2", |
| 1034 | + "io.kubernetes.pod.id": "12345", |
| 1035 | + }, |
| 1036 | + expected: false, |
| 1037 | + }, |
| 1038 | + { |
| 1039 | + name: "managed pod with workload management annotation", |
| 1040 | + annotations: map[string]string{ |
| 1041 | + "some.annotation": "value", |
| 1042 | + WorkloadsAnnotationPrefix + "management": `{"effect": "PreferredDuringScheduling"}`, |
| 1043 | + }, |
| 1044 | + expected: true, |
| 1045 | + }, |
| 1046 | + { |
| 1047 | + name: "managed pod with workload throttle annotation", |
| 1048 | + annotations: map[string]string{ |
| 1049 | + WorkloadsAnnotationPrefix + "throttle": `{"effect": "PreferredDuringScheduling"}`, |
| 1050 | + }, |
| 1051 | + expected: true, |
| 1052 | + }, |
| 1053 | + { |
| 1054 | + name: "pod with annotation similar to workload prefix but not matching", |
| 1055 | + annotations: map[string]string{ |
| 1056 | + "target.workload.openshift.io": "value", // missing trailing slash |
| 1057 | + "some.other.annotation": "value2", |
| 1058 | + }, |
| 1059 | + expected: false, |
| 1060 | + }, |
| 1061 | + { |
| 1062 | + name: "managed pod with multiple annotations", |
| 1063 | + annotations: map[string]string{ |
| 1064 | + "io.kubernetes.pod.name": "test-pod", |
| 1065 | + "io.kubernetes.pod.namespace": "default", |
| 1066 | + WorkloadsAnnotationPrefix + "management": `{"effect": "PreferredDuringScheduling"}`, |
| 1067 | + "custom.annotation": "custom-value", |
| 1068 | + }, |
| 1069 | + expected: true, |
| 1070 | + }, |
| 1071 | + } |
| 1072 | + |
| 1073 | + for _, tc := range testCases { |
| 1074 | + t.Run(tc.name, func(t *testing.T) { |
| 1075 | + result := IsPodSandboxManagedPod(tc.annotations) |
| 1076 | + if result != tc.expected { |
| 1077 | + t.Errorf("IsPodSandboxManagedPod() = %v, expected %v for annotations: %v", |
| 1078 | + result, tc.expected, tc.annotations) |
| 1079 | + } |
| 1080 | + }) |
| 1081 | + } |
| 1082 | +} |
| 1083 | + |
| 1084 | +// mockRuntimeService is a simple mock for testing |
| 1085 | +type mockRuntimeService struct { |
| 1086 | + sandboxStatus *runtimeapi.PodSandboxStatusResponse |
| 1087 | + err error |
| 1088 | +} |
| 1089 | + |
| 1090 | +func (m *mockRuntimeService) PodSandboxStatus(ctx context.Context, podSandboxID string, verbose bool) (*runtimeapi.PodSandboxStatusResponse, error) { |
| 1091 | + return m.sandboxStatus, m.err |
| 1092 | +} |
| 1093 | + |
| 1094 | +func TestIsManagedPodFromRuntimeService(t *testing.T) { |
| 1095 | + ctx := context.Background() |
| 1096 | + |
| 1097 | + testCases := []struct { |
| 1098 | + name string |
| 1099 | + podSandboxID string |
| 1100 | + sandboxStatus *runtimeapi.PodSandboxStatusResponse |
| 1101 | + err error |
| 1102 | + expected bool |
| 1103 | + }{ |
| 1104 | + { |
| 1105 | + name: "empty sandbox ID", |
| 1106 | + podSandboxID: "", |
| 1107 | + expected: false, |
| 1108 | + }, |
| 1109 | + { |
| 1110 | + name: "runtime service returns error", |
| 1111 | + podSandboxID: "sandbox123", |
| 1112 | + err: fmt.Errorf("runtime error"), |
| 1113 | + expected: false, |
| 1114 | + }, |
| 1115 | + { |
| 1116 | + name: "nil sandbox response", |
| 1117 | + podSandboxID: "sandbox123", |
| 1118 | + sandboxStatus: nil, |
| 1119 | + expected: false, |
| 1120 | + }, |
| 1121 | + { |
| 1122 | + name: "nil status in response", |
| 1123 | + podSandboxID: "sandbox123", |
| 1124 | + sandboxStatus: &runtimeapi.PodSandboxStatusResponse{ |
| 1125 | + Status: nil, |
| 1126 | + }, |
| 1127 | + expected: false, |
| 1128 | + }, |
| 1129 | + { |
| 1130 | + name: "regular pod without workload annotations", |
| 1131 | + podSandboxID: "sandbox123", |
| 1132 | + sandboxStatus: &runtimeapi.PodSandboxStatusResponse{ |
| 1133 | + Status: &runtimeapi.PodSandboxStatus{ |
| 1134 | + Annotations: map[string]string{ |
| 1135 | + "some.annotation": "value", |
| 1136 | + }, |
| 1137 | + }, |
| 1138 | + }, |
| 1139 | + expected: false, |
| 1140 | + }, |
| 1141 | + { |
| 1142 | + name: "managed pod with workload annotations", |
| 1143 | + podSandboxID: "sandbox123", |
| 1144 | + sandboxStatus: &runtimeapi.PodSandboxStatusResponse{ |
| 1145 | + Status: &runtimeapi.PodSandboxStatus{ |
| 1146 | + Annotations: map[string]string{ |
| 1147 | + "some.annotation": "value", |
| 1148 | + WorkloadsAnnotationPrefix + "management": `{"effect": "PreferredDuringScheduling"}`, |
| 1149 | + }, |
| 1150 | + }, |
| 1151 | + }, |
| 1152 | + expected: true, |
| 1153 | + }, |
| 1154 | + { |
| 1155 | + name: "managed pod with empty annotations but has workload prefix", |
| 1156 | + podSandboxID: "sandbox123", |
| 1157 | + sandboxStatus: &runtimeapi.PodSandboxStatusResponse{ |
| 1158 | + Status: &runtimeapi.PodSandboxStatus{ |
| 1159 | + Annotations: map[string]string{ |
| 1160 | + WorkloadsAnnotationPrefix + "throttle": "", |
| 1161 | + }, |
| 1162 | + }, |
| 1163 | + }, |
| 1164 | + expected: true, |
| 1165 | + }, |
| 1166 | + } |
| 1167 | + |
| 1168 | + for _, tc := range testCases { |
| 1169 | + t.Run(tc.name, func(t *testing.T) { |
| 1170 | + mockService := &mockRuntimeService{ |
| 1171 | + sandboxStatus: tc.sandboxStatus, |
| 1172 | + err: tc.err, |
| 1173 | + } |
| 1174 | + |
| 1175 | + result := IsManagedPodFromRuntimeService(ctx, mockService, tc.podSandboxID) |
| 1176 | + if result != tc.expected { |
| 1177 | + t.Errorf("IsManagedPodFromRuntimeService() = %v, expected %v", result, tc.expected) |
| 1178 | + } |
| 1179 | + }) |
| 1180 | + } |
| 1181 | +} |
0 commit comments