Skip to content

Commit 3b2a4fb

Browse files
committed
test: add missing tests for StatefulSet with VolumeClaimTemplates for SSABasedGenericKubernetesResourceMatcher
Signed-off-by: David Sondermann <[email protected]>
1 parent e380488 commit 3b2a4fb

10 files changed

+379
-25
lines changed

operator-framework-core/pom.xml

+5
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,11 @@
5454
<artifactId>junit-jupiter-engine</artifactId>
5555
<scope>test</scope>
5656
</dependency>
57+
<dependency>
58+
<groupId>org.junit.jupiter</groupId>
59+
<artifactId>junit-jupiter-params</artifactId>
60+
<scope>test</scope>
61+
</dependency>
5762
<dependency>
5863
<groupId>org.mockito</groupId>
5964
<artifactId>mockito-core</artifactId>

operator-framework-core/src/test/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/SSABasedGenericKubernetesResourceMatcherTest.java

+52-25
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
package io.javaoperatorsdk.operator.processing.dependent.kubernetes;
22

3-
import java.util.Arrays;
43
import java.util.HashMap;
54
import java.util.List;
65
import java.util.Map;
76

87
import org.junit.jupiter.api.BeforeEach;
98
import org.junit.jupiter.api.Test;
9+
import org.junit.jupiter.params.ParameterizedTest;
10+
import org.junit.jupiter.params.provider.ValueSource;
1011

1112
import io.fabric8.kubernetes.api.model.ConfigMap;
1213
import io.fabric8.kubernetes.api.model.HasMetadata;
1314
import io.fabric8.kubernetes.api.model.apps.Deployment;
15+
import io.fabric8.kubernetes.api.model.apps.StatefulSet;
1416
import io.javaoperatorsdk.operator.MockKubernetesClient;
1517
import io.javaoperatorsdk.operator.ReconcilerUtils;
1618
import io.javaoperatorsdk.operator.api.config.ConfigurationService;
@@ -23,22 +25,21 @@
2325

2426
class SSABasedGenericKubernetesResourceMatcherTest {
2527

26-
Context<?> mockedContext = mock(Context.class);
28+
private final Context<?> mockedContext = mock();
2729

28-
SSABasedGenericKubernetesResourceMatcher<HasMetadata> matcher =
29-
new SSABasedGenericKubernetesResourceMatcher<>();
30+
private final SSABasedGenericKubernetesResourceMatcher<HasMetadata> matcher =
31+
SSABasedGenericKubernetesResourceMatcher.getInstance();
3032

3133
@BeforeEach
3234
@SuppressWarnings("unchecked")
3335
void setup() {
34-
var controllerConfiguration = mock(ControllerConfiguration.class);
35-
when(controllerConfiguration.fieldManager()).thenReturn("controller");
36-
var configurationService = mock(ConfigurationService.class);
37-
3836
final var client = MockKubernetesClient.client(HasMetadata.class);
3937
when(mockedContext.getClient()).thenReturn(client);
4038

39+
final var configurationService = mock(ConfigurationService.class);
40+
final var controllerConfiguration = mock(ControllerConfiguration.class);
4141
when(controllerConfiguration.getConfigurationService()).thenReturn(configurationService);
42+
when(controllerConfiguration.fieldManager()).thenReturn("controller");
4243
when(mockedContext.getControllerConfiguration()).thenReturn(controllerConfiguration);
4344
}
4445

@@ -119,52 +120,78 @@ void addedLabelInDesiredMakesMatchFail() {
119120
assertThat(matcher.matches(actualConfigMap, desiredConfigMap, mockedContext)).isFalse();
120121
}
121122

122-
private <R> R loadResource(String fileName, Class<R> clazz) {
123-
return ReconcilerUtils.loadYaml(clazz, SSABasedGenericKubernetesResourceMatcherTest.class,
124-
fileName);
125-
}
126-
127123
@Test
128124
@SuppressWarnings("unchecked")
129125
void sortListItemsTest() {
130-
Map<String, Object> nestedMap1 = new HashMap<>();
126+
var nestedMap1 = new HashMap<String, Object>();
131127
nestedMap1.put("z", 26);
132128
nestedMap1.put("y", 25);
133129

134-
Map<String, Object> nestedMap2 = new HashMap<>();
130+
var nestedMap2 = new HashMap<String, Object>();
135131
nestedMap2.put("b", 26);
136132
nestedMap2.put("c", 25);
137133
nestedMap2.put("a", 24);
138134

139-
List<Object> unsortedListItems = Arrays.asList(1, nestedMap1, nestedMap2);
140-
List<Object> sortedListItems = matcher.sortListItems(unsortedListItems);
141-
135+
var unsortedListItems = List.<Object>of(1, nestedMap1, nestedMap2);
136+
var sortedListItems = matcher.sortListItems(unsortedListItems);
142137
assertThat(sortedListItems).element(0).isEqualTo(1);
143138

144-
Map<String, Object> sortedNestedMap1 = (Map<String, Object>) sortedListItems.get(1);
139+
var sortedNestedMap1 = (Map<String, Object>) sortedListItems.get(1);
145140
assertThat(sortedNestedMap1.keySet()).containsExactly("y", "z");
146141

147-
Map<String, Object> sortedNestedMap2 = (Map<String, Object>) sortedListItems.get(2);
142+
var sortedNestedMap2 = (Map<String, Object>) sortedListItems.get(2);
148143
assertThat(sortedNestedMap2.keySet()).containsExactly("a", "b", "c");
149144
}
150145

151146
@Test
152147
@SuppressWarnings("unchecked")
153148
void testSortMapWithNestedMap() {
154-
Map<String, Object> nestedMap = new HashMap<>();
149+
var nestedMap = new HashMap<String, Object>();
155150
nestedMap.put("z", 26);
156151
nestedMap.put("y", 25);
157152

158-
Map<String, Object> unsortedMap = new HashMap<>();
153+
var unsortedMap = new HashMap<String, Object>();
159154
unsortedMap.put("b", nestedMap);
160155
unsortedMap.put("a", 1);
161156
unsortedMap.put("c", 2);
162157

163-
Map<String, Object> sortedMap = matcher.sortMap(unsortedMap);
164-
158+
var sortedMap = matcher.sortMap(unsortedMap);
165159
assertThat(sortedMap.keySet()).containsExactly("a", "b", "c");
166160

167-
Map<String, Object> sortedNestedMap = (Map<String, Object>) sortedMap.get("b");
161+
var sortedNestedMap = (Map<String, Object>) sortedMap.get("b");
168162
assertThat(sortedNestedMap.keySet()).containsExactly("y", "z");
169163
}
164+
165+
@ParameterizedTest
166+
@ValueSource(strings = {"sample-sts-volumeclaimtemplates-desired.yaml",
167+
"sample-sts-volumeclaimtemplates-desired-with-status.yaml",
168+
"sample-sts-volumeclaimtemplates-desired-with-volumemode.yaml"})
169+
void testSanitizeState_statefulSetWithVolumeClaims(String desiredResourceFileName) {
170+
var desiredStatefulSet = loadResource(desiredResourceFileName, StatefulSet.class);
171+
var actualStatefulSet = loadResource("sample-sts-volumeclaimtemplates.yaml",
172+
StatefulSet.class);
173+
174+
assertThat(matcher.matches(actualStatefulSet, desiredStatefulSet, mockedContext)).isTrue();
175+
}
176+
177+
@ParameterizedTest
178+
@ValueSource(strings = {"sample-sts-volumeclaimtemplates-desired-add.yaml",
179+
"sample-sts-volumeclaimtemplates-desired-update.yaml",
180+
"sample-sts-volumeclaimtemplates-desired-with-status-mismatch.yaml",
181+
"sample-sts-volumeclaimtemplates-desired-with-volumemode-mismatch.yaml"})
182+
void testSanitizeState_statefulSetWithVolumeClaims_withMismatch(String desiredResourceFileName) {
183+
var desiredStatefulSet = loadResource(desiredResourceFileName, StatefulSet.class);
184+
var actualStatefulSet = loadResource("sample-sts-volumeclaimtemplates.yaml",
185+
StatefulSet.class);
186+
187+
assertThat(matcher.matches(actualStatefulSet, desiredStatefulSet, mockedContext)).isFalse();
188+
}
189+
190+
assertThat(matcher.matches(actualStatefulSet, desiredStatefulSet, mockedContext)).isTrue();
191+
}
192+
193+
private static <R> R loadResource(String fileName, Class<R> clazz) {
194+
return ReconcilerUtils.loadYaml(clazz, SSABasedGenericKubernetesResourceMatcherTest.class,
195+
fileName);
196+
}
170197
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# desired StatefulSet with a VolumeClaimTemplate with an additional VolumeClaimTemplate
2+
apiVersion: apps/v1
3+
kind: StatefulSet
4+
metadata:
5+
name: "test"
6+
spec:
7+
replicas: 1
8+
selector:
9+
matchLabels:
10+
app: test-app
11+
serviceName: "nginx-service"
12+
template:
13+
metadata:
14+
labels:
15+
app: test-app
16+
spec:
17+
containers:
18+
- name: nginx
19+
image: nginx:1.17.0
20+
ports:
21+
- containerPort: 80
22+
volumeMounts:
23+
- name: persistent-storage
24+
mountPath: /usr/share/nginx/html
25+
volumeClaimTemplates:
26+
- metadata:
27+
name: persistent-storage
28+
spec:
29+
accessModes:
30+
- ReadWriteOnce
31+
resources:
32+
requests:
33+
storage: 1Gi
34+
storageClassName: standard
35+
- metadata:
36+
name: persistent-storage-new
37+
spec:
38+
accessModes:
39+
- ReadWriteOnce
40+
resources:
41+
requests:
42+
storage: 10Gi
43+
storageClassName: standard
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# desired StatefulSet with a VolumeClaimTemplate with an updated VolumeClaimTemplate
2+
apiVersion: apps/v1
3+
kind: StatefulSet
4+
metadata:
5+
name: "test"
6+
spec:
7+
replicas: 1
8+
selector:
9+
matchLabels:
10+
app: test-app
11+
serviceName: "nginx-service"
12+
template:
13+
metadata:
14+
labels:
15+
app: test-app
16+
spec:
17+
containers:
18+
- name: nginx
19+
image: nginx:1.17.0
20+
ports:
21+
- containerPort: 80
22+
volumeMounts:
23+
- name: persistent-storage
24+
mountPath: /usr/share/nginx/html
25+
volumeClaimTemplates:
26+
- metadata:
27+
name: persistent-storage
28+
spec:
29+
accessModes:
30+
- ReadWriteOnce
31+
resources:
32+
requests:
33+
storage: 2Gi
34+
storageClassName: standard
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# desired StatefulSet with a VolumeClaimTemplate with a mismatching spec.volumeClaimTemplates.spec.status
2+
apiVersion: apps/v1
3+
kind: StatefulSet
4+
metadata:
5+
name: "test"
6+
spec:
7+
replicas: 1
8+
selector:
9+
matchLabels:
10+
app: test-app
11+
serviceName: "nginx-service"
12+
template:
13+
metadata:
14+
labels:
15+
app: test-app
16+
spec:
17+
containers:
18+
- name: nginx
19+
image: nginx:1.17.0
20+
ports:
21+
- containerPort: 80
22+
volumeMounts:
23+
- name: persistent-storage
24+
mountPath: /usr/share/nginx/html
25+
volumeClaimTemplates:
26+
- metadata:
27+
name: persistent-storage
28+
spec:
29+
accessModes:
30+
- ReadWriteOnce
31+
resources:
32+
requests:
33+
storage: 1Gi
34+
storageClassName: standard
35+
status:
36+
phase: Bound
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# desired StatefulSet with a VolumeClaimTemplate with a matching spec.volumeClaimTemplates.spec.status
2+
apiVersion: apps/v1
3+
kind: StatefulSet
4+
metadata:
5+
name: "test"
6+
spec:
7+
replicas: 1
8+
selector:
9+
matchLabels:
10+
app: test-app
11+
serviceName: "nginx-service"
12+
template:
13+
metadata:
14+
labels:
15+
app: test-app
16+
spec:
17+
containers:
18+
- name: nginx
19+
image: nginx:1.17.0
20+
ports:
21+
- containerPort: 80
22+
volumeMounts:
23+
- name: persistent-storage
24+
mountPath: /usr/share/nginx/html
25+
volumeClaimTemplates:
26+
- metadata:
27+
name: persistent-storage
28+
spec:
29+
accessModes:
30+
- ReadWriteOnce
31+
resources:
32+
requests:
33+
storage: 1Gi
34+
storageClassName: standard
35+
status:
36+
phase: Pending
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# desired StatefulSet with a VolumeClaimTemplate with a mismatching spec.volumeClaimTemplates.spec.volumeMode
2+
apiVersion: apps/v1
3+
kind: StatefulSet
4+
metadata:
5+
name: "test"
6+
spec:
7+
replicas: 1
8+
selector:
9+
matchLabels:
10+
app: test-app
11+
serviceName: "nginx-service"
12+
template:
13+
metadata:
14+
labels:
15+
app: test-app
16+
spec:
17+
containers:
18+
- name: nginx
19+
image: nginx:1.17.0
20+
ports:
21+
- containerPort: 80
22+
volumeMounts:
23+
- name: persistent-storage
24+
mountPath: /usr/share/nginx/html
25+
volumeClaimTemplates:
26+
- metadata:
27+
name: persistent-storage
28+
spec:
29+
accessModes:
30+
- ReadWriteOnce
31+
resources:
32+
requests:
33+
storage: 1Gi
34+
storageClassName: standard
35+
volumeMode: Block
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# desired StatefulSet with a VolumeClaimTemplate with a matching spec.volumeClaimTemplates.spec.volumeMode
2+
apiVersion: apps/v1
3+
kind: StatefulSet
4+
metadata:
5+
name: "test"
6+
spec:
7+
replicas: 1
8+
selector:
9+
matchLabels:
10+
app: test-app
11+
serviceName: "nginx-service"
12+
template:
13+
metadata:
14+
labels:
15+
app: test-app
16+
spec:
17+
containers:
18+
- name: nginx
19+
image: nginx:1.17.0
20+
ports:
21+
- containerPort: 80
22+
volumeMounts:
23+
- name: persistent-storage
24+
mountPath: /usr/share/nginx/html
25+
volumeClaimTemplates:
26+
- metadata:
27+
name: persistent-storage
28+
spec:
29+
accessModes:
30+
- ReadWriteOnce
31+
resources:
32+
requests:
33+
storage: 1Gi
34+
storageClassName: standard
35+
volumeMode: Filesystem

0 commit comments

Comments
 (0)