|
9 | 9 | import io.fabric8.kubernetes.api.model.HasMetadata;
|
10 | 10 | import io.fabric8.kubernetes.api.model.PodTemplateSpecBuilder;
|
11 | 11 | import io.fabric8.kubernetes.api.model.Quantity;
|
| 12 | +import io.fabric8.kubernetes.api.model.apps.StatefulSet; |
12 | 13 | import io.fabric8.kubernetes.api.model.apps.StatefulSetBuilder;
|
13 | 14 | import io.fabric8.kubernetes.client.KubernetesClient;
|
14 | 15 | import io.fabric8.kubernetes.client.utils.KubernetesSerialization;
|
|
19 | 20 | import static org.mockito.Mockito.mock;
|
20 | 21 | import static org.mockito.Mockito.verifyNoInteractions;
|
21 | 22 |
|
| 23 | +/** |
| 24 | + * Tests the {@link ResourceRequirementsSanitizer} with combinations of matching and mismatching K8s |
| 25 | + * resources, using a mix of containers and init containers, as well as resource requests and |
| 26 | + * limits. |
| 27 | + */ |
22 | 28 | class ResourceRequirementsSanitizerTest {
|
23 | 29 |
|
24 | 30 | private final Map<String, Object> actualMap = mock();
|
@@ -90,110 +96,128 @@ void testSanitizeResourceRequirements_whenResourceIsNull_doNothing() {
|
90 | 96 |
|
91 | 97 | @Test
|
92 | 98 | void testSanitizeResourceRequirements_whenResourceSizeMismatch_doNothing() {
|
93 |
| - final var actualMap = sanitizeRequestsAndLimits( |
| 99 | + final var actualMap = sanitizeRequestsAndLimits(ContainerType.CONTAINER, |
94 | 100 | Map.of("cpu", new Quantity("2")),
|
95 | 101 | Map.of(),
|
96 | 102 | Map.of("cpu", new Quantity("4")),
|
97 | 103 | Map.of("cpu", new Quantity("4"), "memory", new Quantity("4Gi")));
|
98 |
| - assertResources(actualMap, "requests") |
| 104 | + assertContainerResources(actualMap, "requests") |
99 | 105 | .hasSize(1)
|
100 | 106 | .containsEntry("cpu", "2");
|
101 |
| - assertResources(actualMap, "limits") |
| 107 | + assertContainerResources(actualMap, "limits") |
102 | 108 | .hasSize(1)
|
103 | 109 | .containsEntry("cpu", "4");
|
104 | 110 | }
|
105 | 111 |
|
106 | 112 | @Test
|
107 | 113 | void testSanitizeResourceRequirements_whenResourceKeyMismatch_doNothing() {
|
108 |
| - final var actualMap = sanitizeRequestsAndLimits( |
| 114 | + final var actualMap = sanitizeRequestsAndLimits(ContainerType.INIT_CONTAINER, |
109 | 115 | Map.of("cpu", new Quantity("2")),
|
110 | 116 | Map.of("memory", new Quantity("4Gi")),
|
111 | 117 | Map.of(),
|
112 | 118 | Map.of());
|
113 |
| - assertResources(actualMap, "requests") |
| 119 | + assertInitContainerResources(actualMap, "requests") |
114 | 120 | .hasSize(1)
|
115 | 121 | .containsEntry("cpu", "2");
|
116 |
| - assertResources(actualMap, "limits").isNull(); |
| 122 | + assertInitContainerResources(actualMap, "limits").isNull(); |
117 | 123 | }
|
118 | 124 |
|
119 | 125 | @Test
|
120 | 126 | void testSanitizeResourceRequirements_whenResourcesHaveSameAmountAndFormat_doNothing() {
|
121 |
| - final var actualMap = sanitizeRequestsAndLimits( |
| 127 | + final var actualMap = sanitizeRequestsAndLimits(ContainerType.CONTAINER, |
122 | 128 | Map.of("memory", new Quantity("4Gi")),
|
123 | 129 | Map.of("memory", new Quantity("4Gi")),
|
124 | 130 | Map.of("cpu", new Quantity("2")),
|
125 | 131 | Map.of("cpu", new Quantity("2")));
|
126 |
| - assertResources(actualMap, "requests") |
| 132 | + assertContainerResources(actualMap, "requests") |
127 | 133 | .hasSize(1)
|
128 | 134 | .containsEntry("memory", "4Gi");
|
129 |
| - assertResources(actualMap, "limits") |
| 135 | + assertContainerResources(actualMap, "limits") |
130 | 136 | .hasSize(1)
|
131 | 137 | .containsEntry("cpu", "2");
|
132 | 138 | }
|
133 | 139 |
|
134 | 140 | @Test
|
135 | 141 | void testSanitizeResourceRequirements_whenResourcesHaveNumericalAmountMismatch_doNothing() {
|
136 |
| - final var actualMap = sanitizeRequestsAndLimits( |
| 142 | + final var actualMap = sanitizeRequestsAndLimits(ContainerType.INIT_CONTAINER, |
137 | 143 | Map.of("cpu", new Quantity("2"), "memory", new Quantity("4Gi")),
|
138 | 144 | Map.of("cpu", new Quantity("4"), "memory", new Quantity("4Ti")),
|
139 | 145 | Map.of("cpu", new Quantity("2")),
|
140 | 146 | Map.of("cpu", new Quantity("4000m")));
|
141 |
| - assertResources(actualMap, "requests") |
| 147 | + assertInitContainerResources(actualMap, "requests") |
142 | 148 | .hasSize(2)
|
143 | 149 | .containsEntry("cpu", "2")
|
144 | 150 | .containsEntry("memory", "4Gi");
|
145 |
| - assertResources(actualMap, "limits") |
| 151 | + assertInitContainerResources(actualMap, "limits") |
146 | 152 | .hasSize(1)
|
147 | 153 | .containsEntry("cpu", "2");
|
148 | 154 | }
|
149 | 155 |
|
150 | 156 | @Test
|
151 | 157 | void testSanitizeResourceRequirements_whenResourcesHaveAmountAndFormatMismatchWithSameNumericalAmount_thenSanitizeActualMap() {
|
152 |
| - final var actualMap = sanitizeRequestsAndLimits( |
| 158 | + final var actualMap = sanitizeRequestsAndLimits(ContainerType.CONTAINER, |
153 | 159 | Map.of("cpu", new Quantity("2"), "memory", new Quantity("4Gi")),
|
154 | 160 | Map.of("cpu", new Quantity("2000m"), "memory", new Quantity("4096Mi")),
|
155 | 161 | Map.of("cpu", new Quantity("4")),
|
156 | 162 | Map.of("cpu", new Quantity("4000m")));
|
157 |
| - assertResources(actualMap, "requests") |
| 163 | + assertContainerResources(actualMap, "requests") |
158 | 164 | .hasSize(2)
|
159 | 165 | .containsEntry("cpu", "2000m")
|
160 | 166 | .containsEntry("memory", "4096Mi");
|
161 |
| - assertResources(actualMap, "limits") |
| 167 | + assertContainerResources(actualMap, "limits") |
162 | 168 | .hasSize(1)
|
163 | 169 | .containsEntry("cpu", "4000m");
|
164 | 170 | }
|
165 | 171 |
|
166 | 172 | @SuppressWarnings("unchecked")
|
167 |
| - private Map<String, Object> sanitizeRequestsAndLimits( |
| 173 | + private Map<String, Object> sanitizeRequestsAndLimits(final ContainerType type, |
168 | 174 | final Map<String, Quantity> actualRequests, final Map<String, Quantity> desiredRequests,
|
169 | 175 | final Map<String, Quantity> actualLimits, final Map<String, Quantity> desiredLimits) {
|
170 |
| - final var actual = new StatefulSetBuilder().withNewSpec().withNewTemplate().withNewSpec() |
171 |
| - .addNewContainer() |
172 |
| - .withName("test") |
173 |
| - .withNewResources() |
174 |
| - .withRequests(actualRequests).withLimits(actualLimits) |
175 |
| - .endResources() |
176 |
| - .endContainer() |
177 |
| - .endSpec().endTemplate().endSpec().build(); |
178 |
| - final var desired = new StatefulSetBuilder().withNewSpec().withNewTemplate().withNewSpec() |
179 |
| - .addNewContainer() |
180 |
| - .withName("test") |
181 |
| - .withNewResources() |
182 |
| - .withRequests(desiredRequests).withLimits(desiredLimits) |
183 |
| - .endResources() |
184 |
| - .endContainer() |
185 |
| - .endSpec().endTemplate().endSpec().build(); |
186 |
| - |
| 176 | + final var actual = createStatefulSet(type, actualRequests, actualLimits); |
| 177 | + final var desired = createStatefulSet(type, desiredRequests, desiredLimits); |
187 | 178 | final var actualMap = serialization.convertValue(actual, Map.class);
|
188 | 179 | sanitizeResourceRequirements(actualMap,
|
189 | 180 | actual.getSpec().getTemplate(),
|
190 | 181 | desired.getSpec().getTemplate());
|
191 | 182 | return actualMap;
|
192 | 183 | }
|
193 | 184 |
|
194 |
| - private static MapAssert<String, Object> assertResources(final Map<String, Object> actualMap, |
195 |
| - final String resourceName) { |
| 185 | + private enum ContainerType { |
| 186 | + CONTAINER, INIT_CONTAINER, |
| 187 | + } |
| 188 | + |
| 189 | + private static StatefulSet createStatefulSet(final ContainerType type, |
| 190 | + final Map<String, Quantity> requests, final Map<String, Quantity> limits) { |
| 191 | + var builder = new StatefulSetBuilder().withNewSpec().withNewTemplate().withNewSpec(); |
| 192 | + if (type == ContainerType.CONTAINER) { |
| 193 | + builder = builder.addNewContainer() |
| 194 | + .withName("test") |
| 195 | + .withNewResources() |
| 196 | + .withRequests(requests) |
| 197 | + .withLimits(limits) |
| 198 | + .endResources() |
| 199 | + .endContainer(); |
| 200 | + } else { |
| 201 | + builder = builder.addNewInitContainer() |
| 202 | + .withName("test") |
| 203 | + .withNewResources() |
| 204 | + .withRequests(requests) |
| 205 | + .withLimits(limits) |
| 206 | + .endResources() |
| 207 | + .endInitContainer(); |
| 208 | + } |
| 209 | + return builder.endSpec().endTemplate().endSpec().build(); |
| 210 | + } |
| 211 | + |
| 212 | + private static MapAssert<String, Object> assertContainerResources( |
| 213 | + final Map<String, Object> actualMap, final String resourceName) { |
196 | 214 | return assertThat(GenericKubernetesResource.<Map<String, Object>>get(actualMap,
|
197 | 215 | "spec", "template", "spec", "containers", 0, "resources", resourceName));
|
198 | 216 | }
|
| 217 | + |
| 218 | + private static MapAssert<String, Object> assertInitContainerResources( |
| 219 | + final Map<String, Object> actualMap, final String resourceName) { |
| 220 | + return assertThat(GenericKubernetesResource.<Map<String, Object>>get(actualMap, |
| 221 | + "spec", "template", "spec", "initContainers", 0, "resources", resourceName)); |
| 222 | + } |
199 | 223 | }
|
0 commit comments