0
# Kubernetes Server Mock
1
2
Kubernetes Server Mock is a comprehensive JUnit 5 testing library that provides a mock Kubernetes API server for testing Kubernetes client applications. It offers two primary modes of operation: Expectations mode for setting up specific request-response patterns and CRUD mode which provides a fully functional in-memory Kubernetes API that can store, retrieve, update, and delete resources just like a real cluster.
3
4
## Package Information
5
6
- **Package Name**: kubernetes-server-mock
7
- **Package Type**: Maven
8
- **Language**: Java
9
- **Group ID**: io.fabric8
10
- **Artifact ID**: kubernetes-server-mock
11
- **Installation**: Add Maven dependency
12
13
```xml
14
<dependency>
15
<groupId>io.fabric8</groupId>
16
<artifactId>kubernetes-server-mock</artifactId>
17
<version>7.3.1</version>
18
<scope>test</scope>
19
</dependency>
20
```
21
22
## Core Imports
23
24
```java
25
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
26
import io.fabric8.kubernetes.client.server.mock.KubernetesMockServer;
27
import io.fabric8.kubernetes.client.server.mock.KubernetesMockServerExtension;
28
import io.fabric8.kubernetes.client.KubernetesClient;
29
import io.fabric8.kubernetes.client.NamespacedKubernetesClient;
30
```
31
32
## Basic Usage
33
34
### Annotation-Based Setup (Recommended)
35
36
```java
37
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
38
import io.fabric8.kubernetes.client.KubernetesClient;
39
import io.fabric8.kubernetes.client.server.mock.KubernetesMockServer;
40
import org.junit.jupiter.api.Test;
41
42
@EnableKubernetesMockClient
43
class MyKubernetesTest {
44
KubernetesMockServer server;
45
KubernetesClient client;
46
47
@Test
48
void testExpectationsMode() {
49
// Set up expectations
50
server.expect().get()
51
.withPath("/api/v1/namespaces/test/pods/my-pod")
52
.andReturn(200, new PodBuilder().withNewMetadata().withName("my-pod").endMetadata().build())
53
.once();
54
55
// Use client to perform operations
56
Pod pod = client.pods().inNamespace("test").withName("my-pod").get();
57
assertNotNull(pod);
58
}
59
}
60
```
61
62
### CRUD Mode Setup
63
64
```java
65
@EnableKubernetesMockClient(crud = true)
66
class MyCrudTest {
67
KubernetesMockServer server;
68
KubernetesClient client;
69
70
@Test
71
void testCrudMode() {
72
// In CRUD mode, the server acts like a real Kubernetes API
73
Pod pod = new PodBuilder()
74
.withNewMetadata().withName("test-pod").withNamespace("default").endMetadata()
75
.build();
76
77
// Create a pod
78
Pod created = client.pods().inNamespace("default").resource(pod).create();
79
80
// Retrieve the pod
81
Pod retrieved = client.pods().inNamespace("default").withName("test-pod").get();
82
83
assertEquals("test-pod", retrieved.getMetadata().getName());
84
}
85
}
86
```
87
88
### Manual Setup
89
90
```java
91
import io.fabric8.kubernetes.client.server.mock.KubernetesMockServer;
92
93
class ManualSetupTest {
94
@Test
95
void testManualSetup() {
96
KubernetesMockServer server = new KubernetesMockServer();
97
server.init();
98
99
try (KubernetesClient client = server.createClient()) {
100
// Test operations
101
server.expect().get()
102
.withPath("/api/v1/namespaces")
103
.andReturn(200, new NamespaceListBuilder().build())
104
.once();
105
106
NamespaceList namespaces = client.namespaces().list();
107
assertNotNull(namespaces);
108
} finally {
109
server.destroy();
110
}
111
}
112
}
113
```
114
115
## Architecture
116
117
Kubernetes Server Mock is built around several key components:
118
119
- **Mock Server Core**: `KubernetesMockServer` class that provides the main server functionality and client creation
120
- **JUnit 5 Integration**: `KubernetesMockServerExtension` for automatic test lifecycle management
121
- **Dual Operation Modes**: Support for both expectations-based mocking and full CRUD operations
122
- **Dispatcher System**: Pluggable request dispatching for different operational modes
123
- **Custom Resource Support**: Full support for Custom Resource Definitions and Custom Resources
124
- **WebSocket Support**: Real-time watch operations and exec/attach functionality
125
126
## Capabilities
127
128
### Mock Server Management
129
130
Core mock server lifecycle management including initialization, configuration, and client creation. Essential for all testing scenarios.
131
132
```java { .api }
133
public class KubernetesMockServer extends DefaultMockServer
134
implements Resetable, CustomResourceAware {
135
136
public KubernetesMockServer();
137
public KubernetesMockServer(boolean useHttps);
138
139
public void init();
140
public void init(InetAddress address, int port);
141
public void destroy();
142
143
public NamespacedKubernetesClient createClient();
144
public NamespacedKubernetesClient createClient(HttpClient.Factory factory);
145
public NamespacedKubernetesClient createClient(
146
Consumer<KubernetesClientBuilder> kubernetesClientBuilderCustomizer);
147
}
148
```
149
150
[Mock Server Management](./mock-server-management.md)
151
152
### JUnit 5 Integration
153
154
Automatic mock server setup and teardown for JUnit 5 tests with annotation-based configuration. Handles both static and instance field injection.
155
156
```java { .api }
157
@Target({ TYPE, METHOD, ANNOTATION_TYPE })
158
@Retention(RUNTIME)
159
@ExtendWith(KubernetesMockServerExtension.class)
160
public @interface EnableKubernetesMockClient {
161
boolean https() default true;
162
boolean crud() default false;
163
Class<? extends Consumer<KubernetesClientBuilder>> kubernetesClientBuilderCustomizer()
164
default KubernetesClientBuilderCustomizer.class;
165
}
166
167
public class KubernetesMockServerExtension
168
implements AfterEachCallback, AfterAllCallback, BeforeEachCallback, BeforeAllCallback {
169
}
170
```
171
172
[JUnit 5 Integration](./junit-integration.md)
173
174
### CRUD Operations
175
176
Full in-memory Kubernetes API implementation supporting all standard CRUD operations, resource watching, and advanced features like patches and finalizers.
177
178
```java { .api }
179
public class KubernetesCrudDispatcher extends CrudDispatcher
180
implements KubernetesCrudPersistence, CustomResourceAware {
181
182
public KubernetesCrudDispatcher();
183
public KubernetesCrudDispatcher(List<CustomResourceDefinitionContext> crdContexts);
184
185
public MockResponse handleCreate(RecordedRequest request);
186
public MockResponse handleUpdate(RecordedRequest request);
187
public MockResponse handleGet(String path);
188
public MockResponse handlePatch(RecordedRequest request);
189
public MockResponse handleDelete(String path);
190
public MockResponse handleWatch(String path);
191
}
192
```
193
194
[CRUD Operations](./crud-operations.md)
195
196
### CRUD Request Handlers
197
198
Low-level HTTP request handlers that implement individual CRUD operations. These handlers process POST, PUT, and PATCH requests with full Kubernetes compatibility.
199
200
```java { .api }
201
public interface KubernetesCrudDispatcherHandler {
202
MockResponse handle(String path, String contentType, String requestBody)
203
throws KubernetesCrudDispatcherException;
204
205
default void validatePath(AttributeSet query, JsonNode updatedResource);
206
default void validateResourceVersion(JsonNode currentResource, JsonNode updatedResource);
207
default GenericKubernetesResource validateRequestBody(String requestBody);
208
}
209
210
public class PostHandler implements KubernetesCrudDispatcherHandler;
211
public class PutHandler implements KubernetesCrudDispatcherHandler;
212
public class PatchHandler implements KubernetesCrudDispatcherHandler;
213
```
214
215
[CRUD Handlers](./crud-handlers.md)
216
217
### Custom Resource Support
218
219
Support for Custom Resource Definitions and Custom Resources with automatic API discovery and full CRUD operations.
220
221
```java { .api }
222
public interface CustomResourceAware {
223
void expectCustomResource(CustomResourceDefinitionContext rdc);
224
}
225
226
public class CustomResourceDefinitionProcessor {
227
public void addCrdContext(CustomResourceDefinitionContext context);
228
public String getApiResources(String path);
229
public boolean isStatusSubresourceEnabledForResource(AttributeSet pathAttributes);
230
}
231
```
232
233
[Custom Resource Support](./custom-resources.md)
234
235
### WebSocket Operations
236
237
WebSocket-based functionality for watch operations and exec/attach commands with proper stream handling and message formatting.
238
239
```java { .api }
240
public class WatchEventsListener {
241
public void sendWebSocketResponse(String resource, Watcher.Action action);
242
public boolean attributeMatches(AttributeSet attributes);
243
}
244
245
public class OutputStreamMessage extends WebSocketMessage {
246
public OutputStreamMessage(String body);
247
}
248
249
public class ErrorStreamMessage extends WebSocketMessage {
250
public ErrorStreamMessage(String body);
251
}
252
253
public class StatusStreamMessage extends WebSocketMessage {
254
public StatusStreamMessage(String body);
255
}
256
```
257
258
[WebSocket Operations](./websocket-operations.md)
259
260
### Attribute Extraction
261
262
Core functionality for parsing Kubernetes API paths and extracting resource metadata into structured attribute sets. Essential for resource matching, filtering, and categorization.
263
264
```java { .api }
265
public class KubernetesAttributesExtractor implements AttributeExtractor {
266
public static final String KIND = "kind";
267
public static final String API = "api";
268
public static final String VERSION = "version";
269
public static final String NAME = "name";
270
public static final String NAMESPACE = "namespace";
271
public static final String PLURAL = "plural";
272
273
public Map<String, String> fromKubernetesPath(String path);
274
public AttributeSet fromPath(String path);
275
public AttributeSet fromResource(String resourceString);
276
public AttributeSet extract(HasMetadata hasMetadata);
277
}
278
```
279
280
[Attribute Extraction](./attribute-extraction.md)
281
282
## Types
283
284
### Core Interfaces
285
286
```java { .api }
287
public interface Resetable {
288
void reset();
289
}
290
291
public interface CustomResourceAware {
292
void expectCustomResource(CustomResourceDefinitionContext rdc);
293
}
294
295
public interface KubernetesCrudPersistence {
296
long requestResourceVersion();
297
AttributeSet getKey(String path);
298
Map.Entry<AttributeSet, String> findResource(AttributeSet attributes);
299
boolean isStatusSubresourceEnabledForResource(String path);
300
void processEvent(String path, AttributeSet pathAttributes, AttributeSet oldAttributes,
301
GenericKubernetesResource resource, String newState);
302
}
303
```
304
305
### Support Types
306
307
```java { .api }
308
// From mockwebserver library - represents resource attributes for matching
309
public class AttributeSet {
310
// Used internally for resource identification and filtering
311
// Contains key-value pairs extracted from Kubernetes resources
312
}
313
314
// From kubernetes-client library - generic Kubernetes resource representation
315
public class GenericKubernetesResource {
316
// Represents any Kubernetes resource as a generic object
317
// Used for custom resources and dynamic resource handling
318
}
319
320
// From kubernetes-client library - custom resource definition context
321
public class CustomResourceDefinitionContext {
322
public String getGroup();
323
public String getVersion();
324
public String getKind();
325
public String getPlural();
326
public boolean isNamespaceScoped();
327
}
328
```
329
330
### Exception Types
331
332
```java { .api }
333
public class KubernetesCrudDispatcherException extends Exception {
334
/**
335
* Create exception with message and HTTP status code
336
* @param message - Error message
337
* @param code - HTTP status code (400, 409, 422, etc.)
338
*/
339
public KubernetesCrudDispatcherException(String message, Integer code);
340
341
/**
342
* Create exception with detailed validation information
343
* @param message - Error message
344
* @param code - HTTP status code
345
* @param kind - Resource kind that failed validation
346
* @param requiredFields - Missing required field names
347
*/
348
public KubernetesCrudDispatcherException(String message, Integer code, String kind, String... requiredFields);
349
350
/**
351
* Get HTTP status code for the error
352
* @return HTTP status code (defaults to 400 if not specified)
353
*/
354
public int getCode();
355
356
/**
357
* Convert exception to Kubernetes Status object
358
* @return Status object with error details and field validation information
359
*/
360
public Status toStatus();
361
362
/**
363
* Convert exception to JSON Status response body
364
* @return JSON string containing Kubernetes Status object
365
*/
366
public String toStatusBody();
367
}
368
```